Commit 510e9892 authored by Georgios Dagkakis's avatar Georgios Dagkakis Committed by Sebastien Robin

version that reads from JSON

parent 6158852e
...@@ -24,6 +24,7 @@ class Assembly(Process): ...@@ -24,6 +24,7 @@ class Assembly(Process):
Process.__init__(self) Process.__init__(self)
self.id=id self.id=id
self.objName=name self.objName=name
self.type="Assembly" #String that shows the type of object
self.distType=dist #the distribution that the procTime follows self.distType=dist #the distribution that the procTime follows
self.rng=RandomNumberGenerator(self, self.distType) self.rng=RandomNumberGenerator(self, self.distType)
self.rng.avg=time[0] self.rng.avg=time[0]
...@@ -32,7 +33,11 @@ class Assembly(Process): ...@@ -32,7 +33,11 @@ class Assembly(Process):
self.rng.max=time[3] self.rng.max=time[3]
self.next=[] #list with the next objects in the flow self.next=[] #list with the next objects in the flow
self.previousPart=[] #list with the previous objects that send parts self.previousPart=[] #list with the previous objects that send parts
self.previousFrame=[] #list with the previous objects that send frames self.previousFrame=[] #list with the previous objects that send frames
self.nextIds=[] #list with the ids of the next objects in the flow
self.previousIds=[]
self.previousPartIds=[] #list with the ids of the previous objects in the flow that bring parts
self.previousFrameIds=[] #list with the ids of the previous objects in the flowthat bring frames
#lists to hold statistics of multiple runs #lists to hold statistics of multiple runs
self.Waiting=[] self.Waiting=[]
......
...@@ -17,10 +17,13 @@ class Exit(Process): ...@@ -17,10 +17,13 @@ class Exit(Process):
def __init__(self, id, name): def __init__(self, id, name):
Process.__init__(self) Process.__init__(self)
self.predecessorIndex=0 #holds the index of the predecessor from which the Exit will take an entity next
self.id=id self.id=id
self.objName=name self.objName=name
self.type="Exit" self.type="Exit"
self.previous=[] #list with the previous objects in the flow self.previous=[] #list with the previous objects in the flow
self.nextIds=[] #list with the ids of the next objects in the flow. For the exit it is always empty!
self.previousIds=[] #list with the ids of the previous objects in the flow
#lists to hold statistics of multiple runs #lists to hold statistics of multiple runs
self.Exits=[] self.Exits=[]
...@@ -49,14 +52,29 @@ class Exit(Process): ...@@ -49,14 +52,29 @@ class Exit(Process):
#checks if the Exit can accept an entity and there is an entity waiting for it #checks if the Exit can accept an entity and there is an entity waiting for it
def canAcceptAndIsRequested(self): def canAcceptAndIsRequested(self):
return self.previous[0].haveToDispose() if(len(self.previous)==1):
return self.previous[0].haveToDispose()
isRequested=False
for i in range(len(self.previous)):
if(self.previous[i].haveToDispose()):
isRequested=True
self.predecessorIndex=i
return isRequested
#gets an entity from the predecessor #gets an entity from the predecessor
def getEntity(self): def getEntity(self):
'''
#A=self.previous[0].Res.activeQ[0]
name=self.previous[0].Res.activeQ[0].name #get the name of the entity for the trace name=self.previous[0].Res.activeQ[0].name #get the name of the entity for the trace
self.totalLifespan+=now()-self.previous[0].Res.activeQ[0].startTime #Add the entity's lifespan to the total one. self.totalLifespan+=now()-self.previous[0].Res.activeQ[0].startTime #Add the entity's lifespan to the total one.
self.previous[0].removeEntity() #remove the entity from the previous object self.previous[0].removeEntity() #remove the entity from the previous object
self.outputTrace(name) #del A
'''
name=self.previous[self.predecessorIndex].Res.activeQ[0].name #get the name of the entity for the trace
self.totalLifespan+=now()-self.previous[self.predecessorIndex].Res.activeQ[0].startTime #Add the entity's lifespan to the total one.
self.previous[self.predecessorIndex].removeEntity() #remove the entity from the previous object
self.outputTrace(name)
#actions to be taken after the simulation ends #actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime): def postProcessing(self, MaxSimtime):
......
This diff is collapsed.
...@@ -3,7 +3,6 @@ Created on 8 Nov 2012 ...@@ -3,7 +3,6 @@ Created on 8 Nov 2012
@author: George @author: George
''' '''
''' '''
Models a machine that can also have failures Models a machine that can also have failures
''' '''
...@@ -44,6 +43,8 @@ class Machine(Process): ...@@ -44,6 +43,8 @@ class Machine(Process):
self.next=[] #list with the next objects in the flow self.next=[] #list with the next objects in the flow
self.previous=[] #list with the previous objects in the flow self.previous=[] #list with the previous objects in the flow
self.nextIds=[] #list with the ids of the next objects in the flow
self.previousIds=[] #list with the ids of the previous objects in the flow
self.type="Machine" #String that shows the type of object self.type="Machine" #String that shows the type of object
#lists to hold statistics of multiple runs #lists to hold statistics of multiple runs
...@@ -51,37 +52,7 @@ class Machine(Process): ...@@ -51,37 +52,7 @@ class Machine(Process):
self.Working=[] self.Working=[]
self.Blockage=[] self.Blockage=[]
self.Waiting=[] self.Waiting=[]
'''
self.Up=True #Boolean that shows if the machine is in failure ("Down") or not ("up")
self.currentEntity=None
self.totalBlockageTime=0 #holds the total blockage time
self.totalFailureTime=0 #holds the total failure time
self.totalWaitingTime=0 #holds the total waiting time
self.totalWorkingTime=0 #holds the total working time
self.completedJobs=0 #holds the number of completed jobs
self.timeLastEntityEnded=0 #holds the last time that an entity ended processing in the machine
self.nameLastEntityEnded="" #holds the name of the last entity that ended processing in the machine
self.timeLastEntityEntered=0 #holds the last time that an entity entered in the machine
self.nameLastEntityEntered="" #holds the name of the last entity that entered in the machine
self.downTimeInCurrentEntity=0 #holds the time that the machine was down while processing the current entity
self.timeLastFailure=0 #holds the time that the last failure of the machine started
self.downTimeInTryingToReleaseCurrentEntity=0 #holds the time that the machine was down while trying
#to release the current entity
self.waitToDispose=False #shows if the machine waits to dispose an entity
'''
'''
#if the failure distribution for the machine is fixed, activate the failure
if(self.failureDistType=="Fixed" or self.failureDistType=="Availability"):
MFailure=Failure(self, self.failureDistType, self.MTTF, self.MTTR, self.availability, self.id, self.repairman)
activate(MFailure,MFailure.Run())
'''
#self.initializeForRun()
def initialize(self): def initialize(self):
Process.__init__(self) Process.__init__(self)
...@@ -98,10 +69,15 @@ class Machine(Process): ...@@ -98,10 +69,15 @@ class Machine(Process):
self.nameLastEntityEnded="" #holds the name of the last entity that ended processing in the machine self.nameLastEntityEnded="" #holds the name of the last entity that ended processing in the machine
self.timeLastEntityEntered=0 #holds the last time that an entity entered in the machine self.timeLastEntityEntered=0 #holds the last time that an entity entered in the machine
self.nameLastEntityEntered="" #holds the name of the last entity that entered in the machine self.nameLastEntityEntered="" #holds the name of the last entity that entered in the machine
self.downTimeInCurrentEntity=0 #holds the time that the machine was down while processing the current entity
self.timeLastFailure=0 #holds the time that the last failure of the machine started self.timeLastFailure=0 #holds the time that the last failure of the machine started
self.timeLastFailureEnded=0 #holds the time that the last failure of the machine Ended
self.downTimeProcessingCurrentEntity=0 #holds the time that the machine was down while processing the current entity
self.downTimeInTryingToReleaseCurrentEntity=0 #holds the time that the machine was down while trying self.downTimeInTryingToReleaseCurrentEntity=0 #holds the time that the machine was down while trying
#to release the current entity #to release the current entity
self.downTimeInCurrentEntity=0 #holds the total time that the machine was down while holding current entity
self.timeLastEntityLeft=0 #holds the last time that an entity left the machine
self.processingTimeOfCurrentEntity=0 #holds the total processing time that the current entity required
self.waitToDispose=False #shows if the machine waits to dispose an entity self.waitToDispose=False #shows if the machine waits to dispose an entity
...@@ -116,7 +92,6 @@ class Machine(Process): ...@@ -116,7 +92,6 @@ class Machine(Process):
def Run(self): def Run(self):
#execute all through simulation time #execute all through simulation time
while 1: while 1:
failureTime=0
yield waituntil, self, self.canAcceptAndIsRequested #wait until the machine can accept an entity yield waituntil, self, self.canAcceptAndIsRequested #wait until the machine can accept an entity
#and one predecessor requests it #and one predecessor requests it
...@@ -129,10 +104,12 @@ class Machine(Process): ...@@ -129,10 +104,12 @@ class Machine(Process):
self.nameLastEntityEntered=self.currentEntity.name #this holds the name of the last entity that got into Machine self.nameLastEntityEntered=self.currentEntity.name #this holds the name of the last entity that got into Machine
timeEntered=now() timeEntered=now()
tinMStart=self.rng.generateNumber() #get the processing time tinMStart=self.rng.generateNumber() #get the processing time
tinM=tinMStart tinM=tinMStart
self.processingTimeOfCurrentEntity=tinMStart
interruption=False interruption=False
processingEndedFlag=True processingEndedFlag=True
failureTime=0 failureTime=0
self.downTimeInCurrentEntity=0
#this loop is repeated until the processing time is expired with no failure #this loop is repeated until the processing time is expired with no failure
...@@ -152,7 +129,9 @@ class Machine(Process): ...@@ -152,7 +129,9 @@ class Machine(Process):
breakTime=now() breakTime=now()
yield passivate,self #if there is a failure in the machine it is passivated yield passivate,self #if there is a failure in the machine it is passivated
self.downTimeProcessingCurrentEntity+=now()-breakTime
self.downTimeInCurrentEntity+=now()-breakTime self.downTimeInCurrentEntity+=now()-breakTime
self.timeLastFailureEnded=now()
failureTime+=now()-breakTime failureTime+=now()-breakTime
self.outputTrace("passivated in "+self.objName+" for "+str(now()-breakTime)) self.outputTrace("passivated in "+self.objName+" for "+str(now()-breakTime))
...@@ -165,7 +144,7 @@ class Machine(Process): ...@@ -165,7 +144,7 @@ class Machine(Process):
self.timeLastEntityEnded=now() #this holds the last time that an entity ended processing in Machine self.timeLastEntityEnded=now() #this holds the last time that an entity ended processing in Machine
self.nameLastEntityEnded=self.currentEntity.name #this holds the name of the last entity that ended processing in Machine self.nameLastEntityEnded=self.currentEntity.name #this holds the name of the last entity that ended processing in Machine
self.completedJobs+=1 #Machine completed one more Job self.completedJobs+=1 #Machine completed one more Job
self.downTimeInCurrentEntity=0 self.downTimeProcessingCurrentEntity=0
reqTime=now() #entity has ended processing in Machine and requests for the next object reqTime=now() #entity has ended processing in Machine and requests for the next object
...@@ -182,13 +161,14 @@ class Machine(Process): ...@@ -182,13 +161,14 @@ class Machine(Process):
yield waituntil, self, self.checkIfMachineIsUp yield waituntil, self, self.checkIfMachineIsUp
failureTime+=now()-failTime failureTime+=now()-failTime
self.downTimeInTryingToReleaseCurrentEntity+=now()-failTime self.downTimeInTryingToReleaseCurrentEntity+=now()-failTime
self.downTimeInCurrentEntity+=now()-failTime
self.timeLastFailureEnded=now()
totalTime=now()-timeEntered totalTime=now()-timeEntered
blockageTime=totalTime-(tinMStart+failureTime) blockageTime=totalTime-(tinMStart+failureTime)
self.totalBlockageTime+=totalTime-(tinMStart+failureTime) #the time of blockage is derived from self.totalBlockageTime+=totalTime-(tinMStart+failureTime) #the time of blockage is derived from
#the whole time in the machine #the whole time in the machine
#minus the processing time and the failure time #minus the processing time and the failure time
#sets the routing in and out elements for the queue #sets the routing in and out elements for the queue
def defineRouting(self, p, n): def defineRouting(self, p, n):
...@@ -226,6 +206,11 @@ class Machine(Process): ...@@ -226,6 +206,11 @@ class Machine(Process):
#removes an entity from the Machine #removes an entity from the Machine
def removeEntity(self): def removeEntity(self):
#the time of blockage is derived from the whole time in the machine minus the processing time and the failure time
#self.totalBlockageTime+=(now()-self.timeLastEntityEntered)-(self.processingTimeOfCurrentEntity+self.downTimeInCurrentEntity)
#print (now()-self.timeLastEntityEntered)-(self.processingTimeOfCurrentEntity+self.downTimeInCurrentEntity)
#print self.downTimeInCurrentEntity
self.timeLastEntityLeft=now()
self.outputTrace("releases "+self.objName) self.outputTrace("releases "+self.objName)
self.waitToDispose=False self.waitToDispose=False
self.Res.activeQ.pop(0) self.Res.activeQ.pop(0)
...@@ -241,6 +226,7 @@ class Machine(Process): ...@@ -241,6 +226,7 @@ class Machine(Process):
#actions to be taken after the simulation ends #actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime): def postProcessing(self, MaxSimtime):
alreadyAdded=False #a flag that shows if the blockage time has already been added alreadyAdded=False #a flag that shows if the blockage time has already been added
#if there is an entity that finished processing in a Machine but did not get to reach #if there is an entity that finished processing in a Machine but did not get to reach
...@@ -259,8 +245,8 @@ class Machine(Process): ...@@ -259,8 +245,8 @@ class Machine(Process):
if(len(self.Res.activeQ)>0) and (not (self.nameLastEntityEnded==self.nameLastEntityEntered)): if(len(self.Res.activeQ)>0) and (not (self.nameLastEntityEnded==self.nameLastEntityEntered)):
#if Machine is down we should add this last failure time to the time that it has been down in current entity #if Machine is down we should add this last failure time to the time that it has been down in current entity
if(len(self.Res.activeQ)>0) and (self.Up==False): if(len(self.Res.activeQ)>0) and (self.Up==False):
self.downTimeInCurrentEntity+=now()-self.timeLastFailure self.downTimeProcessingCurrentEntity+=now()-self.timeLastFailure
self.totalWorkingTime+=now()-self.timeLastEntityEntered-self.downTimeInCurrentEntity self.totalWorkingTime+=now()-self.timeLastEntityEntered-self.downTimeProcessingCurrentEntity
#if Machine is down we have to add this failure time to its total failure time #if Machine is down we have to add this failure time to its total failure time
#we also need to add the last blocking time to total blockage time #we also need to add the last blocking time to total blockage time
......
...@@ -22,3 +22,7 @@ class Part(object): ...@@ -22,3 +22,7 @@ class Part(object):
self.currentStop=None #contains the current object that the material is in self.currentStop=None #contains the current object that the material is in
self.creationTime=0 self.creationTime=0
self.startTime=0 #holds the startTime for the lifespan self.startTime=0 #holds the startTime for the lifespan
def __del__(self):
pass
#print self.name, now()
...@@ -3,7 +3,6 @@ Created on 8 Nov 2012 ...@@ -3,7 +3,6 @@ Created on 8 Nov 2012
@author: George @author: George
''' '''
''' '''
Models a FIFO queue where entities can wait in order to get into a server Models a FIFO queue where entities can wait in order to get into a server
''' '''
...@@ -16,6 +15,9 @@ class Queue(Process): ...@@ -16,6 +15,9 @@ class Queue(Process):
def __init__(self, id, name, capacity, dummy): def __init__(self, id, name, capacity, dummy):
Process.__init__(self) Process.__init__(self)
self.predecessorIndex=0 #holds the index of the predecessor from which the Queue will take an entity next
self.successorIndex=0 #holds the index of the successor where the Queue will dispose an entity next
self.id=id self.id=id
self.objName=name self.objName=name
self.capacity=capacity self.capacity=capacity
...@@ -24,6 +26,8 @@ class Queue(Process): ...@@ -24,6 +26,8 @@ class Queue(Process):
self.next=[] #list with the next objects in the flow self.next=[] #list with the next objects in the flow
self.previous=[] #list with the previous objects in the flow self.previous=[] #list with the previous objects in the flow
self.nextIds=[] #list with the ids of the next objects in the flow
self.previousIds=[] #list with the ids of the previous objects in the flow
self.type="Queue" #String that shows the type of object self.type="Queue" #String that shows the type of object
self.isDummy=dummy #Boolean that shows if it is the dummy first Queue self.isDummy=dummy #Boolean that shows if it is the dummy first Queue
...@@ -53,21 +57,95 @@ class Queue(Process): ...@@ -53,21 +57,95 @@ class Queue(Process):
return len(self.Q.activeQ)<self.capacity return len(self.Q.activeQ)<self.capacity
#checks if the Queue can accept an entity #checks if the Queue can accept an entity
#it checks also who called it and returns TRUE only to the predecessor that will give the entity.
#this is kind of slow I think got to check
def canAccept(self): def canAccept(self):
return len(self.Res.activeQ)<self.capacity if(len(self.previous)==1):
return len(self.Res.activeQ)<self.capacity
#checks if the Queue can dispose an entity to the following object if len(self.Res.activeQ)==self.capacity:
return False
#identify the caller method
frame = sys._getframe(1)
arguments = frame.f_code.co_argcount
if arguments == 0:
print "Not called from a method"
return
caller_calls_self = frame.f_code.co_varnames[0]
thecaller = frame.f_locals[caller_calls_self]
#return true only to the predecessor from which the queue will take
flag=False
if thecaller is self.previous[self.predecessorIndex]:
flag=True
return len(self.Res.activeQ)<self.capacity and flag
#checks if the Queue can dispose an entity to the following object
#it checks also who called it and returns TRUE only to the successor that will give the entity.
#this is kind of slow I think got to check
def haveToDispose(self): def haveToDispose(self):
return len(self.Res.activeQ)>0 if(len(self.next)==1):
return len(self.Res.activeQ)>0
#if the Queue is empty it returns false right away
if(len(self.Res.activeQ)==0):
return False
#identify the caller method
frame = sys._getframe(1)
arguments = frame.f_code.co_argcount
if arguments == 0:
print "Not called from a method"
return
caller_calls_self = frame.f_code.co_varnames[0]
thecaller = frame.f_locals[caller_calls_self]
#give the entity to the successor that is waiting for the most time.
#plant does not do this in every occasion!
maxTimeWaiting=0
for i in range(len(self.next)):
if(self.next[i].canAccept()):
timeWaiting=now()-self.next[i].timeLastEntityLeft
if(timeWaiting>maxTimeWaiting or maxTimeWaiting==0):
maxTimeWaiting=timeWaiting
self.successorIndex=i
#return true only to the predecessor from which the queue will take
flag=False
if thecaller is self.next[self.successorIndex]:
flag=True
return len(self.Res.activeQ)>0 and flag
#checks if the Queue can accept an entity and there is an entity waiting for it #checks if the Queue can accept an entity and there is an entity in some predecessor waiting for it
#also updates the predecessorIndex to the one that is to be taken
def canAcceptAndIsRequested(self): def canAcceptAndIsRequested(self):
return len(self.Res.activeQ)<self.capacity and self.previous[0].haveToDispose() if(len(self.previous)==1):
return len(self.Res.activeQ)<self.capacity and self.previous[0].haveToDispose()
isRequested=False
maxTimeWaiting=0
for i in range(len(self.previous)):
if(self.previous[i].haveToDispose()):
isRequested=True
#timeWaiting=now()-(self.previous[i].timeLastEntityEnded+self.previous[i].downTimeInTryingToReleaseCurrentEntity)
if(self.previous[i].downTimeInTryingToReleaseCurrentEntity>0):
timeWaiting=now()-self.previous[i].timeLastFailureEnded
else:
timeWaiting=now()-self.previous[i].timeLastEntityEnded
#if more than one predecessor have to dispose take the part from the one that is blocked longer
if(timeWaiting>=maxTimeWaiting): #or maxTimeWaiting==0):
self.predecessorIndex=i
maxTimeWaiting=timeWaiting
return len(self.Res.activeQ)<self.capacity and isRequested
#gets an entity from the predecessor #gets an entity from the predecessor that the predecessor index points to
def getEntity(self): def getEntity(self):
self.Res.activeQ.append(self.previous[0].Res.activeQ[0]) #get the entity from the previous object self.Res.activeQ=[self.previous[self.predecessorIndex].Res.activeQ[0]]+self.Res.activeQ #get the entity from the previous object
self.previous[0].removeEntity() #remove the entity from the previous object #and put it in front of the activeQ
self.previous[self.predecessorIndex].removeEntity() #remove the entity from the previous object
#removes an entity from the Queue (this is FIFO for now) #removes an entity from the Queue (this is FIFO for now)
def removeEntity(self): def removeEntity(self):
......
...@@ -33,7 +33,7 @@ class Repairman(object): ...@@ -33,7 +33,7 @@ class Repairman(object):
#checks if the worker is available #checks if the worker is available
def checkIfWorkerIsAvailable(self): def checkIfWorkerIsAvailable(self):
return len(self.W.activeQ)<self.capacity return len(self.W.activeQ)<self.capacity
#actions to be taken after the simulation ends #actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime): def postProcessing(self, MaxSimtime):
......
...@@ -23,6 +23,9 @@ class Source(Process): ...@@ -23,6 +23,9 @@ class Source(Process):
self.totalInterArrivalTime=0 #the total interarrival time self.totalInterArrivalTime=0 #the total interarrival time
self.numberOfArrivals=0 #the number of entities that were created self.numberOfArrivals=0 #the number of entities that were created
self.next=[] #list with the next objects in the flow self.next=[] #list with the next objects in the flow
self.nextIds=[] #list with the ids of the next objects in the flow
self.previousIds=[] #list with the ids of the previous objects in the flow. For the source it is always empty!
self.type="Source" #String that shows the type of object self.type="Source" #String that shows the type of object
#self.waitToDispose=False #self.waitToDispose=False
self.rng=RandomNumberGenerator(self, self.distType) self.rng=RandomNumberGenerator(self, self.distType)
...@@ -45,9 +48,9 @@ class Source(Process): ...@@ -45,9 +48,9 @@ class Source(Process):
#self.waitToDispose=True #self.waitToDispose=True
self.numberOfArrivals+=1 #we have one new arrival self.numberOfArrivals+=1 #we have one new arrival
#entity=Entity("Ent"+str(i)) #entity=Entity("Ent"+str(i))
entity=self.item(self.item.type+str(i)) #create the Entity object and assign its name entity=self.item(self.item.type+"_"+self.objName+"_"+str(i)) #create the Entity object and assign its name
entity.creationTime=now() #assign the current simulation time as the Entity's creation time entity.creationTime=now() #assign the current simulation time as the Entity's creation time
self.outputTrace(self.item.type+str(i)) #output the trace self.outputTrace(self.item.type+"_"+self.objName+"_"+str(i)) #output the trace
self.Res.activeQ.append(entity) #append the entity to the resource self.Res.activeQ.append(entity) #append the entity to the resource
i+=1 i+=1
#yield hold,self,self.interArrivalTime #one entity at every interArrivalTime #yield hold,self,self.interArrivalTime #one entity at every interArrivalTime
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment