def build_other_solution(self,
                          result_storage: ResultStorage) -> ResultStorage:
     bs = result_storage.get_best_solution()
     colors = bs.colors
     set_colors = sorted(set(colors))
     nb_colors = len(set(set_colors))
     new_color_dict = {set_colors[i]: i for i in range(nb_colors)}
     new_solution = ColoringSolution(
         problem=self.problem,
         colors=[new_color_dict[colors[i]] for i in range(len(colors))])
     fit = self.aggreg_from_sol(new_solution)
     result_storage.add_solution(new_solution, fit)
     return result_storage
    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 get_starting_solution(self) -> ResultStorage:
     multi_skill_rcpsp = self.problem.build_multimode_rcpsp_calendar_representative()
     from skdecide.builders.discrete_optimization.rcpsp.solver.rcpsp_lp_lns_solver import InitialSolutionRCPSP
     init_solution = InitialSolutionRCPSP(problem=multi_skill_rcpsp,
                                          params_objective_function=self.params_objective_function,
                                          initial_method=self.initial_method)
     s = init_solution.get_starting_solution()
     list_solution_fits = []
     for s, fit in s.list_solution_fits:
         sol: RCPSPSolution = s
         mode = sol.rcpsp_modes
         modes = {i+2: mode[i] for i in range(len(mode))}
         modes[self.problem.source_task] = 1
         modes[self.problem.sink_task] = 1
         # ms_rcpsp_solution = MS_RCPSPSolution(problem=self.problem,
         #                                      modes=modes,
         #                                      schedule=sol.rcpsp_schedule,
         #                                      employee_usage=None)
         ms_rcpsp_solution = MS_RCPSPSolution_Variant(problem=self.problem,
                                                      priority_list_task=sol.rcpsp_permutation,
                                                      modes_vector=sol.rcpsp_modes,
                                                      priority_worker_per_task=[[w for w in self.problem.employees]
                                                                                for i
                                                                                in
                                                                                range(self.problem.n_jobs_non_dummy)])
         list_solution_fits += [(ms_rcpsp_solution, self.aggreg(ms_rcpsp_solution))]
     return ResultStorage(list_solution_fits=list_solution_fits,
                          mode_optim=self.params_objective_function.sense_function)
 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
예제 #5
0
 def retrieve_solutions(self, result,
                        parameters_cp: ParametersCP) -> ResultStorage:
     intermediate_solutions = parameters_cp.intermediate_solution
     l_items = []
     objectives = []
     if intermediate_solutions:
         for i in range(len(result)):
             l_items += [result[i, "list_items"]]
             objectives += [result[i, "objective"]]
     else:
         l_items += [result["list_items"]]
         objectives += [result["objective"]]
     list_solutions_fit = []
     for items, objective in zip(l_items, objectives):
         taken = [0] * self.knapsack_model.nb_items
         weight = 0
         value = 0
         for i in range(len(items)):
             if items[i] != 0:
                 taken[self.knapsack_model.list_items[items[i] -
                                                      1].index] = 1
                 weight += self.knapsack_model.list_items[items[i] -
                                                          1].weight
                 value += self.knapsack_model.list_items[items[i] - 1].value
         sol = KnapsackSolution(problem=self.knapsack_model,
                                value=value,
                                weight=weight,
                                list_taken=taken)
         fit = self.aggreg_sol(sol)
         list_solutions_fit += [(sol, fit)]
     return ResultStorage(
         list_solution_fits=list_solutions_fit,
         best_solution=None,
         mode_optim=self.params_objective_function.sense_function)
예제 #6
0
 def retrieve_solutions(self, parameters_milp: ParametersMilp) -> ResultStorage:
     retrieve_all_solution = parameters_milp.retrieve_all_solution
     nb_solutions_max = parameters_milp.n_solutions_max
     nb_solution = min(nb_solutions_max, self.model.SolCount)
     if not retrieve_all_solution:
         nb_solution = 1
     list_solution_fits = []
     for s in range(nb_solution):
         self.model.params.SolutionNumber = s
         rcpsp_schedule = {}
         modes = {}
         objective = self.model.getAttr("ObjVal")
         for (task, mode, t) in self.x:
             value = self.x[(task, mode, t)].getAttr('Xn')
             if value >= 0.5:
                 rcpsp_schedule[task] = {'start_time': t,
                                         'end_time': t + self.rcpsp_model.mode_details[task][mode]['duration']}
                 modes[task] = mode
         print("Size schedule : ", len(rcpsp_schedule.keys()))
         try:
             modes.pop(1)
             modes.pop(self.rcpsp_model.n_jobs+2)
             modes_vec = [modes[k] for k in sorted(modes)]
             solution = RCPSPSolution(problem=self.rcpsp_model,
                                      rcpsp_schedule=rcpsp_schedule,
                                      rcpsp_modes=modes_vec,
                                      rcpsp_schedule_feasible=True)
             fit = self.aggreg_from_sol(solution)
             list_solution_fits += [(solution, fit)]
         except:
             pass
     return ResultStorage(list_solution_fits=list_solution_fits,
                          best_solution=min(list_solution_fits,
                                            key=lambda x: x[1])[0],
                          mode_optim=self.params_objective_function.sense_function)
예제 #7
0
    def build_other_solution(self, result_storage: ResultStorage) -> ResultStorage:
        new_solution = sgs_variant(solution=result_storage.get_best_solution(),
                                   problem=self.problem,
                                   predecessors_dict=self.immediate_predecessors)
        fit = self.aggreg_from_sol(new_solution)
        result_storage.add_solution(new_solution, fit)
        import random
        for s in random.sample(result_storage.list_solution_fits,
                               min(len(result_storage.list_solution_fits), 50)):
            new_solution = sgs_variant(solution=s[0],
                                       problem=self.problem,
                                       predecessors_dict=self.immediate_predecessors)
            fit = self.aggreg_from_sol(new_solution)
            result_storage.add_solution(new_solution, fit)

        return result_storage
예제 #8
0
 def retrieve_solutions(self, parameters_milp: ParametersMilp) -> ResultStorage:
     retrieve_all_solution = parameters_milp.retrieve_all_solution
     nb_solutions_max = parameters_milp.n_solutions_max
     nb_solution = min(nb_solutions_max, self.model.num_solutions)
     if not retrieve_all_solution:
         nb_solution = 1
     list_solution_fits = []
     print(nb_solution, " solutions found")
     for s in range(nb_solution):
         rcpsp_schedule = {}
         objective = self.model.objective_values[s]
         for (j, t) in product(self.J, self.T):
             value = self.x[j][t].xi(s)
             if value >= 0.5:
                 rcpsp_schedule[j + 1] = {'start_time': t,
                                          'end_time': t + self.rcpsp_model.mode_details[j + 1][1]['duration']}
         print("Size schedule : ", len(rcpsp_schedule.keys()))
         try:
             solution = RCPSPSolution(problem=self.rcpsp_model,
                                      rcpsp_schedule=rcpsp_schedule,
                                      rcpsp_schedule_feasible=True)
             fit = self.aggreg_from_sol(solution)
             list_solution_fits += [(solution, fit)]
         except:
             print("Problem =", rcpsp_schedule, len(rcpsp_schedule))
             pass
     return ResultStorage(list_solution_fits=list_solution_fits,
                          best_solution=min(list_solution_fits,
                                            key=lambda x: x[1])[0],
                          mode_optim=self.params_objective_function.sense_function)
 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_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_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
예제 #12
0
    def solve(self, **kwargs):
        # Initialise the population (here at random)

        count_evals = 0
        current_encoding_index = 0

        for i in range(len(self.encodings)):
            self.problem.set_fixed_attributes(
                self.encodings[i], self.problem.get_dummy_solution())

        while count_evals < self.max_evals:

            ga_solver = Ga(problem=self.problem,
                           encoding=self.encodings[current_encoding_index],
                           objective_handling=self.objective_handling,
                           objectives=self.objectives,
                           objective_weights=self.objective_weights,
                           mutation=self.mutations[current_encoding_index],
                           max_evals=self.sub_evals[current_encoding_index])
            tmp_sol = ga_solver.solve().get_best_solution()
            count_evals += self.sub_evals[current_encoding_index]

            # TODO: implement function below (1 in rcpsp domains, 1 in rcpsp solutions)
            self.problem.set_fixed_attributes(
                self.encodings[current_encoding_index], tmp_sol)

        problem_sol = tmp_sol

        result_storage = ResultStorage(
            list_solution_fits=[(problem_sol,
                                 self.aggreg_from_sol(problem_sol))],
            best_solution=problem_sol,
            mode_optim=self.params_objective_function.sense_function)
        return result_storage
예제 #13
0
 def generate_super_pareto(self):
     sols = []
     for rs in self.list_result_storage:
         for s in rs.list_solution_fits:
             sols.append(s)
     rs = ResultStorage(list_solution_fits=sols, best_solution=None)
     # print('len(rs): ', len(rs.list_solution_fits))
     pareto_store = result_storage_to_pareto_front(result_storage=rs, problem=None)
     # print('len(pareto_store): ', len(pareto_store.list_solution_fits))
     # print('hhhh: ', [x[1].vector_fitness for x in pareto_store.list_solution_fits])
     return pareto_store
예제 #14
0
 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 retrieve_solutions(self, parameters_milp: ParametersMilp) -> ResultStorage:
     solution = [0] * self.number_of_nodes
     for key in self.variable_decision["colors_var"]:
         value = self.variable_decision["colors_var"][key].x
         if value >= 0.5:
             node = key[0]
             color = key[1]
             solution[self.index_nodes_name[node]] = color
     color_solution = ColoringSolution(self.coloring_problem, solution)
     fit = self.aggreg_from_sol(color_solution)
     return ResultStorage(list_solution_fits=[(color_solution, fit)],
                          best_solution=color_solution,
                          mode_optim=self.sense_optim)
 def get_starting_solution(self) -> ResultStorage:
     if self.initial_method == InitialColoringMethod.DUMMY:
         sol = self.problem.get_dummy_solution()
         fit = self.aggreg_sol(sol)
         return ResultStorage(
             list_solution_fits=[(sol, fit)],
             best_solution=sol,
             mode_optim=self.params_objective_function.sense_function)
     else:
         solver = GreedyColoring(
             color_problem=self.problem,
             params_objective_function=self.params_objective_function)
         return solver.solve()
 def retrieve_solutions(self, parameters_milp: ParametersMilp) -> ResultStorage:
     solution = [0] * self.facility_problem.customer_count
     for key in self.variable_decision["x"]:
         try:
             value = self.variable_decision["x"][key].x
         except:
             value = self.variable_decision["x"][key]  ## To deal with already fixed variable.
         if value >= 0.5:
             f = key[0]
             c = key[1]
             solution[c] = f
     facility_solution = FacilitySolution(self.facility_problem, solution)
     result_store = ResultStorage(list_solution_fits=[(facility_solution, self.aggreg_sol(facility_solution))],
                                  best_solution=facility_solution,
                                  mode_optim=self.params_objective_function.sense_function)
     return result_store
 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
예제 #19
0
    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 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
예제 #21
0
 def solve(self, **kwargs):
     strategy: NXGreedyColoringMethod = kwargs.get(
         "strategy", NXGreedyColoringMethod.best)
     print(strategy)
     verbose: bool = kwargs.get("verbose", False)
     strategy_name = strategy.name
     if strategy_name == "best":
         strategies_to_test = strategies
     else:
         strategies_to_test = [strategy_name]
     best_solution = None
     best_nb_color = float('inf')
     for strategy in strategies_to_test:
         try:
             colors = nx.algorithms.coloring.greedy_color(self.nx_graph,
                                                          strategy=strategy,
                                                          interchange=False)
             sorted_nodes = sorted(list(colors.keys()))
             number_colors = len(set(list(colors.values())))
             solution = [colors[i] for i in sorted_nodes]
             if verbose:
                 print(strategy, " : number colors : ", number_colors)
             if number_colors < best_nb_color:
                 best_solution = solution
                 best_nb_color = number_colors
         except Exception as e:
             print("Failed strategy : ", strategy, e)
             pass
     if verbose:
         print("best : ", best_nb_color)
     solution = ColoringSolution(self.color_problem,
                                 colors=best_solution,
                                 nb_color=None)
     solution = solution.to_reformated_solution(
     )  # TODO : make this OPTIONAL
     fit = self.aggreg_sol(solution)
     if verbose:
         print("Solution found : ", solution)
     return ResultStorage(
         list_solution_fits=[(solution, fit)],
         best_solution=solution,
         mode_optim=self.params_objective_function.sense_function)
 def adding_constraint_from_results_store(
         self, cp_solver: CPSolver, child_instance,
         result_storage: ResultStorage) -> Iterable[Any]:
     range_node = range(1, self.problem.number_of_nodes + 1)
     current_solution = result_storage.get_best_solution()
     subpart_color = set(
         random.sample(
             range_node,
             int(self.fraction_to_fix * self.problem.number_of_nodes)))
     dict_color = {
         i + 1: current_solution.colors[i] + 1
         for i in range(self.problem.number_of_nodes)
     }
     current_nb_color = max(dict_color.values())
     for i in range_node:
         if i in subpart_color and dict_color[i] < current_nb_color:
             child_instance.add_string("constraint color_graph[" + str(i) +
                                       "] == " + str(dict_color[i]) + ";\n")
         child_instance.add_string("constraint color_graph[" + str(i) +
                                   "] <= " + str(current_nb_color) + ";\n")
 def adding_constraint_from_results_store(self, milp_solver: LP_Solver_MRSCPSP, result_storage: ResultStorage) -> Iterable[
     Any]:
     current_solution: MS_RCPSPSolution = result_storage.get_best_solution()
     # 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.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
     constraints_dict = {}
     constraints_dict["range_start_time"] = []
     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 - 5]
     nb_jobs = self.problem.nb_tasks
     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)
     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)
         constraints_dict["range_start_time"].append(milp_solver.model.add_constr(milp_solver.start_times_task[job]
                                                                                  <= max_st))
         constraints_dict["range_start_time"].append(milp_solver.model.add_constr(milp_solver.start_times_task[job]
                                                                                  >= min_st))
     if milp_solver.lp_solver == MilpSolverName.GRB:
         milp_solver.model.solver.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 solve(self, **kwargs):
     res_storage = solve(method=self.method,
                         rcpsp_model=self.model_rcpsp,
                         **self.args_solve)
     list_solution_fits = []
     for s, fit in res_storage.list_solution_fits:
         sol: RCPSPSolution = s
         mode = sol.rcpsp_modes
         modes = {i + 2: mode[i] for i in range(len(mode))}
         modes[self.model.source_task] = 1
         modes[self.model.sink_task] = 1
         # print(fit, " found by ", self.method.__name__)
         ms_rcpsp_solution = MS_RCPSPSolution_Variant(
             problem=self.model,
             priority_list_task=sol.rcpsp_permutation,
             modes_vector=sol.rcpsp_modes,
             priority_worker_per_task=[[
                 w for w in self.model.employees
             ] for i in range(self.model.n_jobs_non_dummy)])
         list_solution_fits += [(ms_rcpsp_solution,
                                 self.aggreg_from_sol(ms_rcpsp_solution))]
     return ResultStorage(
         list_solution_fits=list_solution_fits,
         mode_optim=self.params_objective_function.sense_function)
예제 #26
0
 def solve(self,
           initial_variable: Solution,
           nb_iteration_max: int,
           pickle_result=False,
           pickle_name="tsp") -> ResultLS:
     objective = self.aggreg_from_dict_values(
         self.evaluator.evaluate(initial_variable))
     cur_variable = initial_variable.copy()
     if self.store_solution:
         store = ResultStorage(list_solution_fits=[(initial_variable,
                                                    objective)],
                               best_solution=initial_variable.copy(),
                               limit_store=True,
                               nb_best_store=1000)
     else:
         store = ResultStorage(list_solution_fits=[(initial_variable,
                                                    objective)],
                               best_solution=initial_variable.copy(),
                               limit_store=True,
                               nb_best_store=1)
     cur_best_variable = initial_variable.copy()
     cur_objective = objective
     cur_best_objective = objective
     self.restart_handler.best_fitness = objective
     iteration = 0
     while iteration < nb_iteration_max:
         accept = False
         local_improvement = False
         global_improvement = False
         if self.mode_mutation == ModeMutation.MUTATE:
             nv, move = self.mutator.mutate(cur_variable)
             objective = self.aggreg_from_solution(nv)
         elif self.mode_mutation == ModeMutation.MUTATE_AND_EVALUATE:
             nv, move, objective = self.mutator.mutate_and_compute_obj(
                 cur_variable)
             objective = self.aggreg_from_dict_values(objective)
         if self.mode_optim == ModeOptim.MINIMIZATION and objective < cur_objective:
             accept = True
             local_improvement = True
             global_improvement = objective < cur_best_objective
         elif self.mode_optim == ModeOptim.MAXIMIZATION and objective > cur_objective:
             accept = True
             local_improvement = True
             global_improvement = objective > cur_best_objective
         if accept:
             cur_objective = objective
             cur_variable = nv
         else:
             cur_variable = move.backtrack_local_move(nv)
         if self.store_solution:
             store.add_solution(nv, objective)
         if global_improvement:
             print("iter ", iteration)
             print("new obj ", objective, " better than ",
                   cur_best_objective)
             cur_best_objective = objective
             cur_best_variable = cur_variable.copy()
             if not self.store_solution:
                 store.add_solution(cur_variable, objective)
         # Update the temperature
         self.restart_handler.update(nv, objective, global_improvement,
                                     local_improvement)
         # Update info in restart handler
         cur_variable, cur_objective = self.restart_handler.restart(
             cur_variable, cur_objective)
         # possibly restart somewhere
         iteration += 1
         if pickle_result and iteration % 20000 == 0:
             pickle.dump(cur_best_variable, open(pickle_name + ".pk", "wb"))
     store.finalize()
     return store
 def solve(self,
           parameters_cp: ParametersCP,
           nb_iteration_lns: int,
           nb_iteration_no_improvement: Optional[int] = None,
           max_time_seconds: Optional[int] = None,
           skip_first_iteration: bool = False,
           **args) -> ResultStorage:
     sense = self.params_objective_function.sense_function
     if max_time_seconds is None:
         max_time_seconds = 3600 * 24  # One day
     if nb_iteration_no_improvement is None:
         nb_iteration_no_improvement = 2 * nb_iteration_lns
     current_nb_iteration_no_improvement = 0
     deb_time = time.time()
     if not skip_first_iteration:
         store_lns = self.initial_solution_provider.get_starting_solution()
         store_lns = self.post_process_solution.build_other_solution(
             store_lns)
         store_with_all = ResultStorage(list(store_lns.list_solution_fits),
                                        mode_optim=store_lns.mode_optim)
         init_solution, objective = store_lns.get_best_solution_fit()
         best_solution = init_solution.copy()
         satisfy = self.problem_calendar.satisfy(init_solution)
         print("Satisfy ", satisfy)
         best_objective = objective
     else:
         best_objective = float(
             'inf') if sense == ModeOptim.MINIMIZATION else -float("inf")
         best_solution = None
         constraint_iterable = {"empty": []}
         store_lns = None
         store_with_all = None
     constraint_to_keep = set()
     for iteration in range(nb_iteration_lns):
         print('Starting iteration n°', iteration, " current objective ",
               best_objective)
         try:
             print(
                 "Best feasible solution ",
                 max([
                     f for s, f in store_with_all.list_solution_fits
                     if "satisfy" in s.__dict__.keys() and s.satisfy
                 ]))
         except:
             print("No Feasible solution yet")
         with self.cp_solver.instance.branch() as child:
             if iteration == 0 and not skip_first_iteration or iteration >= 1:
                 for c in constraint_to_keep:
                     child.add_string(c)
                 constraint_iterable = self.constraint_handler \
                     .adding_constraint_from_results_store(cp_solver=self.cp_solver,
                                                           child_instance=child,
                                                           result_storage=store_lns)
                 if constraint_iterable[0] == "req":
                     constraint_to_keep.update(
                         set([c for c in constraint_iterable[1:]]))
             if True:
                 if iteration == 0:
                     result = child.solve(
                         timeout=timedelta(
                             seconds=parameters_cp.TimeLimit_iter0),
                         intermediate_solutions=parameters_cp.
                         intermediate_solution)
                 else:
                     result = child.solve(
                         timeout=timedelta(seconds=parameters_cp.TimeLimit),
                         intermediate_solutions=parameters_cp.
                         intermediate_solution)
                 result_store = self.cp_solver.retrieve_solutions(
                     result, parameters_cp=parameters_cp)
                 print("iteration n°", iteration, "Solved !!!")
                 print(result.status)
                 if len(result_store.list_solution_fits) > 0:
                     print("Solved !!!")
                     bsol, fit = result_store.get_best_solution_fit()
                     print("Fitness = ", fit)
                     print("Post Process..")
                     print("Satisfy best current sol : ")
                     print(self.problem_calendar.satisfy(bsol))
                     result_store = self.post_process_solution.build_other_solution(
                         result_store)
                     bsol, fit = result_store.get_best_solution_fit()
                     print("After postpro = ", fit)
                     if sense == ModeOptim.MAXIMIZATION and fit >= best_objective:
                         if fit > best_objective:
                             current_nb_iteration_no_improvement = 0
                         else:
                             current_nb_iteration_no_improvement += 1
                         best_solution = bsol
                         best_objective = fit
                     elif sense == ModeOptim.MAXIMIZATION:
                         current_nb_iteration_no_improvement += 1
                     elif sense == ModeOptim.MINIMIZATION and fit <= best_objective:
                         if fit < best_objective:
                             current_nb_iteration_no_improvement = 0
                         else:
                             current_nb_iteration_no_improvement += 1
                         best_solution = bsol
                         best_objective = fit
                     elif sense == ModeOptim.MINIMIZATION:
                         current_nb_iteration_no_improvement += 1
                     if skip_first_iteration and iteration == 0:
                         store_lns = result_store
                         store_with_all = ResultStorage(
                             list_solution_fits=list(
                                 store_lns.list_solution_fits),
                             mode_optim=store_lns.mode_optim)
                     store_lns = result_store
                     for s, f in store_lns.list_solution_fits:
                         store_with_all.list_solution_fits += [(s, f)]
                     for s, f in store_with_all.list_solution_fits:
                         if s.satisfy:
                             store_lns.list_solution_fits += [(s, f)]
                     print("Satisfy : ",
                           self.problem_calendar.satisfy(best_solution))
                 else:
                     current_nb_iteration_no_improvement += 1
                 if skip_first_iteration and result.status == Status.OPTIMAL_SOLUTION and iteration == 0\
                         and best_solution.satisfy:
                     print("Finish LNS because found optimal solution")
                     break
             else:
                 #except Exception as e:
                 current_nb_iteration_no_improvement += 1
                 print("Failed ! reason : ", e)
             if time.time() - deb_time > max_time_seconds:
                 print("Finish LNS with time limit reached")
                 break
             print(current_nb_iteration_no_improvement, "/",
                   nb_iteration_no_improvement)
             if current_nb_iteration_no_improvement > nb_iteration_no_improvement:
                 print("Finish LNS with maximum no improvement iteration ")
                 break
     return store_with_all
    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
예제 #29
0
 def compute_schedule_from_priority_list(self, permutation_jobs: List[int],
                                         modes_dict: Dict[int, int]):
     current_pred = {
         k: {
             "succs": set(self.immediate_predecessors[k]),
             "nb": len(self.immediate_predecessors[k])
         }
         for k in self.immediate_predecessors
     }
     schedule = {}
     current_ressource_available = self.resources.copy()
     current_ressource_non_renewable = {
         nr: self.resources[nr]
         for nr in self.non_renewable
     }
     schedule[1] = {"start_time": 0, "end_time": 0}
     available_activities = {
         n
         for n in current_pred
         if n not in schedule and current_pred[n]["nb"] == 0
     }
     available_activities.update(
         {n
          for n in self.all_activities if n not in current_pred})
     for neighbor in self.immediate_successors[1]:
         if 1 in current_pred[neighbor]["succs"]:
             current_pred[neighbor]["succs"].remove(1)
             current_pred[neighbor]["nb"] -= 1
             if current_pred[neighbor]["nb"] == 0:
                 available_activities.add(neighbor)
     permutation_jobs.remove(1)
     queue = []
     current_time = 0
     perm = []
     while len(schedule) < self.n_jobs + 2:
         possible_activities = [
             n for n in available_activities
             if all(self.mode_details[n][modes_dict[n]][r] <=
                    current_ressource_available[r]
                    for r in current_ressource_available)
         ]
         while len(possible_activities) > 0:
             next_activity = min(possible_activities,
                                 key=lambda x: permutation_jobs.index(x))
             available_activities.remove(next_activity)
             perm += [next_activity - 2]
             schedule[next_activity] = {}
             schedule[next_activity]["start_time"] = current_time
             schedule[next_activity]["end_time"] = \
                 current_time + self.mode_details[next_activity][modes_dict[next_activity]]["duration"]
             permutation_jobs.remove(next_activity)
             push(queue, (schedule[next_activity]["end_time"],
                          next_activity, "end_"))
             for r in self.resources:
                 current_ressource_available[r] -= self.mode_details[
                     next_activity][modes_dict[next_activity]][r]
                 if r in current_ressource_non_renewable:
                     current_ressource_non_renewable[
                         r] -= self.mode_details[next_activity][
                             modes_dict[next_activity]][r]
             possible_activities = [
                 n for n in available_activities
                 if all(self.mode_details[n][modes_dict[n]][r] <=
                        current_ressource_available[r]
                        for r in current_ressource_available)
             ]
         # print(current_ressource_available, self.rcpsp_model.non_renewable_resources)
         current_time, activity, descr = pop(queue)
         for neighbor in self.immediate_successors[activity]:
             if activity in current_pred[neighbor]["succs"]:
                 current_pred[neighbor]["succs"].remove(activity)
                 current_pred[neighbor]["nb"] -= 1
                 if current_pred[neighbor]["nb"] == 0:
                     available_activities.add(neighbor)
         for r in self.resources:
             if r not in current_ressource_non_renewable:
                 current_ressource_available[r] += self.mode_details[
                     activity][modes_dict[activity]][r]
     # print("Final Time ", current_time)
     sol = RCPSPSolution(
         problem=self.rcpsp_model,
         rcpsp_permutation=perm[:-1],
         rcpsp_schedule=schedule,
         rcpsp_modes=[modes_dict[i + 1] for i in range(self.n_jobs)],
         rcpsp_schedule_feasible=True)
     result_storage = ResultStorage(
         list_solution_fits=[(sol, self.aggreg_from_sol(sol))],
         best_solution=sol,
         mode_optim=self.params_objective_function.sense_function)
     return result_storage
예제 #30
0
 def solve(self, **kwargs) -> ResultStorage:
     greedy_choice = kwargs.get("greedy_choice",
                                GreedyChoice.MOST_SUCCESSORS)
     verbose = kwargs.get("verbose", False)
     current_succ = {
         k: {
             "succs": set(self.successors_map[k]["succs"]),
             "nb": self.successors_map[k]["nb"]
         }
         for k in self.successors_map
     }
     current_pred = {
         k: {
             "succs": set(self.predecessors_map[k]["succs"]),
             "nb": self.predecessors_map[k]["nb"]
         }
         for k in self.predecessors_map
     }
     schedule = {}
     current_ressource_available = self.resources.copy()
     current_ressource_non_renewable = {
         nr: self.resources[nr]
         for nr in self.non_renewable
     }
     schedule[1] = {"start_time": 0, "end_time": 0}
     available_activities = {
         n
         for n in current_pred
         if n not in schedule and current_pred[n]["nb"] == 0
     }
     available_activities.update(
         {n
          for n in self.all_activities if n not in current_pred})
     for neighbor in current_pred:
         if 1 in current_pred[neighbor]["succs"]:
             current_pred[neighbor]["succs"].remove(1)
             current_pred[neighbor]["nb"] -= 1
             if current_pred[neighbor]["nb"] == 0:
                 available_activities.add(neighbor)
     if verbose:
         print(current_pred)
     queue = []
     current_time = 0
     perm = []
     while len(schedule) < self.n_jobs + 2:
         if verbose:
             print(len(schedule))
             print("available activities : ", available_activities)
         possible_activities = [
             n for n in available_activities
             if all(self.mode_details[n][self.modes_dict[n]][r] <=
                    current_ressource_available[r]
                    for r in current_ressource_available)
         ]
         if verbose:
             print("Ressources : ", current_ressource_available)
         while len(possible_activities) > 0:
             if greedy_choice == GreedyChoice.MOST_SUCCESSORS:
                 next_activity = max(possible_activities,
                                     key=lambda x: current_succ[x]["nb"])
             if greedy_choice == GreedyChoice.SAMPLE_MOST_SUCCESSORS:
                 prob = np.array([
                     current_succ[possible_activities[i]]["nb"]
                     for i in range(len(possible_activities))
                 ])
                 s = np.sum(prob)
                 if s != 0:
                     prob = prob / s
                 else:
                     prob = 1. / len(possible_activities) * np.ones(
                         (len(possible_activities)))
                 next_activity = np.random.choice(np.arange(
                     0, len(possible_activities)),
                                                  size=1,
                                                  p=prob)[0]
                 next_activity = possible_activities[next_activity]
             if greedy_choice == GreedyChoice.FASTEST:
                 next_activity = min(possible_activities,
                                     key=lambda x: self.mode_details[x][
                                         self.modes_dict[x]]["duration"])
             if greedy_choice == GreedyChoice.TOTALLY_RANDOM:
                 next_activity = random.choice(possible_activities)
             available_activities.remove(next_activity)
             perm += [next_activity - 2]
             schedule[next_activity] = {}
             schedule[next_activity]["start_time"] = current_time
             schedule[next_activity]["end_time"] = current_time + \
                                                   self.mode_details[next_activity][self.modes_dict[next_activity]]["duration"]
             push(queue, (schedule[next_activity]["end_time"],
                          next_activity, "end_"))
             for r in self.resources:
                 current_ressource_available[r] -= self.mode_details[
                     next_activity][self.modes_dict[next_activity]][r]
                 if r in current_ressource_non_renewable:
                     current_ressource_non_renewable[
                         r] -= self.mode_details[next_activity][
                             self.modes_dict[next_activity]][r]
             if verbose:
                 print(current_time, "Current ressource available : ",
                       current_ressource_available)
             possible_activities = [
                 n for n in available_activities
                 if all(self.mode_details[n][self.modes_dict[n]][r] <=
                        current_ressource_available[r]
                        for r in current_ressource_available)
             ]
         current_time, activity, descr = pop(queue)
         for neighbor in current_pred:
             if activity in current_pred[neighbor]["succs"]:
                 current_pred[neighbor]["succs"].remove(activity)
                 current_pred[neighbor]["nb"] -= 1
                 if current_pred[neighbor]["nb"] == 0:
                     available_activities.add(neighbor)
         for r in self.resources:
             if r not in current_ressource_non_renewable:
                 current_ressource_available[r] += self.mode_details[
                     activity][self.modes_dict[activity]][r]
     if verbose:
         print("Final Time ", current_time)
     sol = RCPSPSolution(
         problem=self.rcpsp_model,
         rcpsp_permutation=perm[:-1],
         rcpsp_schedule=schedule,
         rcpsp_modes=[self.modes_dict[i + 2] for i in range(self.n_jobs)],
         rcpsp_schedule_feasible=True)
     result_storage = ResultStorage(
         list_solution_fits=[(sol, self.aggreg_from_sol(sol))],
         best_solution=sol,
         mode_optim=self.params_objective_function.sense_function)
     return result_storage