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

Operator clean-up. New methods introduced (sortEntities - sortStations)....

Operator clean-up. New methods introduced (sortEntities - sortStations). Methods moved to OperatorManagedJob (findCandidateEntities - findCandidateEntity etc).
parent 0eaf237f
...@@ -119,19 +119,7 @@ class Operator(ObjectResource): ...@@ -119,19 +119,7 @@ class Operator(ObjectResource):
def isAssignedTo(self): def isAssignedTo(self):
return self.operatorAssignedTo return self.operatorAssignedTo
#===========================================================================
# check whether the operator has only one candidateStation to work for
#===========================================================================
def hasOneOption(self):
return len(self.candidateStations)==1
#=======================================================================
# findCandidateEntities method finding the candidateEntities of the operator
#=======================================================================
def findCandidateEntities(self, pendingEntities=[]):
if pendingEntities:
for entity in [x for x in pendingEntities if x.canProceed and x.manager==self]:
self.candidateEntities.append(entity)
#=========================================================================== #===========================================================================
# method that finds a candidate entity for an operator # method that finds a candidate entity for an operator
...@@ -149,40 +137,46 @@ class Operator(ObjectResource): ...@@ -149,40 +137,46 @@ class Operator(ObjectResource):
return candidateStation return candidateStation
#=========================================================================== #===========================================================================
# recursive method that searches for entities with available receivers # sort candidate stations
#=========================================================================== #===========================================================================
def findAvailableEntity(self): def sortStations(self):
from Globals import G from Globals import G
router=G.Router router=G.Router
# if the candidateEntities and the entitiesWithOccupiedReceivers lists are identical then return None candidateMachines=self.candidateStations
if len(set(self.candidateEntities).intersection(router.entitiesWithOccupiedReceivers))==len(self.candidateEntities): # for the candidateMachines
return None if candidateMachines:
availableEntity=next(x for x in self.candidateEntities if not x in router.entitiesWithOccupiedReceivers) # choose the one that waits the most time and give it the chance to grasp the resource
receiverAvailability=False for machine in candidateMachines:
if availableEntity: machine.critical=False
for receiver in availableEntity.candidateReceivers: if machine.broker.waitForOperator:
if not receiver in router.occupiedReceivers: machine.timeWaiting=self.env.now-machine.broker.timeWaitForOperatorStarted
receiverAvailability=True else:
break machine.timeWaiting=self.env.now-machine.timeLastEntityLeft
# if there are no available receivers for the entity # find the stations that hold or are about to be delivered critical entities
if not receiverAvailability: if self in router.preemptiveOperators:
router.entitiesWithOccupiedReceivers.append(availableEntity) for entity in machine.getActiveObjectQueue():
return self.findAvailableEntity() if entity in router.pending and entity.isCritical:
return availableEntity machine.critical=True
break
for previous in machine.previous:
for entity in previous.getActiveObjectQueue():
if entity in router.pending and entity.isCritical:
machine.critical=True
# sort the stations according their timeWaiting
self.candidateStations.sort(key= lambda x: x.timeWaiting, reverse=True)
#=========================================================================== #===========================================================================
# method that finds a candidate entity for an operator # sort entities provided in a list
#=========================================================================== #===========================================================================
def findCandidateEntity(self): def sortEntities(self):
from Globals import G #if we have sorting according to multiple criteria we have to call the sorter many times
router=G.Router if self.schedulingRule=="MC":
# pick a candidateEntity for criterion in reversed(self.multipleCriterionList):
candidateEntity=self.findAvailableEntity() self.activeQSorter(criterion=criterion)
if not router.sorting: #else we just use the default scheduling rule
if not candidateEntity: else:
candidateEntity=next(x for x in self.candidateEntities) print self.schedulingRule
router.conflictingEntities.append(candidateEntity) self.activeQSorter(self.schedulingRule)
return candidateEntity
# ======================================================================= # =======================================================================
# sorts the candidateEntities of the Operator according to the scheduling rule # sorts the candidateEntities of the Operator according to the scheduling rule
...@@ -216,104 +210,92 @@ class Operator(ObjectResource): ...@@ -216,104 +210,92 @@ class Operator(ObjectResource):
self.candidateStations.sort(key= lambda x: x.timeWaiting, reverse=True) self.candidateStations.sort(key= lambda x: x.timeWaiting, reverse=True)
# sort the stations if they hold critical entities # sort the stations if they hold critical entities
self.candidateStations.sort(key=lambda x: x.critical, reverse=False) self.candidateStations.sort(key=lambda x: x.critical, reverse=False)
# # TODO: have to consider what happens in case of a critical order
# #if we have sorting according to multiple criteria we have to call the sorter many times
# if self.schedulingRule=="MC":
# for criterion in reversed(self.multipleCriterionList):
# self.activeCandidateQSorter(criterion=criterion)
# #else we just use the default scheduling rule
# else:
# print self.schedulingRule
# self.activeCandidateQSorter(self.schedulingRule)
# ======================================================================= # =======================================================================
# sorts the Entities of the Queue according to the scheduling rule # sorts the Entities of the Queue according to the scheduling rule
# ======================================================================= # =======================================================================
def activeCandidateQSorter(self, criterion=None): def activeQSorter(self, criterion=None):
# TODO: entityToGet is not updated for all stations, consider using it for all stations or withdraw the idea activeObjectQ=self.candidateEntities
# TODO: sorting candidateStations is strange. some of them are waiting to get an entity, others are waiting for operator while holding an entity
activeObjectQ=self.candidateStations
if criterion==None: if criterion==None:
criterion=self.schedulingRule criterion=self.schedulingRule
#if the schedulingRule is first in first out #if the schedulingRule is first in first out
if criterion=="FIFO": if criterion=="FIFO":
# FIFO sorting has no meaning when sorting candidateEntities # FIFO sorting has no meaning when sorting candidateEntities
self.activeCandidateQSorter('WT') self.activeCandidateQSorter('WT')
# added for testing
# print 'there is no point of using FIFO scheduling rule for operators candidateEntities,\
# WT scheduling rule used instead'
#if the schedulingRule is based on a pre-defined priority #if the schedulingRule is based on a pre-defined priority
elif criterion=="Priority": elif criterion=="Priority":
activeObjectQ.sort(key=lambda x: x.identifyEntityToGet().priority)
#if the scheduling rule is time waiting (time waiting of machine activeObjectQ.sort(key=lambda x: x.priority)
# TODO: consider that the timeLastEntityEnded is not a #if the scheduling rule is time waiting (time waiting of machine)
# indicative identifier of how long the station was waiting
elif criterion=='WT': elif criterion=='WT':
activeObjectQ.sort(key=lambda x: x.identifyEntityToGet().schedule[-1][1])
activeObjectQ.sort(key=lambda x: x.schedule[-1][1])
#if the schedulingRule is earliest due date #if the schedulingRule is earliest due date
elif criterion=="EDD": elif criterion=="EDD":
activeObjectQ.sort(key=lambda x: x.identifyEntityToGet().dueDate)
activeObjectQ.sort(key=lambda x: x.dueDate)
#if the schedulingRule is earliest order date #if the schedulingRule is earliest order date
elif criterion=="EOD": elif criterion=="EOD":
activeObjectQ.sort(key=lambda x: x.identifyEntityToGet().orderDate)
activeObjectQ.sort(key=lambda x: x.orderDate)
#if the schedulingRule is to sort Entities according to the stations they have to visit #if the schedulingRule is to sort Entities according to the stations they have to visit
elif criterion=="NumStages": elif criterion=="NumStages":
activeObjectQ.sort(key=lambda x: len(x.identifyEntityToGet().remainingRoute), reverse=True)
activeObjectQ.sort(key=lambda x: len(x.remainingRoute), reverse=True)
#if the schedulingRule is to sort Entities according to the their remaining processing time in the system #if the schedulingRule is to sort Entities according to the their remaining processing time in the system
elif criterion=="RPC": elif criterion=="RPC":
for object in activeObjectQ:
entity=object.identifyEntityToGet() for entity in activeObjectQ:
RPT=0 RPT=0
for step in entity.remainingRoute: for step in entity.remainingRoute:
processingTime=step.get('processingTime',None) processingTime=step.get('processingTime',None)
if processingTime: if processingTime:
RPT+=float(processingTime.get('mean',0)) RPT+=float(processingTime.get('mean',0))
entity.remainingProcessingTime=RPT entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: x.identifyEntityToGet().remainingProcessingTime, reverse=True) activeObjectQ.sort(key=lambda x: x.remainingProcessingTime, reverse=True)
#if the schedulingRule is to sort Entities according to longest processing time first in the next station #if the schedulingRule is to sort Entities according to longest processing time first in the next station
elif criterion=="LPT": elif criterion=="LPT":
for object in activeObjectQ:
entity=object.identifyEntityToGet() for entity in activeObjectQ:
processingTime = entity.remainingRoute[0].get('processingTime',None) processingTime = entity.remainingRoute[0].get('processingTime',None)
entity.processingTimeInNextStation=float(processingTime.get('mean',0)) entity.processingTimeInNextStation=float(processingTime.get('mean',0))
if processingTime: if processingTime:
entity.processingTimeInNextStation=float(processingTime.get('mean',0)) entity.processingTimeInNextStation=float(processingTime.get('mean',0))
else: else:
entity.processingTimeInNextStation=0 entity.processingTimeInNextStation=0
activeObjectQ.sort(key=lambda x: x.identifyEntityToGet().processingTimeInNextStation, reverse=True) 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 #if the schedulingRule is to sort Entities according to shortest processing time first in the next station
elif criterion=="SPT": elif criterion=="SPT":
for object in activeObjectQ:
entity=object.identifyEntityToGet() for entity in activeObjectQ:
processingTime = entity.remainingRoute[0].get('processingTime',None) processingTime = entity.remainingRoute[0].get('processingTime',None)
if processingTime: if processingTime:
entity.processingTimeInNextStation=float(processingTime.get('mean',0)) entity.processingTimeInNextStation=float(processingTime.get('mean',0))
else: else:
entity.processingTimeInNextStation=0 entity.processingTimeInNextStation=0
activeObjectQ.sort(key=lambda x: x.identifyEntityToGet().processingTimeInNextStation) activeObjectQ.sort(key=lambda x: x.processingTimeInNextStation)
#if the schedulingRule is to sort Entities based on the minimum slackness #if the schedulingRule is to sort Entities based on the minimum slackness
elif criterion=="MS": elif criterion=="MS":
for object in activeObjectQ:
object.identifyEntityToGet() for entity in activeObjectQ:
RPT=0 RPT=0
for step in entity.remainingRoute: for step in entity.remainingRoute:
processingTime=step.get('processingTime',None) processingTime=step.get('processingTime',None)
if processingTime: if processingTime:
RPT+=float(processingTime.get('mean',0)) RPT+=float(processingTime.get('mean',0))
entity.remainingProcessingTime=RPT entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: (x.identifyEntityToGet().dueDate-x.identifyEntityToGet().remainingProcessingTime)) activeObjectQ.sort(key=lambda x: (x.dueDate-x.remainingProcessingTime))
#if the schedulingRule is to sort Entities based on the length of the following Queue #if the schedulingRule is to sort Entities based on the length of the following Queue
elif criterion=="WINQ": elif criterion=="WINQ":
from Globals import G from Globals import G
for object in activeObjectQ: for entity in activeObjectQ:
entity=object.identifyEntityToGet()
nextObjIds=entity.remainingRoute[1].get('stationIdsList',[]) nextObjIds=entity.remainingRoute[1].get('stationIdsList',[])
for obj in G.ObjList: for obj in G.ObjList:
if obj.id in nextObjIds: if obj.id in nextObjIds:
nextObject=obj nextObject=obj
entity.nextQueueLength=len(nextObject.getActiveObjectQueue()) entity.nextQueueLength=len(nextObject.getActiveObjectQueue())
activeObjectQ.sort(key=lambda x: x.identifyEntityToGet().nextQueueLength) activeObjectQ.sort(key=lambda x: x.nextQueueLength)
else: else:
assert False, "Unknown scheduling criterion %r" % (criterion, ) assert False, "Unknown scheduling criterion %r" % (criterion, )
......
...@@ -79,6 +79,50 @@ class OperatorManagedJob(Operator): ...@@ -79,6 +79,50 @@ class OperatorManagedJob(Operator):
# if the candidate entity has only one receiver then return True # if the candidate entity has only one receiver then return True
return len(self.candidateEntities[0].candidateReceivers)==1 return len(self.candidateEntities[0].candidateReceivers)==1
#=======================================================================
# findCandidateEntities method finding the candidateEntities of the operator
#=======================================================================
def findCandidateEntities(self, pendingEntities=[]):
if pendingEntities:
for entity in [x for x in pendingEntities if x.canProceed and x.manager==self]:
self.candidateEntities.append(entity)
#===========================================================================
# recursive method that searches for entities with available receivers
#===========================================================================
def findAvailableEntity(self):
from Globals import G
router=G.Router
# if the candidateEntities and the entitiesWithOccupiedReceivers lists are identical then return None
if len(set(self.candidateEntities).intersection(router.entitiesWithOccupiedReceivers))==len(self.candidateEntities):
return None
availableEntity=next(x for x in self.candidateEntities if not x in router.entitiesWithOccupiedReceivers)
receiverAvailability=False
if availableEntity:
for receiver in availableEntity.candidateReceivers:
if not receiver in router.occupiedReceivers:
receiverAvailability=True
break
# if there are no available receivers for the entity
if not receiverAvailability:
router.entitiesWithOccupiedReceivers.append(availableEntity)
return self.findAvailableEntity()
return availableEntity
#===========================================================================
# method that finds a candidate entity for an operator
#===========================================================================
def findCandidateEntity(self):
from Globals import G
router=G.Router
# pick a candidateEntity
candidateEntity=self.findAvailableEntity()
if not router.sorting:
if not candidateEntity:
candidateEntity=next(x for x in self.candidateEntities)
router.conflictingEntities.append(candidateEntity)
return candidateEntity
# ======================================================================= # =======================================================================
# sorts the candidateEntities of the Operator according to the scheduling rule # sorts the candidateEntities of the Operator according to the scheduling rule
# TODO: maybe the argument is not needed. the candidate entities is a variable of the object # TODO: maybe the argument is not needed. the candidate entities is a variable of the object
......
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