def two_task_scenario(): S = Scenario('Scenario_1', horizon=horizon) T1 = S.Task('T1') T2 = S.Task('T2') R1 = S.Resource('R1') R2 = S.Resource('R2') S += T1 * 2 + T2 #T1 has priority to break ties return S
def makeSchedule(content): horizon = content["horizon"] print(horizon) # Define all the players MyScenario = Scenario('manufacturing_schedule', horizon=horizon) MyResources = {} MyTasks = {} # Define the resources (manufacturing lines) manufacturing_lines = content["manufacturing_lines"] print(manufacturing_lines) for manufacturing_line in manufacturing_lines: MyResources[manufacturing_line] = MyScenario.Resource( str(manufacturing_line)) # Define tasks which are already present which must remain in the same location # Known as blocking tasks blocks = content["blocks"] print(blocks) for block in blocks: blockid = str(block["goal_name"] + "_" + str(block["sku_number"])) manufacturing_line_name = block["manufacturing_line_name"] start = block["start"] end = block["end"] # Create task and add the resource that will execute it task = MyScenario.Task(blockid, length=end - start) task += MyResources[manufacturing_line_name] # Define the bounds MyScenario += task > start, task < end # New tasks which must be scheduled tasks = content["tasks"] print(tasks) for task in tasks: taskid = str(task["goal_name"] + "_" + str(task["sku_number"])) duration = task["duration"] manufacturing_line_names = task["manufacturing_line_names"] deadline = task["deadline"] t = MyScenario.Task(taskid, length=duration, delay_cost=1) resources = MyResources[manufacturing_line_names[0]] for i in range(1, len(manufacturing_line_names)): resources = resources | MyResources[manufacturing_line_names[i]] t += resources MyScenario += t > 0, t < deadline solvers.mip.solve(MyScenario, msg=1) plotters.matplotlib.plot(MyScenario, img_filename='household.png') return MyScenario.solution()
import sys sys.path.append('../src') import getopt opts, _ = getopt.getopt(sys.argv[1:], 't:', ['test']) n_night_shifts = 5 n_day_shifts = 5 n_tasks = n_night_shifts + n_day_shifts horizon = n_tasks from pyschedule import Scenario, solvers, plotters S = Scenario('shift_bounds', horizon=horizon) R = S.Resource('P') for i in range(n_night_shifts): # added some completion time cost, so without any # constraint, there would be first 5 night shifts # and then 5 day shifts T = S.Task('N%i' % i, completion_time_cost=2) # the shift type of night shifts is -1 T.shift_type = -1 T += R for i in range(n_day_shifts): T = S.Task('D%i' % i, completion_time_cost=1) # the shift type of day shifts is -1 T.shift_type = 1 T += R for i in range(horizon): # for every set of periods 1..i, make sure that # there is always at most one more night shift than
# Installer python 3.6 pour windows (3.8 pas compatible pour l'instant) # Pour exécuter le fichier : # py -3.6 lenomdufichier.py from pyschedule import Scenario, solvers, plotters, alt # On crée un scénario , la période est en heures dans ce cas S = Scenario('emploiDeMaison', horizon=10) # 2 ressources: Alice et Bob Alice, Bob = S.Resource('Alice'), S.Resource('Bob') # 3 tâches: cuisiner, nettoyer, and polir cuisiner = S.Task('cuisiner', 1) nettoyer = S.Task('nettoyer', 2) polir = S.Task('polir', 3) # chaque tache peut être réalisée par Alice ou Bob cuisiner += Alice | Bob nettoyer += Alice | Bob polir += Alice | Bob # Résoudre et imprimer l'ordonnac S.use_makespan_objective() solvers.mip.solve(S, msg=1) print(S.solution()) # Dans cet exemple, nous utilisons un objectif makespan,
import sys sys.path += ['../src','src'] import getopt opts, _ = getopt.getopt(sys.argv[1:], 't:', ['test']) from pyschedule import Scenario, solvers, plotters horizon = 20 S = Scenario('switch',horizon=horizon) # Set some colors for the tasks task_colors = dict() task_group_colors = { 'A': 'green', 'B': 'red', 'C':'blue'} R_machine = S.Resource('machine') T = dict() task_types = { 'A': 1, 'B': 2, 'C': 3} task_lengths = { 'A': 2, 'B': 3, 'C':1 } max_n_switches = 10 for i in range(max_n_switches): name = 'S_%i'%i T[name] = S.Task(name,group='switch') T[name] += R_machine T[name]['schedule_cost'] = 0.001 for task_type in task_types: setup_param = '%s_state'%task_type T[name][setup_param] = 1 for task_type in task_types: for i in range(task_types[task_type]):
from pyschedule import Scenario, solvers, plotters, alt S = Scenario('resource_cost', horizon=10) # assign a cost per period of 5 R = S.Resource('R', cost_per_period=5) T = S.Task('T', length=2, delay_cost=1) T += R solvers.mip.solve(S, msg=1) print(S.solution()) plotters.matplotlib.plot(S, img_filename='pyschedule_3.png')
# test artefact for the case that pyschedule is # read from folder import sys sys.path += ['../src','src'] import getopt opts, _ = getopt.getopt(sys.argv[1:], 't:', ['test']) from pyschedule import Scenario, solvers, plotters, Task S = Scenario('shift_bounds',horizon=8) # define two employees empl0 = S.Resource('empl0') empl1 = S.Resource('empl1') # employee 0 starts at two and ends # at most four hours later empl0_beg = S.Task('empl0_beg',completion_time_cost=2) empl0_beg += empl0 empl0_fin = S.Task('empl0_fin',completion_time_cost=2) empl0_fin += empl0 #S += 2 <= empl0_beg, empl0_fin < empl0_beg + 6 # employee 1 begins at any time and finishes # at most four hours later empl1_beg = S.Task('empl1_beg',completion_time_cost=2) empl1_beg += empl1 empl1_fin = S.Task('empl1_fin',completion_time_cost=2) empl1_fin += empl1 #S += empl1_fin < empl1_beg + 6 # interchangeable tasks that need to be finished as
def getPeriodFromTime(time): return data['allTimes'].index(time) print(name_list) # the planning horizon has n periods S = Scenario('household', horizon=len(data['allTimes'])) resource_list = [] task_list = [] for i in range(len(name_list)): resource_list.append( S.Resource(name_list[i].replace(" ", ""), length=1, periods=[ getPeriodFromTime(t) for t in data['times'][i]['availableTimes'] ])) for i in range(len(name_list2)): task_list.append( S.Task(name_list2[i].replace(" ", ""), length=1, periods=[ getPeriodFromTime(t) for t in data2['times'][i]['availableTimes'] ])) name_perms = list(combinations(range(len(name_list)), 2)) final = [[S.resources()[x[0]], S.resources()[x[1]]] for x in name_perms]
# test artefact for the case that pyschedule is # read from folder from pyschedule import Scenario, solvers, plotters, alt import getopt import sys sys.path.append('../src') opts, _ = getopt.getopt(sys.argv[1:], 't:', ['test']) horizon = 18 S = Scenario('parallel_courses', horizon=horizon) # size 2 means teacher can do two things in parallel Teacher = S.Resource('T', size=2, periods=[0, 1, 2, 3, 4, 5, 7, 8, 9]) Courses_English = S.Tasks('CE', num=7, delay_cost=1, plot_color='red', english=1) Courses_Math = S.Tasks('CM', num=7, delay_cost=1, plot_color='green', math=1) Courses_English += Teacher Courses_Math += Teacher S += Teacher['english'][0:horizon:1].max + \ Teacher['math'][0:horizon:1].max <= 1 if solvers.mip.solve(S, time_limit=600, msg=0): if ('--test', '') in opts: assert(len(set(T.start_value for T in Courses_English) & set(T.start_value for T in Courses_Math)) == 0) print('test passed') else:
def createScenario(_P=used_P): global cumul_P, cumul_L, cumul_T, use_windows, task_indxs, instances_task, used_tours cumul_P = 0 cumul_L = 0 cumul_T = 0 task_indxs = [] use_windows = [] instances_task = {} instances_task[0] = 1 used_tours = [] # Produktionslinien Assignment S = Scenario('Produktionsplanung', horizon=1440) # Erstelle Lininen lines = {j: S.Resource('line_%i' % j) for j in range(_P)} # lineA, lineB, lineC, lineD = S.Resource('lineA'), S.Resource('lineB'), S.Resource('lineC'), S.Resource('lineD') ''' ################################################################################ # Suche das kleinste element in der time-matrix das ungleich null ist und # setze es in einer 0-1-matrix (used) auf 1. # aka. alle Zeiten werden bedient ################################################################################ ''' used = np.full_like(array_Time, False) # array_used_binary Time_sd = ma.masked_values(array_Time[:], 0) # array_Time_search_and_delete_min while not np.array_equal(Time_sd, np.zeros_like(array_Time)): j, t = np.unravel_index(Time_sd.argmin(), Time_sd.shape) used[j, t], Time_sd[j, t] = True, 0 Time_sd = ma.masked_values(Time_sd, 0) # print(used, Time_sd) # createNewTask(j,t) usetime = int(array_Time[j, t]) # print(usetime) ''' ################################################################################ prod_end = up_bound if usetime in range() addTaskFunc(scen=S, _task_indx = task_indx, _art = art, _usetime = usetime, _loc = j) ################################################################################ ''' route = pickRoute(j) # print(route) art = random.randint(0, 3) print(len(task_indxs)) if len(task_indxs) == 0: # Ersten Task erstellen task_indxs.append(0) addTaskFunc(S, _task_indx=task_indxs[0], _art=art, _usetime=usetime, _loc=j) art_store = art print(use_windows) print(usetime) print(task_indxs[-1]) # for i in range(0,len(use_windows)): if usetime in range(use_windows[-1][0], use_windows[-1][1]): # addNewInstance(task_indxs[-1], art) if instances_task[task_indxs[-1]] + 1 <= b_i[art_store]: addNewInstance(task_indxs[-1], art_store) print("YES", art_store, instances_task[task_indxs[-1]], b_i[art_store]) continue else: task_indxs.append(task_indxs[-1] + 1) addTaskFunc(S, _task_indx=task_indxs[-1], _art=art, _usetime=usetime, _loc=j) print("YES/NO", art, instances_task, b_i[art]) instances_task[task_indxs[-1]] = 1 continue else: print("NO") task_indxs.append(task_indxs[-1] + 1) addTaskFunc(S, _task_indx=task_indxs[-1], _art=art, _usetime=usetime, _loc=j) instances_task[task_indxs[-1]] = 1 try: print(instances_task[task_indxs[-1]], b_i[art]) except: pass # print(used) # print(task_indxs) # print(instances_task) print(''' ################################################################################ # Erstellung neuer Tasks und Prüfung auf Auswirkungen auf Transport ################################################################################ ''') # addTaskFunc(scen=S, _task_indx = 1, _art = 0, _usetime = 420, _loc = 2) # addTaskFunc(S, 5, 2, 800, 5) # addTaskFunc(S,1,0,420,2) # addTaskFunc(S,2,1,622,4) # addTaskFunc(S,3,1,824,5) # addTaskFunc(S,4,0,900,2) # addTaskFunc(S,5,1,620,2) # addTaskFunc(S,6,0,800,2) return S
title=None): pass begin = date(year=2018, month=8, day=6) today = date.today() until = begin + timedelta(days=120) horizon = (until - begin).days print("From {0} to {1} ({2} days)".format(begin, until, horizon)) S = Scenario('lss_brewing', horizon=horizon) # Available fermenters donkey = S.Resource('ferm.donkey') diddy = S.Resource('ferm.diddy') funky = S.Resource('ferm.funky') dread = S.Resource('ferm.dread') dixie = S.Resource('ferm.dixie') kiddy = S.Resource('ferm.kiddy') fermenters = donkey | diddy | funky | dread | dixie | kiddy fermenters_all = [donkey, diddy, funky, dread, dixie, kiddy] # Make sure beer is bottled or transfered to BBT before another fermentation # starts for t in range(horizon): for fermenter in fermenters_all: S += fermenter['block'][:t] <= 1
def solve(solver_data): # create scenario scenario = Scenario(name='scenario', horizon=int(solver_data['horizon'])) # resources list resources = {} resources_map = {} resources_mapi = {} resources_ai = 0 # tasks list tasks = {} tasks_map = {} tasks_mapi = {} tasks_ai = 0 # blocks ai blocks_ai = 0 # # enter resources print('[INFO] Importing resources...') for i, resource in enumerate(solver_data['resources']): print('[INFO] Importing resources... ({}/{})'.format( i + 1, len(solver_data['resources'])), end='\r') # convert to [name, size = 1] if not isinstance(resource, list): resource = [resource, 1] # label given to the solver backend rname = 'r' + str(resources_ai) has_parallel = False if resource[0].startswith('teacher_'): for task in solver_data['tasks']: if resource[0] in task['resources'] and task['tags'][ 'block_value'] != task['length']: has_parallel = True print('Found parallel', resource, ' ') break size = 2 if has_parallel else 1 resources[rname] = scenario.Resource(rname, size=size) resources_map[rname] = resource[0] resources_mapi[resource[0]] = rname resources_ai += 1 if has_parallel: scenario += resources[rname]['block_value'][ 0:int(solver_data['horizon']):1] <= 1 # # enter tasks print('[INFO] Importing tasks...') for task in solver_data['tasks']: tname = 't' + str(tasks_ai) tasks[tname] = scenario.Task(tname, length=task['length'], **task['tags']) tasks_map[tname] = task['label'] tasks_mapi[task['label']] = tname tasks_ai += 1 tasks[tname]['r_' + tname] = 1 if 'period' in task and task['period'] != -1: tasks[tname].periods = [task['period']] else: if task['length'] == 4: tasks[tname].periods = [ i for i in range(0, solver_data['horizon']) if i % 4 == 0 ] else: tasks[tname].periods = [ i for i in range(0, solver_data['horizon']) if i % 2 == 0 ] # add resources to task for res_name in task['resources']: tasks[tname] += resources[resources_mapi[res_name]] # # enter blocks print('[INFO] Importing blocks...') for block in solver_data['blocks']: bname = 'b' + str(blocks_ai) task = scenario.Task(bname, length=1, periods=[block["start"]], plot_color='#000000', block_value=1) task += resources[resources_mapi[block["resource"]]] blocks_ai += 1 print('[INFO] Importing sblocks...') for block in solver_data['sblocks']: bname = 'b' + str(blocks_ai) task = scenario.Task(bname, length=1, periods=[block["start"]], plot_color='#000000', schedule_cost=block["cost"], block_value=1) task += resources[resources_mapi[block["resource"]]] blocks_ai += 1 # # enter sync constraints print('[INFO] Importing sync constraints...') for constraint in solver_data['constraints']['sync']: scenario += tasks[tasks_mapi[constraint['tasks'][0]]] <= tasks[ tasks_mapi[constraint['tasks'][1]]] + tasks[tasks_mapi[ constraint['tasks'][0]]].length # # enter cap constraints print(solver_data['constraints']['cap']) # solver_data['constraints']['cap'] = [ # ['group_118', 'group_117'], ['group_118', 'group_116']] for i, constraint in enumerate(solver_data['constraints']['cap']): print('[INFO] Importing capacity constraints... ({}/{})'.format( i + 1, len(solver_data['constraints']['cap']))) for res in resources.values(): if res.size == 1: continue cond = res[constraint[0]][0:int(solver_data['horizon']):1].max for t in constraint[1:]: cond = cond + res[t][0:int(solver_data['horizon']):1].max scenario += cond <= 1 # # solve if solvers.mip.solve(scenario, msg=1): # plotters.matplotlib.plot(scenario, img_filename='out.png', fig_size=( # resources_ai / 3, resources_ai / 2)) solution = scenario.solution() real_solution = [[str(l[0]), str(l[1]), l[2], l[3]] for l in solution] for item in real_solution: if item[0][0] == 'b': continue item[0] = tasks_map[str(item[0])] item[1] = resources_map[str(item[1])] return {'solved': True, 'data': real_solution} else: return {'solved': False, 'error': 'Impossible'}
# Also see: https://developers.google.com/optimization/mip/integer_opt # https://towardsdatascience.com/modeling-and-optimization-of-a-weekly-workforce-with-python-and-pyomo-29484ba065bb from pyschedule import Scenario, solvers, plotters, alt, plotters from raw_data import tasks_data, workers_tasks_eligibility, workers_skills # the planning horizon has 10 periods S = Scenario("construction", horizon=10) # resources resources = {worker_id: S.Resource(worker_id, size=1) for worker_id in workers_skills} # tasks tasks = { task_id: S.Task(task_id, length=task_data["duration"], delay_cost=1) for task_id, task_data in tasks_data.items() } # for t in tasks.values(): # print(t.length) # Worker-Task eligibility. for task_id in tasks: eligible_workers = [] for worker_id, task_ids in workers_tasks_eligibility.items(): if task_id in task_ids: eligible_workers.append(resources[worker_id]) if len(eligible_workers) == 0: continue print(f"{task_id}: {eligible_workers}") for worker in eligible_workers: tasks[task_id] += alt(worker)
from pyschedule import Scenario, solvers, plotters from datetime import datetime, date, time, timedelta import matplotlib from colorhash import ColorHash hide_list = [] S = Scenario('lss_doubebatch', horizon=60*9) hlt = S.Resource('hlt') mt = S.Resource('mt') bk = S.Resource('bk') vessels = [hlt, mt, bk] # Make sure beer is bottled or transfered to BBT before another fermentation # starts for t in range(S.horizon): S += mt['dirty'][:t] <= 1 def make_brew(name): mash = S.Task('mash.{0}'.format(name), length=60) mash.dirty = 1 mash += mt sparge1 = S.Task('sparge.{0}.1'.format(name), length=20) sparge1 += [mt, bk] sparge2 = S.Task('sparge.{0}.2'.format(name), length=20)
] for c in config_files: merger.merge(config, yaml.load(open('configs/%s.yml' % (c,), 'r'))) config['tclasses'] = transform_classes(config) config['blocks'] = config['blocks'] if 'blocks' in config else {} scen = Scenario('Schedule', horizon=(DAYS * 5)) # Will be created when needed teachers = {} classes = {} for cls, _ in config['tclasses'].items(): classes[cls] = scen.Resource(cls) courses = {} for course, info in config['courses'].items(): if isinstance(info, list): info = { "profs": [info[0]], "length": info[1] } courses[course] = task = scen.Task(course, info["length"]) if info["length"] == 4: task.periods = [x for x in range(0, DAYS * 5) if x % 5 == 0] elif info["length"] == 2: task.periods = [x for x in range(0, DAYS * 5) if x % 5 == 0]
from pyschedule import plotters, Scenario, solvers S = Scenario('asdf', horizon=20) r = S.Resource('r', periods=range(20)) t2 = S.Task('CE2', length=20) t2 += r res = solvers.mip.solve_tsp(S, msg=0) print(S.solution()) print(S)
from pyschedule import Scenario, solvers, plotters horizon = 10 S = Scenario('Scenario', horizon=horizon) tasks = S.Tasks('T', num=int(horizon / 2), is_group=True, completion_time_cost=2, state=1) breaks = S.Tasks('B', num=int(horizon / 2), is_group=True, completion_time_cost=1, state=-1) R = S.Resource('R') tasks += R breaks += R # ensure that state is always between 0 and 1 for t in range(horizon): S += R['state'][:t] <= 1 S += R['state'][:t] >= 0 if solvers.mip.solve(S, msg=0): if ('--test', '') in opts: assert (list(set([T.start_value % 2 for T in tasks]))[0] == 0) assert (list(set([T.start_value % 2 for T in breaks]))[0] == 1) print('test passed') else: plotters.matplotlib.plot(S, fig_size=(10, 5))
# test artefact for the case that pyschedule is # read from folder import sys sys.path.append('../src') import getopt opts, _ = getopt.getopt(sys.argv[1:], 't:', ['test']) from pyschedule import Scenario, solvers, plotters, alt horizon = 20 S = Scenario('parallel_courses',horizon=horizon) #size 2 means teacher can do two things in parallel Teacher = S.Resource('T',size=2) Courses_English = S.Tasks('CE',num=10,completion_time_cost=1,plot_color='red',english=1) Courses_Math = S.Tasks('CM',num=10,completion_time_cost=1,plot_color='green',math=1) Courses_English += Teacher Courses_Math += Teacher S += Teacher['english'][0:horizon:1].max + Teacher['math'][0:horizon:1].max <= 1 if solvers.mip.solve(S,time_limit=600,msg=0): if ('--test','') in opts: assert(len(set( T.start_value for T in Courses_English ) & set( T.start_value for T in Courses_Math )) == 0) print('test passed') else: plotters.matplotlib.plot(S,show_task_labels=True) else: print('no solution found')