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]
...@@ -33,6 +34,10 @@ class Assembly(Process): ...@@ -33,6 +34,10 @@ class Assembly(Process):
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,13 +52,28 @@ class Exit(Process): ...@@ -49,13 +52,28 @@ 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):
if(len(self.previous)==1):
return self.previous[0].haveToDispose() 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
#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) self.outputTrace(name)
#actions to be taken after the simulation ends #actions to be taken after the simulation ends
......
'''
Created on 21 Feb 2013
@author: George
'''
'''
The main script that is ran.
It reads the inputs, runs the experiments and calls the post-processing method
'''
from SimPy.Simulation import *
from Source import Source
from Globals import G
from Machine import Machine
from Exit import Exit
from Queue import Queue
from QueueLIFO import QueueLIFO
from Repairman import Repairman
from Part import Part
from Frame import Frame
from Assembly import Assembly
import xlwt
import xlrd
import time
import numpy as np
from random import Random
import sys
#read general simulation inputs
def readGeneralInput():
GeneralXL=xlrd.open_workbook('inputs/General.xls')
GeneralSheet = GeneralXL.sheet_by_index(0)
G.numberOfReplications=int(GeneralSheet.cell(1,1).value)
G.maxSimTime=GeneralSheet.cell(2,1).value
G.trace=GeneralSheet.cell(3,1).value
G.confidenceLevel=GeneralSheet.cell(4,1).value
#create the simulation objects
def createObjects():
#Read Source Data and create sources
SourceXL=xlrd.open_workbook('inputs/Source.xls')
SourceSheet = SourceXL.sheet_by_index(0)
i=1
G.SourceList=[] #a list that will hold all the sources
while(SourceSheet.cell(0,i).value!="END"):
if SourceSheet.cell(3,i).value=="Part":
S=Source(i, "S"+str(i), SourceSheet.cell(1,i).value, SourceSheet.cell(2,i).value, Part)
elif SourceSheet.cell(3,i).value=="Frame":
S=Source(i, "S"+str(i), SourceSheet.cell(1,i).value, SourceSheet.cell(2,i).value, Frame)
G.SourceList.append(S)
i+=1
G.ObjList=G.ObjList+G.SourceList #add sources also to object list
#Read Queue Data and create queues
QueueXL=xlrd.open_workbook('inputs/Queue.xls')
QueueSheet = QueueXL.sheet_by_index(0)
i=1
G.QueueList=[] #a list that will hold all the queues
while(QueueSheet.cell(0,i).value!="END"):
if QueueSheet.cell(2,i).value=="Yes":
Q=Queue(i, "Q"+str(i), int(QueueSheet.cell(1,i).value), True)
else:
Q=Queue(i, "Q"+str(i), int(QueueSheet.cell(1,i).value), False)
i+=1
G.QueueList.append(Q)
G.ObjList=G.ObjList+G.QueueList #add queues also to object list
#Read Queue Data and create QueueLifo
QueueLIFOXL=xlrd.open_workbook('inputs/QueueLIFO.xls')
QueueLIFOSheet = QueueLIFOXL.sheet_by_index(0)
i=1
G.QueueLIFOList=[] #a list that will hold all the queues
while(QueueLIFOSheet.cell(0,i).value!="END"):
if QueueLIFOSheet.cell(2,i).value=="Yes":
Q=QueueLIFO(i, "QLIFO"+str(i), int(QueueLIFOSheet.cell(1,i).value), True)
else:
Q=QueueLIFO(i, "QLIFO"+str(i), int(QueueLIFOSheet.cell(1,i).value), False)
i+=1
G.QueueLIFOList.append(Q)
G.ObjList=G.ObjList+G.QueueLIFOList #add queues also to object list
#Read Repairman Data and create repairmen
RepairmanXL=xlrd.open_workbook('inputs/Repairman.xls')
RepairmanSheet = RepairmanXL.sheet_by_index(0)
i=1
G.RepairmanList=[] #a list that will hold all the repairmen
while(RepairmanSheet.cell(0,i).value!="END"):
W=Repairman(i, "W"+str(i), RepairmanSheet.cell(1,i).value)
G.RepairmanList.append(W)
i+=1
G.ObjList=G.ObjList+G.RepairmanList #add repairmen also to object list
#Read Machine Data and create machines
MachineXL=xlrd.open_workbook('inputs/Machine.xls')
MachineSheet = MachineXL.sheet_by_index(0)
i=1
G.MachineList=[] #a list that will hold all the machines
while(MachineSheet.cell(0,i).value!="END"):
if MachineSheet.cell(11,i).value=="Yes" and len(G.RepairmanList)>0:
MR=G.RepairmanList[0]
else:
MR="None"
M=Machine(i, "M"+str(i), int(MachineSheet.cell(1,i).value), MachineSheet.cell(2,i).value, [MachineSheet.cell(3,i).value, MachineSheet.cell(4,i).value,
MachineSheet.cell(5,i).value, MachineSheet.cell(6,i).value], MachineSheet.cell(7,i).value,
MachineSheet.cell(8,i).value, MachineSheet.cell(9,i).value, MachineSheet.cell(10,i).value,
MR)
G.MachineList.append(M)
i+=1
G.ObjList=G.ObjList+G.MachineList #add machines also to object list #add sources also to object list
#Read Exit Data and create exits
ExitXL=xlrd.open_workbook('inputs/Exit.xls')
ExitSheet = ExitXL.sheet_by_index(0)
i=1
G.ExitList=[] #a list that will hold all the exits
while(ExitSheet.cell(0,i).value!="END"):
E=Exit(i, "E"+str(i))
G.ExitList.append(E)
i+=1
G.ObjList=G.ObjList+G.ExitList #add exits also to object list
#Read Assembly Data and create assemblies
AssemblyXL=xlrd.open_workbook('inputs/Assembly.xls')
AssemblySheet = AssemblyXL.sheet_by_index(0)
i=1
G.AssemblyList=[] #a list that will hold all the machines
while(AssemblySheet.cell(0,i).value!="END"):
A=Assembly(i, "A"+str(i), AssemblySheet.cell(1,i).value, [AssemblySheet.cell(2,i).value, AssemblySheet.cell(3,i).value,
AssemblySheet.cell(4,i).value, AssemblySheet.cell(5,i).value])
G.AssemblyList.append(A)
i+=1
G.ObjList=G.ObjList+G.AssemblyList #add machines also to object list #add sources also to object list
#reads the topology and defines it for the objects
def setTopology(topologyFilename):
G.TopologyList=[]
try:
TopologyXL=xlrd.open_workbook('inputs/'+topologyFilename+'.xls')
except IOError:
print "no such topology file. The programm is terminated"
sys.exit()
TopologySheet = TopologyXL.sheet_by_index(0)
i=1
while(TopologySheet.cell(i,0).value!="END"):
curList=list(str(TopologySheet.cell(i,0).value))
if curList[0]=="S":
next=str(TopologySheet.cell(i,2).value)
for j in range(len(G.ObjList)):
if G.ObjList[j].objName==next:
nextObjInd=j
G.SourceList[int(curList[1])-1].defineRouting([G.ObjList[nextObjInd]])
G.TopologyList.append(G.SourceList[int(curList[1])-1])
elif curList[0]=="Q":
previous=str(TopologySheet.cell(i,1).value)
next=str(TopologySheet.cell(i,2).value)
for j in range(len(G.ObjList)):
if G.ObjList[j].objName==previous:
previousObjInd=j
if G.ObjList[j].objName==next:
nextObjInd=j
G.QueueList[int(curList[1])-1].defineRouting([G.ObjList[previousObjInd]], [G.ObjList[nextObjInd]])
G.TopologyList.append(G.QueueList[int(curList[1])-1])
elif curList[0]=="M":
previous=str(TopologySheet.cell(i,1).value)
next=str(TopologySheet.cell(i,2).value)
for j in range(len(G.ObjList)):
if G.ObjList[j].objName==previous:
previousObjInd=j
if G.ObjList[j].objName==next:
nextObjInd=j
G.MachineList[int(curList[1])-1].defineRouting([G.ObjList[previousObjInd]], [G.ObjList[nextObjInd]])
G.TopologyList.append(G.MachineList[int(curList[1])-1])
elif curList[0]=="A":
previousPart=str(TopologySheet.cell(i,3).value)
previousFrame=str(TopologySheet.cell(i,4).value)
next=str(TopologySheet.cell(i,2).value)
for j in range(len(G.ObjList)):
if G.ObjList[j].objName==previousPart:
previousPartObjInd=j
if G.ObjList[j].objName==previousFrame:
previousFrameObjInd=j
if G.ObjList[j].objName==next:
nextObjInd=j
G.AssemblyList[int(curList[1])-1].defineRouting([G.ObjList[previousPartObjInd]], [G.ObjList[previousFrameObjInd]], [G.ObjList[nextObjInd]])
G.TopologyList.append(G.AssemblyList[int(curList[1])-1])
elif curList[0]=="E":
previous=str(TopologySheet.cell(i,1).value)
for j in range(len(G.ObjList)):
if G.ObjList[j].objName==previous:
previousObjInd=j
G.ExitList[int(curList[1])-1].defineRouting([G.ObjList[previousObjInd]])
G.TopologyList.append(G.ExitList[int(curList[1])-1])
i+=1
G.TopologyList.append(G.RepairmanList[0])
#initializes all the objects that are in the topology
def initializeObjects():
for j in range(len(G.TopologyList)):
G.TopologyList[j].initialize()
#activates all the objects
def activateObjects():
for j in range(len(G.TopologyList)):
try:
activate(G.TopologyList[j],G.TopologyList[j].Run())
except AttributeError:
pass
#the main script that is ran
def main():
topologyId=raw_input("give the topology id\n")
G.ObjList=[]
start=time.time() #start counting execution time
readGeneralInput()
createObjects()
setTopology("Topology"+topologyId)
for j in range(len(G.TopologyList)):
print G.TopologyList[j].objName
for i in range(G.numberOfReplications):
print "start run number "+str(i+1)
G.seed+=1
G.Rnd=Random(G.seed)
initialize() #initialize the simulation
initializeObjects()
activateObjects()
for j in range(len(G.TopologyList)):
pass
#print G.TopologyList[j]
simulate(until=G.maxSimTime) #start the simulation
#carry on the post processing operations for every object in the topology
for j in range(len(G.TopologyList)):
G.TopologyList[j].postProcessing(G.maxSimTime)
#output trace to excel
if(G.trace=="Yes"):
G.traceFile.save('trace'+str(i+1)+'.xls')
G.traceIndex=0 #index that shows in what row we are
G.sheetIndex=1 #index that shows in what sheet we are
G.traceFile = xlwt.Workbook() #create excel file
G.traceSheet = G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True) #create excel sheet
G.outputSheet.write(G.outputIndex,0, "Execution Time")
G.outputSheet.write(G.outputIndex,1, str(time.time()-start)+" seconds")
G.outputIndex+=2
#output data to excel for every object in the topology
for j in range(len(G.TopologyList)):
G.TopologyList[j].outputResultsXL(G.maxSimTime)
G.outputFile.save("output.xls")
print "execution time="+str(time.time()-start)
if __name__ == '__main__': main()
\ No newline at end of file
...@@ -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
...@@ -53,36 +54,6 @@ class Machine(Process): ...@@ -53,36 +54,6 @@ class Machine(Process):
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)
self.Up=True #Boolean that shows if the machine is in failure ("Down") or not ("up") self.Up=True #Boolean that shows if the machine is in failure ("Down") or not ("up")
...@@ -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
...@@ -130,9 +105,11 @@ class Machine(Process): ...@@ -130,9 +105,11 @@ class Machine(Process):
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,7 +161,8 @@ class Machine(Process): ...@@ -182,7 +161,8 @@ 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)
...@@ -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):
if(len(self.previous)==1):
return len(self.Res.activeQ)<self.capacity return len(self.Res.activeQ)<self.capacity
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 #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):
if(len(self.next)==1):
return len(self.Res.activeQ)>0 return len(self.Res.activeQ)>0
#checks if the Queue can accept an entity and there is an entity waiting for it #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 in some predecessor waiting for it
#also updates the predecessorIndex to the one that is to be taken
def canAcceptAndIsRequested(self): def canAcceptAndIsRequested(self):
if(len(self.previous)==1):
return len(self.Res.activeQ)<self.capacity and self.previous[0].haveToDispose() return len(self.Res.activeQ)<self.capacity and self.previous[0].haveToDispose()
#gets an entity from the predecessor 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 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):
......
...@@ -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