def cplex_makespan_model(n: int, m: int, durations, machines) -> CpoModel: # n number of jobs, m machines # 1 line for un job with tasks on m machines naive = np.sum(durations) mdl = CpoModel() #Une variable est l'intervalle de durée pour une tache x = [[ mdl.interval_var(size=durations[i, j], name="O{}-{}".format(i, j)) for j in range(m) ] for i in range(n)] #contrainte end max d'une tache calculée avant for i in range(n): for j in range(m): mdl.add(mdl.end_of(x[i][j]) <= naive) #precedence for i in range(n): #for each job for j in range(m - 1): #taches ordonnées mdl.add(mdl.end_before_start(x[i][j], x[i][j + 1])) # une machine ne peut faire qu'une tache à la fois listtaches = [[] for k in range(m)] for i in range(n): for j in range(m): listtaches[machines[i, j]].append(x[i][j]) for k in range(m): mdl.add(mdl.no_overlap(listtaches[k])) makespan = mdl.integer_var(0, naive, name="makespan") # le makespan est le max des tps pour chaque job mdl.add(makespan == mdl.max([mdl.end_of(x[i][m - 1]) for i in range(n)])) mdl.add(mdl.minimize(makespan)) return mdl, x
def recherche_exact(instance, temps): ''' :param temps: int, temps de recherche :param instance: nom de l'instance str :return: None ''' problem_data, optimum = loader(instance) nb_machine = problem_data["nb_machine"] nb_jobs = problem_data["nb_jobs"] problem = problem_data["problem"] machine, durations = separate(problem) model = CpoModel(name='Scheduling') # Variable job_operations = [[model.interval_var(size=durations[j][m], name="O{}-{}".format(j, m)) for m in range(nb_machine)] for j in range(nb_jobs)] # chaque opération doit commencer aprés la fin de la précedente for j in range(nb_jobs): for s in range(1, nb_machine): model.add(model.end_before_start(job_operations[j][s - 1], job_operations[j][s])) # Pas d'overlap pour les operations executées sur une même machine machine_operations = [[] for m in range(nb_machine)] for j in range(nb_jobs): for s in range(0, nb_machine): machine_operations[machine[j][s]].append(job_operations[j][s]) for lops in machine_operations: model.add(model.no_overlap(lops)) # Minimiser la date de fin model.add(model.minimize(model.max([model.end_of(job_operations[i][nb_machine - 1]) for i in range(nb_jobs)]))) # Solve model print("Solving model....") msol = model.solve(TimeLimit=temps)
workers_usage += mdl.pulse(tasks[t.id], 1) cash -= mdl.step_at_start(tasks[t.id], 200 * t.duration) # Make houses for i, sd in enumerate(HOUSES): make_house(i, sd) # Number of workers should not be greater than the limit mdl.add(workers_usage <= NB_WORKERS) # Cash should not be negative mdl.add(cash >= 0) # Minimize overall completion date mdl.add(mdl.minimize(mdl.max([mdl.end_of(task) for task in all_tasks]))) #----------------------------------------------------------------------------- # Solve the model and display the result #----------------------------------------------------------------------------- def compact(name): # Example: H3-garden -> G3 # ^ ^ loc, task = name[1:].split('-', 1) return task[0].upper() + loc # Solve model print("Solving model....")
mdl.add(mdl.no_overlap(domain)) checked = checksymmetries(players_compositions, 9) for i,c in enumerate(checked): if i ==2: mdl.add(mdl.start_before_start(compositions[c[1]],compositions[c[0]])) else: mdl.add(mdl.start_before_start(compositions[c[0]],compositions[c[1]])) ENDS = [] STARTS = [] WAITNESS=[] for k in range(numplayers): for j in range(numcompositions): print(players_compositions[k][j]) #print(mdl.name_of(songs[k][j])) ENDS.append(mdl.end_of(compositions[j])*players_compositions[k][j]) #STARTS.append(mdl.sum([mdl.times(mdl.start_of(songs[k][j] ),mdl.sum([100*mdl.equal(players_compositions[k][j],0),players_compositions[k][j]]) ), 100*mdl.times(mdl.equal(mdl.start_of(songs[k][j]),0),mdl.equal(players_compositions[k][j],0))])) STARTS.append(mdl.times(mdl.start_of(compositions[j] ),1000*mdl.equal(players_compositions[k][j],0)+ players_compositions[k][j])) MAX=mdl.max(ENDS) MIN=mdl.min(STARTS) print(-sum([waittimes[i]*players_compositions[k][i] for i in range(numcompositions)])) WAITNESS.append(mdl.sum([MAX,-MIN,-sum([waittimes[i]*players_compositions[k][i] for i in range(numcompositions)])])) EXPR=mdl.sum(WAITNESS) #mdl.add(mdl.minimize(EXPR)) mdl.add(mdl.minimize(mdl.sum([*[ mdl.max([ mdl.end_of(compositions[i])*players_compositions[k][i] for i in range(numcompositions)]) for k in range (numplayers)], *[-mdl.min([mdl.times(mdl.start_of(compositions[j]),1000*mdl.equal(players_compositions[k][j],0)+ players_compositions[k][j]) + 100*mdl.times(mdl.equal(mdl.start_of(compositions[j]),0),mdl.equal(players_compositions[k][j],0)) for j in range(numcompositions)]) for k in range (numplayers)], -92]))) #[mdl.max(ENDS) for k in range(numplayers)]
kk = [tasks[p][k] for p in range(WORKERS_COUNT) for k in range(len(tasks[p])) if (tasks[p][k].get_name() == a_t)] if len(kk) != 0: mdl.add(mdl.alternative(tasks_act[i], kk, 1)) # в один момент времени - одна задача for i in range(WORKERS_COUNT): mdl.add(mdl.no_overlap(tasks[i])) # все задачи должны быть выполнены for i in range(ORDERS_COUNT): a_t = TASK_TEMPLATE_NAME.format(num=str(i), name=WAIT_ORDERS[i][1]) 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()
#----------------------------------------------------------------------------- # Build the model #----------------------------------------------------------------------------- # Create model mdl = CpoModel() # Create array of variables for subsquares vx = [mdl.interval_var(size=SIZE_SUBSQUARE[i], name="X" + str(i), end=(0, SIZE_SQUARE)) for i in range(NB_SUBSQUARE)] vy = [mdl.interval_var(size=SIZE_SUBSQUARE[i], name="Y" + str(i), end=(0, SIZE_SQUARE)) for i in range(NB_SUBSQUARE)] # Create dependencies between variables for i in range(len(SIZE_SUBSQUARE)): for j in range(i): mdl.add( (mdl.end_of(vx[i]) <= mdl.start_of(vx[j])) | (mdl.end_of(vx[j]) <= mdl.start_of(vx[i])) | (mdl.end_of(vy[i]) <= mdl.start_of(vy[j])) | (mdl.end_of(vy[j]) <= mdl.start_of(vy[i]))) # To speed-up the search, create cumulative expressions on each dimension rx = mdl.sum([mdl.pulse(vx[i], SIZE_SUBSQUARE[i]) for i in range(NB_SUBSQUARE)]) mdl.add(mdl.always_in(rx, (0, SIZE_SQUARE), SIZE_SQUARE, SIZE_SQUARE)) ry = mdl.sum([mdl.pulse(vy[i], SIZE_SUBSQUARE[i]) for i in range(NB_SUBSQUARE)]) mdl.add(mdl.always_in(ry, (0, SIZE_SQUARE), SIZE_SQUARE, SIZE_SQUARE)) # Define search phases, also to speed-up the search mdl.set_search_phases([mdl.search_phase(vx), mdl.search_phase(vy)]) #----------------------------------------------------------------------------- # Solve the model and display the result
# that will be further minimized with the additional machine # costs. # This solution is consistent with the second phase, # set it as starting point model.set_starting_point(msol.get_solution()) bounds = msol.get_objective_bounds() model.remove(cost_tasks) cost_overall = cost_tasks for machine in data['machines']: m_id = machine['id'] # Add machine idle consumption cost_overall += model.sum([ (model.element(energy_sum_array, model.end_of(on_i)) - model.element(energy_sum_array, model.start_of(on_i))) * machine['idle_consumption'] for on_i in on_intervals[m_id] ]) # Add power up/down cost on_off_cost = machine['power_up_cost'] + machine['power_down_cost'] cost_overall += model.sum([ on_off_cost * model.presence_of(on_interval) for on_interval in on_intervals[m_id] ]) # We can be sure that the lower bound of # first phase is a lower bound of this phase model.add(cost_overall >= bounds[0])
if m.demand_non_renewable[j] > 0: non_renewables[j] += m.demand_non_renewable[j] * mdl.presence_of( modes[m]) # Constrain renewable resources capacity for j in range(NB_RENEWABLE): mdl.add( mdl.always_in(renewables[j], (INTERVAL_MIN, INTERVAL_MAX), 0, CAPACITIES_RENEWABLE[j])) # Constrain non-renewable resources capacity for j in range(NB_NON_RENEWABLE): mdl.add(non_renewables[j] <= CAPACITIES_NON_RENEWABLE[j]) # Minimize overall schedule end date mdl.add(mdl.minimize(mdl.max([mdl.end_of(tasks[t]) for t in tasks_data]))) #----------------------------------------------------------------------------- # Solve the model and display the result #----------------------------------------------------------------------------- # Solve model print("Solving model....") msol = mdl.solve(FailLimit=30000, TimeLimit=10) print("Solution: ") msol.print_solution() if msol and visu.is_visu_enabled(): load = [CpoStepFunction() for j in range(NB_RENEWABLE)] for m in modes_data: itv = msol.get_var_solution(modes[m])
mdl.add(mdl.alternative(tasks[i], [tasks_m1[i], tasks_m2[i]])) # Build a map to retrieve task id from variable name (for display purpose) task_id = dict() for i in range(NB_TASKS): task_id[tasks_m1[i].get_name()] = i task_id[tasks_m2[i].get_name()] = i # Constrain tasks to no overlap on each machine s1 = mdl.sequence_var(tasks_m1, types=TASK_TYPE, name='M1') s2 = mdl.sequence_var(tasks_m2, types=TASK_TYPE, name='M2') mdl.add(mdl.no_overlap(s1, SETUP_M1, 1)) mdl.add(mdl.no_overlap(s2, SETUP_M2, 1)) # Minimize the makespan mdl.add(mdl.minimize(mdl.max([mdl.end_of(tasks[i]) for i in range(NB_TASKS)]))) #----------------------------------------------------------------------------- # Solve the model and display the result #----------------------------------------------------------------------------- def compact(name): # Example: A31_M1_TP1 -> 31 task, foo = name.split('_', 1) return task[1:] def showsequence(s, setup): seq = msol.get_var_solution(s) visu.sequence(name=s.get_name()) vs = seq.get_value()
# Учтём матрицу активности for i in LINKED_TASKS: for k, j in enumerate(TASKS): if k == i["task_num"]: mdl.add(mdl.forbid_start(tasks[k], RND_CALENDAR[i["linked_rnd"]])) mdl.add(mdl.forbid_end(tasks[k], RND_CALENDAR[i["linked_rnd"]])) for k, j in enumerate(TASKS): mdl.add(mdl.forbid_extent(tasks[k], RND_CALENDAR[j["rnd"]])) for k, j in enumerate(TASKS): mdl.add( mdl.forbid_extent(tasks[k], get_deadline_area(TASKS[k]["deadline"]))) # Минимизируем время завершения последней задачи mdl.add(mdl.minimize(mdl.max([mdl.end_of(t) for t in tasks]))) # ----------------------------------------------------------------------------- # Решение solver'ом и вывод # ----------------------------------------------------------------------------- print("Solving model....") msol = mdl.solve(FailLimit=100000, TimeLimit=10) print("Solution: ") msol.print_solution() # mdl.export_as_cpo() # if msol and visu.is_visu_enabled(): load = [CpoStepFunction() for j in range(NB_RESOURCES)] for i in range(NB_TASKS): itv = msol.get_var_solution(tasks[i])
for m in range(NB_MACHINES) ] for j in range(NB_JOBS)] # All operations executed on the same machine must no overlap for i in range(NB_JOBS): mdl.add(mdl.no_overlap([job_operations[i][j] for j in range(NB_MACHINES)])) # All operations executed for the same job must no overlap for j in range(NB_MACHINES): mdl.add(mdl.no_overlap([job_operations[i][j] for i in range(NB_JOBS)])) # Minimization completion time mdl.add( mdl.minimize( mdl.max([ mdl.end_of(job_operations[i][j]) for i in range(NB_JOBS) for j in range(NB_MACHINES) ]))) #----------------------------------------------------------------------------- # 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():
name="worker3") } workers.update(workers3) deliveryworker = { "deliveryworker": mdl.sequence_var([itvs[(h, 2)] for h in range(numdetails)], types=[h for h in range(numdetails)], name="deliveryworker") } workers.update(deliveryworker) for w in WorkerNames: mdl.add(mdl.no_overlap(workers[w])) mdl.add( mdl.minimize( mdl.sum(euro_penalty[i] * mdl.float_div( mdl.max([mdl.end_of(itvs[(i, 2)]) - 480, 0]), mdl.end_of(itvs[(i, 2)]) - 480 + mdl.equal(mdl.end_of(itvs[(i, 2)]) - 480, 0)) for i in range(numdetails)))) #mdl.add(mdl.minimize(mdl.sum(euro_penalty[i] * mdl.float_div(mdl.max([mdl.end_of(itvs[(i, 2)]) - 480, 0]),mdl.max([mdl.end_of(itvs[(i, 2)]) - 480)) for i in range(numdetails))))) #mdl.add(mdl.minimize(mdl.sum(euro_penalty[i] * mdl.max([mdl.step_at(mdl.end_of(itvs[(i, 2)]) - 480,1), 0]) for i in range(numdetails)))) #mdl.add(mdl.minimize(mdl.sum(euro_penalty[i] * mdl.float_div(mdl.max([mdl.exponent(mdl.end_of(itvs[(i, 2)]) - 480)-1, 0]), mdl.exponent(mdl.end_of(itvs[(i, 2)]) - 480)) for i in range(numdetails)))) #mdl.add(mdl.minimize(mdl.sum(euro_penalty[i] * mdl.float_div(mdl.max([mdl.exponent(mdl.power(mdl.end_of(itvs[(i, 2)]) - 480, 0.33))-1, 0]), mdl.exponent(mdl.power(mdl.end_of(itvs[(i, 2)]) - 480, 0.33))) for i in range(numdetails)))) #mdl.add(mdl.minimize(mdl.sum(euro_penalty[i] * mdl.presence_of(itvs[(i, 2)]) for i in range(numdetails)))) print("Solving model....") msol = mdl.solve(FailLimit=100000, TimeLimit=10) print("Solution: ") msol.print_solution()
def floorPlanner(CONFIG, SCHEDULER, RATE, printFlag=0, figFlag=0): HEIGHT_REC = 4 WIDTH_REC = 4 NUM_RESOURCES = 16 # Sizes of the hardware resources SIZE_HARDWARE = [1 for _ in range(NUM_RESOURCES)] RESOUCE_dict = { 0: 'A72', 1: 'A53-0', 2: 'A53-1', 3: 'FFT', 4: 'DAP-0', 5: 'DAP-1', 6: 'Memory', 7: 'Cache-1', 8: 'Cache-2', 9: 'Cache-3', 10: 'Cache-4' } # read from rpt file df = pd.read_fwf("inputs/" + CONFIG + "/trace_" + SCHEDULER + "_" + RATE + "/matrix_traffic_" + SCHEDULER + "_" + RATE + ".rpt") # read file --- MODIFY HERE df = df.drop(df.columns[df.columns.str.contains('unnamed', case=False)], axis=1) # drop unnamed df = df.drop(range(10)) # drop the first 10 lines vol = df.values.tolist() vol_commu = [list(map(int, i)) for i in vol] extend_factor = NUM_RESOURCES - len(vol_commu) for i in range(extend_factor): RESOUCE_dict[len(vol_commu) + i] = 'empty' for _ in range(extend_factor): for row in range(len(vol_commu)): vol_commu[row].extend([0]) for _ in range(extend_factor): vol_commu.append([0 for _ in range(len(vol_commu[0]))]) #----------------------------------------------------------------------------- # Build the model #----------------------------------------------------------------------------- # Create model mdl = CpoModel() # Create array of variables for subsquares vx = [ mdl.interval_var(size=SIZE_HARDWARE[i], name="X" + str(i), end=(0, WIDTH_REC)) for i in range(NUM_RESOURCES) ] vy = [ mdl.interval_var(size=SIZE_HARDWARE[i], name="Y" + str(i), end=(0, HEIGHT_REC)) for i in range(NUM_RESOURCES) ] # Create dependencies between variables for i in range(len(SIZE_HARDWARE)): for j in range(i): mdl.add((mdl.end_of(vx[i]) <= mdl.start_of(vx[j])) | (mdl.end_of(vx[j]) <= mdl.start_of(vx[i])) | (mdl.end_of(vy[i]) <= mdl.start_of(vy[j])) | (mdl.end_of(vy[j]) <= mdl.start_of(vy[i]))) # Set up the objective """ obj = mdl.minimize( mdl.sum( vol_commu[i][j] * ( mdl.max( [mdl.end_of(vx[i]) - mdl.end_of(vx[j]), mdl.end_of(vx[j]) - mdl.end_of(vx[i])] )\ + mdl.max( [mdl.start_of(vy[i]) - mdl.end_of(vy[j]), mdl.start_of(vy[j]) - mdl.end_of(vy[i])] ) ) \ for i in range(NUM_RESOURCES) for j in range(NUM_RESOURCES) if vol_commu[i][j]) ) """ obj = mdl.minimize( mdl.sum( vol_commu[i][j] * ( mdl.max( [mdl.end_of(vx[i]) - mdl.end_of(vx[j]), mdl.end_of(vx[j]) - mdl.end_of(vx[i])] )\ + mdl.min([mdl.min([mdl.max( [mdl.start_of(vy[i]) - mdl.end_of(vy[j]), 0] ), mdl.max( [mdl.start_of(vy[j]) - mdl.end_of(vy[i]), 0] )]), 1]) ) \ for i in range(NUM_RESOURCES) for j in range(NUM_RESOURCES) if vol_commu[i][j]) ) mdl.add(obj) # To speed-up the search, create cumulative expressions on each dimension rx = mdl.sum( [mdl.pulse(vx[i], SIZE_HARDWARE[i]) for i in range(NUM_RESOURCES)]) mdl.add(mdl.always_in(rx, (0, WIDTH_REC), WIDTH_REC, WIDTH_REC)) ry = mdl.sum( [mdl.pulse(vy[i], SIZE_HARDWARE[i]) for i in range(NUM_RESOURCES)]) mdl.add(mdl.always_in(ry, (0, HEIGHT_REC), HEIGHT_REC, HEIGHT_REC)) # Define search phases, also to speed-up the search mdl.set_search_phases([mdl.search_phase(vx), mdl.search_phase(vy)]) #----------------------------------------------------------------------------- # Solve the model and display the result #----------------------------------------------------------------------------- # Solve model print("Solving model....") msol = mdl.solve(TimeLimit=20, LogPeriod=50000) if printFlag: print("Solution: ") msol.print_solution() if msol and visu.is_visu_enabled(): import matplotlib.pyplot as plt import matplotlib.cm as cm from matplotlib.patches import Polygon import matplotlib.ticker as ticker # Plot external square if figFlag: plt.show() print("Plotting squares....") fig, ax = plt.subplots() plt.plot((0, 0), (0, HEIGHT_REC), (WIDTH_REC, HEIGHT_REC), (WIDTH_REC, 0)) plt.xlim((0, WIDTH_REC)) plt.ylim((0, HEIGHT_REC // 2)) for i in range(len(SIZE_HARDWARE)): # Display square i sx, sy = msol.get_var_solution(vx[i]), msol.get_var_solution(vy[i]) (sx_st, sx_ed, sy_st, sy_ed) = (sx.get_start(), sx.get_end(), sy.get_start(), sy.get_end()) # transform #sx1, sx2, sy1, sy2 = sx_st, sx_ed, sy_st, sy_ed sx1 = sx_st + 0.5 if sy_st % 2 else sx_st sy1 = sy_st / 2 sx2, sy2 = sx1 + 0.5, sy1 + 0.5 poly = Polygon([(sx1, sy1), (sx1, sy2), (sx2, sy2), (sx2, sy1)], fc=cm.Set2(float(i) / len(SIZE_HARDWARE))) ax.add_patch(poly) # Display identifier of square i at its center ax.text(float(sx1 + sx2) / 2, float(sy1 + sy2) / 2, RESOUCE_dict[i], ha='center', va='center') ax.xaxis.set_major_locator(ticker.MultipleLocator(0.5)) ax.yaxis.set_major_locator(ticker.MultipleLocator(0.5)) plt.margins(0) fig.savefig("outputs/MESH/" + CONFIG + "_" + SCHEDULER + "_" + RATE + ".png") if figFlag: plt.show()
def create_model(self): mdl = CpoModel(name = "TAS Scheduling") ##################################################### # Creating interval variables for WEST module ##################################################### i = 0 MS1_vars = [] MS4_vars = [] GTW_vars = [] WEST_vars = [] table_occupied_WEST = [] kits_pulse_for_choice = [] for i in range(len(self.timeOUEST)): min_start_time = int(date_converter.convert_to_work_time(datetime.timestamp(pd.to_datetime(self.req_matOUEST.iloc[i,2])))) #print(min_start_time, self.req_matOUEST.iloc[i,2]) meca_length = int(self.timeOUEST.iloc[i, 2] / 10) qc_length = int(self.timeOUEST.iloc[i, 3] / 10) kit_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), name = "kitting " + self.timeOUEST.index[i]) kit_interval1mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_max, name = "kitting 1 op " + self.timeOUEST.index[i], optional = True) kit_interval2mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_mid, name = "kitting 2 op " + self.timeOUEST.index[i], optional = True) kit_interval3mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_min, name = "kitting 3 op " + self.timeOUEST.index[i], optional = True) mdl.add(mdl.alternative(interval = kit_interval, array = [kit_interval1mec, kit_interval2mec, kit_interval3mec])) kits_pulse_for_choice += [kit_interval1mec, kit_interval2mec, kit_interval3mec] meca_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = meca_length, name = "meca " + self.timeOUEST.index[i]) qc_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = qc_length, name = "qc " + self.timeOUEST.index[i]) table_slot_occupied_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = (0, 9999999999999), name = "Table occupied " + self.timeOUEST.index[i]) table_occupied_WEST += [table_slot_occupied_interval] mdl.add(mdl.end_before_start(kit_interval, meca_interval)) mdl.add(mdl.end_before_start(meca_interval, qc_interval)) mdl.add(mdl.start_at_end(table_slot_occupied_interval, kit_interval)) mdl.add(mdl.start_at_end(meca_interval, table_slot_occupied_interval)) WEST_vars += [kit_interval] WEST_vars += [meca_interval] WEST_vars += [qc_interval] if i < 19: MS1_vars += [kit_interval] MS1_vars += [meca_interval] MS1_vars += [qc_interval] elif i >= 45: GTW_vars += [kit_interval] GTW_vars += [meca_interval] GTW_vars += [qc_interval] else: MS4_vars += [kit_interval] MS4_vars += [meca_interval] MS4_vars += [qc_interval] ###################################################### # Creating interval variables for EAST module ###################################################### FOV_vars = [] MS2_vars = [] MS3_vars = [] EAST_vars = [] table_occupied_EAST = [] for i in range(len(self.timeEST)): min_start_time = int(date_converter.convert_to_work_time(datetime.timestamp(pd.to_datetime(self.req_matOUEST.iloc[i,2])))) meca_length = int(self.timeOUEST.iloc[i, 2] / 10) qc_length = int(self.timeOUEST.iloc[i, 3] / 10) kit_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), name = "kitting " + self.timeEST.index[i]) kit_interval1mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_max, name = "kitting 1 op " + self.timeEST.index[i], optional = True) kit_interval2mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_mid, name = "kitting 2 op " + self.timeEST.index[i], optional = True) kit_interval3mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_min, name = "kitting 3 op " + self.timeEST.index[i], optional = True) mdl.add(mdl.alternative(interval = kit_interval, array = [kit_interval1mec, kit_interval2mec, kit_interval3mec])) kits_pulse_for_choice += [kit_interval1mec, kit_interval2mec, kit_interval3mec] meca_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = meca_length, name = "meca " + self.timeEST.index[i]) qc_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = qc_length, name = "qc " + self.timeEST.index[i]) table_slot_occupied_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = (0, 9999999999999), name = "Table occupied " + self.timeEST.index[i]) table_occupied_EAST += [table_slot_occupied_interval] mdl.add(mdl.end_before_start(kit_interval, meca_interval)) mdl.add(mdl.end_before_start(meca_interval, qc_interval)) mdl.add(mdl.start_at_end(table_slot_occupied_interval, kit_interval)) mdl.add(mdl.start_at_end(meca_interval, table_slot_occupied_interval)) EAST_vars += [kit_interval] EAST_vars += [meca_interval] EAST_vars += [qc_interval] if i < 11: FOV_vars += [kit_interval] FOV_vars += [meca_interval] FOV_vars += [qc_interval] elif i >= 25: MS3_vars += [kit_interval] MS3_vars += [meca_interval] MS3_vars += [qc_interval] else: MS2_vars += [kit_interval] MS2_vars += [meca_interval] MS2_vars += [qc_interval] ################################################## # Setting requirement relations between interval variables ################################################## for task in MS1_vars: for i in range(len(self.req_taskOUEST)): if (self.req_taskOUEST.index[i] in task.name) and "meca" in task.name: for j in range(len(self.req_taskOUEST.iloc[i, 0])): for other_task in WEST_vars: if self.req_taskOUEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name: mdl.add(mdl.end_before_start(other_task, task)) #print("##############################################") for task in MS4_vars: for i in range(len(self.req_taskOUEST)): if (self.req_taskOUEST.index[i] in task.name) and "meca" in task.name: for j in range(len(self.req_taskOUEST.iloc[i, 0])): for other_task in WEST_vars: if self.req_taskOUEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name: mdl.add(mdl.end_before_start(other_task, task)) #print("##############################################") for task in GTW_vars: for i in range(len(self.req_taskOUEST)): if (self.req_taskOUEST.index[i] in task.name) and "meca" in task.name: for j in range(len(self.req_taskOUEST.iloc[i, 0])): for other_task in WEST_vars: if self.req_taskOUEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name: mdl.add(mdl.end_before_start(other_task, task)) #print("##############################################") for task in MS2_vars: for i in range(len(self.req_taskEST)): if (self.req_taskEST.index[i] in task.name) and "meca" in task.name: for j in range(len(self.req_taskEST.iloc[i, 0])): for other_task in EAST_vars: if self.req_taskEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name: mdl.add(mdl.end_before_start(other_task, task)) #print("##############################################") for task in MS3_vars: for i in range(len(self.req_taskEST)): if (self.req_taskEST.index[i] in task.name) and "meca" in task.name: for j in range(len(self.req_taskEST.iloc[i, 0])): for other_task in EAST_vars: if self.req_taskEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name: mdl.add(mdl.end_before_start(other_task, task)) #print("##############################################") for task in FOV_vars: for i in range(len(self.req_taskEST)): if (self.req_taskEST.index[i] in task.name) and "meca" in task.name: for j in range(len(self.req_taskEST.iloc[i, 0])): for other_task in EAST_vars: if self.req_taskEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name: mdl.add(mdl.end_before_start(other_task, task)) ############################################## # Adding resources constraints ############################################## all_tasks = EAST_vars + WEST_vars meca_resources = [mdl.pulse(task, 1) for task in EAST_vars if "meca" in task.name] meca_resources += [mdl.pulse(task, 1) for task in WEST_vars if "meca" in task.name] meca_resources += [mdl.pulse(task, 1) for task in kits_pulse_for_choice if "kitting 1 op" in task.name] meca_resources += [mdl.pulse(task, 2) for task in kits_pulse_for_choice if "kitting 2 op" in task.name] meca_resources += [mdl.pulse(task, 3) for task in kits_pulse_for_choice if "kitting 3 op" in task.name] qc_resources = [mdl.pulse(task, 1) for task in EAST_vars if "qc" in task.name] qc_resources += [mdl.pulse(task, 1) for task in WEST_vars if "qc" in task.name] work_slots_EAST = [mdl.pulse(task, 1) for task in EAST_vars if "qc" in task.name or "meca" in task.name] work_slots_WEST = [mdl.pulse(task, 1) for task in WEST_vars if "qc" in task.name or "meca" in task.name] kitting_slots_EAST = [mdl.pulse(task, 1) for task in table_occupied_EAST] kitting_slots_EAST += [mdl.pulse(task, 1) for task in EAST_vars if "kitting" in task.name] kitting_slots_WEST = [mdl.pulse(task, 1) for task in table_occupied_WEST] kitting_slots_WEST += [mdl.pulse(task, 1) for task in WEST_vars if "kitting" in task.name] mdl.add(mdl.sum(meca_resources) <= 3) mdl.add(mdl.sum(qc_resources) <= 1) mdl.add(mdl.sum(work_slots_EAST) <= 2) mdl.add(mdl.sum(work_slots_WEST) <= 2) mdl.add(mdl.sum(kitting_slots_EAST) <= 3) mdl.add(mdl.sum(kitting_slots_WEST) <= 3) [mdl.add(mdl.start_of(task) % (14*6) < 11*6) for task in all_tasks if "meca" in task.name] MS1_meca_qc = [task for task in MS1_vars if (("meca" in task.name) or ("qc" in task.name))] mdl.add(mdl.no_overlap(MS1_meca_qc)) MS2_meca_qc = [task for task in MS2_vars if (("meca" in task.name) or ("qc" in task.name))] mdl.add(mdl.no_overlap(MS2_meca_qc)) MS3_meca_qc = [task for task in MS3_vars if (("meca" in task.name) or ("qc" in task.name))] mdl.add(mdl.no_overlap(MS3_meca_qc)) MS4_meca_qc = [task for task in MS4_vars if (("meca" in task.name) or ("qc" in task.name))] mdl.add(mdl.no_overlap(MS4_meca_qc)) FOV_meca_qc = [task for task in FOV_vars if (("meca" in task.name) or ("qc" in task.name))] mdl.add(mdl.no_overlap(FOV_meca_qc)) GTW_meca_qc = [task for task in GTW_vars if (("meca" in task.name) or ("qc" in task.name))] mdl.add(mdl.no_overlap(GTW_meca_qc)) mdl.add(mdl.minimize(mdl.max([mdl.end_of(t) for t in all_tasks]) - mdl.min([mdl.start_of(t) for t in all_tasks]))) return mdl
# Force each operation to start after the end of the previous for j in range(NB_JOBS): for m in range(1, NB_MACHINES): mdl.add( mdl.end_before_start(job_operations[j][m - 1], job_operations[j][m])) # Force no overlap for operations executed on a same machine for m in range(NB_MACHINES): mdl.add(mdl.no_overlap([job_operations[j][m] for j in range(NB_JOBS)])) # Minimize termination date mdl.add( mdl.minimize( 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():
for j in range(NB_JOBS): for t in Tasks[j]: mdl.add( mdl.alternative( tasks[j,JOBS[j][2 * t],t], [mtasks[j,s] for s in Skills[j] if s[0][:len('M'+str(JOBS[j][2 * t]))] == 'M'+str(JOBS[j][2 * t]) and s[0][len('M'+str(JOBS[j][2 * t])): len('M'+str(JOBS[j][2 * t]))+1] in 'e' ] ) ) for m in Maschines: # print([(j,s) for j in range(NB_JOBS) for s in Skills[j] if s[0]==m]) mdl.add( mdl.no_overlap([mtasks[j,s] for j in range(NB_JOBS) for s in Skills[j] if s[0]==m]) ) # Minimize termination date mdl.add(mdl.minimize(mdl.max([mdl.end_of(tasks[i,JOBS[i][2 * Tasks[i][-1] ],NB_MACHINES - 1]) for i in range(NB_JOBS)]))) #----------------------------------------------------------------------------- # Solve the model and display the result #----------------------------------------------------------------------------- # Solve model #print("Solving model....") t = timer() msol = mdl.solve(TimeLimit = 10 * 60, LogVerbosity = 'Quiet', Workers = 1) #in sec total_time = timer() - t #msol.print_solution() #print(f'Total execution time: {total_time}') #print("Solution: ") #print("Cost will be "+str( msol.get_objective_values()[0] )) output = '' m_prime = Maschines[0]
renewables[j] += mdl.pulse(modes[m['id']], dem) for j in range(NB_NON_RENEWABLE): dem = m['demandNonRenewable'][j] if dem > 0: non_renewables[j] += dem * mdl.presence_of(modes[m['id']]) # Constrain renewable resources capacity for j in range(NB_RENEWABLE): mdl.add(mdl.always_in(renewables[j], (INTERVAL_MIN, INTERVAL_MAX), 0, CAPACITIES_RENEWABLE[j])) # Constrain non-renewable resources capacity for j in range(NB_NON_RENEWABLE): mdl.add(non_renewables[j] <= CAPACITIES_NON_RENEWABLE[j]) # Minimize overall schedule end date mdl.add(mdl.minimize(mdl.max([mdl.end_of(t) for t in tasks.values()]))) #----------------------------------------------------------------------------- # Solve the model and display the result #----------------------------------------------------------------------------- # Solve model print("Solving model....") msol = mdl.solve(FailLimit=30000, TimeLimit=10) print("Solution: ") msol.print_solution() if msol and visu.is_visu_enabled(): load = [CpoStepFunction() for j in range(NB_RENEWABLE)] for m in MODES:
vy = [ mdl.interval_var(size=WEIGHT_SIZE_B[i], name="Y" + str(i), end=(0, SIZE_SHELF["y"] * 1)) for i in range(NB_WEIGHTS) ] # Запретим пересекать границы полок и учтём температуры for i in range(NB_WEIGHTS): mdl.add( mdl.forbid_extent(vx[i], get_allowable_area(SHELVES, 'x', PRODUCT_T[i]))) # Запретим пересечение продуктов for i in range(NB_WEIGHTS): for j in range(i): mdl.add((mdl.end_of(vx[i]) <= mdl.start_of(vx[j])) | (mdl.end_of(vx[j]) <= mdl.start_of(vx[i])) | (mdl.end_of(vy[i]) <= mdl.start_of(vy[j])) | (mdl.end_of(vy[j]) <= mdl.start_of(vy[i]))) # Соберём списки продуктов, которые не могут быть рядом for i in range(NB_WEIGHTS): for j in range(i): if ((PRODUCT_CATS[i], PRODUCT_CATS[j]) in INCOMPATIBLE_GROUPS) or ( (PRODUCT_CATS[j], PRODUCT_CATS[i]) in INCOMPATIBLE_GROUPS): print("Find incompatible group ({}, {})".format( PRODUCT_NAMES[i], PRODUCT_NAMES[j])) mdl.add( mdl.logical_not((mdl.start_of(vx[i]) == mdl.end_of(vx[j])) | (mdl.start_of(vx[j]) == mdl.end_of(vx[i])) | (mdl.start_of(vy[i]) == mdl.end_of(vy[j]))