def showsequence(s,name): vs = s.get_value() starts=[] ends=[] nms=[] colors = [] print(name) for i,v in enumerate(vs): starts.append(v.start) ends.append(v.end) nms.append(v.get_name()) colors.append(i) visu.sequence(name=name,intervals=[(st,ends[i],colors[i],nms[i]) for i,st in enumerate(starts) ]) for j in range(numplayers): starts2=[] ends2=[] nms2=[] colors2 = [] for i,v in enumerate(vs): if players_compositions[j][int(nms[i][-1])-1] != 0: starts2.append(v.start) ends2.append(v.end) nms2.append(v.get_name()) colors2.append(colors[i]) visu.sequence(name='musician' + str(j+1),intervals=[(st,ends2[i],colors2[i],nms2[i]) for i,st in enumerate(starts2) ])
def showsequence(s, setup): seq = msol.get_var_solution(s) visu.sequence(name=s.get_name()) vs = seq.get_value() for v in vs: nm = v.get_name() visu.interval(v, tp[id[nm]], compact(nm)) for i in range(len(vs) - 1): end = vs[i].get_end() tp1 = tp[id[vs[i].get_name()]] tp2 = tp[id[vs[i + 1].get_name()]] visu.transition(end, end + setup.get_value(tp1, tp2))
def showsequence(s, name): vs = s.get_value() starts = [] ends = [] nms = [] for i, v in enumerate(vs): if v.end < minutes_in_day: starts.append(v.start) ends.append(v.end) nm = v.get_name().replace("1_", "").replace("2_", "").replace("3_", "") nms.append(nm) for i, s in enumerate(starts): if msol.get_var_solution( "delivery" + re.findall('(\d+)', nms[len(starts) - 1])[0]).get_end() > 480: nms.pop() ends.pop() starts.pop() visu.sequence(name=name, intervals=[(s, ends[i], i, nms[i]) for i, s in enumerate(starts)])
print("Solution: ") msol.print_solution() ############################################################################## # Display result ############################################################################## def compact(name): # Example: H3-garden -> G3 # ^ ^ loc, task = name[1:].split('-', 1) return task[0].upper() + loc if msol and visu.is_visu_enabled(): workers_function = CpoStepFunction() for v in all_tasks: itv = msol.get_var_solution(v) workers_function.add_value(itv.get_start(), itv.get_end(), 1) visu.timeline('Solution SchedState') visu.panel(name="Schedule") for v in all_tasks: visu.interval(msol.get_var_solution(v), house[v], compact(v.get_name())) visu.panel(name="Houses state") for f in all_state_functions: visu.sequence(name=f.get_name(), segments=msol.get_var_solution(f)) visu.panel(name="Nb of workers") visu.function(segments=workers_function, style='line') visu.show()
mdl.add(minimize(max([end_of(ITVS[i][nbMchs - 1]) for i in range(nbJobs)]))) ############################################################################## # Model solving ############################################################################## # Solve model print("Solving model....") msol = mdl.solve(FailLimit=10000, TimeLimit=10) print("Solution: ") msol.print_solution() ############################################################################## # Display result ############################################################################## # Draw solution if msol and visu.is_visu_enabled(): visu.timeline("Solution for permutation flow-shop " + filename) visu.panel("Jobs") for i in range(nbJobs): visu.sequence(name='J' + str(i), intervals=[(msol.get_var_solution(ITVS[i][j]), j, 'M' + str(j)) for j in range(nbMchs)]) visu.panel("Machines") for j in range(nbMchs): visu.sequence(name='M' + str(j), intervals=[(msol.get_var_solution(ITVS[i][j]), j, 'J' + str(i)) for i in range(nbJobs)]) visu.show()
for i in range(NB_JOBS) ]))) # ----------------------------------------------------------------------------- # Solve the model and display the result # ----------------------------------------------------------------------------- # Solve model print("Resolution...") msol = mdl.solve(TimeLimit=15) print("Solution : ") msol.print_solution() # Draw solution if msol and visu.is_visu_enabled() and display == 1: visu.timeline("Solution pour le fichier " + path_file) visu.panel("Jobs") for i in range(NB_JOBS): visu.sequence(name='J' + str(i), intervals=[(msol.get_var_solution(job_operations[i][j]), MACHINES[i][j], 'M' + str(MACHINES[i][j])) for j in range(NB_MACHINES)]) visu.panel("Machines") for k in range(NB_MACHINES): visu.sequence(name='M' + str(k), intervals=[ (msol.get_var_solution(machine_operations[k][i]), k, 'J' + str(i)) for i in range(NB_JOBS) ]) visu.show()
mdl.add(minimize(max([end_of(ITVS[i][nbMchs - 1]) for i in range(nbJobs)]))) ############################################################################## # Model solving ############################################################################## # Solve model print("Solving model....") msol = mdl.solve(FailLimit=10000, TimeLimit=10) print("Solution: ") msol.print_solution() ############################################################################## # Display result ############################################################################## # Display solution if msol and visu.is_visu_enabled(): visu.timeline("Solution for flow-shop " + filename) visu.panel("Jobs") for i in range(nbJobs): visu.sequence(name='J' + str(i), intervals=[(msol.get_var_solution(ITVS[i][j]), j, 'M' + str(j)) for j in range(nbMchs)]) visu.panel("Machines") for j in range(nbMchs): visu.sequence(name='M' + str(j), intervals=[(msol.get_var_solution(ITVS[i][j]), j, 'J' + str(i)) for i in range(nbJobs)]) visu.show()
# Add minimization objective mdl.add(minimize(max([end_of(OPS[o[0]]) for o in ops]))) ############################################################################## # Model solving ############################################################################## # Solve model print("Solving model....") msol = mdl.solve(FailLimit=100000, TimeLimit=10) print("Solution: ") msol.print_solution() ############################################################################## # Display result ############################################################################## # Draw solution if msol and visu.is_visu_enabled(): visu.timeline("Solution for flexible job-shop " + filename) visu.panel("Machines") for j in range(nb_mchs): visu.sequence(name='M' + str(j)) for v in MACHS[j]: itv = msol.get_var_solution(v) if itv.is_present(): job = Job[v.get_name()] visu.interval(itv, job, 'J' + str(job)) visu.show()
mdl.add(mdl.sum([mdl.presence_of(t) for k in tasks for t in k if t.get_name() == a_t]) > 0) # OF mdl.add( mdl.minimize(mdl.max([mdl.end_of(t) * mdl.presence_of(t) for i, tp in enumerate(tasks) for j, t in enumerate(tp)])) ) # добавим учёт времени на переходы workers_sequence = [] for i in range(WORKERS_COUNT): s = mdl.sequence_var(tasks[i], name="{}".format(INSTALLERS[i][0]), types=[x for x in range(len(tasks[i]))]) workers_sequence.append(s) mdl.add(mdl.no_overlap(s, mdl.transition_matrix(szvals=PATH_POINTS_TIMES, name="DD"))) # вывод решения print("Solving model....") msol = mdl.solve(FailLimit=10000000, TimeLimit=60 * 3, LogVerbosity="Terse") print("Solution: ") # msol.print_solution() if msol and visu.is_visu_enabled(): for w in range(WORKERS_COUNT): print("Task for installer {}".format(INSTALLERS[w][0])) visu.sequence(name=trans_ru(INSTALLERS[w][0])) for i, t in enumerate(tasks[w]): wt = msol.get_var_solution(t) if wt.is_present(): print("--- {}".format(wt.get_name())) visu.interval(wt, i, compact_name(trans_ru(wt.get_name()))) visu.show()
# 1. Calling the solve print("\nSolving model....") msol = mdl.solve(url=None, key=None, FailLimit=30000) print("done") # 2. Displaying the objective and solution print("Cost will be " + str(msol.get_objective_values()[0])) # 3. Viewing the results of sequencing problems in a Gantt chart rcParams['figure.figsize'] = 15, 3 workers_function = CpoStepFunction() for h in Houses: for t in TaskNames: itv = msol.get_var_solution(task[h, t]) workers_function.add_value(itv.get_start(), itv.get_end(), 1) visu.timeline('Solution SchedState') visu.panel(name="Schedule") for h in Houses: for t in TaskNames: visu.interval(msol.get_var_solution(task[h, t]), h, t) visu.panel(name="Houses state") for h in Houses: f = state[h] visu.sequence(name=f.get_name(), segments=msol.get_var_solution(f)) visu.panel(name="Nb of workers") visu.function(segments=workers_function, style='line') visu.show()
msol = mdl.solve(url = None, key = None, FailLimit = 30000) print("done") # 2. Displaying the objective and solution print("Cost will be "+str(msol.get_objective_values()[0])) # 3. Viewing the results of sequencing problems in a Gantt chart rcParams['figure.figsize'] = 15, 3 worker_idx = {w : i for i,w in enumerate(Workers)} worker_tasks = [[] for w in range(nbWorkers)] for h in Houses: for s in Skills: worker = s[0] wt = wtasks[(h,s)] worker_tasks[worker_idx[worker]].append(wt) visu.timeline('Solution SchedOptional', 0, Deadline) for i,w in enumerate(Workers): visu.sequence(name=w) for t in worker_tasks[worker_idx[w]]: wt = msol.get_var_solution(t) if wt.is_present(): # if desc[t].skills[w] == max(desc[t].skills): # # Green-like color when task is using the most skilled worker # color = 'lightgreen' # else: # # Red-like color when task does not use the most skilled worker # color = 'salmon' color = 'salmon' visu.interval(wt, color, wt.get_name()) visu.show()
def CP(env_time, P_elems, resource_matrix, domain_applications, generated_jobs): '''! Creates a schedule using the Constraint Programming model @param env_time: Current time of the simulation environment @param P_elems: Instances of processing elements in the SoC configuration generated in the simulation environment @param resource_matrix: All processing elements in the SoC configuration @param domain_applications: Applications under consideration for workload generation @param generated_jobs: Instances of applications (jobs) currently being executed in the system ''' ###### Step 1 - Initialize variable and parameters plt.close('all') # Set docplex related parameters context.solver.trace_log = False #params.CpoParameters.OptimalityTolerance = 2 #params.CpoParameters.RelativeOptimalityTolerance= 2 Dags = [] Dags_2 = {} # Get the task in Outstanding and Ready Queues # Since tasks in Completed Queue are already done, they will not be considered for task in common.TaskQueues.outstanding.list: if task.jobID not in Dags: Dags.append(task.jobID) for i in range(len(domain_applications.list)): name = domain_applications.list[i].name if name == task.jobname: Dags_2[task.jobID] = {} Dags_2[task.jobID]['selection'] = i for task in common.TaskQueues.ready.list: if task.jobID not in Dags: Dags.append(task.jobID) for i in range(len(domain_applications.list)): name = domain_applications.list[i].name if name == task.jobname: Dags_2[task.jobID] = {} Dags_2[task.jobID]['selection'] = i #Dags.sort() common.ilp_job_list = [(key, Dags_2[key]['selection']) for key in Dags_2.keys()] #print(Dags_2) NbDags = len(Dags) # Current number of jobs in the system PEs = [] # List of PE element in the given SoC configuration print('[I] Time %d: There is %d job(s) in the system' % (env_time, NbDags)) print('[D] Time %d: ID of the jobs in the system are' % (env_time), Dags) ###### Step 2 - Prepare Data # First, check if there are any tasks currently being executed on a PE # if yes, retrieve remaining time of execution on that PE and # do not assign a task during ILP solution for i, PE in enumerate(P_elems): if (PE.type == 'MEM') or (PE.type == 'CAC'): # Do not consider Memory ond Cache continue PEs.append(PE.name) # Populate the name of the PEs in the SoC #print(PEs) for ID in Dags_2.keys(): Dags_2[ID]['Tasks'] = [ ] # list of tasks that CPLEX will return a schedule for Dags_2[ID]['Functionality'] = [] # list of task-PE relationship Dags_2[ID]['Con_Precedence'] = [] # list of task dependencies app_id = Dags_2[ID]['selection'] #print(len(Dags), len(self.generated_job_list)) num_of_tasks = len(domain_applications.list[app_id].task_list) for task in domain_applications.list[app_id].task_list: Dags_2[ID]['Tasks'].append(task.base_ID) # Next, gather the information about which PE can run which Tasks # and if so, the expected execution time for resource in resource_matrix.list: if (resource.type == 'MEM') or ( resource.type == 'CAC'): # Do not consider Memory ond Cache continue else: if task.name in resource.supported_functionalities: ind = resource.supported_functionalities.index( task.name) #Functionality.append((resource.name, task.base_ID, resource.performance[ind])) Dags_2[ID]['Functionality'].append( (resource.name, task.base_ID, resource.performance[ind])) # Finally, gather dependency information between tasks for i, predecessor in enumerate(task.predecessors): #print(task.ID, predecessor, num_of_tasks, last_ID, task.base_ID) for resource in resource_matrix.list: if (resource.type == 'MEM') or (resource.type == 'CAC'): continue else: #pred_name = self.generated_job_list[job_ind].task_list[predecessor-last_ID].name pred_name = domain_applications.list[app_id].task_list[ predecessor - (task.ID - task.base_ID)].name if (pred_name in resource.supported_functionalities): c_vol = domain_applications.list[app_id].comm_vol[ predecessor - (task.ID - task.base_ID), task.base_ID] Dags_2[ID]['Con_Precedence'].append( (resource.name, Dags_2[ID]['Tasks'][predecessor - (task.ID - task.base_ID)], task.base_ID, c_vol)) #print(Dags_2[ID]['Tasks']) #print(len(Dags_2[ID]['Functionality'])) #print(Dags_2[ID]['Con_Precedence']) ###### Step 3 - Create the model mdl = CpoModel() # Create dag interval variables dags = {d: mdl.interval_var(name="dag" + str(d)) for d in Dags_2.keys()} #print(dags) # Create tasks interval variables and pe_tasks interval variables # pe_tasks are optional and only one of them will be mapped to the corresponding # tasks interval variable # For example, task_1 has 3 pe_tasks (i.e.,P1-task_1, P2-task_1, P3, task_1) # only of these will be selected. If the first one is selected, it means that task_1 will be executed in P1 tasks_2 = {} pe_tasks_2 = {} task_names_ids_2 = {} last_ID = 0 for d in Dags_2.keys(): num_of_tasks = len(generated_jobs[d].task_list) for t in Dags_2[d]['Tasks']: tasks_2[(d, t)] = mdl.interval_var(name=str(d) + "_" + str(t)) for f in Dags_2[d]['Functionality']: #print(f) name = str(d) + "_" + str(f[1]) + '-' + str(f[0]) if len(common.TaskQueues.running.list) == 0 and len( common.TaskQueues.completed.list) == 0: pe_tasks_2[(d, f)] = mdl.interval_var(optional=True, size=int(f[2]), name=name) task_names_ids_2[name] = last_ID + f[1] else: for ii, running_task in enumerate( common.TaskQueues.running.list): if (d == running_task.jobID) and ( f[1] == running_task.base_ID) and ( f[0] == P_elems[running_task.PE_ID].name): ind = resource_matrix.list[ running_task. PE_ID].supported_functionalities.index( running_task.name) exec_time = resource_matrix.list[ running_task.PE_ID].performance[ind] free_time = int(running_task.start_time + exec_time - env_time) #print(free_time) pe_tasks_2[(d, f)] = mdl.interval_var(optional=True, start=0, end=free_time, name=name) task_names_ids_2[name] = last_ID + f[1] break elif (d == running_task.jobID) and (f[1] == running_task.base_ID): pe_tasks_2[(d, f)] = mdl.interval_var(optional=True, size=INTERVAL_MAX, name=name) task_names_ids_2[name] = last_ID + f[1] break else: pe_tasks_2[(d, f)] = mdl.interval_var(optional=True, size=int(f[2]), name=name) task_names_ids_2[name] = last_ID + f[1] for iii, completed_task in enumerate( common.TaskQueues.completed.list): if (d == completed_task.jobID) and ( f[1] == completed_task.base_ID) and ( f[0] == P_elems[completed_task.PE_ID].name): #print(completed_task.name) #pe_tasks[(d,f)] = mdl.interval_var(optional=True, size =0, name = name ) pe_tasks_2[(d, f)] = mdl.interval_var(optional=True, start=0, end=0, name=name) task_names_ids_2[name] = last_ID + f[1] elif (d == completed_task.jobID) and ( f[1] == completed_task.base_ID): pe_tasks_2[(d, f)] = mdl.interval_var(optional=True, size=INTERVAL_MAX, name=name) task_names_ids_2[name] = last_ID + f[1] #print('3',pe_tasks[(d,f)]) last_ID += num_of_tasks #print(tasks_2) #print(task_names_ids_2) # Add the temporal constraints for d in Dags_2.keys(): for c in Dags_2[d]['Con_Precedence']: for (p1, task1, d1) in Dags_2[d]['Functionality']: if p1 == c[0] and task1 == c[1]: p1_id = PEs.index(p1) for (p2, task2, d2) in Dags_2[d]['Functionality']: if p2 == c[0] and task2 == c[2]: mdl.add( mdl.end_before_start( pe_tasks_2[d, (p1, task1, d1)], pe_tasks_2[d, (p2, task2, d2)], 0)) elif p2 != c[0] and task2 == c[2]: p2_id = PEs.index(p2) #print(p2_id) bandwidth = common.ResourceManager.comm_band[p1_id, p2_id] comm_time = int((c[3]) / bandwidth) for ii, completed_task in enumerate( common.TaskQueues.completed.list): if ((d == completed_task.jobID) and (task1 == completed_task.base_ID) and (p1 == P_elems[completed_task.PE_ID].name)): mdl.add( mdl.end_before_start( pe_tasks_2[d, (p1, task1, d1)], pe_tasks_2[d, (p2, task2, d2)], max( 0, comm_time + completed_task.finish_time - env_time))) #print (d, p1,p2, task1,task2, max(0,int(c[3])+completed_task.finish_time-self.env.now) ) break else: #print(d, p1,p2, task1,task2, c[3]) mdl.add( mdl.end_before_start( pe_tasks_2[d, (p1, task1, d1)], pe_tasks_2[d, (p2, task2, d2)], comm_time)) # Add the span constraints # This constraint enables to identify tasks in a dag for d in Dags_2.keys(): mdl.add( mdl.span(dags[d], [tasks_2[(d, t)] for t in Dags_2[d]['Tasks']])) # Add the alternative constraints # This constraint ensures that only one PE is chosen to execute a particular task for d in Dags_2.keys(): for t in Dags_2[d]['Tasks']: mdl.add( mdl.alternative(tasks_2[d, t], [ pe_tasks_2[d, f] for f in Dags_2[d]['Functionality'] if f[1] == t ])) # Add the no overlap constraints # This constraint ensures that there will be no overlap for the task being executed on the same PE for p in PEs: b_list = [ pe_tasks_2[d, f] for d in Dags_2.keys() for f in Dags_2[d]['Functionality'] if f[0] == p ] if b_list: mdl.add( mdl.no_overlap([ pe_tasks_2[d, f] for d in Dags_2.keys() for f in Dags_2[d]['Functionality'] if f[0] == p ])) else: continue # Add the objective mdl.add( mdl.minimize(mdl.sum([mdl.end_of(dags[d]) for i, d in enumerate(Dags)]))) #mdl.add(mdl.minimize(mdl.max([mdl.end_of(pe_tasks_2[(d,f)]) for i,d in enumerate(Dags) for f in Dags_2[d]['Functionality'] ]))) #mdl.add(mdl.minimize(mdl.max(mdl.end_of(dags[d]) for i,d in enumerate(Dags)))) ###### Step 4 - Solve the model and print some results # Solve the model print("\nSolving CP model....") msol = mdl.solve(TimeLimit=60) #msol = mdl.solve() #print("Completed") #print(msol.print_solution()) #print(msol.is_solution_optimal()) print(msol.get_objective_gaps()) print(msol.get_objective_values()[0]) tem_list = [] for d in Dags: #for f in Functionality: for f in Dags_2[d]['Functionality']: #solution = msol.get_var_solution(pe_tasks[(d,f)]) solution = msol.get_var_solution(pe_tasks_2[(d, f)]) if solution.is_present(): #ID = task_names_ids[solution.get_name()] ID = task_names_ids_2[solution.get_name()] tem_list.append( (ID, f[0], solution.get_start(), solution.get_end())) tem_list.sort(key=lambda x: x[2], reverse=False) #print(tem_list) actual_schedule = [] for i, p in enumerate(PEs): count = 0 for item in tem_list: if item[1] == p: actual_schedule.append((item[0], i, count + 1)) count += 1 actual_schedule.sort(key=lambda x: x[0], reverse=False) #print(actual_schedule) common.table = [] for element in actual_schedule: common.table.append((element[1], element[2])) #print(common.table) #print(len(common.table)) if (common.simulation_mode == 'validation'): colors = ['salmon', 'turquoise', 'lime', 'coral', 'lightpink'] PEs.reverse() for i, p in enumerate(PEs): #visu.panel() #visu.pause(PE_busy_times[p]) visu.sequence(name=p) for ii, d in enumerate(Dags): #for f in Functionality: for f in Dags_2[d]['Functionality']: #wt = msol.get_var_solution(pe_tasks[(d,f)]) wt = msol.get_var_solution(pe_tasks_2[(d, f)]) if wt.is_present() and p == f[0]: color = colors[ii % len(colors)] #visu.interval(wt, color, str(task_names_ids[wt.get_name()])) visu.interval(wt, color, str(task_names_ids_2[wt.get_name()])) visu.show() for d in Dags: for task in generated_jobs[d].task_list: task_sched_ID = 0 task.dynamic_dependencies.clear( ) # Clear dependencies from previosu ILP run ind = Dags.index(d) for i in range(ind): selection = Dags_2[Dags[i]]['selection'] task_sched_ID += len( domain_applications.list[selection].task_list) task_sched_ID += task.base_ID task_order = common.table[task_sched_ID][1] for k in Dags: for dyn_depend in generated_jobs[k].task_list: dyn_depend_sched_ID = 0 ind_k = Dags.index(k) for ii in range(ind_k): selection = Dags_2[Dags[ii]]['selection'] dyn_depend_sched_ID += len( domain_applications.list[selection].task_list) dyn_depend_sched_ID += dyn_depend.base_ID if ((common.table[dyn_depend_sched_ID][0] == common.table[task_sched_ID][0]) and (common.table[dyn_depend_sched_ID][1] == task_order - 1) and (dyn_depend.ID not in task.predecessors) and (dyn_depend.ID not in task.dynamic_dependencies)): task.dynamic_dependencies.append(dyn_depend.ID)
pe_tasks_real = [[] for p in range(nbPEs)] # Tasks assigned to a given worker #print(pe_tasks_real) for d in Dags: for f in Functionality: pe = f[0] pe_t = pe_tasks[(d, f)] pe_tasks_real[pe_idx[pe]].append(pe_t) #print(len(pe_tasks_real[0])) #print(len(pe_tasks_real[1])) #print(pe_idx) colors = ['blue', 'red', 'green'] visu.timeline('Solution SchedOptional', 0, 75) for i, p in enumerate(PEs): visu.sequence(name=p) for t in pe_tasks_real[pe_idx[p]]: wt = msol_2.get_var_solution(t) if wt.is_present(): #if desc[t].skills[w] == max(desc[t].skills): # Green-like color when task is using the most skilled worker # color = 'lightgreen' #else: # Red-like color when task does not use the most skilled worker # color = 'salmon' #color = colors[i] color = 'y' visu.interval(wt, color, wt.get_name()) print(t) visu.show()
def showdelivery(): starts = [] ends = [] nms = [] color = [] intervals = [ (msol.get_var_solution("delivery" + str(i + 1)).get_start(), msol.get_var_solution("delivery" + str(i + 1)).get_end(), i, msol.get_var_solution("delivery" + str(i + 1)).get_name()) for i in range(numdetails) if msol.get_var_solution("delivery" + str(i + 1)).get_end() < minutes_in_day ] for i, interval in enumerate(intervals): starts.append(interval[0]) ends.append(interval[1]) color.append(interval[2]) nms.append(interval[3]) n = 1 while n < len(starts): for i in range(len(starts) - n): if starts[i] > starts[i + 1]: starts[i], starts[i + 1] = starts[i + 1], starts[i] ends[i], ends[i + 1] = ends[i + 1], ends[i] color[i], color[i + 1] = color[i + 1], color[i] nms[i], nms[i + 1] = nms[i + 1], nms[i] n += 1 starts_res = [starts[0]] ends_res = [ends[0]] nms_res = [nms[0]] color_res = [color[0]] used = [starts[0]] p = 0 for y, t in enumerate(starts): for i, s in enumerate(starts): k = len(ends_res) for j, r in enumerate(ends_res): if s >= r: p = p + 1 if (p == k) & (not (i in used)): starts_res.append(s) ends_res.append(ends[i]) nms_res.append(nms[i]) color_res.append(color[i]) used.append(s) p = 0 print(starts_res, ends_res, nms_res) print('----') visu.sequence(name='delivery', intervals=[(starts_res[i], ends_res[i], color_res[i], nms_res[i]) for i, s in enumerate(starts_res)]) if len(used) == len(starts): break for e, w in enumerate(starts): if not (w in used): print(used) starts_res = [starts[e]] ends_res = [ends[e]] nms_res = [nms[e]] color_res = [color[e]] used.append(w) break
############################################################################## # Model solving ############################################################################## # Solve model print("Solving model....") msol = mdl.solve(TimeLimit=10) print("Solution: ") msol.print_solution() ############################################################################## # Display result ############################################################################## # Draw solution if msol and visu.is_visu_enabled(): visu.timeline("Solution for job-shop " + filename) visu.panel("Jobs") for i in range(nb_jobs): visu.sequence(name='J' + str(i), intervals=[(msol.get_var_solution(ITVS[i][j]), mch[i][j], 'M' + str(mch[i][j])) for j in range(nb_mchs)]) visu.panel("Machines") for k in range(nb_mchs): visu.sequence(name='M' + str(k), intervals=[(msol.get_var_solution(MACH[k][i]), k, 'J' + str(i)) for i in range(nb_jobs)]) visu.show()
def solve(proc_t, due_dates, rel_dates, nb_m, setup_types): """ REF: https://ibmdecisionoptimization.github.io/tutorials/html/Scheduling_Tutorial.html http://ibmdecisionoptimization.github.io/docplex-doc/cp/docplex.cp.model.py.html Inspired by House Building Problem, hence the following terms are defined: Worker => Machines Tasks => Jobs Houses => 1 (does not fulfill a purpose here) Skills => each machine has the skill to process each job Deadline => a day """ NbHouses = 1 Deadline = 24 * 60 Workers = ["M" + str(i) for i in range(nb_m)] Tasks = ["T" + str(i) for i in range(proc_t.shape[0])] Durations = proc_t ReleaseDate = rel_dates DueDate = due_dates Skills = [] for w in Workers: for t in Tasks: Skills.append((w, t, 1)) nbWorkers = len(Workers) Houses = range(NbHouses) mdl5 = CpoModel() tasks = {} wtasks = {} wseq = {} transitionTimes = transition_matrix(len(Tasks)) for h in Houses: for i, t in enumerate(Tasks): # add interval decision var for each job, range from 0 to Deadline, and fixed length of PT # thus each task has to fit with its pt in the fictional deadline (max time) tasks[(h, t)] = mdl5.interval_var(start=[0, Deadline], size=Durations[i]) # Add transition times between tasks, which do NOT share the same setup time for j, t2 in enumerate(Tasks): if np.dot(setup_types[i], setup_types[j]) == 0: transitionTimes.set_value(i, j, 10) else: transitionTimes.set_value(i, j, 0) for i, s in enumerate(Skills): # looping over each possible combination of machine and job (skill) # add interval decision var for each combi, range from 0 to DD for each job. # Thus each job on each machine must be processed within a range of 0 upto its DD. wtasks[(h, s)] = mdl5.interval_var(start=[0, DueDate[i % len(Tasks)]], optional=True) for w in Workers: wseq[w] = mdl5.sequence_var( [wtasks[(h, s)] for s in Skills if s[0] == w], types=[int(s[1][1:]) for s in Skills if s[0] == w]) for h in Houses: for t in Tasks: # add constraint such that if j is in the solution space, # then there is exactly one job on a machine. mdl5.add( mdl5.alternative(tasks[h, t], [wtasks[h, s] for s in Skills if s[1] == t])) for w in Workers: # add overlap constraint to enforce transitions is required mdl5.add(mdl5.no_overlap(wseq[w], transitionTimes)) # objective maximize the difference between the due dates and the processing times mdl5.add( mdl5.maximize( mdl5.sum( mdl5.size_of(wtasks[h, s]) - mdl5.end_of(wtasks[h, s]) for h in Houses for s in Skills))) # Solve it solver_log_stream = StringIO() msol5 = mdl5.solve(log_output=solver_log_stream) # transform model solution to a format, which can be handled afterwards worker_idx = {w: i for i, w in enumerate(Workers)} worker_tasks = [[] for w in range(nbWorkers) ] # Tasks assigned to a given worker for h in Houses: for s in Skills: worker = s[0] wt = wtasks[(h, s)] worker_tasks[worker_idx[worker]].append(wt) sol_dict = {k: [] for k in range(nb_m)} for i, w in enumerate(Workers): visu.sequence(name=w) for k, t in enumerate(worker_tasks[worker_idx[w]]): wt = msol5.get_var_solution(t) if wt.is_present(): sol_dict[i].append((k, wt.start, wt.end)) for i, w in enumerate(Workers): sol_dict[i].sort(key=lambda tup: tup[1]) return [sol_dict, msol5, transitionTimes]
# mdl.export_as_cpo() # Solve model print("Solving model....") msol = mdl.solve(TimeLimit=10) print("Solution: ") msol.print_solution() ############################################################################## # Display result ############################################################################## def compact(name): # Example: H3-garden -> G3 # ^ ^ loc, task = name[1:].split('-', 1) return task[0].upper() + loc if msol and visu.is_visu_enabled(): visu.timeline('Solution SchedCalendar') visu.panel() visu.pause(joe_calendar) visu.sequence(name='Joe', intervals=[(msol.get_var_solution(t), type[t], compact(t.name)) for t in joe_tasks]) visu.panel() visu.pause(jim_calendar) visu.sequence(name='Jim', intervals=[(msol.get_var_solution(t), type[t], compact(t.name)) for t in jim_tasks]) visu.show()
print("\nSolving model....") msol3 = mdl3.solve(FailLimit=30000) print("done") if msol3: print("Cost will be " + str(msol3.get_objective_values()[0])) # Allocate tasks to workers tasks = {w: [] for w in WorkerNames} for k, v in Worker.items(): tasks[v].append(k) types = {t: i for i, t in enumerate(TaskNames)} import docplex.cp.utils_visu as visu import matplotlib.pyplot as plt #matplotlib inline #Change the plot size from pylab import rcParams rcParams['figure.figsize'] = 15, 3 visu.timeline('Solution SchedCalendar') for w in WorkerNames: visu.panel() visu.pause(Calendar[w]) visu.sequence(name=w, intervals=[(msol3.get_var_solution(itvs[h, t]), types[t], t) for t in tasks[w] for h in Houses]) visu.show() else: print("No solution found")
print("Solution: ") msol.print_solution() ############################################################################## # Display result ############################################################################## def compact(name): # Example: H3-garden -> G3 # ^ ^ loc, task = name[1:].split('-', 1) return task[0].upper() + loc # Draw solution if msol and visu.is_visu_enabled(): visu.timeline('Solution SchedOptional', 0, deadline) for w in range(nbWorkers): visu.sequence(name=workerNames[w]) for t in worker_tasks[w]: wt = msol.get_var_solution(t) if wt.is_present(): if desc[t].skills[w] == max(desc[t].skills): # Green-like color when task is using the most skilled worker color = 'lightgreen' else: # Red-like color when task does not use the most skilled worker color = 'salmon' visu.interval(wt, color, compact(wt.get_name())) visu.show()
msol.print_solution() ############################################################################## # Display result ############################################################################## def compact(name): # Example: H3-garden -> G3 # ^ ^ loc, task = name[1:].split('-', 1) return task[0].upper() + loc # Draw solution if msol and visu.is_visu_enabled(): visu.timeline('Solution SchedOptional', 0, deadline) for w in range(nbWorkers): visu.sequence(name=workerNames[w]) for t in worker_tasks[w]: wt = msol.get_var_solution(t) if wt.is_present(): if desc[t].skills[w] == max(desc[t].skills): # Green-like color when task is using the most skilled worker color = 'lightgreen' else: # Red-like color when task does not use the most skilled worker color = 'salmon' visu.interval(wt, color, compact(wt.get_name())) visu.show()
for task, interval in task_intervals_on_machines[m_id]: val = msol.get_value(interval) if val != (): tasks.append( (msol.get_var_solution(interval), 1, interval.get_name())) cost_sum += energy_intervals_array[val[2] - 1].get_value( val[0]) * task['power_consumption'] # Add segments to cost function for i in range(val[0], val[1]): cost_i = energy_prices[i] * task['power_consumption'] energy_costs.add_value(i, i + 1, cost_i) # Do not show this machine if no task if assigned to it if tasks and ons: visu.timeline("Machine " + str(m_id), 0, int(TIMESLOTS)) visu.panel("Tasks") visu.sequence(name='Machine', intervals=ons) visu.sequence(name='Tasks', intervals=tasks) visu.function(name='Cost={}'.format(cost_sum), segments=energy_costs) for j in range(NUM_RESOURCES): visu.panel('resources_{}'.format(j)) res = CpoStepFunction() for task, interval in task_intervals_on_machines[m_id]: val = msol.get_value(interval) if val != (): res.add_value(val[0], val[1], task['resource_usage'][j]) visu.function(segments=res, color=j) visu.show()
mdl.add(minimize(max([end_of(OPS[o[0]]) for o in ops]))) ############################################################################## # Model solving ############################################################################## # Solve model print("Solving model....") msol = mdl.solve(FailLimit=100000, TimeLimit=10) print("Solution: ") msol.print_solution() ############################################################################## # Display result ############################################################################## # Draw solution if msol and visu.is_visu_enabled(): visu.timeline("Solution for flexible job-shop " + filename) visu.panel("Machines") for j in range(nb_mchs): visu.sequence(name='M' + str(j)) for v in MACHS[j]: itv = msol.get_var_solution(v) if itv.is_present(): job = Job[v.get_name()] visu.interval(itv, job, 'J' + str(job)) visu.show()
mdl.max([ mdl.end_of(job_operations[i][NB_MACHINES - 1]) for i in range(NB_JOBS) ]))) #----------------------------------------------------------------------------- # Solve the model and display the result #----------------------------------------------------------------------------- # Solve model print("Solving model....") msol = mdl.solve(FailLimit=10000, TimeLimit=10) print("Solution: ") msol.print_solution() # Display solution if msol and visu.is_visu_enabled(): visu.timeline("Solution for flow-shop " + filename) visu.panel("Jobs") for i in range(NB_JOBS): visu.sequence(name='J' + str(i), intervals=[(msol.get_var_solution(job_operations[i][j]), j, 'M' + str(j)) for j in range(NB_MACHINES)]) visu.panel("Machines") for j in range(NB_MACHINES): visu.sequence(name='M' + str(j), intervals=[(msol.get_var_solution(job_operations[i][j]), j, 'J' + str(i)) for i in range(NB_JOBS)]) visu.show()
def compact(name): # Example: H3-garden -> G3 # ^ ^ loc, task = name[1:].split('-', 1) return task[0].upper() + loc # Solve model print("Solving model....") msol = mdl.solve(FailLimit=10000, TimeLimit=10) print("Solution: ") msol.print_solution() # Draw solution if msol and visu.is_visu_enabled(): visu.timeline('Solution SchedOptional', 0, DEADLINE) for w in range(NB_WORKERS): visu.sequence(name=WORKER_NAMES[w]) for t in worker_tasks[w]: wt = msol.get_var_solution(t) if wt.is_present(): if desc[t].skills[w] == max(desc[t].skills): # Green-like color when task is using the most skilled worker color = 'lightgreen' else: # Red-like color when task does not use the most skilled worker color = 'salmon' visu.interval(wt, color, compact(wt.get_name())) visu.show()