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):
Process.__init__(self)
self.id=id
self.objName=name
self.type="Assembly" #String that shows the type of object
self.distType=dist #the distribution that the procTime follows
self.rng=RandomNumberGenerator(self, self.distType)
self.rng.avg=time[0]
......@@ -32,7 +33,11 @@ class Assembly(Process):
self.rng.max=time[3]
self.next=[] #list with the next objects in the flow
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
self.Waiting=[]
......
......@@ -17,10 +17,13 @@ class Exit(Process):
def __init__(self, id, name):
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.objName=name
self.type="Exit"
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
self.Exits=[]
......@@ -49,14 +52,29 @@ class Exit(Process):
#checks if the Exit can accept an entity and there is an entity waiting for it
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
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
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.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
def postProcessing(self, MaxSimtime):
......
This diff is collapsed.
......@@ -3,7 +3,6 @@ Created on 8 Nov 2012
@author: George
'''
'''
Models a machine that can also have failures
'''
......@@ -44,6 +43,8 @@ class Machine(Process):
self.next=[] #list with the next 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
#lists to hold statistics of multiple runs
......@@ -51,37 +52,7 @@ class Machine(Process):
self.Working=[]
self.Blockage=[]
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):
Process.__init__(self)
......@@ -98,10 +69,15 @@ class Machine(Process):
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.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
#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
......@@ -116,7 +92,6 @@ class Machine(Process):
def Run(self):
#execute all through simulation time
while 1:
failureTime=0
yield waituntil, self, self.canAcceptAndIsRequested #wait until the machine can accept an entity
#and one predecessor requests it
......@@ -129,10 +104,12 @@ class Machine(Process):
self.nameLastEntityEntered=self.currentEntity.name #this holds the name of the last entity that got into Machine
timeEntered=now()
tinMStart=self.rng.generateNumber() #get the processing time
tinM=tinMStart
tinM=tinMStart
self.processingTimeOfCurrentEntity=tinMStart
interruption=False
processingEndedFlag=True
failureTime=0
failureTime=0
self.downTimeInCurrentEntity=0
#this loop is repeated until the processing time is expired with no failure
......@@ -152,7 +129,9 @@ class Machine(Process):
breakTime=now()
yield passivate,self #if there is a failure in the machine it is passivated
self.downTimeProcessingCurrentEntity+=now()-breakTime
self.downTimeInCurrentEntity+=now()-breakTime
self.timeLastFailureEnded=now()
failureTime+=now()-breakTime
self.outputTrace("passivated in "+self.objName+" for "+str(now()-breakTime))
......@@ -165,7 +144,7 @@ class Machine(Process):
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.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
......@@ -182,13 +161,14 @@ class Machine(Process):
yield waituntil, self, self.checkIfMachineIsUp
failureTime+=now()-failTime
self.downTimeInTryingToReleaseCurrentEntity+=now()-failTime
self.downTimeInCurrentEntity+=now()-failTime
self.timeLastFailureEnded=now()
totalTime=now()-timeEntered
blockageTime=totalTime-(tinMStart+failureTime)
self.totalBlockageTime+=totalTime-(tinMStart+failureTime) #the time of blockage is derived from
#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
def defineRouting(self, p, n):
......@@ -226,6 +206,11 @@ class Machine(Process):
#removes an entity from the Machine
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.waitToDispose=False
self.Res.activeQ.pop(0)
......@@ -241,6 +226,7 @@ class Machine(Process):
#actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime):
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
......@@ -259,8 +245,8 @@ class Machine(Process):
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(len(self.Res.activeQ)>0) and (self.Up==False):
self.downTimeInCurrentEntity+=now()-self.timeLastFailure
self.totalWorkingTime+=now()-self.timeLastEntityEntered-self.downTimeInCurrentEntity
self.downTimeProcessingCurrentEntity+=now()-self.timeLastFailure
self.totalWorkingTime+=now()-self.timeLastEntityEntered-self.downTimeProcessingCurrentEntity
#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
......
......@@ -22,3 +22,7 @@ class Part(object):
self.currentStop=None #contains the current object that the material is in
self.creationTime=0
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
@author: George
'''
'''
Models a FIFO queue where entities can wait in order to get into a server
'''
......@@ -16,6 +15,9 @@ class Queue(Process):
def __init__(self, id, name, capacity, dummy):
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.objName=name
self.capacity=capacity
......@@ -24,6 +26,8 @@ class Queue(Process):
self.next=[] #list with the next 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.isDummy=dummy #Boolean that shows if it is the dummy first Queue
......@@ -53,21 +57,95 @@ class Queue(Process):
return len(self.Q.activeQ)<self.capacity
#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):
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):
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):
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):
self.Res.activeQ.append(self.previous[0].Res.activeQ[0]) #get the entity from the previous object
self.previous[0].removeEntity() #remove 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
#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)
def removeEntity(self):
......
......@@ -33,7 +33,7 @@ class Repairman(object):
#checks if the worker is available
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
def postProcessing(self, MaxSimtime):
......
......@@ -23,6 +23,9 @@ class Source(Process):
self.totalInterArrivalTime=0 #the total interarrival time
self.numberOfArrivals=0 #the number of entities that were created
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.waitToDispose=False
self.rng=RandomNumberGenerator(self, self.distType)
......@@ -45,9 +48,9 @@ class Source(Process):
#self.waitToDispose=True
self.numberOfArrivals+=1 #we have one new arrival
#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
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
i+=1
#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