Commit 004b38b9 authored by Georgios Dagkakis's avatar Georgios Dagkakis

allocation algorithms changed in order to work with the JSON input. Still...

allocation algorithms changed in order to work with the JSON input. Still verification work to be done
parent 300a2574
...@@ -17,7 +17,7 @@ from dream.simulation.Globals import G ...@@ -17,7 +17,7 @@ from dream.simulation.Globals import G
class AllocManagement(): class AllocManagement():
def Run(self): def Run(self):
G.CurrentCapacityDict=G.CapacityDict
for kWeek in range(G.planningHorizon): for kWeek in range(G.planningHorizon):
# activate allocation procedure for future items at target week # activate allocation procedure for future items at target week
procedureFuture = AllocationRoutine(initialWeek=kWeek, itemType=1) procedureFuture = AllocationRoutine(initialWeek=kWeek, itemType=1)
...@@ -26,9 +26,9 @@ class AllocManagement(): ...@@ -26,9 +26,9 @@ class AllocManagement():
# activate allocation procedure for PPOS items at target week # activate allocation procedure for PPOS items at target week
procedurePPOS = AllocationRoutine(initialWeek=G.TargetPPOSweek, itemType=0) procedurePPOS = AllocationRoutine(initialWeek=G.TargetPPOSweek, itemType=0)
procedurePPOS.Run() procedurePPOS.Run()
G.reCapacity.append(G.currentCapacity) G.reCapacity.append(G.currentCapacity)
k=0
print 'excess future', [i.orderID for i in G.ExcessFutureBuffer[k]], [i.qty for i in G.ExcessFutureBuffer[k]]
...@@ -34,37 +34,70 @@ class Allocation(): ...@@ -34,37 +34,70 @@ class Allocation():
# allocate item on its own route # allocate item on its own route
def allocationStd(self, MA): def allocationStd(self, MA):
requiredCapacity = [x*MA.qty for x in G.route[MA.MAid]] sufficient=True #flag that shows if we have sufficient capacity
# read the capacity that the MA requires
requiredCapacity={}
for x in G.RouteDict[MA.MAid]['route']:
requiredCapacity[x]=G.RouteDict[MA.MAid]['route'][x]*MA.qty
remainingCapacity = numpy.array(G.currentCapacity[self.week]) - numpy.array(requiredCapacity) print '-'*100
remainingCapacity = remainingCapacity.tolist() print 'MA',MA.MAid,'week',self.week
print 'Quantity to allocate=', MA.qty
print 'required',requiredCapacity
print 'available', G.CurrentCapacityDict
# read the remaining capacity for thegiven week and subtract the required from it
remainingCapacity={}
for bottleneck in G.CurrentCapacityDict:
remainingCapacity[bottleneck]=G.CurrentCapacityDict[bottleneck][self.week]-requiredCapacity[bottleneck]
# if we dropped below zero then the capacity is not sufficient
if remainingCapacity[bottleneck]<0:
sufficient=False
#remainingCapacity = numpy.array(G.currentCapacity[self.week]) - numpy.array(requiredCapacity)
#remainingCapacity = remainingCapacity.tolist()
print 'remaining',remainingCapacity
print sufficient
# check if there is sufficient capacity to process the order # check if there is sufficient capacity to process the order
if min(remainingCapacity) >= 0: if sufficient:
# update remaining capacity # update remaining capacity
allocableQty = MA.qty allocableQty = MA.qty
if MA.qty >= G.minPackingSize: if MA.qty >= G.minPackingSize:
G.currentCapacity[self.week] = remainingCapacity for bottleneck in G.CurrentCapacityDict:
G.CurrentCapacityDict[bottleneck][self.week]=remainingCapacity[bottleneck]
print 'allocation performed fully! remaining:'
print G.CurrentCapacityDict
# if the capacity available is not sufficient, the max allocable qty is derived # if the capacity available is not sufficient, the max allocable qty is derived
else: else:
# calculate max qty allocable # calculate max qty allocable
excessUnits = [0 for i in range(len(requiredCapacity))] #excessUnits = [0 for i in range(len(requiredCapacity))]
for i in range(len(remainingCapacity)): excessUnits={}
if requiredCapacity[i]>0 and remainingCapacity[i]<0: excess=0
excessUnits[i] = remainingCapacity[i]/G.route[MA.MAid][i] for bottleneck in remainingCapacity:
excess = math.ceil(math.fabs(min(excessUnits))) if requiredCapacity[bottleneck]>0 and remainingCapacity[bottleneck]<0:
excessUnits= remainingCapacity[bottleneck]/G.RouteDict[MA.MAid]['route'][bottleneck]
if math.ceil(math.fabs(excessUnits))>excess:
excess = math.ceil(math.fabs(excessUnits))
print 'excess', excess
# for i in range(len(remainingCapacity)):
# if requiredCapacity[i]>0 and remainingCapacity[i]<0:
# excessUnits[i] = remainingCapacity[i]/G.route[MA.MAid][i]
# excess = math.ceil(math.fabs(min(excessUnits)))
# update remaining capacity # update remaining capacity
assert(excess <= MA.qty or MA.qty < G.minPackingSize) assert(excess <= MA.qty or MA.qty < G.minPackingSize)
allocableQty = MA.qty - excess allocableQty = MA.qty - excess
print 'MA quantity', MA.qty
print 'allocableQty', allocableQty
if allocableQty >= G.minPackingSize: if allocableQty >= G.minPackingSize:
rCap = numpy.array(G.currentCapacity[self.week]) - numpy.multiply(allocableQty,G.route[MA.MAid]) #rCap = numpy.array(G.currentCapacity[self.week]) - numpy.multiply(allocableQty,G.route[MA.MAid])
G.currentCapacity[self.week] = rCap.tolist() for bottleneck in G.CurrentCapacityDict:
G.CurrentCapacityDict[bottleneck][self.week]-=allocableQty*G.RouteDict[MA.MAid]['route'][bottleneck]
print 'allocation performed partially! remaining:'
print G.CurrentCapacityDict
# update attributes/variables affected by allocation # update attributes/variables affected by allocation
if allocableQty >= G.minPackingSize: if allocableQty >= G.minPackingSize:
...@@ -82,51 +115,67 @@ class Allocation(): ...@@ -82,51 +115,67 @@ class Allocation():
G.PPOSLateness[G.replication] += max([0, self.week - MA.originalWeek])*allocableQty G.PPOSLateness[G.replication] += max([0, self.week - MA.originalWeek])*allocableQty
G.PPOSEarliness[G.replication] += max([0, MA.originalWeek - self.week])*allocableQty G.PPOSEarliness[G.replication] += max([0, MA.originalWeek - self.week])*allocableQty
print '-'*100
def alternativeRoutes(self, MA): def alternativeRoutes(self, MA):
sufficient=False #flag that shows if we have sufficient capacity
print '='*100
print 'MA',MA.MAid,'week',self.week
print 'Quantity to allocate=', MA.qty
# identify MAs with the same SP as the MA investigated # identify MAs with the same SP as the MA investigated
MAlist=[] #FIXME: the PPOS attribute can be used instead for the current MA alternativeMADict={} #FIXME: the PPOS attribute can be used instead for the current MA
# loop through the MAinfo
for alernativeMA in G.RouteDict:
for i in G.PPOSlist: # if it is the same MA do not consider it
if i != MA.MAid and G.PPOSlist[i]['SP'] == G.PPOSlist[MA.MAid]['SP']: # and G.PPOSlist[i][2] != G.PPOSlist[MA.MAid][2]: if alernativeMA==MA.MAid:
MAlist.append(i) continue
# if the alternative MA is of the same SP add it to the list
PPOS=G.RouteDict[alernativeMA]['PPOS']
SP=G.RouteDict[alernativeMA]['SP']
if PPOS==MA.PPOSid and SP==MA.SPid:
alternativeMADict[alernativeMA]=G.RouteDict[alernativeMA]
print 'alternativeRoutes',alternativeMADict
print 'available',G.CurrentCapacityDict
# calculate max number of units for each alternative MA # calculate max number of units for each alternative MA
maxUnits = [] maxUnits = {}
for i in MAlist: for alternativeMA in alternativeMADict:
i=int(i)
MAunits=[] MAunits=[]
for j in range(len(G.route[i])): for routeElement in alternativeMADict[alternativeMA]['route']:
if G.route[i][j] != 0: units=alternativeMADict[alternativeMA]['route'][routeElement]
MAunits.append(G.currentCapacity[self.week][j]/G.route[i][j]) if units!= 0:
maxUnits.append(math.floor(min(MAunits))) MAunits.append(G.CurrentCapacityDict[routeElement][self.week]/units)
sufficient=True
maxUnits[alternativeMA]=math.floor(min(MAunits))
print 'print units that can be allocated in alternative routes:', maxUnits
# choose MA with max number of units # choose MA with max number of units
if len(maxUnits) != 0 and max(maxUnits) != 0: if maxUnits and sufficient:
maxU=0
maxU = maxUnits[0] maxID=[]
maxID = [0] for MAid in maxUnits:
if maxUnits[MAid]>maxU:
if len(maxUnits) > 1: maxU=maxUnits[MAid]
for i in range(1,len(maxUnits)): maxID = [MAid]
if maxUnits[i] > maxU: if maxUnits[MAid]==maxU:
maxU = maxUnits[i] maxID.append(MAid)
maxID = [i]
if maxUnits[i] == maxU:
maxID.append(i)
# choose MA randomly among those with max number of units # choose MA randomly among those with max number of units
x = random.choice(maxID) chosenMAId = random.choice(maxID)
print 'chose to allocate in MA with id =', chosenMAId
allocableQty = min([maxU, MA.qty]) allocableQty = min([maxU, MA.qty])
print 'in this route we can allocate ',allocableQty
if allocableQty >= G.minPackingSize: if allocableQty >= G.minPackingSize:
# update remaining capacity for bottleneck in G.CurrentCapacityDict:
remCap = numpy.array(G.currentCapacity[self.week]) - allocableQty* numpy.array(G.route[MAlist[x]]) G.CurrentCapacityDict[bottleneck][self.week]-=allocableQty*G.RouteDict[chosenMAId]['route'][bottleneck]
G.currentCapacity[self.week] = remCap.tolist()
print 'allocation performed in the alternative route! remaining:'
print G.CurrentCapacityDict
# update attributes/variables affected by allocation # update attributes/variables affected by allocation
MA.qty -= allocableQty MA.qty -= allocableQty
MA.minQty = max([0, MA.minQty - allocableQty]) MA.minQty = max([0, MA.minQty - allocableQty])
...@@ -134,14 +183,14 @@ class Allocation(): ...@@ -134,14 +183,14 @@ class Allocation():
# update allocation output variable # update allocation output variable
# distinguish case of FutureDemand from PPOSdemand # distinguish case of FutureDemand from PPOSdemand
if MA.future == 1: if MA.future == 1:
G.AllocationFuture[G.replication].append([MA.orderID, MAlist[x], allocableQty, self.week+1]) G.AllocationFuture[G.replication].append([MA.orderID, alternativeMADict[chosenMAId], allocableQty, self.week+1])
G.FutureLateness[G.replication] += max([0, self.week - MA.originalWeek])*allocableQty G.FutureLateness[G.replication] += max([0, self.week - MA.originalWeek])*allocableQty
G.FutureEarliness[G.replication] += max([0, MA.originalWeek - self.week])*allocableQty G.FutureEarliness[G.replication] += max([0, MA.originalWeek - self.week])*allocableQty
else: else:
G.AllocationPPOS[G.replication].append([MA.orderID, MAlist[x], allocableQty, self.week+1]) G.AllocationPPOS[G.replication].append([MA.orderID, alternativeMADict[chosenMAId], allocableQty, self.week+1])
G.PPOSLateness[G.replication] += max([0, self.week - MA.originalWeek])*allocableQty G.PPOSLateness[G.replication] += max([0, self.week - MA.originalWeek])*allocableQty
G.PPOSEarliness[G.replication] += max([0, MA.originalWeek - self.week])*allocableQty G.PPOSEarliness[G.replication] += max([0, MA.originalWeek - self.week])*allocableQty
print '='*100
\ No newline at end of file
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
Created on 5 Sep 2013 Created on 5 Sep 2013
@author: Anna @author: Anna
''' '''
from dream.simulation.Globals import G from dream.simulation.Globals import G
from Allocation import Allocation from Allocation import Allocation
from dream.simulation.JobMA import Job from dream.simulation.JobMA import JobMA
class AllocationRoutine(): class AllocationRoutine():
def __init__(self, initialWeek, itemType): def __init__(self, initialWeek, itemType):
...@@ -62,7 +62,7 @@ class AllocationRoutine(): ...@@ -62,7 +62,7 @@ class AllocationRoutine():
for item in self.internalBuffer: for item in self.internalBuffer:
# if the item presents min qty then create a new item and store it into minBuffer # if the item presents min qty then create a new item and store it into minBuffer
if item.minQty: if item.minQty:
newJob = Job(item.orderID, item.MAid, item.SPid, item.PPOSid, item.minQty, item.minQty, item.originalWeek, item.future) newJob = JobMA(item.orderID, item.MAid, item.SPid, item.PPOSid, item.minQty, item.minQty, item.originalWeek, item.future)
self.minBuffer.append(newJob) self.minBuffer.append(newJob)
item.qty = item.qty - item.minQty item.qty = item.qty - item.minQty
item.minQty = 0 item.minQty = 0
......
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