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

unsuccesful implementation of JobShop Topologies - only for review

parent 6e60e81f
......@@ -322,7 +322,6 @@ class CoreObject(Process):
# dummy variables that help prioritize the objects requesting to give objects to the Machine (activeObject)
maxTimeWaiting=0 # dummy variable counting the time a successor is waiting
receiver=None
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
......
......@@ -25,7 +25,9 @@ Created on 18 Aug 2013
Class that acts as an abstract. It should have no instances. All the Entities should inherit from it
'''
# ======================== The entity object ================================
# ===========================================================================
# The entity object
# ===========================================================================
class Entity(object):
type="Entity"
......@@ -50,11 +52,14 @@ class Entity(object):
self.currentStation=None
# values to be used in the internal processing of compoundObjects
self.internal = False # informs if the entity is being processed internally
# =============== outputs results to JSON File ==========================
# =======================================================================
# outputs results to JSON File
# =======================================================================
def outputResultsJSON(self):
pass
# =====initializes all the Entity for a new simulation replication ======
# =======================================================================
# initializes all the Entity for a new simulation replication
# =======================================================================
def initialize(self):
pass
\ No newline at end of file
......@@ -30,10 +30,13 @@ from SimPy.Simulation import activate, passivate, waituntil, now, hold
from Exit import Exit
#the ExitJobShop object
# ===========================================================================
# the ExitJobShop object
# ===========================================================================
class ExitJobShop(Exit):
#set all the objects in previous
# =======================================================================
# set all the objects in previous
# ===========================================================================
def initialize(self):
from Globals import G
self.previous=G.ObjList
......
......@@ -102,8 +102,18 @@ def findObjectById(id):
return None
# =======================================================================
# Error in the setting up of the WIP
# =======================================================================
class SetWipTypeError(Exception):
def __init__(self, setWipError):
Exception.__init__(self, setWipError)
# =======================================================================
# method to set-up the entities in the current stations
# as Work In Progress
# -----------------------------------------
# in this case the current station must be defined!
# otherwise there is no current station but a list of possible stations
# although the entity cannot be in more than one stations
# =======================================================================
def setWIP(entityList):
for entity in entityList:
......@@ -114,9 +124,32 @@ def setWIP(entityList):
entity.schedule.append([object,now()]) #append the time to schedule so that it can be read in the result
# if the entity is of type Job/OrderComponent/Order
elif entity.type=='Job' or 'OrderComponent' or 'Order':
object=findObjectById(entity.remainingRoute[0][0]) # find the object in the 'G.ObjList'
# 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'
# 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]
else:
raise SetWipTypeError('The starting station of the the entity is not defined uniquely')
except SetWipTypeError as setWipError:
print 'WIP definition error: {0}'.format(setWipError)
# get the starting station of the entity and load it with it
object = findObjectById(objectId)
object.getActiveObjectQueue().append(entity) # append the entity to its Queue
object.receiver=findObjectById(entity.remainingRoute[1][0])
# read the IDs of the possible successors of the object
nextObjectIds=entity.remainingRoute[1].get('stationIdsList',[])
# for each objectId in the nextObjects find the corresponding object and populate the object's next list
nextObjects=[]
for nextObjectId in nextObjectIds:
nextObject=findObjectById(nextObjectId)
nextObjects.append(nextObject)
# update the receiver of the object
object.next=nextObjects
object.receiver = object.updateReceiverObject()
# # # # # # object.receiver=findObjectById(entity.remainingRoute[1][0])
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
......
......@@ -22,7 +22,9 @@
"route": [
{
"stepNumber": "0",
"stationId": "Q0",
"stationIdsList": [
"Q0"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
......@@ -30,7 +32,9 @@
},
{
"stepNumber": "1",
"stationId": "M0",
"stationIdsList": [
"M0"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "1"
......@@ -45,7 +49,9 @@
"route": [
{
"stepNumber": "0",
"stationId": "OD0",
"stationIdsList": [
"OD0"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
......@@ -53,7 +59,9 @@
},
{
"stepNumber": "1",
"stationId": "Q1",
"stationIdsList": [
"Q1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
......@@ -61,7 +69,9 @@
},
{
"stepNumber": "2",
"stationId": "M1",
"stationIdsList": [
"M1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "1"
......@@ -69,7 +79,9 @@
},
{
"stepNumber": "3",
"stationId": "E1",
"stationIdsList": [
"E1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
......@@ -84,7 +96,9 @@
"route": [
{
"stepNumber": "0",
"stationId": "OD0",
"stationIdsList": [
"OD0"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
......@@ -92,7 +106,9 @@
},
{
"stepNumber": "1",
"stationId": "Q2",
"stationIdsList": [
"Q2"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
......@@ -100,7 +116,9 @@
},
{
"stepNumber": "2",
"stationId": "M2",
"stationIdsList": [
"M2"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "1"
......@@ -108,7 +126,9 @@
},
{
"stepNumber": "3",
"stationId": "E1",
"stationIdsList": [
"E1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
......
......@@ -89,6 +89,18 @@ class Job(Entity): # inherits from the Entity c
# =======================================================================
def initialize(self):
# has to be re-initialized each time a new Job is added
self.remainingRoute=list(self.route)
self.currentStation=self.route[0][0]
self.remainingRoute=list(self.route)
# check the number of stations in the stationIdsList for the current step (0)
# if it is greater than 1 then there is a problem definition
objectIds = self.route[0].get('stationIdsList',[])
try:
if len(objectIds)==1:
from Globals import findObjectById
self.currentStation=findObjectById(objectIds[0])
else:
from Globals import SetWipTypeError
raise SetWipTypeError('The starting station of the the entity is not defined uniquely')
except SetWipTypeError as setWipError:
print 'WIP definition error: {0}'.format(setWipError)
# self.currentStation=self.route[0][0]
This diff is collapsed.
......@@ -99,6 +99,12 @@ 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:
......@@ -125,6 +131,7 @@ 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
......@@ -139,10 +146,12 @@ 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):
......@@ -150,6 +159,13 @@ class Machine(CoreObject):
self.totalWorkingTime+=now()-(self.timeLastEntityEntered)
continue
print '////////////////////////////////////'
print 'time', now()
print 'object', self.objName, 'processed', self.currentEntity.name
print '////////////////////////////////////'
# output to trace that the processing in the Machine self.objName ended
try:
self.outputTrace(self.getActiveObjectQueue()[0].name,"ended processing in "+self.objName)
......
......@@ -44,9 +44,21 @@ class MachineJobShop(Machine):
#gets an entity from the predecessor that the predecessor index points to
def getEntity(self):
activeEntity=Machine.getEntity(self) #run the default code
self.procTime=activeEntity.remainingRoute[0][1] #read the processing time from the entity
# 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=activeEntity.remainingRoute[0][1] #read the processing time from the entity
import Globals
self.receiver=Globals.findObjectById(activeEntity.remainingRoute[1][0]) #read the next station
# read the list of next stations
nextObjectIds=activeEntity.remainingRoute[1].get('stationIdsList',[])
nextObjects = []
for nextObjectId in nextObjectIds:
nextObject=Globals.findObjectById(nextObjectId)
nextObjects.append(nextObject)
self.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
......@@ -61,7 +73,9 @@ class MachineJobShop(Machine):
#check it the caller object holds an Entity that requests for current object
if len(callerObject.getActiveObjectQueue())>0:
activeEntity=callerObject.getActiveObjectQueue()[0]
if activeEntity.remainingRoute[0][0]==self.id:
# 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 activeEntity.remainingRoute[0][0]==self.id:
return len(self.getActiveObjectQueue())<self.capacity #return according to the state of the Queue
return False
......@@ -70,7 +84,10 @@ class MachineJobShop(Machine):
# get active object and its queue
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
#return True if the Machine in the state of disposing and the caller is the receiver
# find the receiver waiting the most
activeObject.receiver=activeObject.updateReceiverObject()
#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)
......
......@@ -57,8 +57,16 @@ class MachinePreemptive(MachineJobShop):
else:
remainingProcessingTime=self.procTime-(now()-self.timeLastEntityEntered)
#update the remaining route of activeEntity
activeEntity.remainingRoute.insert(0, [self.id, remainingProcessingTime])
activeEntity.remainingRoute.insert(0, [self.lastGiver.id, 0])
activeEntity.remainingRoute.insert(0, {'stationIdsList':str([self.id]),\
'processingTime':\
{'distributionType':'Fixed',\
'mean':str(remainingProcessingTime)}})
# activeEntity.remainingRoute.insert(0, [self.id, remainingProcessingTime])
activeEntity.remainingRoute.insert(0, {'stationIdsList':str([self.lastGiver.id]),\
'processingTime':\
{'distributionType':'Fixed',\
'mean':'0'}})
# activeEntity.remainingRoute.insert(0, [self.lastGiver.id, 0])
#set the receiver as the object where the active entity was preempted from
self.receiver=self.lastGiver
self.waitToDispose=True #set that I have to dispose
......
......@@ -94,9 +94,17 @@ class OrderDecomposition(CoreObject):
# dummy variables that help prioritize the objects requesting to give objects to the Machine (activeObject)
isRequested=False # is requested is dummyVariable checking if it is requested to accept an item
maxTimeWaiting=0 # dummy variable counting the time a predecessor is blocked
# print 'time', now()
# for obj in activeObject.previous:
# print 'orderDecompose previous', obj.id, obj.objName
# loop through the possible givers to see which have to dispose and which is the one blocked for longer
for object in activeObject.previous:
# print 'object in previous', object.objName
# print 'has to dispose', object.haveToDispose(activeObject)
# if object.receiver!=None:
# print 'has receiver', object.receiver.objName
# else:
# print 'has no receiver'
if(object.haveToDispose(activeObject) and object.receiver==self):
isRequested=True # if the predecessor objects have entities to dispose of
if(object.downTimeInTryingToReleaseCurrentEntity>0):# and the predecessor has been down while trying to give away the Entity
......@@ -109,6 +117,9 @@ class OrderDecomposition(CoreObject):
activeObject.giver=object # the object to deliver the Entity to the activeObject is set to the ith member of the previous list
maxTimeWaiting=timeWaiting
# in the next loops, check the other predecessors in the previous list
# print 'orderDecompose giver:', activeObject.giver.objName , activeObject.giver.id
# print 'canAcceptAndIsRequested returns', activeObject.Up and isRequested
# print ''
return activeObject.Up and isRequested
# =======================================================================
......@@ -123,7 +134,14 @@ class OrderDecomposition(CoreObject):
activeEntity=activeObjectQueue[0]
import Globals
self.receiver=Globals.findObjectById(activeEntity.remainingRoute[0][0]) #read the next station
# update the next list of the object
nextObjectIds=activeEntity.remainingRoute[0].get('stationIdsList',[])
for nextObjectId in nextObjectIds:
self.next.append(Globals.findObjectById(nextObjectId))
# self.next = Globals.findObjectById(activeEntity.remainingRoute[0].get('stationIdsList',[]))
# find the suitable receiver
self.receiver = self.updateReceiverObject()
# self.receiver=Globals.findObjectById(activeEntity.remainingRoute[0][0]) #read the next station
#return True if the OrderDecomposition in the state of disposing and the caller is the receiver
return self.Up and (callerObject is self.receiver)
......@@ -177,12 +195,14 @@ class OrderDecomposition(CoreObject):
for routeentity in JSONRoute: # for each 'step' dictionary in the JSONRoute
stepNumber=int(routeentity.get('stepNumber', '0')) # get the stepNumber
nextId=routeentity.get('stationId', 'not found') # the stationId
processingTime=routeentity['processingTime'] # and the 'processingTime' dictionary
distributionType=processingTime.get('distributionType', 'not found')# and from that dictionary
mean=float(processingTime.get('mean', 'not found')) # get the 'mean'
route[stepNumber]=[nextId, mean] # finally add the 'nextId' and 'mean'
# to the job route
routeentity.pop(str(stepNumber),None) # remove the stepNumber key
# nextId=routeentity.get('stationId', 'not found') # the stationId
# processingTime=routeentity['processingTime'] # and the 'processingTime' dictionary
# distributionType=processingTime.get('distributionType', 'not found')# and from that dictionary
# mean=float(processingTime.get('mean', 'not found')) # get the 'mean'
# route[stepNumber]=[nextId, 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
extraPropertyDict = {}
......@@ -194,10 +214,12 @@ class OrderDecomposition(CoreObject):
#have to talk about it with NEX
exitAssigned=False
for element in route:
elementId=element[0]
# elementId=element[0]
elementIds = element.get('stationIdsList',[])
for obj in G.ObjList:
if obj.id==elementId and obj.type=='Exit':
exitAssigned=True
for elementId in elementIds:
if obj.id==elementId and obj.type=='Exit':
exitAssigned=True
if not exitAssigned:
exitId=None
for obj in G.ObjList:
......@@ -205,7 +227,9 @@ class OrderDecomposition(CoreObject):
exitId=obj.id
break
if exitId:
route.append([exitId, 0])
# route.append([exitId, 0])
route.append({'stationIdsList':str([exitId]),\
'processingTime':{}})
# initiate the OrderComponent
OC=OrderComponent(id, name, route, \
......
......@@ -233,37 +233,46 @@ class Queue(CoreObject):
for entity in activeObjectQ:
RPT=0
for step in entity.remainingRoute:
RPT+=step[1]
processingTime=step['processingTime']
RPT+=processingTime.get('mean',0)
# RPT+=step[1]
entity.remainingProcessingTime=RPT
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
elif criterion=="LPT":
for entity in activeObjectQ:
LPT=0
entity.processingTimeInNextStation=entity.remainingRoute[0][1]
processingTime = entity.remainingRoute[0]['processingTime']
entity.processingTimeInNextStation=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
elif criterion=="SPT":
for entity in activeObjectQ:
LPT=0
entity.processingTimeInNextStation=entity.remainingRoute[0][1]
processingTime = entity.remainingRoute[0]['processingTime']
entity.processingTimeInNextStation=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
elif criterion=="MS":
for entity in activeObjectQ:
RPT=0
for step in entity.remainingRoute:
RPT+=step[1]
processingTime=step['processingTime']
RPT+=processingTime.get('mean',0)
# RPT+=step[1]
entity.remainingProcessingTime=RPT
activeObjectQ.sort(key=lambda x: (x.dueDate-x.remainingProcessingTime))
#if the schedulingRule is to sort Entities based on the length of the following Queue
elif criterion=="WINQ":
from Globals import G
for entity in activeObjectQ:
nextObjId=entity.remainingRoute[1][0]
nextObjIds=entity.remainingRoute[1].get('stationIdsList',[])
# nextObjId=entity.remainingRoute[1][0]
for obj in G.ObjList:
if obj.id==nextObjId:
nextObject=obj
if obj.id in nextObjIds:
nextObject=obj
entity.nextQueueLength=len(nextObject.getActiveObjectQueue())
activeObjectQ.sort(key=lambda x: x.nextQueueLength)
\ No newline at end of file
......@@ -48,7 +48,9 @@ class QueueJobShop(Queue):
#check it the caller object holds an Entity that requests for current object
if len(callerObject.getActiveObjectQueue())>0:
activeEntity=callerObject.getActiveObjectQueue()[0]
if activeEntity.remainingRoute[0][0]==self.id:
# check if the object in the active entity's route next step
if self.id in activeEntity.remainingRoute[0].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
......@@ -57,6 +59,8 @@ class QueueJobShop(Queue):
# get active object and its queue
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
# update the receiver object
activeObject.receiver=activeObject.updateReceiverObject()
#return True if the Queue has Entities and the caller is the receiver
return len(activeObjectQueue)>0 and (callerObject is self.receiver)
......@@ -64,7 +68,15 @@ class QueueJobShop(Queue):
def getEntity(self):
activeEntity=Queue.getEntity(self)
import Globals
self.receiver=Globals.findObjectById(activeEntity.remainingRoute[1][0]) #read the next station
# read the possible receivers - update the next list
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
......
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