def retrieve_solutions( self, result, parameters_cp: ParametersCP = ParametersCP.default() ) -> ResultStorage: intermediate_solutions = parameters_cp.intermediate_solution colors = [] objectives = [] solutions_fit = [] if intermediate_solutions: for i in range(len(result)): colors += [result[i, "color_graph"]] objectives += [result[i, "objective"]] else: colors += [result["color_graph"]] objectives += [result["objective"]] for k in range(len(colors)): sol = [ colors[k][self.index_nodes_name[self.nodes_name[i]]] - 1 for i in range(self.number_of_nodes) ] color_sol = ColoringSolution(self.coloring_problem, sol) fit = self.aggreg_sol(color_sol) solutions_fit += [(color_sol, fit)] return ResultStorage( list_solution_fits=solutions_fit, limit_store=False, mode_optim=self.params_objective_function.sense_function)
def __init__(self, rcpsp_model: RCPSPModel, option_neighbor: OptionNeighbor = OptionNeighbor.MIX_ALL, **kwargs): self.rcpsp_model = rcpsp_model self.solver = CP_MRCPSP_MZN(rcpsp_model=self.rcpsp_model, cp_solver_name=CPSolverName.CHUFFED) self.solver.init_model(output_type=True) self.parameters_cp = ParametersCP.default() params_objective_function = get_default_objective_setup( problem=self.rcpsp_model) # constraint_handler = ConstraintHandlerFixStartTime(problem=rcpsp_problem, # fraction_fix_start_time=0.5) # self.constraint_handler = ConstraintHandlerStartTimeInterval_CP(problem=self.rcpsp_model, # fraction_to_fix=0.6, # minus_delta=5, # plus_delta=5) self.constraint_handler = build_neighbor_operator( option_neighbor=option_neighbor, rcpsp_model=self.rcpsp_model) self.initial_solution_provider = InitialSolutionRCPSP( problem=self.rcpsp_model, initial_method=InitialMethodRCPSP.PILE, params_objective_function=params_objective_function) self.lns_solver = LNS_CP( problem=self.rcpsp_model, cp_solver=self.solver, initial_solution_provider=self.initial_solution_provider, constraint_handler=self.constraint_handler, params_objective_function=params_objective_function)
def solve(self, parameters_cp: ParametersCP = ParametersCP.default(), **args): result = self.instance.solve( timeout=timedelta(seconds=parameters_cp.TimeLimit), intermediate_solutions=parameters_cp.intermediate_solution) return self.retrieve_solutions(result=result, parameters_cp=parameters_cp)
def __init__(self, rcpsp_model: RCPSPModelCalendar, params_objective_function: ParamsObjectiveFunction = None, **kwargs): self.rcpsp_model = rcpsp_model self.resources = rcpsp_model.resources self.non_renewable = rcpsp_model.non_renewable_resources self.n_jobs = rcpsp_model.n_jobs self.mode_details = rcpsp_model.mode_details self.graph = rcpsp_model.compute_graph() self.nx_graph: nx.DiGraph = self.graph.to_networkx() self.successors_map = {} self.predecessors_map = {} # successors = nx.dfs_successors(self.nx_graph, 1, self.n_jobs+2) successors = { n: nx.algorithms.descendants(self.nx_graph, n) for n in self.nx_graph.nodes() } self.source = 1 self.sink = self.n_jobs + 2 self.all_activities = set(range(1, self.n_jobs + 3)) for k in successors: self.successors_map[k] = { "succs": successors[k], "nb": len(successors[k]) } predecessors = { n: nx.algorithms.ancestors(self.nx_graph, n) for n in self.nx_graph.nodes() } for k in predecessors: self.predecessors_map[k] = { "succs": predecessors[k], "nb": len(predecessors[k]) } self.aggreg_from_sol, self.aggreg_from_dict, self.params_objective_function = \ build_aggreg_function_and_params_objective(problem=self.rcpsp_model, params_objective_function= params_objective_function) if isinstance(self.rcpsp_model, (MultiModeRCPSPModel, RCPSPModelCalendar)): solver = CP_MRCPSP_MZN_MODES(self.rcpsp_model, cp_solver_name=CPSolverName.CHUFFED) params_cp = ParametersCP.default() params_cp.time_limit = 1 params_cp.pool_solutions = 10000 params_cp.nr_solutions = 1000 #params_cp.nr_solutions = float("inf") params_cp.all_solutions = False result_storage = solver.solve(parameters_cp=params_cp, verbose=True) one_mode_setting = result_storage[0] self.modes_dict = {} for i in range(len(one_mode_setting)): self.modes_dict[i + 1] = one_mode_setting[i] else: self.modes_dict = {t: 1 for t in self.mode_details} self.with_calendar = isinstance(self.rcpsp_model, RCPSPModelCalendar)
def retrieve_solutions( self, result, parameters_cp: ParametersCP = ParametersCP.default()): intermediate_solutions = parameters_cp.intermediate_solution best_solution = None best_makespan = -float("inf") list_solutions_fit = [] starts = [] mruns = [] object_result: List[MRCPSP_Result] = [] if intermediate_solutions: for i in range(len(result)): object_result += [result[i]] # print("Objective : ", result[i, "objective"]) else: object_result += [result] for res in object_result: modes = [] for j in range(len(res.mode_chosen)): if (self.modeindex_map[j + 1]['task'] != 1) and (self.modeindex_map[j + 1]['task'] != self.rcpsp_model.n_jobs + 2): modes.append(self.modeindex_map[res.mode_chosen[j]] ['original_mode_index']) elif (self.modeindex_map[j + 1]['task'] == 1) or (self.modeindex_map[j + 1]['task'] == self.rcpsp_model.n_jobs + 2): modes.append(1) rcpsp_schedule = {} start_times = res.dict["start"] for i in range(len(start_times)): rcpsp_schedule[i + 1] = { 'start_time': start_times[i], 'end_time': start_times[i] + self.rcpsp_model.mode_details[i + 1][modes[i]]['duration'] } sol = RCPSPSolution(problem=self.rcpsp_model, rcpsp_schedule=rcpsp_schedule, rcpsp_modes=modes[1:-1], rcpsp_schedule_feasible=True) objective = self.aggreg_from_dict_values( self.rcpsp_model.evaluate(sol)) if objective > best_makespan: best_makespan = objective best_solution = sol.copy() list_solutions_fit += [(sol, objective)] result_storage = ResultStorage( list_solution_fits=list_solutions_fit, best_solution=best_solution, mode_optim=self.params_objective_function.sense_function, limit_store=False) return result_storage
def solve(self, parameters_cp: ParametersCP = ParametersCP.default(), **args): if self.instance is None: self.init_model(**args) timeout = parameters_cp.TimeLimit intermediate_solutions = parameters_cp.intermediate_solution result = self.instance.solve( timeout=timedelta(seconds=timeout), intermediate_solutions=intermediate_solutions) verbose = args.get("verbose", True) if verbose: print(result.status) return self.retrieve_solutions(result=result, parameters_cp=parameters_cp)
def get_starting_solution(self) -> ResultStorage: if self.initial_method == InitialMethodRCPSP.PILE: print("Compute greedy") greedy_solver = PileSolverRCPSP(self.problem) store_solution = greedy_solver.solve(greedy_choice=GreedyChoice.MOST_SUCCESSORS) if self.initial_method == InitialMethodRCPSP.PILE_CALENDAR: print("Compute greedy") greedy_solver = PileSolverRCPSP_Calendar(self.problem) store_solution = greedy_solver.solve(greedy_choice=GreedyChoice.MOST_SUCCESSORS) elif self.initial_method == InitialMethodRCPSP.DUMMY: print("Compute dummy") solution = self.problem.get_dummy_solution() fit = self.aggreg(solution) store_solution = ResultStorage(list_solution_fits=[(solution, fit)], best_solution=solution, mode_optim=self.params_objective_function.sense_function) elif self.initial_method == InitialMethodRCPSP.CP: solver = CP_MRCPSP_MZN(rcpsp_model=self.problem, params_objective_function=self.params_objective_function) store_solution = solver.solve(parameters_cp=ParametersCP.default()) elif self.initial_method == InitialMethodRCPSP.LS: dummy = self.problem.get_dummy_solution() _, mutations = get_available_mutations(self.problem, dummy) print(mutations) list_mutation = [mutate[0].build(self.problem, dummy, **mutate[1]) for mutate in mutations if mutate[0] == PermutationMutationRCPSP] # and mutate[1]["other_mutation"] == TwoOptMutation] mixed_mutation = BasicPortfolioMutation(list_mutation, np.ones((len(list_mutation)))) res = RestartHandlerLimit(500, cur_solution=dummy, cur_objective=self.problem.evaluate(dummy)) sa = SimulatedAnnealing(evaluator=self.problem, mutator=mixed_mutation, restart_handler=res, temperature_handler=TemperatureSchedulingFactor(2, res, 0.9999), mode_mutation=ModeMutation.MUTATE, params_objective_function=self.params_objective_function, store_solution=True, nb_solutions=10000) store_solution = sa.solve(dummy, nb_iteration_max=10000, pickle_result=False) return store_solution
def retrieve_solutions( self, result, parameters_cp: ParametersCP = ParametersCP.default() ) -> ResultStorage: intermediate_solutions = parameters_cp.intermediate_solution best_solution = None best_makespan = -float("inf") list_solutions_fit = [] starts = [] if intermediate_solutions: for i in range(len(result)): if isinstance(result[i], RCPSPSolCP): starts += [result[i].dict["s"]] else: starts += [result[i, "s"]] else: if isinstance(result, RCPSPSolCP): starts += [result.dict["s"]] else: starts = [result["s"]] for start_times in starts: rcpsp_schedule = {} for k in range(len(start_times)): rcpsp_schedule[k + 1] = { 'start_time': start_times[k], 'end_time': start_times[k] + self.rcpsp_model.mode_details[k + 1][1]['duration'] } sol = RCPSPSolution(problem=self.rcpsp_model, rcpsp_schedule=rcpsp_schedule, rcpsp_schedule_feasible=True) objective = self.aggreg_from_dict_values( self.rcpsp_model.evaluate(sol)) if objective > best_makespan: best_makespan = objective best_solution = sol.copy() list_solutions_fit += [(sol, objective)] result_storage = ResultStorage( list_solution_fits=list_solutions_fit, best_solution=best_solution, mode_optim=self.params_objective_function.sense_function, limit_store=False) return result_storage
def solve(self, parameters_cp: ParametersCP = ParametersCP.default(), **args): # partial_solution: PartialSolution=None, **args): if self.instance is None: self.init_model(**args) timeout = parameters_cp.TimeLimit intermediate_solutions = parameters_cp.intermediate_solution try: result = self.instance.solve( timeout=timedelta(seconds=timeout), intermediate_solutions=intermediate_solutions) except Exception as e: print(e) return None verbose = args.get("verbose", False) if verbose: print(result.status) print(result.statistics["solveTime"]) return self.retrieve_solutions(result, parameters_cp=parameters_cp)
def solve(self, parameters_cp: ParametersCP = None, **kwargs) -> ResultStorage: if parameters_cp is None: parameters_cp = ParametersCP.default() if self.model is None: self.init_model(**kwargs) # limit_time_s = kwargs.get("limit_time_s", 100) limit_time_s = parameters_cp.TimeLimit intermediate_solutions = parameters_cp.intermediate_solution result = self.instance.solve( timeout=timedelta(seconds=limit_time_s), intermediate_solutions=intermediate_solutions) verbose = kwargs.get("verbose", False) if verbose: print('Solving finished') print(result.status) print(result.statistics) return self.retrieve_solutions(result=result, parameters_cp=parameters_cp)
def __init__(self, rcpsp_model: MS_RCPSPModel, option_neighbor: OptionNeighbor=OptionNeighbor.MIX_ALL, **kwargs): self.rcpsp_model = rcpsp_model self.solver = CP_MS_MRCPSP_MZN(rcpsp_model=self.rcpsp_model, cp_solver_name=CPSolverName.CHUFFED, **kwargs) self.solver.init_model(output_type=True, **kwargs) self.parameters_cp = kwargs.get("parameters_cp", ParametersCP.default()) params_objective_function = get_default_objective_setup(problem=self.rcpsp_model) self.constraint_handler = build_neighbor_operator(option_neighbor=option_neighbor, rcpsp_model=self.rcpsp_model) self.post_pro = PostProMSRCPSP(problem=self.rcpsp_model, params_objective_function=params_objective_function) self.initial_solution_provider = InitialSolutionMS_RCPSP(problem=self.rcpsp_model, initial_method=InitialMethodRCPSP.PILE_CALENDAR, params_objective_function=params_objective_function) self.lns_solver = LNS_CP(problem=self.rcpsp_model, cp_solver=self.solver, initial_solution_provider=self.initial_solution_provider, constraint_handler=self.constraint_handler, post_process_solution=self.post_pro, params_objective_function=params_objective_function)
def retrieve_solutions( self, result, parameters_cp: ParametersCP = ParametersCP.default()): intermediate_solutions = parameters_cp.intermediate_solution best_solution = None best_makespan = -float("inf") list_solutions_fit = [] mruns = [] if intermediate_solutions: for i in range(len(result)): mruns += [result[i, "mrun"]] else: mruns += [result["mrun"]] all_modes = [] for mrun in mruns: modes = [1] * (self.rcpsp_model.n_jobs + 2) for i in range(len(mrun)): if mrun[i] == 1 and (self.modeindex_map[i + 1]['task'] != 1) and (self.modeindex_map[i + 1]['task'] != self.rcpsp_model.n_jobs + 2): modes[self.modeindex_map[i + 1]['task'] - 1] = self.modeindex_map[i + 1]['original_mode_index'] all_modes += [modes] return all_modes
def __init__(self, problem_calendar: RCPSPModelCalendar, partial_solution: PartialSolution = None, **kwargs): self.problem_calendar = problem_calendar if not isinstance(problem_calendar, RCPSPModelCalendar): self.problem_calendar = RCPSPModelCalendar( resources={ r: [problem_calendar.resources[r]] * problem_calendar.horizon for r in problem_calendar.resources }, non_renewable_resources=self.problem_calendar. non_renewable_resources, mode_details=self.problem_calendar.mode_details, successors=self.problem_calendar.successors, horizon=self.problem_calendar.horizon) self.problem_no_calendar = RCPSPModel( resources={ r: int(max(self.problem_calendar.resources[r])) for r in self.problem_calendar.resources }, non_renewable_resources=self.problem_calendar. non_renewable_resources, mode_details=self.problem_calendar.mode_details, successors=self.problem_calendar.successors, horizon=self.problem_calendar.horizon, name_task=self.problem_calendar.name_task) # solver = CP_MRCPSP_MZN(rcpsp_model=self.problem_no_calendar, # cp_solver_name=CPSolverName.CHUFFED) # solver = CP_RCPSP_MZN(rcpsp_model=self.problem_no_calendar, # cp_solver_name=CPSolverName.CHUFFED) solver = CP_MRCPSP_MZN(rcpsp_model=self.problem_no_calendar, cp_solver_name=CPSolverName.CHUFFED) solver.init_model(output_type=True, model_type="multi", partial_solution=partial_solution) parameters_cp = ParametersCP.default() parameters_cp.TimeLimit = 500 parameters_cp.TimeLimit_iter0 = 500 params_objective_function = get_default_objective_setup( problem=self.problem_no_calendar) # constraint_handler = ConstraintHandlerFixStartTime(problem=rcpsp_problem, # fraction_fix_start_time=0.5) constraint_handler = ConstraintHandlerStartTimeInterval_CP( problem=self.problem_no_calendar, fraction_to_fix=0.99, minus_delta=10, plus_delta=10, delta_time_from_makepan_to_not_fix=5) # constraint_handler = ConstraintHandlerAddCalendarConstraint(self.problem_calendar, # self.problem_no_calendar, # constraint_handler) constraint_handler = build_neighbor_operator( option_neighbor=OptionNeighbor.MIX_LARGE_NEIGH, rcpsp_model=self.problem_no_calendar) constraint_handler = ConstraintHandlerAddCalendarConstraint( self.problem_calendar, self.problem_no_calendar, constraint_handler) initial_solution_provider = InitialSolutionRCPSP( problem=self.problem_calendar, initial_method=InitialMethodRCPSP.PILE_CALENDAR, params_objective_function=params_objective_function) self.initial_solution_provider = initial_solution_provider self.constraint_handler = constraint_handler self.params_objective_function = params_objective_function self.cp_solver = solver self.post_process_solution = PostProcessSolutionNonFeasible( self.problem_calendar, self.problem_no_calendar, partial_solution=partial_solution)
from skdecide.builders.discrete_optimization.generic_tools.cp_tools import ParametersCP from skdecide.builders.discrete_optimization.rcpsp_multiskill.solvers.lp_model import LP_Solver_MRSCPSP, MilpSolverName from skdecide.builders.discrete_optimization.rcpsp_multiskill.solvers.ms_rcpsp_cp_lns_solver import LNS_CP_MS_RCPSP_SOLVER, OptionNeighbor from skdecide.builders.discrete_optimization.rcpsp_multiskill.rcpsp_multiskill import MS_RCPSPModel, MS_RCPSPModel_Variant from skdecide.builders.discrete_optimization.generic_tools.ea.ga_tools import ParametersAltGa from skdecide.builders.discrete_optimization.rcpsp_multiskill.solvers.ms_rcpsp_ga_solver import GA_MSRCPSP_Solver from skdecide.builders.discrete_optimization.rcpsp_multiskill.solvers.calendar_solver_iterative import SolverWithCalendarIterative solvers = { "lp": [(LP_Solver_MRSCPSP, { "lp_solver": MilpSolverName.CBC, "parameters_milp": ParametersMilp.default() })], "cp": [(CP_MS_MRCPSP_MZN, { "cp_solver_name": CPSolverName.CHUFFED, "parameters_cp": ParametersCP.default() })], "lns": [(LNS_CP_MS_RCPSP_SOLVER, { "nb_iteration_lns": 500, "option_neighbor": OptionNeighbor.MIX_LARGE_NEIGH })], "lns-cp": [(LNS_CP_MS_RCPSP_SOLVER, { "nb_iteration_lns": 20, "option_neighbor": OptionNeighbor.MIX_LARGE_NEIGH })], "ls": [(LS_RCPSP_Solver, { "ls_solver": LS_SOLVER.SA, "nb_iteration_max": 20 })], "ga": [(GA_MSRCPSP_Solver, { "parameters_ga": ParametersAltGa.default_msrcpsp()
def solve_lns(self, fraction_to_fix: float = 0.9, nb_iteration: int = 10, parameters_cp: ParametersCP = None, **kwargs): if parameters_cp is None: parameters_cp = ParametersCP.default() first_solution = self.get_solution(**kwargs) dict_color = { i + 1: first_solution.colors[i] + 1 for i in range(self.number_of_nodes) } nb_colors = first_solution.nb_color kwargs["nb_colors"] = nb_colors self.init_model(**kwargs) limit_time_s = kwargs.get("limit_time_s", 100) range_node = range(1, self.number_of_nodes + 1) iteration = 0 current_solution = first_solution current_best_solution = current_solution.copy() current_nb_color = current_best_solution.nb_color while iteration < nb_iteration: with self.instance.branch() as child: subpart_color = set( random.sample(range_node, int(fraction_to_fix * self.number_of_nodes))) for i in range_node: if i in subpart_color and dict_color[ i] < current_nb_color - 2: # print("constraint color_graph["+str(i)+"] == "+ str(dict_color[i])+";\n") child.add_string("constraint color_graph[" + str(i) + "] == " + str(dict_color[i]) + ";\n") child.add_string("constraint color_graph[" + str(i) + "] <= " + str(current_nb_color) + ";\n") child.add_string(f"solve minimize(obj);\n") res = child.solve( timeout=timedelta(seconds=parameters_cp.TimeLimit), intermediate_solutions=parameters_cp.intermediate_solution) result_storage = self.retrieve_solutions( res, parameters_cp=parameters_cp) print(res.status) sol, fit = result_storage.get_best_solution_fit() nb_color = self.coloring_problem.evaluate(sol)["nb_colors"] if res.solution is not None and nb_color < current_nb_color: current_nb_color = nb_color current_best_solution = sol dict_color = { i + 1: current_best_solution.colors[i] + 1 for i in range(self.number_of_nodes) } print(iteration, " : , ", fit) print('IMPROVED : ') else: try: print(iteration, " : found solution ", nb_color) except: print(iteration, " failed ") # print({i: res["color_graph"][i-1] for i in range_node}) iteration += 1 fit = self.coloring_problem.evaluate(current_best_solution) return current_best_solution, fit
def __init__(self, problem_calendar: MS_RCPSPModel, partial_solution: PartialSolution = None, option_neighbor: OptionNeighbor = OptionNeighbor.MIX_FAST, **kwargs): self.problem_calendar = problem_calendar self.problem_no_calendar = self.problem_calendar.copy() self.problem_no_calendar = MS_RCPSPModel( skills_set=self.problem_calendar.skills_set, resources_set=self.problem_calendar.resources_set, non_renewable_resources=self.problem_calendar. non_renewable_resources, resources_availability={ r: [int(max(self.problem_calendar.resources_availability[r]))] * len(self.problem_calendar.resources_availability[r]) for r in self.problem_calendar.resources_availability }, employees={ emp: self.problem_calendar.employees[emp].copy() for emp in self.problem_calendar.employees }, employees_availability=self.problem_calendar. employees_availability, mode_details=self.problem_calendar.mode_details, successors=self.problem_calendar.successors, horizon=self.problem_calendar.horizon, horizon_multiplier=self.problem_calendar.horizon_multiplier) for emp in self.problem_calendar.employees: self.problem_no_calendar.employees[emp].calendar_employee = \ [max(self.problem_calendar.employees[emp].calendar_employee)]\ *len(self.problem_calendar.employees[emp].calendar_employee) solver = CP_MS_MRCPSP_MZN(rcpsp_model=self.problem_no_calendar, cp_solver_name=CPSolverName.CHUFFED) solver.init_model(output_type=True, model_type="single", partial_solution=partial_solution, add_calendar_constraint_unit=False, exact_skills_need=False) parameters_cp = ParametersCP.default() parameters_cp.TimeLimit = 500 parameters_cp.TimeLimit_iter0 = 500 params_objective_function = get_default_objective_setup( problem=self.problem_no_calendar) # constraint_handler = ConstraintHandlerFixStartTime(problem=rcpsp_problem, # fraction_fix_start_time=0.5) constraint_handler = build_neighbor_operator( option_neighbor=option_neighbor, rcpsp_model=self.problem_no_calendar) constraint_handler = ConstraintHandlerAddCalendarConstraint( self.problem_calendar, self.problem_no_calendar, constraint_handler) initial_solution_provider = InitialSolutionMS_RCPSP( problem=self.problem_calendar, initial_method=InitialMethodRCPSP.PILE_CALENDAR, params_objective_function=params_objective_function) self.initial_solution_provider = initial_solution_provider self.constraint_handler = constraint_handler self.params_objective_function = params_objective_function self.cp_solver = solver self.post_process_solution = PostProcessSolutionNonFeasible( self.problem_calendar, self.problem_no_calendar, partial_solution=partial_solution)
def retrieve_solutions( self, result, parameters_cp: ParametersCP = ParametersCP.default()): intermediate_solutions = parameters_cp.intermediate_solution best_solution = None best_makespan = -float("inf") list_solutions_fit = [] starts = [] mruns = [] units_used = [] if intermediate_solutions: for i in range(len(result)): if isinstance(result[i], MS_RCPSPSolCP): starts += [result[i].dict["start"]] mruns += [result[i].dict["mrun"]] units_used += [result[i].dict["unit_used"]] else: starts += [result[i, "start"]] mruns += [result[i, "mrun"]] units_used += [result[i, "unit_used"]] # array_skill = result[i, "array_skills_required"] # print("Objective : ", result[i, "objective"]) else: if isinstance(result, MS_RCPSPSolCP): starts += [result.dict["start"]] mruns += [result.dict["mrun"]] units_used += [result.dict["unit_used"]] else: starts += [result["start"]] mruns += [result["mrun"]] units_used += [result["unit_used"]] # array_skill = result["array_skills_required"] for start_times, mrun, unit_used in zip(starts, mruns, units_used): #print("New Solution") modes = [] usage = {} for i in range(len(mrun)): if mrun[i] and (self.modeindex_map[i + 1]['task'] != 1) and (self.modeindex_map[i + 1]['task'] != self.rcpsp_model.n_jobs_non_dummy + 2): modes.append(self.modeindex_map[i + 1]['original_mode_index']) elif (self.modeindex_map[i + 1]['task'] == 1) or (self.modeindex_map[i + 1]['task'] == self.rcpsp_model.n_jobs_non_dummy + 2): modes.append(1) for w in range(len(unit_used)): for task in range(len(unit_used[w])): if unit_used[w][task] == 1: task_id = task + 1 #print("Unit used : , ", w, "taskid : ", # task_id, unit_used[w][task]) mode = modes[task_id - 1] skills_needed = set([ s #, self.rcpsp_model.mode_details[task_id][mode][s]) for s in self.rcpsp_model.skills_set if s in self.rcpsp_model.mode_details[task_id][mode] and self.rcpsp_model.mode_details[task_id][mode][s] > 0 ]) skills_worker = set([ s # self.rcpsp_model.employees[self.employees_position[w]].dict_skill[s].skill_value) for s in self.rcpsp_model.employees[ self.employees_position[w]].dict_skill if self.rcpsp_model.employees[ self.employees_position[w]].dict_skill[s]. skill_value > 0 ]) intersection = skills_needed.intersection( skills_worker) if len(intersection) > 0: if task_id not in usage: usage[task_id] = {} usage[task_id][ self.employees_position[w]] = intersection rcpsp_schedule = {} for i in range(len(start_times)): rcpsp_schedule[i + 1] = { 'start_time': start_times[i], 'end_time': start_times[i] + self.rcpsp_model.mode_details[i + 1][modes[i]]['duration'] } sol = MS_RCPSPSolution( problem=self.rcpsp_model, modes={i + 1: modes[i] for i in range(len(modes))}, schedule=rcpsp_schedule, employee_usage=usage) objective = self.aggreg_from_dict_values( self.rcpsp_model.evaluate(sol)) if objective > best_makespan: best_makespan = objective best_solution = sol.copy() list_solutions_fit += [(sol, objective)] result_storage = ResultStorage( list_solution_fits=list_solutions_fit, best_solution=best_solution, mode_optim=self.params_objective_function.sense_function, limit_store=False) return result_storage