def bench(self): orders = self.orderList.orders[:] self.orderList.orders = [] i = self.startValue while i <= len(orders): pprint("PERF Number of orders = " + str(i), BLUE) self.orderList.orders = orders[:i] optimizer = Optimizer(self.plant, self.orderList, Simulator(self.plant), Evaluator(self.plant)) schedule = optimizer.initialIndividual() t = time() simulator = Simulator(self.plant) simulator.simulate(schedule) t = time() - t self.addCairoPlotTime(t) self.addGnuPlotTime(i, t) i += 1
def simulate(self, inschedule): """ Simulates the schedule and checks delays caused by machine quantities, capacities constraints or breaks. inSchedule is the set of enter times of each order where each item is a tuple of (Order, Machine, RemainingProcessingTime). """ pprint("SIM Starting new simulation...", CYAN, self.printing) self.inSchedule = inschedule assert type(self.inSchedule) == Schedule assert len(self.inSchedule.schedule) == 0 assert len(self.inSchedule.finishTimes) == 0 schedule = self.inSchedule.startTimes[:] # sort schedule by enter times schedule.sort(lambda a, b: cmp(a[2], b[2])) # t = first enter time in schedule t = schedule[0][2] self.delay = 0 self.numOfOrdersFinished = 0 numOfTotalOrders = len(schedule) schedule.sort( lambda a, b: cmp(b[0].currentMachine, a[0].currentMachine)) # while all orders finish processing while self.numOfOrdersFinished < numOfTotalOrders: self.checkScheduleEnterTimes(schedule, t) # loop on all machines to check if any order finished processing time for nodeIndex, node in enumerate(self.graph): # check if the node is a MachineNode not a TraverseNode if type(node) == list: self.checkMachineNodeFinishTime(nodeIndex, node, t) # if the node is a TraverseNode not MachineNode to check next machine #quantity and capacity, and if there is a break else: self.checkTraverseNodeFinishTime(nodeIndex, node, t) t += 1 pprint( "SIM --------------------------------------------------------------", CYAN, self.printing) # reset the simulator self.graph = [] self.createGraph()
def plotCairoPlot(self): try: from thirdparty.CairoPlot import dot_line_plot except: pprint("PERF Will not output to graph. Install CairoPlot.", RED) return dot_line_plot( path.join( "benchmarks", self.prefix + "-" + self.testName + "-" + str(self.testNumber)) + ".png", self.cairoPlotTimes, 800, 800, (255, 255, 255), 5, True, True, True, None, None, None, None) dot_line_plot( path.join( "benchmarks", self.prefix + "-" + self.testName + "-" + str(self.testNumber)) + ".ps", self.cairoPlotTimes, 800, 800, (255, 255, 255), 5, True, True, True, None, None, None, None)
def bench(self): i = 10 while i <= 200: pprint("PERF Mutation Range = " + str(i), BLUE) optimizer = Optimizer(self.plant, self.orderList, Simulator(self.plant), Evaluator(self.plant)) optimizer.populationSize = 10 optimizer.iterations = 10 optimizer.indivMutationRate = 0.5 optimizer.selectionRate = 0.5 optimizer.mutationRange = i t = time() optimizer.run() t = time() - t t -= optimizer.simulatorTime self.addCairoPlotTime(t) self.addGnuPlotTime(i, t) i += 20
def bench(self): val = 4 i = self.startValue while i <= 6: pprint("PERF Large Value = " + str(i * val), BLUE) for o in self.orderList.orders: o.deadline *= val for r in o.recipe.recipe: r[1] *= val optimizer = Optimizer(self.plant, self.orderList, Simulator(self.plant), Evaluator(self.plant)) schedule = optimizer.initialIndividual() t = time() simulator = Simulator(self.plant) simulator.simulate(schedule) t = time() - t self.addCairoPlotTime(t) self.addGnuPlotTime((i + 1) * val, t) i += 1
def bench(self): orders = self.orderList.orders[:] self.orderList.orders = [] i = self.startValue while i <= len(orders): pprint("PERF Number of orders = " + str(i), BLUE) self.orderList.orders = orders[:i] optimizer = Optimizer(self.plant, self.orderList, Simulator(self.plant), Evaluator(self.plant)) optimizer.populationSize = 10 optimizer.iterations = 10 optimizer.indivMutationRate = 0.5 optimizer.selectionRate = 0.5 optimizer.mutationRange = 10 t = time() optimizer.run() t = time() - t t -= optimizer.simulatorTime self.addCairoPlotTime(t) self.addGnuPlotTime(i, t) i += 1
def bench(self): recipes = [] for o in self.orderList.orders: recipes.append(o.recipe.recipe[:]) o.recipe.recipe = [] machines = self.plant.machines[:] self.plant.machines = [] i = self.startValue while i <= len(machines): pprint("PERF Number of machines = " + str(i), BLUE) self.plant.machines = machines[:i] for j, o in enumerate(self.orderList.orders): o.recipe.recipe = recipes[j][:i] scheduler = Scheduler(self.plant, self.orderList) t = time() scheduler.start() t = time() - t self.addCairoPlotTime(t) self.addGnuPlotTime(i, t) i += 1
def checkScheduleEnterTimes(self, schedule, t): """ Checks if an order's entering time at first machine """ # loop over the enter times to set the first machine of each order for i, s in enumerate(schedule): if s == None: continue # checks if enter time at first machine passed if s[2] <= t: entered = False currentMachineIndex = 0 # check if order was already in the pant currentMachine = s[0].currentMachine if currentMachine != "": currentMachineIndex = self.machineIndexInGraph( currentMachine) machine = self.graph[currentMachineIndex][0].machine # check if there is no break for this machine at: # * The enter time of the order # * The processing time of the order in the machine if [ z in machine.setOfBreaks() for z in range(t, t + s[0].recipe[machine.name]) ].count(True) == 0: # loop over the basins of the machine for n in self.graph[currentMachineIndex]: # check if the basin is empty if n.currentOrder == None: # assign current order of this basin with the processing time n.currentOrder = [ s[0], s[0].recipe[n.machine.name] ] # remove enter time from the schedule list schedule[i] = None entered = True pprint( "SIM %10s %20s %15s at time %5s." % (n.currentOrder[0], "entered", n.machine, t), YELLOW, self.printing) self.inSchedule.schedule.append( [n.currentOrder[0], str(n.machine.name), t]) break # order will be delayed in case the machine is busy if entered == False: pprint( "SIM %10s %20s %15s at time %5s." % (n.currentOrder[0], "could not enter", n.machine, t), RED, self.printing) s[2] += 1 self.delay += 1 else: pprint( "SIM %10s %20s %15s at time %5s because of machine break." % (s[0], "could not enter", machine, t), RED, self.printing) s[2] += 1 self.delay += 1
def bench(self): val = 2 i = self.startValue while i < 10: pprint("PERF Large Value = " + str(i * val), BLUE) for o in self.orderList.orders: o.deadline *= val for r in o.recipe.recipe: r[1] *= val optimizer = Optimizer(self.plant, self.orderList, Simulator(self.plant), Evaluator(self.plant)) optimizer.populationSize = 10 optimizer.iterations = 10 optimizer.indivMutationRate = 0.5 optimizer.selectionRate = 0.5 optimizer.mutationRange = 500 t = time() optimizer.run() t = time() - t t -= optimizer.simulatorTime self.addCairoPlotTime(t) self.addGnuPlotTime((i + 1) * val, t) i += 1
def run(self): """ Runs the main Scheduler logic. """ for machine in self.plant.machines: var = self.createMachineQuantityVarName(machine) self.problem.addVariable(var, [machine.quantity]) for machine in self.plant.machines: for order in self.orderList.orders: var = self.createTimeAtMachineVarName(order, machine) self.problem.addVariable(var, [order.recipe[machine.name]]) for machineIndex, machine in enumerate(self.plant.machines): for order in self.orderList.orders: self.addOrderEnterTimeAtMachineVar(order, machine.name, machineIndex) for machineIndex, machine in enumerate(self.plant.machines): if machine.precedence == True and \ machineIndex != len(self.plant.machines) - 1: self.addCapacityConstraint(machine, machineIndex) self.addMachineQuantityConstraint(machine) for machineIndex, machine in enumerate(self.plant.machines): if len(machine.setOfBreaks()) != 0: for order in self.orderList.orders: enterVar = self.createEnterTimeVarName(order, machine) self.problem.addConstraint( MachineBreaksConstraint(order, machine), [enterVar]) for order in self.orderList.orders: self.addFinishTimeVar(order) pprint("SCHED Computing solutions...", BLUE, self.printing) solutions = self.problem.getSolutions() return solutions, len(solutions)
def bench(self): recipes = [] for o in self.orderList.orders: recipes.append(o.recipe.recipe[:]) o.recipe.recipe = [] machines = self.plant.machines[:] self.plant.machines = [] i = self.startValue while i <= len(machines): pprint("PERF Number of machines = " + str(i), BLUE) self.plant.machines = machines[:i] for j, o in enumerate(self.orderList.orders): o.recipe.recipe = recipes[j][:i] optimizer = Optimizer(self.plant, self.orderList, Simulator(self.plant), Evaluator(self.plant)) schedule = optimizer.initialIndividual() t = time() simulator = Simulator(self.plant) simulator.simulate(schedule) t = time() - t self.addCairoPlotTime(t) self.addGnuPlotTime(i, t) i += 1
def optimizerMachinesPerf(plant, orderList, testNum): machines = plant.machines[:] orders = orderList.orders[:] pprint( "PERF Starting optimizer benchmark test " + str(testNum) + " on machines", BLUE) orderList.orders = orders[:] recipes = [] for o in orderList.orders: recipes.append(o.recipe.recipe[:]) o.recipe.recipe = [] plant.machines = [] times = [0] for i in range(1, len(machines) + 1): pprint("PERF Number of machines = " + str(i), BLUE) plant.machines = machines[:i] for j, o in enumerate(orderList.orders): o.recipe.recipe = recipes[j][:i] optimizer = Optimizer(plant, orderList, Simulator(plant), Evaluator(plant)) optimizer.populationSize = 10 optimizer.iterations = 10 optimizer.indivMutationRate = 0.5 optimizer.selectionRate = 0.5 optimizer.mutationRange = 10 t = time() optimizer.run() t = time() - t t -= optimizer.simulatorTime times.append(t) pprint("PERF Time = " + str(t), GREEN) try: from thirdparty.CairoPlot import dot_line_plot except: pprint("PERF Will not output to graph.", RED) return dot_line_plot( path.join("benchmarks", "optimizer-machines-" + str(testNum)) + FORMAT, times, 800, 800, (255, 255, 255), 5, True, True, True, None, None, None, None)
def optimizerLargeValuesPerf(plant, orderList, testNum): machines = plant.machines[:] orders = orderList.orders[:] pprint( "PERF Starting optimizer benchmark test " + str(testNum) + " with large values", BLUE) orderList.orders = orders[:6] plant.machines = machines[:] times = [0] val = 2 for i in range(1, 6): pprint("PERF Large Value = " + str(i * val), BLUE) for o in orderList.orders: o.deadline *= val for r in o.recipe.recipe: r[1] *= val optimizer = Optimizer(plant, orderList, Simulator(plant), Evaluator(plant)) optimizer.populationSize = 5 optimizer.iterations = 5 optimizer.indivMutationRate = 0.5 optimizer.selectionRate = 0.5 optimizer.mutationRange = 500 t = time() optimizer.run() t = time() - t t -= optimizer.simulatorTime times.append(t) pprint("PERF Time = " + str(t), GREEN) try: from thirdparty.CairoPlot import dot_line_plot except: pprint("PERF Will not output to graph.", RED) return dot_line_plot( path.join("benchmarks", "optimizer-largevalues-" + str(testNum)) + FORMAT, times, 800, 800, (255, 255, 255), 5, True, True, True, None, None, None, None)
def simulatorMachinesPerf(plant, orderList, testNum): machines = plant.machines[:] orders = orderList.orders[:] pprint( "PERF Starting simulator benchmark test " + str(testNum) + " on machines", BLUE) orderList.orders = orders[:] recipes = [] for o in orderList.orders: recipes.append(o.recipe.recipe[:]) o.recipe.recipe = [] plant.machines = [] times = [0] for i in range(1, len(machines) + 1): pprint("PERF Number of machines = " + str(i), BLUE) plant.machines = machines[:i] for j, o in enumerate(orderList.orders): o.recipe.recipe = recipes[j][:i] optimizer = Optimizer(plant, orderList, Simulator(plant), Evaluator(plant)) schedule = optimizer.initialIndividual() t = time() simulator = Simulator(plant) simulator.simulate(schedule) t = time() - t times.append(t) pprint("PERF Time = " + str(t), GREEN) try: from thirdparty.CairoPlot import dot_line_plot except: pprint("PERF Will not output to graph.", RED) return dot_line_plot( path.join("benchmarks", "simulator-machines-" + str(testNum)) + FORMAT, times, 800, 800, (255, 255, 255), 5, True, True, True, None, None, None, None)
def simulatorLargeValuesPerf(plant, orderList, testNum): machines = plant.machines[:] orders = orderList.orders[:] pprint( "PERF Starting simulator benchmark test " + str(testNum) + " with large values", BLUE) orderList.orders = orders[:] plant.machines = machines[:] times = [0] val = 4 for i in range(1, 7): pprint("PERF Large Value = " + str(i * val), BLUE) for o in orderList.orders: o.deadline *= val for r in o.recipe.recipe: r[1] *= val optimizer = Optimizer(plant, orderList, Simulator(plant), Evaluator(plant)) schedule = optimizer.initialIndividual() t = time() simulator = Simulator(plant) simulator.simulate(schedule) t = time() - t times.append(t) pprint("PERF Time = " + str(t), GREEN) try: from thirdparty.CairoPlot import dot_line_plot except: pprint("PERF Will not output to graph.", RED) return dot_line_plot( path.join("benchmarks", "simulator-largevalues-" + str(testNum)) + FORMAT, times, 800, 800, (255, 255, 255), 5, True, True, True, None, None, None, None)
def optimizerMutationRangePerf(plant, orderList, testNum): machines = plant.machines[:] orders = orderList.orders[:] pprint( "PERF Starting optimizer benchmark test " + str(testNum) + " on mutation range", BLUE) orderList.orders = orders[:] plant.machines = machines[:] times = [0] for i in range(10, 200, 20): pprint("PERF Selection rate = " + str(i), BLUE) optimizer = Optimizer(plant, orderList, Simulator(plant), Evaluator(plant)) optimizer.populationSize = 5 optimizer.iterations = 5 optimizer.indivMutationRate = 0.5 optimizer.selectionRate = 0.5 optimizer.mutationRange = i t = time() optimizer.run() t = time() - t t -= optimizer.simulatorTime times.append(t) pprint("PERF Time = " + str(t), GREEN) try: from thirdparty.CairoPlot import dot_line_plot except: pprint("PERF Will not output to graph.", RED) return dot_line_plot( path.join("benchmarks", "optimizer-mutationrange-" + str(testNum)) + FORMAT, times, 800, 800, (255, 255, 255), 5, True, True, True, None, None, None, None)
def schedulerMachinesPerf(plant, orderList, testNum): machines = plant.machines[:] orders = orderList.orders[:] pprint("PERF Starting benchmark test " + str(testNum) + " on machines", BLUE) orderList.orders = orders[:] recipes = [] for o in orderList.orders: recipes.append(o.recipe.recipe[:]) o.recipe.recipe = [] plant.machines = [] machinetimes = [0] for i in range(1, len(machines) + 1): pprint("PERF Number of machines = " + str(i), BLUE) plant.machines = machines[:i] for j, o in enumerate(orderList.orders): o.recipe.recipe = recipes[j][:i] scheduler = Scheduler(plant, orderList) t = time() scheduler.start() t = time() - t machinetimes.append(t) pprint("PERF Time = " + str(t), GREEN) try: from thirdparty.CairoPlot import dot_line_plot except: pprint("PERF Will not output to graph.", RED) return dot_line_plot( path.join("benchmarks", "machines-" + str(testNum)) + ".ps", machinetimes, 800, 800, (255, 255, 255), 5, True, True, True, None, None, None, None)
"optimize": (optimize, ["plant-name", "order-list-name", "config-name"], "Optimize a schedule for an order list on a plant"), "run": (run, ["plant-name", "order-list-name", "config-name"], "Compute and optimize a schedule for an order list on a plant"), "perf": (perf, ["benchmark-number"], "Run a benchmark of the scheduler, the optimizer and the simulator") } def showHelp(): """ Shows help data from the commands dict. """ print("Plant Maker\nUsage:\n") for c in commands: print(c, end = " ") for a in commands[c][1]: print("<" + a + ">", end = " ") print("-- " + commands[c][2]) if __name__ == '__main__': if len(sys.argv) < 3: showHelp() else: arguments = sys.argv[2:] try: commands[sys.argv[1]][0](arguments) except KeyboardInterrupt: pprint("Operation cancelled by user.", GREEN)
def checkScheduleEnterTimes(self, schedule, t): """ Checks if an order's entering time at first machine """ # loop over the enter times to set the first machine of each order for i, s in enumerate(schedule): if s == None: continue # checks if enter time at first machine passed if s[2] <= t: entered = False currentMachineIndex = 0 # check if order was already in the pant currentMachine = s[0].currentMachine if currentMachine != "": currentMachineIndex = self.machineIndexInGraph( currentMachine) machine = self.graph[currentMachineIndex][0].machine # check if there is no break for this machine at: # * The enter time of the order # * The processing time of the order in the machine if any([ z in machine.setOfBreaks for z in range(t, t + s[0].recipe[machine.name]) ]) == False: # loop over the basins of the machine for node in self.graph[currentMachineIndex]: # check if the basin is empty if node.currentOrder == None: # check if orders in the machine is not important if node.machine.precedence == False: # assign current order of this basin with the processing time node.currentOrder = [ s[0], s[0].recipe[node.machine.name] ] pprint( "SIM %10s %20s %15s at time %5s." % (node.currentOrder[0], "entered", node.machine, t), YELLOW, self.printing) self.inSchedule.schedule.append([ node.currentOrder[0], str(node.machine.name), t ]) schedule[i] = None entered = True break # check if orders in the machine must be reserved (Drier) else: # set the minimum finish time the order can finish the # next machine time = max( self.minTimeFinish( self.graph[currentMachineIndex]), s[0].recipe[node.machine.name]) node.currentOrder = [s[0], time] # if there is a delay if time != s[0].recipe[node.machine.name]: pprint( "SIM %10s %20s %15s at time %5s with overtime %5s." % (s[0], "entered", node.machine, t, time - s[0].recipe[node.machine.name]), RED, self.printing) self.delay += time - s[0].recipe[ node.machine.name] else: pprint( "SIM %10s %20s %15s at time %5s." % (s[0], "entered", node.machine, t), YELLOW, self.printing) self.inSchedule.schedule.append([ node.currentOrder[0], str(node.machine.name), t ]) # remove enter time from the schedule list schedule[i] = None entered = True break # order will be delayed in case the machine is busy if entered == False: pprint( "SIM %10s %20s %15s at time %5s." % (node.currentOrder[0], "could not enter", node.machine, t), RED, self.printing) s[2] += 1 self.delay += 1 else: pprint( "SIM %10s %20s %15s at time %5s because of machine break." % (s[0], "could not enter", machine, t), RED, self.printing) s[2] += 1 self.delay += 1
def addGnuPlotTime(self, x, y): self.gnuPlotTimes.append((x, y)) pprint("PERF Time = " + str(y), GREEN)
either a help str or to a function pointer, it is used to generalize resolution of both cases when calling the program with command line arguments. """ import sys from os import path from app.controller import Controller from order.orderlist import OrderList from plant.plant import Plant from extra.printer import pprint, GREEN, RED from benchmark.benchrun import runPerf try: import psyco psyco.full() except: pprint("Will not run with optimization. Install psyco!", RED) def configFileExists(configName): configFilename = path.join("configs", configName + ".xml") if not path.exists(configFilename): raise Exception("Configuration doesn't exist") return configFilename def plantFileExists(plantName): """ Constructs the Plant filename from str plantName and returns it if the file exists, if it doesn't, an Exception is thrown. """ plantFilename = path.join("plants", plantName + ".xml")
def checkTraverseNodeFinishTime(self, nodeIndex, node, t): """ Checks if a traverse finished moving an order, and check next machine's constraints """ for j, o in enumerate(node.orders): if o == None: continue if o[1] > 0: o[1] -= 1 else: machine = self.graph[nodeIndex + 1][0].machine # check if there is no break for this machine at: # * The enter time of the order in the machine # * The processing time of the order if it enters now if [ z in machine.setOfBreaks() for z in range(t, t + o[0].recipe[machine.name]) ].count(True) == 0: # check if one of the next machine basins for m in self.graph[nodeIndex + 1]: # check if one of the basins is empty if m.currentOrder == None: # check if orders in the machine is not important if m.machine.precedence == False: m.currentOrder = [ o[0], o[0].recipe[m.machine.name] ] pprint( "SIM %10s %20s %15s at time %5s." % (o[0], "entered", m.machine, t), YELLOW, self.printing) # check if orders in the machine must be reserved (Drier) else: # set the minimum finish time the order can finish the # next machine time = max( self.minTimeFinish(self.graph[nodeIndex + 1]), o[0].recipe[m.machine.name]) m.currentOrder = [o[0], time] # if there is a delay if time != o[0].recipe[m.machine.name]: pprint( "SIM %10s %20s %15s at time %5s with overtime %5s." % (o[0], "entered", m.machine, t, time - o[0].recipe[m.machine.name]), RED, self.printing) else: pprint( "SIM %10s %20s %15s at time %5s." % (o[0], "entered", m.machine, t), YELLOW, self.printing) self.inSchedule.schedule.append( [m.currentOrder[0], str(m.machine.name), t]) if o[1] < 0: pprint( "SIM %10s before %15s was delayed %5s." % (o[0], m.machine, o[1]), RED, self.printing) self.delay += 1 node.orders[j] = None break # If there is a break time for the machine, and the order cannot # enter the machine for processing else: pprint( "SIM %10s %20s %15s at time %5s because of machine break." % (o[0], "could not enter", machine, t), RED, self.printing) self.delay += 1
def start(self, endMarginLimit=10, machineMarginLimit=3): assert len(self.orderList.orders) > 0 assert len(self.plant.machines) > 0 pprint("SCHED Started...", BLUE, self.printing) self.endMargin = 1 while self.endMargin <= endMarginLimit: self.machineMargin = 1 machineMarginLimit = self.endMargin while self.machineMargin <= machineMarginLimit: try: pprint("SCHED End Margin: %d, Machine Margin: %d" % \ (self.endMargin, self.machineMargin), YELLOW, self.printing) self.problem.reset() solutions, numberOfSolutions = self.run() if numberOfSolutions > 0: pprint("SCHED Finished.", BLUE) return solutions except Exception as e: pprint("SCHED Exception " + str(e), RED) pprint("SCHED Trying new value for End Margin.", RED) endMarginLimit += 1 self.machineMargin += 1 self.endMargin += 1 pprint("SCHED No solutions found.", RED, self.printing) return None
def simulate(self, inSchedule): pprint("SIM Starting new simulation...", CYAN, self.printing) assert type(inSchedule) == Schedule assert len(inSchedule.schedule) == 0 assert len(inSchedule.finishTimes) == 0 schedule = inSchedule.startTimes[:] schedule.sort(lambda a, b: cmp(a[2], b[2])) t = schedule[0][2] delay = 0 numOfOrdersFinished = 0 numOfTotalOrders = len(schedule) while numOfOrdersFinished < numOfTotalOrders: for i, s in enumerate(schedule): if s == None: continue if s[2] <= t: entered = False currentMachineIndex = 0 currentMachine = s[0].currentMachine if currentMachine != "": currentMachineIndex = self.machineIndexInGraph( currentMachine) machine = self.graph[currentMachineIndex][0].machine if [ z in machine.setOfBreaks() for z in range(t, t + s[0].recipe[machine.name]) ].count(True) == 0: for n in self.graph[currentMachineIndex]: if n.currentOrder == None: n.currentOrder = [ s[0], s[0].recipe[n.machine.name] ] schedule[i] = None entered = True pprint( "SIM %10s %20s %15s at time %5s." % (n.currentOrder[0], "entered", n.machine, t), YELLOW, self.printing) inSchedule.schedule.append([ n.currentOrder[0], str(n.machine.name), t ]) break if entered == False: pprint( "SIM %10s %20s %15s at time %5s." % (n.currentOrder[0], "could not enter", n.machine, t), RED, self.printing) s[2] += 1 delay += 1 else: pprint( "SIM %10s %20s %15s at time %5s because of machine break." % (s[0], "could not enter", machine, t), RED, self.printing) s[2] += 1 delay += 1 for i, n in enumerate(self.graph): if type(n) == list: for m in n: if m.currentOrder != None: if m.currentOrder[1] != 0: m.currentOrder[1] -= 1 else: if n == self.graph[-1]: pprint( "SIM %10s %20s at time %5s." % (m.currentOrder[0], "finished", t), GREEN, self.printing) inSchedule.finishTimes.append( [m.currentOrder[0], t]) m.currentOrder = None numOfOrdersFinished += 1 else: self.graph[i + 1].orders.append([ m.currentOrder[0], self.plant.craneMoveTime ]) pprint( "SIM %10s %20s %15s at time %5s." % (m.currentOrder[0], "left", m.machine, t), YELLOW, self.printing) m.currentOrder = None else: for j, o in enumerate(n.orders): if o == None: continue if o[1] > 0: o[1] -= 1 else: machine = self.graph[i + 1][0].machine if [ z in machine.setOfBreaks() for z in range( t, t + o[0].recipe[machine.name]) ].count(True) == 0: for m in self.graph[i + 1]: if m.currentOrder == None: if m.machine.precedence == False: m.currentOrder = [ o[0], o[0].recipe[m.machine.name] ] pprint( "SIM %10s %20s %15s at time %5s." % (o[0], "entered", m.machine, t), YELLOW, self.printing) else: time = max( self.minTimeFinish( self.graph[i + 1]), o[0].recipe[m.machine.name]) m.currentOrder = [o[0], time] if time != o[0].recipe[ m.machine.name]: pprint( "SIM %10s %20s %15s at time %5s with overtime %5s." % (o[0], "entered", m.machine, t, time - o[0]. recipe[m.machine.name]), RED, self.printing) else: pprint( "SIM %10s %20s %15s at time %5s." % (o[0], "entered", m.machine, t), YELLOW, self.printing) inSchedule.schedule.append([ m.currentOrder[0], str(m.machine.name), t ]) if o[1] < 0: pprint( "SIM %10s before %15s was delayed %5s." % (o[0], m.machine, o[1]), RED, self.printing) delay += 1 n.orders[j] = None break else: pprint( "SIM %10s %20s %15s at time %5s because of machine break." % (o[0], "could not enter", machine, t), RED, self.printing) delay += 1 t += 1 pprint( "SIM --------------------------------------------------------------", CYAN, self.printing)
def addCairoPlotTime(self, t): self.cairoPlotTimes.append(t) pprint("PERF Time = " + str(t), GREEN)
def simulate(self, inSchedule): """ Simulates the schedule and checks delays caused by machine quantities, capacities constraints or breaks. inSchedule is the set of enter times of each order where each item is a tuple of (Order, Machine, RemainingProcessingTime). """ pprint("SIM Starting new simulation...", CYAN, self.printing) assert type(inSchedule) == Schedule assert len(inSchedule.schedule) == 0 assert len(inSchedule.finishTimes) == 0 schedule = inSchedule.startTimes[:] # sort schedule by enter times schedule.sort(lambda a, b: cmp(a[2], b[2])) # t = first enter time in schedule t = schedule[0][2] delay = 0 numOfOrdersFinished = 0 numOfTotalOrders = len(schedule) # while all orders finish processing while numOfOrdersFinished < numOfTotalOrders: # loop over the enter times to set the first machine of each order for i, s in enumerate(schedule): if s == None: continue # checks if enter time at first machine passed if s[2] <= t: entered = False currentMachineIndex = 0 # check if order was already in the pant currentMachine = s[0].currentMachine if currentMachine != "": currentMachineIndex = self.machineIndexInGraph( currentMachine) machine = self.graph[currentMachineIndex][0].machine # check if there is no break for this machine at: # * The enter time of the order # * The processing time of the order in the machine if [ z in machine.setOfBreaks() for z in range(t, t + s[0].recipe[machine.name]) ].count(True) == 0: # loop over the basins of the machine for n in self.graph[currentMachineIndex]: # check if the basin is empty if n.currentOrder == None: # assign current order of this basin with the processing time n.currentOrder = [ s[0], s[0].recipe[n.machine.name] ] # remove enter time from the schedule list schedule[i] = None entered = True pprint( "SIM %10s %20s %15s at time %5s." % (n.currentOrder[0], "entered", n.machine, t), YELLOW, self.printing) inSchedule.schedule.append([ n.currentOrder[0], str(n.machine.name), t ]) break # order will be delayed in case the machine is busy if entered == False: pprint( "SIM %10s %20s %15s at time %5s." % (n.currentOrder[0], "could not enter", n.machine, t), RED, self.printing) s[2] += 1 delay += 1 else: pprint( "SIM %10s %20s %15s at time %5s because of machine break." % (s[0], "could not enter", machine, t), RED, self.printing) s[2] += 1 delay += 1 # loop on all machines to check if any order finished processing time for i, n in enumerate(self.graph): # check if the node is a MachineNode not a TraverseNode if type(n) == list: # m represents each basin in the machine for m in n: # if there is an order in the basin if m.currentOrder != None: # if the remaining processing time > 0 if m.currentOrder[1] != 0: # decrement the remaining processing time by 1 m.currentOrder[1] -= 1 # the order finished processing on this machine else: # remove order from the machine currentOrder m.currentOrder = None # check if this machine was the last one if n == self.graph[-1]: pprint( "SIM %10s %20s at time %5s." % (m.currentOrder[0], "finished", t), GREEN, self.printing) inSchedule.finishTimes.append( [m.currentOrder[0], t]) numOfOrdersFinished += 1 # the machine is not the last one else: self.graph[i + 1].orders.append([ m.currentOrder[0], self.plant.craneMoveTime ]) pprint( "SIM %10s %20s %15s at time %5s." % (m.currentOrder[0], "left", m.machine, t), YELLOW, self.printing) # if the node is a TraverseNode not MachineNode to check next machine #quantity and capacity, and if there is a break else: for j, o in enumerate(n.orders): if o == None: continue if o[1] > 0: o[1] -= 1 else: machine = self.graph[i + 1][0].machine # check if there is no break for this machine at: # * The enter time of the order in the machine # * The processing time of the order if it enters now if [ z in machine.setOfBreaks() for z in range( t, t + o[0].recipe[machine.name]) ].count(True) == 0: # check if one of the next machine basins for m in self.graph[i + 1]: # check if one of the basins is empty if m.currentOrder == None: # check if orders in the machine is not important if m.machine.precedence == False: m.currentOrder = [ o[0], o[0].recipe[m.machine.name] ] pprint( "SIM %10s %20s %15s at time %5s." % (o[0], "entered", m.machine, t), YELLOW, self.printing) # check if orders in the machine must be reserved (Drier) else: # set the minimum finish time the order can finish the # next machine time = max( self.minTimeFinish( self.graph[i + 1]), o[0].recipe[m.machine.name]) m.currentOrder = [o[0], time] # if there is a delay if time != o[0].recipe[ m.machine.name]: pprint( "SIM %10s %20s %15s at time %5s with overtime %5s." % (o[0], "entered", m.machine, t, time - o[0]. recipe[m.machine.name]), RED, self.printing) else: pprint( "SIM %10s %20s %15s at time %5s." % (o[0], "entered", m.machine, t), YELLOW, self.printing) inSchedule.schedule.append([ m.currentOrder[0], str(m.machine.name), t ]) if o[1] < 0: pprint( "SIM %10s before %15s was delayed %5s." % (o[0], m.machine, o[1]), RED, self.printing) delay += 1 n.orders[j] = None break # If there is a break time for the machine, and the order cannot # enter the machine for processing else: pprint( "SIM %10s %20s %15s at time %5s because of machine break." % (o[0], "could not enter", machine, t), RED, self.printing) delay += 1 t += 1 pprint( "SIM --------------------------------------------------------------", CYAN, self.printing)