SimPy
想用Python写一个仿真程序,网上的中文资料很少,比较完整的是IBM的这篇技术文章:
英文原版:Charming Python: SimPy simplifies complex models
中文版:可爱的 Python: SimPy 简化了复杂模型
本来是不错的文章,但是由于写的比较早(2002年12月26日),很多语句的用法在新版中发生了很大的变化。搞了一个晚上,程序勉强调通,但是那个记录最大最小时间的问题一直解决不了。实在搞不下去了,就到SimPy自带的doc中扒扒,没想到这个例子已经被收入正式的发行包中。具体位置在:/usr/share/doc/python-simpy-doc/SimPyModels/Market.py,如果是windows用户,请自己查找Market.py文件,应该是有的。
教训啊教训。
附Market.py原文:
from SimPy.Simulation import *
import random
from math import sqrt
AISLES = 6 # Number of open aisles
ITEMTIME = 0.1 # Time to ring up one item
AVGITEMS = 20 # Average number of items purchased
CLOSING = 60*12 # Minutes from store open to store close
AVGCUST = 1500 # Average number of daily customers
RUNS = 8 # Number of times to run the simulation
SEED = 111333555 # seed value for random numbers
class Customer(Process):
def __init__(self):
Process.__init__(self)
# Randomly pick how many items this customer is buying
self.items = 1 + int(random.expovariate(1.0/AVGITEMS))
def checkout(self):
start = now() # Customer decides to check out
yield request, self, checkout_aisle
at_checkout = now() # Customer gets to front of line
waittime.tally(at_checkout-start)
yield hold, self, self.items*ITEMTIME
leaving = now() # Customer completes purchase
checkouttime.tally(leaving-at_checkout)
yield release, self, checkout_aisle
class Customer_Factory(Process):
def run(self):
while 1:
c = Customer()
activate(c, c.checkout())
arrival = random.expovariate(float(AVGCUST)/CLOSING)
yield hold, self, arrival
class Monitor2(Monitor):
def __init__(self):
Monitor.__init__(self)
self.min, self.max = (int(2**31-1),0)
def tally(self, x):
self.observe(x)
self.min = min(self.min, x)
self.max = max(self.max, x)
random.seed(SEED)
print ‘Market’
for run in range(RUNS):
waittime = Monitor2()
checkouttime = Monitor2()
checkout_aisle = Resource(AISLES)
initialize()
cf = Customer_Factory()
activate(cf, cf.run(), 0.0)
simulate(until=CLOSING)
print “Waiting time average: %.1f“ % waittime.mean(), \
“(std dev %.1f, maximum %.1f)” % (sqrt(waittime.var()),waittime.max)
print ‘AISLES:’, AISLES, ‘ ITEM TIME:’, ITEMTIME
import random
from math import sqrt
AISLES = 6 # Number of open aisles
ITEMTIME = 0.1 # Time to ring up one item
AVGITEMS = 20 # Average number of items purchased
CLOSING = 60*12 # Minutes from store open to store close
AVGCUST = 1500 # Average number of daily customers
RUNS = 8 # Number of times to run the simulation
SEED = 111333555 # seed value for random numbers
class Customer(Process):
def __init__(self):
Process.__init__(self)
# Randomly pick how many items this customer is buying
self.items = 1 + int(random.expovariate(1.0/AVGITEMS))
def checkout(self):
start = now() # Customer decides to check out
yield request, self, checkout_aisle
at_checkout = now() # Customer gets to front of line
waittime.tally(at_checkout-start)
yield hold, self, self.items*ITEMTIME
leaving = now() # Customer completes purchase
checkouttime.tally(leaving-at_checkout)
yield release, self, checkout_aisle
class Customer_Factory(Process):
def run(self):
while 1:
c = Customer()
activate(c, c.checkout())
arrival = random.expovariate(float(AVGCUST)/CLOSING)
yield hold, self, arrival
class Monitor2(Monitor):
def __init__(self):
Monitor.__init__(self)
self.min, self.max = (int(2**31-1),0)
def tally(self, x):
self.observe(x)
self.min = min(self.min, x)
self.max = max(self.max, x)
random.seed(SEED)
print ‘Market’
for run in range(RUNS):
waittime = Monitor2()
checkouttime = Monitor2()
checkout_aisle = Resource(AISLES)
initialize()
cf = Customer_Factory()
activate(cf, cf.run(), 0.0)
simulate(until=CLOSING)
print “Waiting time average: %.1f“ % waittime.mean(), \
“(std dev %.1f, maximum %.1f)” % (sqrt(waittime.var()),waittime.max)
print ‘AISLES:’, AISLES, ‘ ITEM TIME:’, ITEMTIME