科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件Python:SimPy 简化了复杂模型

Python:SimPy 简化了复杂模型

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文介绍了Python的SimPy 简化了复杂模型的概念等问题

作者:IBM中国 来源:IBM中国 2007年9月15日

关键字: 软件

  • 评论
  • 分享微博
  • 分享邮件
上述代码定义了 Customer 类的操作,但我们需要在运行模拟之前,创建一些实际的顾客对象。我们可以为一天中将要购物的每位顾客生成顾客对象,并为每位顾客分配相应的付款时间。但更简洁的方法是“在每位顾客到商店时”,让工厂对象生成所需的顾客对象。实际上模拟并不会同时对一天内将要购物的所有顾客感兴趣,而是只对那些要同时争用付款通道的顾客感兴趣。注意:Customer_Factory 类本身是模拟的一部分 — 它是一个进程。尽管对于这个客户工厂,您可能联想到人造的机器工人(la Fritz Lang 的 Metropolis),但还是应该只把它看作编程的便利工具;它并不直接对应已建模域中的任何事物。

清单 4. 生成顾客流 class Customer_Factory(Simulation.Process):

def run(self):

while 1:

c = Customer()

Simulation.activate(c, c.checkout())

arrival = random.expovariate(float(AVGCUST)/CLOSING)

yield hold, self, arrival

正如我前面提到的,我想收集一些当前 SimPy Monitor 类没有解决的统计信息。也就是,我并不仅仅对平均付款时间感兴趣,而且还对给定方案中最糟糕情况感兴趣。所以我创建了一个增强的监控程序,它收集最小和最大的计数值。

用监控程序监视模拟 class Monitor2(Monitor):

def __init__(self):

Monitor.__init__(self)

self.min, self.max = (int(2**31-1),0)

def tally(self, x):

Monitor.tally(self, x)

self.min = min(self.min, x)

self.max = max(self.max, x)

我们模拟的最后一步当然是运行它。在大多数标准示例中,只运行一次模拟。但对于我的食品杂货店,我决定通过几次模拟进行循环,每次对应于某一天的业务。这看来是个好主意,因为有些统计信息会随每天的情况而有相当大的不同(因为到达的顾客人次以及所购商品数采用随机产生的不同值)。

清单 6. 每天运行模拟 for run in range(RUNS):

waittime = Monitor2()

checkouttime = Monitor2()

checkout_aisle = Simulation.Resource(AISLES)

Simulation.initialize()

cf = Customer_Factory()

Simulation.activate(cf, cf.run(), 0.0)

Simulation.simulate(until=CLOSING)

#print "Customers:", checkouttime.count()

print "Waiting time average: %.1f" % waittime.mean(), "(std dev %.1f, maximum %.1f)" % (sqrt(waittime.var()),waittime.max)

#print "Checkout time average: %1f" % checkouttime.mean(), # "(standard deviation %.1f)" % sqrt(checkouttime.var())

print 'AISLES:', AISLES, ' ITEM TIME:', ITEMTIME

三人不欢:一些结果(以及它们意味着什么)

当我最初考虑食品杂货店模型时,我认为模拟可以解答几个直接问题。例如,我想象店主可能会选择购买改进的扫描仪(减少 ITEMTIME),或者选择雇佣更多职员(增加 AISLES)。我想只要在每个方案下运行这个模拟(假设雇员和技术成本给定的情况下),并确定上面两种选择哪种更能减少成本。

只有运行了模拟后,我才意识到可能会出现比预料的更有趣的事情。查看收集的所有数据,我意识到我不知道要尝试优化的是什么。什么。例如,减少平均付款时间和减少最差情况的时间,哪个更重要?哪些方面会提高总体顾客满意度?另外,如何比较顾客在付款之前所用的等待时间以及扫描所购商品所花的时间?以我个人的经验,我会在等待的队列中感到不耐烦,但在扫描我的商品时,我不会感到很麻烦(即使这会花一些时间)。

当然,我没有经营食品杂货店,所以我不知道所有这些问题的答案。但这个模拟确实让我准确地决定什么是折衷方案;而且它很简单,足以稍作调整就可适用于许多行为(包括那些还未显式地参数化的行为 — 例如,“一整天中顾客真的会一直不断地来吗?”)。

我只要演示最后一个示例,就可以说明该模型的价值。我在上面曾写道复杂系统的行为难以概念化。我认为这里的示例可以证明这一事实。在可用的通道从 6 条减少到 5 条(其它参数不变)时,您认为会出现什么情况?最初我想会稍微增加最糟糕情况下的付款时间。而事实并非如此:

清单 7. 通道数变化前后运行的两个样本 % python Market.py

Waiting time average: 0.5 (std dev 0.9, maximum 4.5)

Waiting time average: 0.3 (std dev 0.6, maximum 3.7)

Waiting time average: 0.4 (std dev 0.8, maximum 5.6)

Waiting time average: 0.4 (std dev 0.8, maximum 5.2)

Waiting time average: 0.4 (std dev 0.8, maximum 5.8)

Waiting time average: 0.3 (std dev 0.6, maximum 5.2)

Waiting time average: 0.5 (std dev 1.1, maximum 5.2)

Waiting time average: 0.5 (std dev 1.0, maximum 5.4)

AISLES: 6  ITEM TIME: 0.1

% python Market.py

Waiting time average: 2.1 (std dev 2.3, maximum 9.5)

Waiting time average: 1.8 (std dev 2.3, maximum 10.9)

Waiting time average: 1.3 (std dev 1.7, maximum 7.3)

Waiting time average: 1.7 (std dev 2.1, maximum 9.5)

Waiting time average: 4.2 (std dev 5.6, maximum 21.3)

Waiting time average: 1.6 (std dev 2.6, maximum 12.0)

Waiting time average: 1.3 (std dev 1.6, maximum 7.5)

Waiting time average: 1.5 (std dev 2.1, maximum 11.2)

AISLES: 5  ITEM TIME: 0.1

减少一条付款通道不是使平均等待时间增加 1/5 或类似的情况,而是使它增加了大约 4 倍。而且,最不幸的顾客(在这些特定的运行期间)的等待时间从 6 分钟增加到了 21 分钟。如果我是经理,我认为了解这个极限情况对顾客满意度而言是极其重要的。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章