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 ]) 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) 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) return list_strings
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: 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_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, 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: 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, 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: 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] 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] 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: Union[CP_RCPSP_MZN, CP_MRCPSP_MZN], child_instance, result_storage: ResultStorage, ) -> Iterable[Any]: solution, fit = result_storage.get_best_solution_fit() if "satisfy" in solution.__dict__.keys() and solution.satisfy: return self.other_constraint.adding_constraint_from_results_store( cp_solver, child_instance, result_storage ) ressource_breaks, constraints = get_ressource_breaks( self.problem_calendar, self.problem_no_calendar, solution ) list_strings = [] max_time = max( [solution.rcpsp_schedule[x]["end_time"] for x in solution.rcpsp_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_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""" ) elif isinstance(cp_solver, CP_RCPSP_MZN): if ( constraints[r][t][0] is not None and constraints[r][t][1] is not None ): s = ( """constraint s[""" + str(index + 1) + """]<=""" + str(constraints[r][t][0]) + " \/ " "s[" "" + 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 s[""" + 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 s[""" + 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 index in ressource_breaks[r]: if random.random() < 0.1: continue ind = index[0] rq = self.problem_calendar.resources[r][ind] if isinstance(cp_solver, CP_MRCPSP_MZN): 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""" ) elif isinstance(cp_solver, CP_RCPSP_MZN): s = ( """constraint """ + str(rq) + """>=sum( i in Tasks ) ( bool2int(s[i] <=""" + str(ind) + """ /\ """ + str(ind) + """< s[i] + d[i]) * rr[""" + str(index_ressource + 1) + """,i]);\n""" ) child_instance.add_string(s) list_strings += [s] 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.0 * 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