def adding_constraint_from_results_store(self, milp_solver: LP_RCPSP_Solver, result_storage: ResultStorage) -> Iterable[Any]: nb_jobs = self.problem.n_jobs + 2 constraints_dict = {} current_solution, fit = result_storage.get_best_solution_fit() # Starting point : start = [] for j in milp_solver.J: start_time_j = current_solution.rcpsp_schedule[j+1]["start_time"] for t in milp_solver.T: if start_time_j == t: start += [(milp_solver.x[j][t], 1)] else: start += [(milp_solver.x[j][t], 0)] milp_solver.model.start = start # Fix start time for a subset of task. jobs_to_fix = set(random.sample(current_solution.rcpsp_schedule.keys(), int(self.fraction_fix_start_time * nb_jobs))) constraints_dict["fix_start_time"] = [] for job_to_fix in jobs_to_fix: for t in milp_solver.T: if current_solution.rcpsp_schedule[job_to_fix]["start_time"] == t: constraints_dict["fix_start_time"].append(milp_solver.model.add_constr( milp_solver.x[job_to_fix - 1][t] == 1)) else: constraints_dict["fix_start_time"].append(milp_solver.model.add_constr( milp_solver.x[job_to_fix - 1][t] == 0)) if milp_solver.lp_solver == LP_RCPSP_Solver.GRB: milp_solver.model.solver.update() return constraints_dict
def adding_constraint_from_results_store( self, cp_solver: Union[CP_RCPSP_MZN, CP_MRCPSP_MZN], child_instance, result_storage: ResultStorage) -> Iterable[Any]: constraints_dict = {} current_solution, fit = result_storage.get_best_solution_fit() max_time = max([ current_solution.rcpsp_schedule[x]["end_time"] for x in current_solution.rcpsp_schedule ]) delta_t = max_time / self.nb_cut_part task_of_interest = [ t for t in current_solution.rcpsp_schedule if delta_t * self.current_sub_part <= current_solution.rcpsp_schedule[t]["start_time"] <= delta_t * (self.current_sub_part + 1) ] last_jobs = [ x for x in current_solution.rcpsp_schedule if current_solution.rcpsp_schedule[x]["end_time"] >= max_time - self.delta_time_from_makepan_to_not_fix ] nb_jobs = self.problem.n_jobs + 2 jobs_to_fix = set( random.sample(current_solution.rcpsp_schedule.keys(), int(self.fraction_to_fix * nb_jobs))) for lj in last_jobs: if lj in jobs_to_fix: jobs_to_fix.remove(lj) for t in task_of_interest: if t in jobs_to_fix: jobs_to_fix.remove(t) list_strings = [] for job in jobs_to_fix: start_time_j = current_solution.rcpsp_schedule[job]["start_time"] min_st = max(start_time_j - self.minus_delta, 0) max_st = min(start_time_j + self.plus_delta, max_time) if isinstance(cp_solver, CP_RCPSP_MZN): string1 = "constraint s[" + str(job) + "] <= " + str( max_st) + ";\n" string2 = "constraint s[" + str(job) + "] >= " + str( min_st) + ";\n" elif isinstance(cp_solver, CP_MRCPSP_MZN): string1 = "constraint start[" + str(job) + "] <= " + str( max_st) + ";\n" string2 = "constraint start[" + str(job) + "] >= " + str( min_st) + ";\n" list_strings += [string1] list_strings += [string2] child_instance.add_string(string1) child_instance.add_string(string2) for job in current_solution.rcpsp_schedule: if isinstance(cp_solver, CP_RCPSP_MZN): string = "constraint s[" + str(job) + "] <= " + str(max_time + 50) + ";\n" if isinstance(cp_solver, CP_MRCPSP_MZN): string = "constraint start[" + str(job) + "] <= " + str( max_time + 50) + ";\n" child_instance.add_string(string) self.current_sub_part = (self.current_sub_part + 1) % self.nb_cut_part return list_strings
def adding_constraint_from_results_store(self, milp_solver: LP_Solver_MRSCPSP, result_storage: ResultStorage) -> Iterable[Any]: nb_jobs = self.problem.nb_tasks constraints_dict = {} current_solution, fit = result_storage.get_best_solution_fit() start = [] for j in current_solution.schedule: start_time_j = current_solution.schedule[j]["start_time"] mode = current_solution.modes[j] start += [(milp_solver.start_times_task[j], start_time_j)] start += [(milp_solver.modes[j][mode], 1)] for m in milp_solver.modes[j]: start += [(milp_solver.modes[j][m], 1 if mode == m else 0)] milp_solver.model.start = start # Fix start time for a subset of task. jobs_to_fix = set(random.sample(current_solution.rcpsp_schedule.keys(), int(self.fraction_fix_start_time * nb_jobs))) constraints_dict["fix_start_time"] = [] for job_to_fix in jobs_to_fix: constraints_dict["fix_start_time"].append(milp_solver.model.add_constr( milp_solver.start_times_task[job_to_fix]-current_solution.schedule[job_to_fix]["start_time"] == 0)) if milp_solver.lp_solver == MilpSolverName.GRB: milp_solver.model.solver.update() return constraints_dict
def adding_constraint_from_results_store( self, milp_solver: ColoringLP, result_storage: ResultStorage) -> Iterable[Any]: subpart_color = set( random.sample( milp_solver.nodes_name, int(self.fraction_to_fix * milp_solver.number_of_nodes))) dict_color_fixed = {} dict_color_start = {} current_solution = result_storage.get_best_solution_fit()[0] max_color = max(current_solution.colors) for n in milp_solver.nodes_name: dict_color_start[n] = current_solution.colors[ milp_solver.index_nodes_name[n]] if n in subpart_color and dict_color_start[n] <= max_color - 1: dict_color_fixed[n] = dict_color_start[n] colors_var = milp_solver.variable_decision["colors_var"] lns_constraint = {} for key in colors_var: n, c = key if c == dict_color_start[n]: colors_var[n, c].start = 1 colors_var[n, c].varhintval = 1 else: colors_var[n, c].start = 0 colors_var[n, c].varhintval = 0 if n in dict_color_fixed: if c == dict_color_fixed[n]: lns_constraint[(n, c)] = milp_solver.model.addConstr( colors_var[key] == 1, name=str((n, c))) else: lns_constraint[(n, c)] = milp_solver.model.addConstr( colors_var[key] == 0, name=str((n, c))) return lns_constraint
def adding_constraint_from_results_store(self, cp_solver: CP_MS_MRCPSP_MZN, child_instance, result_storage: ResultStorage) -> Iterable[Any]: new_fitness = result_storage.get_best_solution_fit()[1] if self.last_index_param is not None: if new_fitness != self.last_fitness: self.status[self.last_index_param]["nb_improvement"] += 1 self.last_fitness = new_fitness self.list_proba[self.last_index_param] *= 1.05 self.list_proba = self.list_proba / np.sum(self.list_proba) else: self.list_proba[self.last_index_param] *= 0.95 self.list_proba = self.list_proba / np.sum(self.list_proba) else: self.last_fitness = new_fitness if random.random() <= 0.95: choice = np.random.choice(self.index_np, size=1, p=self.list_proba)[0] else: max_improvement = max([self.status[x]["nb_improvement"]/max(self.status[x]["nb_usage"], 1) for x in self.status]) choice = random.choice([x for x in self.status if self.status[x]["nb_improvement"]/max(self.status[x]["nb_usage"], 1) == max_improvement]) d_params = {key: getattr(self.list_params[int(choice)], key) for key in self.list_params[0].__dict__.keys()} print("Params : ", d_params) ch = ConstraintHandlerStartTimeInterval_CP(problem=self.problem, **d_params) self.current_iteration += 1 self.last_index_param = choice self.status[self.last_index_param]["nb_usage"] += 1 print("Status ", self.status) return ch.adding_constraint_from_results_store(cp_solver, child_instance, result_storage)
def adding_constraint_from_results_store(self, milp_solver: LP_MRCPSP_GUROBI, result_storage: ResultStorage) -> Iterable[ Any]: current_solution, fit = result_storage.get_best_solution_fit() st = milp_solver.start_solution if self.problem.evaluate(st)["makespan"] < self.problem.evaluate(current_solution)["makespan"]: current_solution = st start = [] for j in current_solution.rcpsp_schedule: start_time_j = current_solution.rcpsp_schedule[j]["start_time"] mode_j = 1 if j == 1 or j == self.problem.n_jobs+2 else current_solution.rcpsp_modes[j-2] start += [(milp_solver.durations[j], self.problem.mode_details[j][mode_j]["duration"])] for k in milp_solver.variable_per_task[j]: task, mode, time = k if start_time_j == time and mode == mode_j: milp_solver.x[k].start = 1 milp_solver.starts[j].start = start_time_j else: milp_solver.x[k].start = 0 #milp_solver.model.start = start constraints_dict = {} constraints_dict["range_start_time"] = [] max_time = max([current_solution.rcpsp_schedule[x]["end_time"] for x in current_solution.rcpsp_schedule]) last_jobs = [x for x in current_solution.rcpsp_schedule if current_solution.rcpsp_schedule[x]["end_time"] >= max_time - 5] nb_jobs = self.problem.n_jobs + 2 jobs_to_fix = set(random.sample(current_solution.rcpsp_schedule.keys(), int(self.fraction_to_fix * nb_jobs))) for lj in last_jobs: if lj in jobs_to_fix: jobs_to_fix.remove(lj) for job in jobs_to_fix: start_time_j = current_solution.rcpsp_schedule[job]["start_time"] min_st = max(start_time_j - self.minus_delta, 0) max_st = min(start_time_j + self.plus_delta, max_time) for key in milp_solver.variable_per_task[job]: t = key[2] if t < min_st or t > max_st: constraints_dict["range_start_time"].append(milp_solver.model.addConstr(milp_solver.x[key] == 0)) milp_solver.model.update() return constraints_dict
def adding_constraint_from_results_store(self, milp_solver: Union[LP_RCPSP, LP_MRCPSP], result_storage: ResultStorage) -> Iterable[Any]: constraints_dict = {} current_solution, fit = result_storage.get_best_solution_fit() # milp_solver.init_model(greedy_start=False, start_solution=current_solution) # Starting point : start = [] for j in milp_solver.J: start_time_j = current_solution.rcpsp_schedule[j+1]["start_time"] for t in milp_solver.T: if start_time_j == t: start += [(milp_solver.x[j][t], 1)] else: start += [(milp_solver.x[j][t], 0)] milp_solver.model.start = start constraints_dict["range_start_time"] = [] max_time = max([current_solution.rcpsp_schedule[x]["end_time"] for x in current_solution.rcpsp_schedule]) last_jobs = [x for x in current_solution.rcpsp_schedule if current_solution.rcpsp_schedule[x]["end_time"] >= max_time-5] nb_jobs = self.problem.n_jobs + 2 jobs_to_fix = set(random.sample(current_solution.rcpsp_schedule.keys(), int(self.fraction_to_fix * nb_jobs))) for lj in last_jobs: if lj in jobs_to_fix: jobs_to_fix.remove(lj) for job in jobs_to_fix: start_time_j = current_solution.rcpsp_schedule[job]["start_time"] min_st = max(start_time_j-self.minus_delta, 0) max_st = min(start_time_j+self.plus_delta, max_time) for t in milp_solver.T: if t < min_st or t > max_st: constraints_dict["range_start_time"].append(milp_solver.model.add_constr(milp_solver.x[job-1][t] == 0)) if milp_solver.lp_solver == LP_RCPSP_Solver.GRB: milp_solver.model.solver.update() return constraints_dict
def adding_constraint_from_results_store( self, cp_solver: Union[CP_MS_MRCPSP_MZN], child_instance, result_storage: ResultStorage) -> Iterable[Any]: solution, fit = result_storage.get_best_solution_fit() solution: MS_RCPSPSolution = solution if ("satisfy" in solution.__dict__.keys() and solution.satisfy): print("adding the other constraints !") return self.other_constraint.adding_constraint_from_results_store( cp_solver, child_instance, ResultStorage(list_solution_fits=[(solution, fit)], mode_optim=result_storage.mode_optim)) ressource_breaks, constraints, constraints_employee = get_ressource_breaks( self.problem_calendar, solution) list_strings = [] max_time = max( [solution.schedule[x]["end_time"] for x in solution.schedule]) tasks = sorted(self.problem_calendar.mode_details.keys()) for r in constraints: for t in constraints[r]: index = tasks.index(t) s = None if isinstance(cp_solver, CP_MS_MRCPSP_MZN): if constraints[r][t][0] is not None and constraints[r][t][ 1] is not None: s = """constraint start["""+str(index+1)+"""]<="""+str(constraints[r][t][0])+" \/ " \ "start["""+str(index+1)+"""]>="""+str(constraints[r][t][1])+""";\n""" elif constraints[r][t][0] is None and constraints[r][t][ 1] is not None: s = """constraint start[""" + str( index + 1) + """]>=""" + str( constraints[r][t][1]) + """;\n""" elif constraints[r][t][ 0] is not None and constraints[r][t][1] is None: s = """constraint start[""" + str( index + 1) + """]<=""" + str( constraints[r][t][0]) + """;\n""" if s is not None: child_instance.add_string(s) list_strings += [s] # for r in ressource_breaks: # index_ressource = cp_solver.resources_index.index(r) # for t in range(len(self.problem_calendar.resources[r])): # rq = self.problem_calendar.resources[r][t] # if t<max_time: # if isinstance(cp_solver, CP_MRCPSP_MZN): # s = """constraint """ + str(rq) + """>=sum( i in Act ) ( # bool2int(start[i] <=""" + str(t) + """ /\ """ + str(t) \ # + """< start[i] + adur[i]) * arreq[""" + str(index_ressource + 1) + """,i]);\n""" # elif isinstance(cp_solver, CP_RCPSP_MZN): # s = """constraint """ + str(rq) + """>=sum( i in Tasks ) ( # bool2int(s[i] <=""" + str(t) + """ /\ """ + str(t) \ # + """< s[i] + d[i]) * rr[""" + str(index_ressource + 1) + """,i]);\n""" # child_instance.add_string(s) # list_strings += [s] for r in ressource_breaks: for index in ressource_breaks[r]: if random.random() < 0.6: continue ind = index[0] if r in self.problem_calendar.resources_availability: index_ressource = cp_solver.resources_index.index(r) rq = self.problem_calendar.resources_availability[r][ind] # if random.random() <= 0.3: # continue s = """constraint """+str(rq)+""">=sum( i in Act ) ( bool2int(start[i] <="""+str(ind)+""" /\ """+str(ind)\ + """< start[i] + adur[i]) * arreq["""+str(index_ressource+1)+""",i]);\n""" child_instance.add_string(s) list_strings += [s] # print(s) # print("Res", r) # print("Time", index) if r in self.problem_calendar.employees: index_ressource = cp_solver.employees_position.index(r) rq = int(self.problem_calendar.employees[r]. calendar_employee[ind]) # if random.random() <= 0.3: # continue s = """constraint """+str(rq)+""">=sum( i in Act ) ( bool2int(start[i] <="""+str(ind)+""" /\ """+str(ind)\ + """< start[i] + adur[i]) * unit_used["""+str(index_ressource+1)+""",i]);\n""" child_instance.add_string(s) list_strings += [s] # print(s) # print("Res", r) # print("Time", index) satisfiable = [(s, f) for s, f in result_storage.list_solution_fits if "satisfy" in s.__dict__.keys() and s.satisfy] if len(satisfiable) > 0: res = ResultStorage(list_solution_fits=satisfiable, mode_optim=result_storage.mode_optim) self.other_constraint.adding_constraint_from_results_store( cp_solver, child_instance, res) return ["req"] + list_strings
def adding_constraint_from_results_store(self, cp_solver: CP_MS_MRCPSP_MZN, child_instance, result_storage: ResultStorage) -> Iterable[Any]: constraints_dict = {} r = random.random() if r <= 0.2: current_solution, fit = result_storage.get_last_best_solution() elif r <= 0.4: current_solution, fit = result_storage.get_best_solution_fit() elif r <= 0.99: current_solution, fit = result_storage.get_random_best_solution() else: current_solution, fit = result_storage.get_random_solution() print('Fit', fit) current_solution: MS_RCPSPSolution = current_solution max_time = max([current_solution.schedule[x]["end_time"] for x in current_solution.schedule]) last_jobs = [x for x in current_solution.schedule if current_solution.schedule[x]["end_time"] >= max_time-20] # last_jobs = [] nb_jobs = self.problem.n_jobs_non_dummy + 2 jobs_to_fix = set(random.sample(current_solution.schedule.keys(), int(self.fraction_to_fix * nb_jobs))) for lj in last_jobs: if lj in jobs_to_fix: jobs_to_fix.remove(lj) list_strings = [] self.employees_position = sorted(self.problem.employees) task_to_fix = set(random.sample(current_solution.schedule.keys(), int(self.fraction_task_to_fix_employee * nb_jobs))) employee_to_not_fix = set(random.sample(range(1, len(self.employees_position)+1), min(5, int(1. * len(self.employees_position))))) employee_usage = {emp: [task for task in current_solution.employee_usage if emp in current_solution.employee_usage[task]] for emp in self.problem.employees} employee_usage_max_time = {emp: max([current_solution.schedule[t]["end_time"] for t in employee_usage[emp]]) if len(employee_usage[emp])>0 else 0 for emp in employee_usage} # employee_usage_time = {emp: sum([current_solution.schedule[t]["end_time"] - # current_solution.schedule[t]["start_time"] # for t in employee_usage[emp]]) # for emp in employee_usage} if False: sorted_employee = list(sorted(employee_usage, key=lambda x: employee_usage_max_time[x])) for i in range(int(len(employee_usage)/4)): index = self.employees_position.index(sorted_employee[i])+1 string1 = "constraint sum(task in Act)(unit_used[" + str(index) + ", task] >= "\ + str(int(len(employee_usage[sorted_employee[i]]))) +";\n" for i in range(int(len(employee_usage)/4)): index = self.employees_position.index(sorted_employee[len(sorted_employee)-1-i])+1 string1 = "constraint sum(task in Act)(unit_used[" + str(index) + ", task] <= "\ + str(int(len(employee_usage[sorted_employee[len(sorted_employee)-1-i]]))) +";\n" for i in range(1, len(self.employees_position)+1): # if i in employee_to_not_fix: # continue for task in task_to_fix: emp = self.employees_position[i-1] if task in current_solution.employee_usage and emp in current_solution.employee_usage[task] and \ len(current_solution.employee_usage[task][emp]) > 0: string1 = "constraint unit_used["+str(i)+"," + str(task) + "] = 1;\n" else: string1 = "constraint unit_used["+str(i)+"," + str(task) + "] = 0;\n" child_instance.add_string(string1) list_strings += [string1] for job in [self.problem.sink_task]: start_time_j = current_solution.schedule[job]["start_time"] string1 = "constraint start[" + str(job) + "] <= " + str(start_time_j) + ";\n" list_strings += [string1] child_instance.add_string(string1) for job in jobs_to_fix: start_time_j = current_solution.schedule[job]["start_time"] min_st = max(start_time_j-self.minus_delta, 0) max_st = min(start_time_j+self.plus_delta, max_time) string1 = "constraint start[" + str(job) + "] <= " + str(max_st) + ";\n" string2 = "constraint start[" + str(job) + "] >= " + str(min_st) + ";\n" list_strings += [string1] list_strings += [string2] child_instance.add_string(string1) child_instance.add_string(string2) for job in current_solution.schedule.keys(): if job in jobs_to_fix: continue # start_time_j = current_solution.schedule[job]["start_time"] # min_st = max(start_time_j-100, 0) # max_st = min(start_time_j+100, max_time) # string1 = "constraint start[" + str(job) + "] <= " + str(max_time) + ";\n" # string2 = "constraint start[" + str(job) + "] >= " + str(min_st) + ";\n" # list_strings += [string1] # list_strings += [string2] # child_instance.add_string(string1) # child_instance.add_string(string2) return list_strings