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

Router and Operator clean-up

parent 3aa1af0f
...@@ -119,23 +119,6 @@ class Operator(ObjectResource): ...@@ -119,23 +119,6 @@ class Operator(ObjectResource):
def isAssignedTo(self): def isAssignedTo(self):
return self.operatorAssignedTo return self.operatorAssignedTo
#===========================================================================
# method that finds a candidate entity for an operator
#===========================================================================
def findCandidateStation(self):
from Globals import G
router=G.Router
candidateStation=None
possibleReceivers=[x for x in self.candidateStations if not x in router.conflictingStations and not x in router.getReceivers()]
if possibleReceivers:
candidateStation=next(x for x in possibleReceivers)
if not candidateStation:
candidateStation=next(x for x in self.candidateStations)
router.conflictingStations.append(candidateStation)
return candidateStation
#=========================================================================== #===========================================================================
# sort candidate stations # sort candidate stations
#=========================================================================== #===========================================================================
...@@ -167,39 +150,6 @@ class Operator(ObjectResource): ...@@ -167,39 +150,6 @@ class Operator(ObjectResource):
else: else:
self.activeQSorter(self.schedulingRule) self.activeQSorter(self.schedulingRule)
# =======================================================================
# sorts the candidateEntities of the Operator according to the scheduling rule
# TODO: find a way to sort machines or candidate entities for machines,
# now picks the machine that waits the most
# =======================================================================
def sortCandidateEntities(self):
from Globals import G
router=G.Router
candidateMachines=self.candidateStations
# for the candidateMachines
if candidateMachines:
# choose the one that waits the most time and give it the chance to grasp the resource
for machine in candidateMachines:
machine.critical=False
if machine.broker.waitForOperator:
machine.timeWaiting=self.env.now-machine.broker.timeWaitForOperatorStarted
else:
machine.timeWaiting=self.env.now-machine.timeLastEntityLeft
# find the stations that hold or are about to be delivered critical entities
if self in router.preemptiveOperators:
for entity in machine.getActiveObjectQueue():
if entity in router.pending and entity.isCritical:
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)
# sort the stations if they hold critical entities
self.candidateStations.sort(key=lambda x: x.critical, reverse=False)
# ======================================================================= # =======================================================================
# sorts the Entities of the Queue according to the scheduling rule # sorts the Entities of the Queue according to the scheduling rule
# ======================================================================= # =======================================================================
......
...@@ -132,7 +132,7 @@ class Router(ObjectInterruption): ...@@ -132,7 +132,7 @@ class Router(ObjectInterruption):
self.assignOperators() self.assignOperators()
# unAssign exits # unAssign exits
self.unAssignExits() self.unAssignExits()
# signal the stations that ought to be signaled # signal the stations that ought to be signalled
self.signalOperatedStations() self.signalOperatedStations()
self.printTrace('', 'router exiting') self.printTrace('', 'router exiting')
self.printTrace('','=-'*20) self.printTrace('','=-'*20)
...@@ -412,212 +412,3 @@ class Router(ObjectInterruption): ...@@ -412,212 +412,3 @@ class Router(ObjectInterruption):
break break
occupiedStations.append(operator.candidateStation) occupiedStations.append(operator.candidateStation)
occupiedEntities.append(operator.candidateEntity) occupiedEntities.append(operator.candidateEntity)
\ No newline at end of file
#=======================================================================
# Find the candidateEntities for each candidateOperator
# find the candidateEntities of each candidateOperator and sort them according
# to the scheduling rules of the operator and choose an entity that will be served
# and by which machines
#=======================================================================
def sortCandidateEntities(self):
from Globals import G
# sort the candidateEntities list of each operator according to its schedulingRule
for operator in [x for x in self.candidateOperators if x.candidateStations]:
operator.sortCandidateEntities()
#===========================================================================
# get all the candidate stations that have been chosen by an operator
#===========================================================================
def getReceivers(self):
candidateStations=[]
for operator in self.candidateOperators:
if operator.candidateStation:
if not operator.candidateStation in candidateStations:
candidateStations.append(operator.candidateStation)
return candidateStations
#=======================================================================
# Find candidate entities and their receivers
# TODO: if there is a critical entity, its manager should be served first
# TODO: have to sort again after choosing candidateEntity
#=======================================================================
def findCandidateReceivers(self):
# finally we have to sort before giving the entities to the operators
# If there is an entity which must have priority then it should be assigned first
# TODO: sorting after choosing candidateEntity
# for the candidateOperators that do have candidateEntities pick a candidateEntity
for operator in [x for x in self.candidateOperators if x.candidateStations]:
# find the first available entity that has no occupied receivers
operator.candidateStation = operator.findCandidateStation()
# find the resources that are 'competing' for the same station
if not self.sorting:
# if there are entities that have conflicting receivers
if len(self.conflictingStations):
self.conflictingOperators=[operator for operator in self.candidateOperators\
if operator.candidateStation in self.conflictingStations]
# keep the sorting provided by the queues if there is conflict between operators
conflictingGroup=[] # list that holds the operators that have the same recipient
removedOperators=[]
if self.conflictingOperators:
# for each of the candidateReceivers
for station in self.conflictingStations:
# find the group of operators that compete for this station
conflictingGroup=[operator for operator in self.conflictingOperators if operator.candidateStation==station]
# the operator that can proceed is the manager of the entity as sorted by the queue that holds them
conflictingGroup.sort()
# the operators that are not first in the list cannot proceed
for operator in conflictingGroup:
if conflictingGroup.index(operator)!=0 and not operator in removedOperators:
self.candidateOperators.remove(operator)
removedOperators.append(operator)
# =======================================================================
# sorts the Operators of the Queue according to the scheduling rule
# =======================================================================
def activeQSorter(self, criterion=None, candList=[]):
activeObjectQ=candList
if not activeObjectQ:
assert False, "empty candidateOperators list"
if criterion==None:
criterion=self.multipleCriterionList[0]
#if the schedulingRule is first in first out
if criterion=="FIFO":
# FIFO sorting has no meaning when sorting candidateEntities
self.activeQSorter(criterion='WT',candList=activeObjectQ)
#if the schedulingRule is based on a pre-defined priority
elif criterion=="Priority":
# if the activeObjectQ is a list of entities then perform the default sorting
try:
activeObjectQ.sort(key=lambda x: x.priority)
# if the activeObjectQ is a list of operators then sort them according to their candidateEntities
except:
activeObjectQ.sort(key=lambda x: x.candidateEntity.priority)
#if the scheduling rule is time waiting (time waiting of machine
# TODO: consider that the timeLastEntityEnded is not a
# indicative identifier of how long the station was waiting
elif criterion=='WT':
try:
activeObjectQ.sort(key=lambda x: x.schedule[-1][1])
except:
activeObjectQ.sort(key=lambda x: x.candidateEntity.schedule[-1][1])
#if the schedulingRule is earliest due date
elif criterion=="EDD":
try:
activeObjectQ.sort(key=lambda x: x.dueDate)
except:
activeObjectQ.sort(key=lambda x: x.candidateEntity.dueDate)
#if the schedulingRule is earliest order date
elif criterion=="EOD":
try:
activeObjectQ.sort(key=lambda x: x.orderDate)
except:
activeObjectQ.sort(key=lambda x: x.candidateEntity.orderDate)
#if the schedulingRule is to sort Entities according to the stations they have to visit
elif criterion=="NumStages":
try:
activeObjectQ.sort(key=lambda x: len(x.remainingRoute), reverse=True)
except:
activeObjectQ.sort(key=lambda x: len(x.candidateEntity.remainingRoute), reverse=True)
#if the schedulingRule is to sort Entities according to the their remaining processing time in the system
elif criterion=="RPC":
try:
for entity in activeObjectQ:
RPT=0
for step in entity.remainingRoute:
processingTime=step.get('processingTime',None)
if processingTime:
RPT+=float(processingTime.get('mean',0))
entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: x.remainingProcessingTime, reverse=True)
except:
for entity in [operator.candidateEntity for operator in activeObjectQ]:
RPT=0
for step in entity.remainingRoute:
processingTime=step.get('processingTime',None)
if processingTime:
RPT+=float(processingTime.get('mean',0))
entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: x.candidateEntity.remainingProcessingTime, reverse=True)
#if the schedulingRule is to sort Entities according to longest processing time first in the next station
elif criterion=="LPT":
try:
for entity in activeObjectQ:
processingTime = entity.remainingRoute[0].get('processingTime',None)
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
if processingTime:
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
else:
entity.processingTimeInNextStation=0
activeObjectQ.sort(key=lambda x: x.processingTimeInNextStation, reverse=True)
except:
for entity in [operator.candidateEntity for operator in activeObjectQ]:
processingTime = entity.remainingRoute[0].get('processingTime',None)
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
if processingTime:
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
else:
entity.processingTimeInNextStation=0
activeObjectQ.sort(key=lambda x: x.candidateEntity.processingTimeInNextStation, reverse=True)
#if the schedulingRule is to sort Entities according to shortest processing time first in the next station
elif criterion=="SPT":
try:
for entity in activeObjectQ:
processingTime = entity.remainingRoute[0].get('processingTime',None)
if processingTime:
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
else:
entity.processingTimeInNextStation=0
activeObjectQ.sort(key=lambda x: x.processingTimeInNextStation)
except:
for entity in [operator.candidateEntity for operator in activeObjectQ]:
processingTime = entity.remainingRoute[0].get('processingTime',None)
if processingTime:
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
else:
entity.processingTimeInNextStation=0
activeObjectQ.sort(key=lambda x: x.candidateEntity.processingTimeInNextStation)
#if the schedulingRule is to sort Entities based on the minimum slackness
elif criterion=="MS":
try:
for entity in activeObjectQ:
RPT=0
for step in entity.remainingRoute:
processingTime=step.get('processingTime',None)
if processingTime:
RPT+=float(processingTime.get('mean',0))
entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: (x.dueDate-x.remainingProcessingTime))
except:
for entity in [operator.candidateEntity for operator in activeObjectQ]:
RPT=0
for step in entity.remainingRoute:
processingTime=step.get('processingTime',None)
if processingTime:
RPT+=float(processingTime.get('mean',0))
entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: (x.candidateEntity.dueDate-x.candidateEntity.remainingProcessingTime))
#if the schedulingRule is to sort Entities based on the length of the following Queue
elif criterion=="WINQ":
try:
from Globals import G
for entity in activeObjectQ:
nextObjIds=entity.remainingRoute[1].get('stationIdsList',[])
for obj in G.ObjList:
if obj.id in nextObjIds:
nextObject=obj
entity.nextQueueLength=len(nextObject.getActiveObjectQueue())
activeObjectQ.sort(key=lambda x: x.nextQueueLength)
except:
from Globals import G
for entity in [operator.candidateEntity for operator in activeObjectQ]:
nextObjIds=entity.remainingRoute[1].get('stationIdsList',[])
for obj in G.ObjList:
if obj.id in nextObjIds:
nextObject=obj
entity.nextQueueLength=len(nextObject.getActiveObjectQueue())
activeObjectQ.sort(key=lambda x: x.candidateEntity.nextQueueLength)
else:
assert False, "Unknown scheduling criterion %r" % (criterion, )
\ No newline at end of file
...@@ -438,3 +438,152 @@ class RouterManaged(Router): ...@@ -438,3 +438,152 @@ class RouterManaged(Router):
self.printTrace('candidateReceivers for each entity ',[(str(entity.id),\ self.printTrace('candidateReceivers for each entity ',[(str(entity.id),\
str(entity.candidateReceiver.id)) str(entity.candidateReceiver.id))
for entity in self.pending if entity.candidateReceiver]) for entity in self.pending if entity.candidateReceiver])
# =======================================================================
# sorts the Operators of the Queue according to the scheduling rule
# =======================================================================
def activeQSorter(self, criterion=None, candList=[]):
activeObjectQ=candList
if not activeObjectQ:
assert False, "empty candidateOperators list"
if criterion==None:
criterion=self.multipleCriterionList[0]
#if the schedulingRule is first in first out
if criterion=="FIFO":
# FIFO sorting has no meaning when sorting candidateEntities
self.activeQSorter(criterion='WT',candList=activeObjectQ)
#if the schedulingRule is based on a pre-defined priority
elif criterion=="Priority":
# if the activeObjectQ is a list of entities then perform the default sorting
try:
activeObjectQ.sort(key=lambda x: x.priority)
# if the activeObjectQ is a list of operators then sort them according to their candidateEntities
except:
activeObjectQ.sort(key=lambda x: x.candidateEntity.priority)
#if the scheduling rule is time waiting (time waiting of machine
# TODO: consider that the timeLastEntityEnded is not a
# indicative identifier of how long the station was waiting
elif criterion=='WT':
try:
activeObjectQ.sort(key=lambda x: x.schedule[-1][1])
except:
activeObjectQ.sort(key=lambda x: x.candidateEntity.schedule[-1][1])
#if the schedulingRule is earliest due date
elif criterion=="EDD":
try:
activeObjectQ.sort(key=lambda x: x.dueDate)
except:
activeObjectQ.sort(key=lambda x: x.candidateEntity.dueDate)
#if the schedulingRule is earliest order date
elif criterion=="EOD":
try:
activeObjectQ.sort(key=lambda x: x.orderDate)
except:
activeObjectQ.sort(key=lambda x: x.candidateEntity.orderDate)
#if the schedulingRule is to sort Entities according to the stations they have to visit
elif criterion=="NumStages":
try:
activeObjectQ.sort(key=lambda x: len(x.remainingRoute), reverse=True)
except:
activeObjectQ.sort(key=lambda x: len(x.candidateEntity.remainingRoute), reverse=True)
#if the schedulingRule is to sort Entities according to the their remaining processing time in the system
elif criterion=="RPC":
try:
for entity in activeObjectQ:
RPT=0
for step in entity.remainingRoute:
processingTime=step.get('processingTime',None)
if processingTime:
RPT+=float(processingTime.get('mean',0))
entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: x.remainingProcessingTime, reverse=True)
except:
for entity in [operator.candidateEntity for operator in activeObjectQ]:
RPT=0
for step in entity.remainingRoute:
processingTime=step.get('processingTime',None)
if processingTime:
RPT+=float(processingTime.get('mean',0))
entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: x.candidateEntity.remainingProcessingTime, reverse=True)
#if the schedulingRule is to sort Entities according to longest processing time first in the next station
elif criterion=="LPT":
try:
for entity in activeObjectQ:
processingTime = entity.remainingRoute[0].get('processingTime',None)
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
if processingTime:
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
else:
entity.processingTimeInNextStation=0
activeObjectQ.sort(key=lambda x: x.processingTimeInNextStation, reverse=True)
except:
for entity in [operator.candidateEntity for operator in activeObjectQ]:
processingTime = entity.remainingRoute[0].get('processingTime',None)
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
if processingTime:
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
else:
entity.processingTimeInNextStation=0
activeObjectQ.sort(key=lambda x: x.candidateEntity.processingTimeInNextStation, reverse=True)
#if the schedulingRule is to sort Entities according to shortest processing time first in the next station
elif criterion=="SPT":
try:
for entity in activeObjectQ:
processingTime = entity.remainingRoute[0].get('processingTime',None)
if processingTime:
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
else:
entity.processingTimeInNextStation=0
activeObjectQ.sort(key=lambda x: x.processingTimeInNextStation)
except:
for entity in [operator.candidateEntity for operator in activeObjectQ]:
processingTime = entity.remainingRoute[0].get('processingTime',None)
if processingTime:
entity.processingTimeInNextStation=float(processingTime.get('mean',0))
else:
entity.processingTimeInNextStation=0
activeObjectQ.sort(key=lambda x: x.candidateEntity.processingTimeInNextStation)
#if the schedulingRule is to sort Entities based on the minimum slackness
elif criterion=="MS":
try:
for entity in activeObjectQ:
RPT=0
for step in entity.remainingRoute:
processingTime=step.get('processingTime',None)
if processingTime:
RPT+=float(processingTime.get('mean',0))
entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: (x.dueDate-x.remainingProcessingTime))
except:
for entity in [operator.candidateEntity for operator in activeObjectQ]:
RPT=0
for step in entity.remainingRoute:
processingTime=step.get('processingTime',None)
if processingTime:
RPT+=float(processingTime.get('mean',0))
entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: (x.candidateEntity.dueDate-x.candidateEntity.remainingProcessingTime))
#if the schedulingRule is to sort Entities based on the length of the following Queue
elif criterion=="WINQ":
try:
from Globals import G
for entity in activeObjectQ:
nextObjIds=entity.remainingRoute[1].get('stationIdsList',[])
for obj in G.ObjList:
if obj.id in nextObjIds:
nextObject=obj
entity.nextQueueLength=len(nextObject.getActiveObjectQueue())
activeObjectQ.sort(key=lambda x: x.nextQueueLength)
except:
from Globals import G
for entity in [operator.candidateEntity for operator in activeObjectQ]:
nextObjIds=entity.remainingRoute[1].get('stationIdsList',[])
for obj in G.ObjList:
if obj.id in nextObjIds:
nextObject=obj
entity.nextQueueLength=len(nextObject.getActiveObjectQueue())
activeObjectQ.sort(key=lambda x: x.candidateEntity.nextQueueLength)
else:
assert False, "Unknown scheduling criterion %r" % (criterion, )
\ No newline at end of file
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