"""
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: vignaux $ $Revision: 462 $
# $Date: 2010-04-05 05:52:22 +0200 (Mo, 05 Apr 2010) $
|