Commit e8834d6a authored by Ioannis Papagiannopoulos's avatar Ioannis Papagiannopoulos Committed by Jérome Perrin

Topology18 corrected - agreement with ulbranch, corresponding corrections to Objects

parent 6568104c
......@@ -125,12 +125,11 @@ def setWIP(entityList):
# if the entity is of type Job/OrderComponent/Order
elif entity.type=='Job' or 'OrderComponent' or 'Order':
# find the list of starting station of the entity
objects=entity.remainingRoute[0].get('stationIdsList',[])
# # # # # # object=findObjectById(entity.remainingRoute[0][0]) # find the object in the 'G.ObjList'
currentObjectIds=entity.remainingRoute[0].get('stationIdsList',[])
# if the list of starting stations has length greater than one then there is a starting WIP definition error
try:
if len(objects)==1:
objectId=objects[0]
if len(currentObjectIds)==1:
objectId=currentObjectIds[0]
else:
raise SetWipTypeError('The starting station of the the entity is not defined uniquely')
except SetWipTypeError as setWipError:
......@@ -146,10 +145,17 @@ def setWIP(entityList):
for nextObjectId in nextObjectIds:
nextObject=findObjectById(nextObjectId)
nextObjects.append(nextObject)
# update the receiver of the object
# update the receiver and the next list of the object
object.next=nextObjects
object.receiver = object.updateReceiverObject()
# # # # # # object.receiver=findObjectById(entity.remainingRoute[1][0])
maxTimeWaiting=0 # dummy variable counting the time a successor is waiting
for nextObject in object.next:
if(nextObject.canAccept(object)): # if a successor can accept an object
timeWaiting=now()-nextObject.timeLastEntityLeft # the time it has been waiting is updated and stored in dummy variable timeWaiting
if(timeWaiting>maxTimeWaiting or maxTimeWaiting==0):# if the timeWaiting is the maximum among the ones of the successors
maxTimeWaiting=timeWaiting
object.receiver=nextObject # set the receiver as the longest waiting possible receiver
# in the next loops, check the other successors in the previous list
entity.remainingRoute.pop(0) # remove data from the remaining route.
entity.schedule.append([object,now()]) #append the time to schedule so that it can be read in the result
entity.currentStation=object # update the current station of the entity
......
......@@ -34,7 +34,9 @@
"route": [
{
"stepNumber": "0",
"stationId": "Q1",
"stationIdsList": [
"Q1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
......@@ -42,7 +44,9 @@
},
{
"stepNumber": "1",
"stationId": "M1",
"stationIdsList": [
"M1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "1"
......@@ -50,7 +54,9 @@
},
{
"stepNumber": "2",
"stationId": "Q3",
"stationIdsList": [
"Q3"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
......@@ -58,7 +64,9 @@
},
{
"stepNumber": "3",
"stationId": "M3",
"stationIdsList": [
"M3"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "3"
......@@ -66,7 +74,9 @@
},
{
"stepNumber": "4",
"stationId": "Q2",
"stationIdsList": [
"Q2"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
......@@ -74,7 +84,9 @@
},
{
"stepNumber": "5",
"stationId": "M2",
"stationIdsList": [
"M2"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "2"
......@@ -82,7 +94,9 @@
},
{
"stepNumber": "6",
"stationId": "E1",
"stationIdsList": [
"E1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
......
......@@ -805,14 +805,6 @@ def createWIP():
for routeentity in JSONRoute: # for each 'step' dictionary in the JSONRoute
stepNumber=int(routeentity.get('stepNumber', '0')) # get the stepNumber
routeentity.pop('stepNumber',None) # remove the stepNumber key from the dict
# nextIds=routeentity.get('stationIdsList', []) # the stationId
# processingTime=routeentity['processingTime'] # and the 'processingTime' dictionary
# distributionType=processingTime.get('distributionType', 'not found')# and from that dictionary
# # get the 'mean'
# mean=float(processingTime.get('mean', 'not found'))
# route[stepNumber]=[nextIds, mean] # finally add the 'nextId' and 'mean'
# # to the job route
route[stepNumber]=routeentity
# keep a reference of all extra properties passed to the job
......@@ -863,14 +855,6 @@ def createWIP():
for routeentity in JSONRoute: # for each 'step' dictionary in the JSONRoute
stepNumber=int(routeentity.get('stepNumber', '0')) # get the stepNumber
routeentity.pop('stepNumber',None) # remove the stepNumber key
# nextIds=routeentity.get('stationIdsList', []) # the stationId
# processingTime=routeentity['processingTime'] # and the 'processingTime' dictionary
# distributionType=processingTime.get('distributionType', 'not found')# and from that dictionary
# # get the 'mean'
# mean=float(processingTime.get('mean', 'not found'))
# route[stepNumber]=[nextIds, mean] # finally add the 'nextId' and 'mean'
# # to the job route
route[stepNumber]=routeentity
# keep a reference of all extra properties passed to the job
......@@ -943,14 +927,6 @@ def createWIP():
for routeentity in JSONRoute: # for each 'step' dictionary in the JSONRoute
stepNumber=int(routeentity.get('stepNumber', '0')) # get the stepNumber
routeentity.pop('stepNumber',None) # remove the stepNumber key
# nextIds=routeentity.get('stationIdsList', []) # the stationId
# processingTime=routeentity['processingTime'] # and the 'processingTime' dictionary
# distributionType=processingTime.get('distributionType', 'not found')# and from that dictionary
# # get the 'mean'
# mean=float(processingTime.get('mean', 'not found'))
# route[stepNumber]=[nextIds, mean] # finally add the 'nextId' and 'mean'
# # to the job route
route[stepNumber]=routeentity
# keep a reference of all extra properties passed to the job
......
......@@ -100,11 +100,6 @@ class Machine(CoreObject):
self.downTimeInCurrentEntity=0 #holds the total time that the
#object was down while holding current entity
print '++++++++++++++++++++++++++++++++++++'
print 'time', now()
print 'object', self.objName, 'got entity', self.currentEntity.name
print '++++++++++++++++++++++++++++++++++++'
# this loop is repeated until the processing time is expired with no failure
# check when the processingEndedFlag switched to false
while processingNotFinished:
......@@ -131,7 +126,6 @@ class Machine(CoreObject):
# it seems to be random which happens 1st
# this should not appear often to stochastic models though where times are random
interruption=True
print 'interruption'
# passivate the Machine for as long as there is no repair
# start counting the down time at breatTime dummy variable
breakTime=now() # dummy variable that the interruption happened
......@@ -146,25 +140,16 @@ class Machine(CoreObject):
#if during the interruption the object became empty break
if (len(self.getActiveObjectQueue())==0 and self.shouldPreempt):
print 'preemption'
break
# if no interruption occurred the processing in M1 is ended
else:
processingNotFinished=False
print 'processing finished'
#if during the interruption the object became empty continue
if (len(self.getActiveObjectQueue())==0 and self.shouldPreempt):
self.shouldPreempt=False
self.totalWorkingTime+=now()-(self.timeLastEntityEntered)
continue
print '////////////////////////////////////'
print 'time', now()
print 'object', self.objName, 'processed', self.currentEntity.name
print '////////////////////////////////////'
continue
# output to trace that the processing in the Machine self.objName ended
try:
......@@ -176,9 +161,7 @@ class Machine(CoreObject):
# update the total working time
self.totalWorkingTime+=self.totalProcessingTimeInCurrentEntity # the total processing time for this entity
# is what the distribution initially gave
# update the variables keeping track of Entity related attributes of the machine
self.timeLastEntityEnded=now() # this holds the time that the last entity ended processing in Machine
self.nameLastEntityEnded=self.currentEntity.name # this holds the name of the last entity that ended processing in Machine
......
......@@ -29,25 +29,28 @@ from SimPy.Simulation import Process, Resource
from SimPy.Simulation import activate, passivate, waituntil, now, hold
from Machine import Machine
#the MachineJobShop object
# ===========================================================================
# the MachineJobShop object
# ===========================================================================
class MachineJobShop(Machine):
#set all the objects in previous and next
# =======================================================================
# set all the objects in previous and next
# =======================================================================
def initialize(self):
from Globals import G
self.previous=G.ObjList
self.next=G.ObjList
Machine.initialize(self) #run default behaviour
#gets an entity from the predecessor that the predecessor index points to
# =======================================================================
# gets an entity from the predecessor that the predecessor index points to
# =======================================================================
def getEntity(self):
activeEntity=Machine.getEntity(self) #run the default code
# read the processing time from the corresponding remainingRoute entry
processingTime=activeEntity.remainingRoute[0]['processingTime']
self.distType=processingTime.get('distributionType','not found')
self.procTime=processingTime.get('mean', 0)
self.procTime=float(processingTime.get('mean', 0))
# self.procTime=activeEntity.remainingRoute[0][1] #read the processing time from the entity
import Globals
# read the list of next stations
......@@ -61,35 +64,65 @@ class MachineJobShop(Machine):
# self.receiver=Globals.findObjectById(activeEntity.remainingRoute[1][0]) #read the next station
activeEntity.remainingRoute.pop(0) #remove data from the remaining route of the entity
return activeEntity
#calculates the processing time
# =======================================================================
# calculates the processing time
# =======================================================================
def calculateProcessingTime(self):
return self.procTime #this is the processing time for this unique entity
#checks if the Queue can accept an entity
#it checks also the next station of the Entity and returns true only if the active object is the next station
# =======================================================================
# checks if the Queue can accept an entity
# it checks also the next station of the Entity
# and returns true only if the active object is the next station
# =======================================================================
def canAccept(self, callerObject=None):
if callerObject!=None:
#check it the caller object holds an Entity that requests for current object
if len(callerObject.getActiveObjectQueue())>0:
activeEntity=callerObject.getActiveObjectQueue()[0]
# if the machine's Id is in the list of the entity's next stations
if self.id in activeEntity.remainingRoute[0].get('stationIdsList',[]):
if self.id in activeEntity.remainingRoute[1].get('stationIdsList',[]):
# if activeEntity.remainingRoute[0][0]==self.id:
return len(self.getActiveObjectQueue())<self.capacity #return according to the state of the Queue
return False
#checks if the Machine can dispose an entity. Returns True only to the potential receiver
# =======================================================================
# checks if the Machine can dispose an entity.
# Returns True only to the potential receiver
# =======================================================================
def haveToDispose(self, callerObject=None):
# get active object and its queue
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
# find the receiver waiting the most
activeObject.receiver=activeObject.updateReceiverObject()
thecaller = callerObject
#if we have only one successor just check if machine waits to dispose and also is up
# this is done to achieve better (cpu) processing time
if(len(activeObject.next)==1 or callerObject==None):
activeObject.receiver=activeObject.next[0]
return len(activeObjectQueue)>0\
and activeObject.waitToDispose\
and activeObject.Up\
and thecaller==activeObject.receiver
thecaller=callerObject
# give the entity to the successor that is waiting for the most time.
# (plant simulation does not do this in every occasion!)
maxTimeWaiting=0 # dummy variable counting the time a successor is waiting
for object in activeObject.next:
if(object.canAccept(activeObject)): # if a successor can accept an object
timeWaiting=now()-object.timeLastEntityLeft # the time it has been waiting is updated and stored in dummy variable timeWaiting
if(timeWaiting>maxTimeWaiting or maxTimeWaiting==0):# if the timeWaiting is the maximum among the ones of the successors
maxTimeWaiting=timeWaiting
activeObject.receiver=object # set the receiver as the longest waiting possible receiver
# in the next loops, check the other successors in the previous list
#return True if the Machine in the state of disposing and the caller is the receiver
return len(activeObjectQueue)>0 and activeObject.waitToDispose\
and activeObject.Up and (callerObject is self.receiver)
return len(activeObjectQueue)>0\
and activeObject.waitToDispose\
and activeObject.Up\
and (thecaller is self.receiver)
\ No newline at end of file
......@@ -234,7 +234,7 @@ class Queue(CoreObject):
RPT=0
for step in entity.remainingRoute:
processingTime=step['processingTime']
RPT+=processingTime.get('mean',0)
RPT+=float(processingTime.get('mean',0))
# RPT+=step[1]
entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: x.remainingProcessingTime, reverse=True)
......@@ -243,7 +243,7 @@ class Queue(CoreObject):
for entity in activeObjectQ:
LPT=0
processingTime = entity.remainingRoute[0]['processingTime']
entity.processingTimeInNextStation=processingTime.get('mean',0)
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
# entity.processingTimeInNextStation=entity.remainingRoute[0][1]
activeObjectQ.sort(key=lambda x: x.processingTimeInNextStation, reverse=True)
#if the schedulingRule is to sort Entities according to shortest processing time first in the next station
......@@ -251,7 +251,7 @@ class Queue(CoreObject):
for entity in activeObjectQ:
LPT=0
processingTime = entity.remainingRoute[0]['processingTime']
entity.processingTimeInNextStation=processingTime.get('mean',0)
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
# entity.processingTimeInNextStation=entity.remainingRoute[0][1]
activeObjectQ.sort(key=lambda x: x.processingTimeInNextStation)
#if the schedulingRule is to sort Entities based on the minimum slackness
......@@ -260,7 +260,7 @@ class Queue(CoreObject):
RPT=0
for step in entity.remainingRoute:
processingTime=step['processingTime']
RPT+=processingTime.get('mean',0)
RPT+=float(processingTime.get('mean',0))
# RPT+=step[1]
entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: (x.dueDate-x.remainingProcessingTime))
......
......@@ -30,53 +30,80 @@ from SimPy.Simulation import activate, passivate, waituntil, now, hold
from Queue import Queue
#the QueueJobShop object
# ===========================================================================
# the QueueJobShop object
# ===========================================================================
class QueueJobShop(Queue):
#set all the objects in previous and next
# =======================================================================
# set all the objects in previous and next
# =======================================================================
def initialize(self):
from Globals import G
self.previous=G.ObjList
self.next=G.ObjList
Queue.initialize(self) #run default behaviour
#checks if the Queue can accept an entity
#it checks also the next station of the Entity and returns true only if the active object is the next station
# =======================================================================
# checks if the Queue can accept an entity
# it checks also the next station of the Entity
# and returns true only if the active object is the next station
# =======================================================================
def canAccept(self, callerObject=None):
if callerObject!=None:
#check it the caller object holds an Entity that requests for current object
if len(callerObject.getActiveObjectQueue())>0:
activeEntity=callerObject.getActiveObjectQueue()[0]
# check if the object in the active entity's route next step
if self.id in activeEntity.remainingRoute[0].get('stationIdsList',[]):
if self.id in activeEntity.remainingRoute[1].get('stationIdsList',[]):
# if activeEntity.remainingRoute[0][0]==self.id:
return len(self.getActiveObjectQueue())<self.capacity #return according to the state of the Queue
return False
#checks if the Machine can dispose an entity. Returns True only to the potential receiver
# =======================================================================
# checks if the Machine can dispose an entity.
# Returns True only to the potential receiver
# =======================================================================
def haveToDispose(self, callerObject=None):
# get active object and its queue
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
# update the receiver object
activeObject.receiver=activeObject.updateReceiverObject()
thecaller = callerObject
#if we have only one possible receiver just check if the Queue holds one or more entities
if(len(activeObject.next)==1 or callerObject==None):
activeObject.receiver=activeObject.next[0]
return len(activeObjectQueue)>0\
and thecaller==activeObject.receiver
#give the entity to the possible receiver that is waiting for the most time.
#plant does not do this in every occasion!
maxTimeWaiting=0
# loop through the object in the successor list
for object in activeObject.next:
if(object.canAccept()): # if the object can accept
timeWaiting=now()-object.timeLastEntityLeft # compare the time that it has been waiting
if(timeWaiting>maxTimeWaiting or maxTimeWaiting==0):# with the others'
maxTimeWaiting=timeWaiting
self.receiver=object # and update the receiver to the index of this object
#return True if the Queue has Entities and the caller is the receiver
return len(activeObjectQueue)>0 and (callerObject is self.receiver)
return len(activeObjectQueue)>0 and (thecaller is self.receiver)
#gets an entity from the predecessor that the predecessor index points to
# =======================================================================
# gets an entity from the predecessor that the predecessor index points to
# =======================================================================
def getEntity(self):
activeObject = self.getActiveObject()
activeEntity=Queue.getEntity(self)
import Globals
# read the possible receivers - update the next list
import Globals
nextObjectIds=activeEntity.remainingRoute[1].get('stationIdsList',[])
nextObjects = []
for nextObjectId in nextObjectIds:
nextObject = Globals.findObjectById(nextObjectId)
nextObjects.append(nextObject)
activeObject.next = nextObjects
# self.next=Globals.findObjectById(activeEntity.remainingRoute[1].get('stationIdsList',[]))
# self.receiver=Globals.findObjectById(activeEntity.remainingRoute[1][0]) #read the next station
activeEntity.remainingRoute.pop(0) #remove data from the remaining route of the entity
return activeEntity
......
......@@ -13,59 +13,73 @@
"extraPropertyDict": {
"route": [
{
"stationIdsList": [
"Q1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
},
"stationId": "Q1",
"stepNumber": "0"
},
{
"stationIdsList": [
"M1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "1"
},
"stationId": "M1",
"stepNumber": "1"
},
{
"stationIdsList": [
"Q3"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
},
"stationId": "Q3",
"stepNumber": "2"
},
{
"stationIdsList": [
"M3"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "3"
},
"stationId": "M3",
"stepNumber": "3"
},
{
"stationIdsList": [
"Q2"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
},
"stationId": "Q2",
"stepNumber": "4"
},
{
"stationIdsList": [
"M2"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "2"
},
"stationId": "M2",
"stepNumber": "5"
},
{
"stationIdsList": [
"E1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
},
"stationId": "E1",
"stepNumber": "6"
}
],
......
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