__doc__=""" bank11_OO.py: Simulate customers arriving
at random, using a Source, requesting service
from two counters each with their own queue
random servicetime.
Uses a Monitor object to record waiting times
"""
from SimPy.Monitor import *
from SimPy.Simulation import *
from random import Random
from SimPy.SimGUI import *
class Source(Process):
""" Source generates customers randomly"""
def __init__(self,sim,seed=333):
Process.__init__(self,sim=sim)
self.SEED = seed
def generate(self,number,interval):
rv = Random(self.SEED)
for i in range(number):
c = Customer(name = "Customer%02d"%(i,),sim=self.sim)
self.sim.activate(c,c.visit(timeInBank=12.0))
t = rv.expovariate(1.0/interval)
yield hold,self,t
def NoInSystem(R):
""" The number of customers in the resource R
in waitQ and active Q"""
return (len(R.waitQ)+len(R.activeQ))
class Customer(Process):
""" Customer arrives, is served and leaves """
#~ def __init__(self,name,sim):
#~ Process.__init__(self,name=name,sim=sim)
def visit(self,timeInBank=0):
arrive = self.sim.now()
Qlength = [NoInSystem(self.sim.counter[i]) for i in range(self.sim.Nc)]
if gui.params.trace:
gui.writeConsole("%7.4f %s: Here I am. Queues are: %s"%(self.sim.now(),self.name,Qlength))
for i in range(self.sim.Nc):
if Qlength[i] ==0 or Qlength[i]==min(Qlength): join =i ; break
yield request,self,self.sim.counter[join]
wait = self.sim.now()-arrive
self.sim.waitMonitor.observe(wait,t=self.sim.now())
if gui.params.trace:
gui.writeConsole("%7.4f %s: Waited %6.3f"%(self.sim.now(),self.name,wait))
tib = self.sim.counterRV.expovariate(1.0/timeInBank)
yield hold,self,tib
yield release,self,self.sim.counter[join]
if gui.params.trace:
gui.writeConsole("%7.4f %s: Finished "%(self.sim.now(),self.name))
class CounterModel(Simulation):
def run(self,counterseed=3939393):
self.initialize()
self.Nc = 2
self.counter = [Resource(name="Clerk0",sim=self),Resource(name="Clerk1",sim=self)]
self.counterRV = Random(counterseed)
gui.mon1 = self.waitMonitor = Monitor("Customer waiting times",sim=self)
self.waitMonitor.tlab="arrival time"
self.waitMonitor.ylab="waiting time"
source = Source(seed = gui.params.sourceseed,sim=self)
self.activate(source,source.generate(gui.params.numberCustomers
,gui.params.interval),0.0)
result = self.simulate(until=gui.params.endtime)
gui.writeStatusLine(text="Time at simulation end: %.1f -- Customers still waiting: %s"
%(self.now(),len(self.counter[0].waitQ)+len(self.counter[1].waitQ)))
def statistics():
if gui.noRunYet:
showwarning(title='Model warning',
message="Run simulation first -- no data available.")
return
gui.writeConsole(text="\nRun parameters: %s"%gui.params)
gui.writeConsole(text="Average wait for %4d customers was %6.2f"%
(gui.mon1.count(), gui.mon1.mean()))
def run():
CounterModel().run(gui.params.counterseed)
gui.noRunYet = False
def showAuthors():
gui.showTextBox(text="Tony Vignaux\nKlaus Muller",title="Author information")
class MyGUI(SimGUI):
def __init__(self,win,**p):
SimGUI.__init__(self,win,**p)
self.help.add_command(label="Author(s)",
command=showAuthors,underline=0)
self.view.add_command(label="Statistics",
command=statistics,underline=0)
self.run.add_command(label="Run bank11 model",
command=run,underline=0)
self.params=Parameters(
endtime=2000,
sourceseed=1133,
counterseed=3939393,
numberCustomers=50,
interval=10.0,
trace=0)
root=Tk()
gui=MyGUI(root,title="SimPy GUI example",doc=__doc__,consoleHeight=40)
gui.mainloop()
|