1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
"""
jacksonnetwork_OO.py
Messages arrive randomly at rate 1.5 per second
at a communication network with 3 nodes
(computers). Each computer (node) can queue
messages. Service-times are exponential with
mean m_i at node i. These values are given in
the column headed n_i in the table below. On
completing service at node i a message transfers
to node j with probability p_ij and leaves the
system with probability p_i3.
These transition probabilities are as follows:
Node m_i p_i0 p_i1 p_i2 p_i3
i (leave)
0 1.0 0 0.5 0.5 0
1 2.0 0 0 0.8 0.2
2 1.0 0.2 0 0 0.8
Your task is to estimate
(1) the average time taken for jobs going
through the system and
(2) the average number of jobs in the system.
"""
from SimPy.Simulation import *
import random as ran
## Model components ------------------------
def choose2dA(i,P):
""" return a random choice from a set j = 0..n-1
with probs held in list of lists P[j] (n by n)
using row i
call: next = choose2d(i,P)
"""
U = ran.random()
sumP = 0.0
for j in range(len(P[i])): # j = 0..n-1
sumP += P[i][j]
if U < sumP: break
return(j)
class Msg(Process):
"""a message"""
noInSystem=0
def execute(self,i):
""" executing a message """
startTime = self.sim.now()
Msg.noInSystem += 1
##print "DEBUG noInSystm = ",Msg.noInSystem
self.sim.NoInSystem.observe(Msg.noInSystem)
self.trace("Arrived node %d"%(i,))
while i <> 3:
yield request,self,self.sim.node[i]
self.trace("Got node %d"%(i,))
st = ran.expovariate(1.0/mean[i])
yield hold,self,st
yield release,self,self.sim.node[i]
self.trace("Finished with %d"%(i,))
i = choose2dA(i,P)
self.trace("Transfer to %d"%(i,))
self.sim.TimeInSystem.tally(self.sim.now()-startTime)
self.trace( "leaving %d %d in system"%(i,Msg.noInSystem))
Msg.noInSystem -= 1
self.sim.NoInSystem.accum(Msg.noInSystem)
def trace(self,message):
if MTRACING: print "%7.4f %3d %10s"%(self.sim.now(),self.name, message)
class MsgSource(Process):
""" generates a sequence of msgs """
def execute(self,rate,maxN):
self.count=0 # hold number of messages generated
while (self.count < maxN):
self.count+=1
p = Msg("Message %d"%(self.count,),sim=self.sim)
self.sim.activate(p,p.execute(i=startNode))
yield hold,self,ran.expovariate(rate)
self.trace("generator finished with "+`self.count`+" ========")
def trace(self,message):
if GTRACING: print "%7.4f \t%s"%(self.sim.now(), message)
## Experiment data -------------------------
rate = 1.5 ## arrivals per second
maxNumber = 1000 ## of Messages
GTRACING = False ## tracing Messages Source?
startNode = 0 ## Messages always enter at node 0
ran.seed(77777)
MTRACING = False ## tracing Message action?
mean=[1.0, 2.0, 1.0] ## service times, seconds
P = [[0, 0.5, 0.5, 0 ], ## transition matrix P_ij
[0, 0, 0.8, 0.2],
[0.2, 0, 0, 0.8]]
## Model -----------------------------------
class JacksonnetworkModel(Simulation):
def run(self):
self.initialize()
self.TimeInSystem = Monitor("time",sim=self)
self.NoInSystem = Monitor("Number",sim=self)
self.node = [Resource(1,sim=self),Resource(1,sim=self),Resource(1,sim=self)]
self.g = MsgSource("MsgSource",sim=self)
self.activate(self.g,self.g.execute(rate,maxNumber))
self.simulate(until=5000.0)
## Experiment ------------------------------
modl=JacksonnetworkModel()
modl.run()
## Analysis/output -------------------------
print 'jacksonnetwork'
print "Mean number in system = %10.4f"%(modl.NoInSystem.timeAverage(),)
print "Mean delay in system = %10.4f"%(modl.TimeInSystem.mean(),)
print "Total time run = %10.4f"%(modl.now(),)
print "Total jobs arrived = %10d"%(modl.g.count)
print "Total jobs completed = %10d"%(modl.TimeInSystem.count(),)
print "Average arrival rate = %10.4f"%(modl.g.count/modl.now(),)
# $Author$ $Revision$
# $Date$
|