def init_model(self, **kwargs): greedy_start = kwargs.get("greedy_start", True) verbose = kwargs.get("verbose", False) use_cliques = kwargs.get("use_cliques", False) if greedy_start: if verbose: print("Computing greedy solution") greedy_solver = GreedyColoring(self.coloring_problem, params_objective_function=self.params_objective_function) result_store = greedy_solver.solve(strategy=NXGreedyColoringMethod.best, verbose=verbose) self.start_solution = result_store.get_best_solution_fit()[0] else: if verbose: print("Get dummy solution") solution = self.coloring_problem.get_dummy_solution() self.start_solution = solution nb_colors = self.start_solution.nb_color color_model = Model("color") colors_var = {} range_node = range(self.number_of_nodes) range_color = range(nb_colors) for node in self.nodes_name: for color in range_color: colors_var[node, color] = color_model.addVar(vtype=GRB.BINARY, obj=0, name="x_" + str((node, color))) one_color_constraints = {} for n in range_node: one_color_constraints[n] = color_model.addConstr(quicksum([colors_var[n, c] for c in range_color]) == 1) color_model.update() cliques = [] g = self.graph.to_networkx() if use_cliques: for c in nx.algorithms.clique.find_cliques(g): cliques += [c] cliques = sorted(cliques, key=lambda x: len(x), reverse=True) else: cliques = [[e[0], e[1]] for e in g.edges()] cliques_constraint = {} index_c = 0 opt = color_model.addVar(vtype=GRB.INTEGER, lb=0, ub=nb_colors, obj=1) if use_cliques: for c in cliques[:100]: cliques_constraint[index_c] = color_model.addConstr(quicksum([(color_i + 1) * colors_var[node, color_i] for node in c for color_i in range_color]) >= sum([i + 1 for i in range(len(c))])) cliques_constraint[(index_c, 1)] = color_model.addConstr(quicksum([colors_var[node, color_i] for node in c for color_i in range_color]) <= opt) index_c += 1 edges = g.edges() constraints_neighbors = {} for e in edges: for c in range_color: constraints_neighbors[(e[0], e[1], c)] = \ color_model.addConstr(colors_var[e[0], c] + colors_var[e[1], c] <= 1) for n in range_node: color_model.addConstr(quicksum([(color_i + 1) * colors_var[n, color_i] for color_i in range_color]) <= opt) color_model.update() color_model.modelSense = GRB.MINIMIZE color_model.setParam(GRB.Param.Threads, 8) color_model.setParam(GRB.Param.PoolSolutions, 10000) color_model.setParam(GRB.Param.Method, -1) color_model.setParam("MIPGapAbs", 0.001) color_model.setParam("MIPGap", 0.001) color_model.setParam("Heuristics", 0.01) self.model = color_model self.variable_decision = {"colors_var": colors_var} self.constraints_dict = {"one_color_constraints": one_color_constraints, "constraints_neighbors": constraints_neighbors} self.description_variable_description = {"colors_var": {"shape": (self.number_of_nodes, nb_colors), "type": bool, "descr": "for each node and each color," " a binary indicator"}} self.description_constraint["one_color_constraints"] = {"descr": "one and only one color " "should be assignated to a node"} self.description_constraint["constraints_neighbors"] = {"descr": "no neighbors can have same color"}
class LPKnapsackGurobi(SolverDO): def __init__(self, knapsack_model: KnapsackModel, params_objective_function: ParamsObjectiveFunction = None): self.knapsack_model = knapsack_model self.model = None self.variable_decision = {} self.constraints_dict = {} self.description_variable_description = {} self.description_constraint = {} self.aggreg_sol, self.aggreg_dict, self.params_objective_function = \ build_aggreg_function_and_params_objective(problem=self.knapsack_model, params_objective_function=params_objective_function) def init_model(self, **args): warm_start = args.get('warm_start', {}) self.model = Model("Knapsack") self.variable_decision = {"x": {}} self.description_variable_description = { "x": { "shape": self.knapsack_model.nb_items, "type": bool, "descr": "dictionary with key the item index \ and value the boolean value corresponding \ to taking the item or not" } } self.description_constraint["weight"] = { "descr": "sum of weight of used items doesn't exceed max capacity" } weight = {} list_item = self.knapsack_model.list_items max_capacity = self.knapsack_model.max_capacity x = {} for item in list_item: i = item.index x[i] = self.model.addVar(vtype=GRB.BINARY, obj=item.value, name="x_" + str(i)) if i in warm_start: x[i].start = warm_start[i] x[i].varhinstval = warm_start[i] weight[i] = item.weight self.variable_decision["x"] = x self.model.update() self.constraints_dict["weight"] = self.model.addConstr( quicksum([weight[i] * x[i] for i in x]) <= max_capacity) self.model.update() self.model.setParam("TimeLimit", 200) self.model.modelSense = GRB.MAXIMIZE self.model.setParam(GRB.Param.PoolSolutions, 10000) self.model.setParam("MIPGapAbs", 0.00001) self.model.setParam("MIPGap", 0.00000001) def retrieve_solutions(self, range_solutions: Iterable[int]): # nObjectives = S.NumObj solutions = [] fits = [] # x = S.getVars() for s in range_solutions: weight = 0 xs = {} self.model.params.SolutionNumber = s obj = self.model.getAttr("ObjVal") for e in self.variable_decision["x"]: value = self.variable_decision["x"][e].getAttr('Xn') if value <= 0.1: xs[e] = 0 continue xs[e] = 1 weight += self.knapsack_model.index_to_item[e].weight solutions += [ KnapsackSolution(problem=self.knapsack_model, value=obj, weight=weight, list_taken=[xs[e] for e in sorted(xs)]) ] fits += [self.aggreg_sol(solutions[-1])] return ResultStorage( list_solution_fits=[(s, f) for s, f in zip(solutions, fits)], mode_optim=self.params_objective_function.sense_function) def solve(self, parameter_gurobi: ParametersMilp): self.model.setParam("TimeLimit", parameter_gurobi.TimeLimit) self.model.modelSense = GRB.MAXIMIZE self.model.setParam(GRB.Param.PoolSolutions, parameter_gurobi.PoolSolutions) self.model.setParam("MIPGapAbs", parameter_gurobi.MIPGapAbs) self.model.setParam("MIPGap", parameter_gurobi.MIPGap) print("optimizing...") self.model.optimize() nSolutions = self.model.SolCount nObjectives = self.model.NumObj objective = self.model.getObjective().getValue() print('Problem has', nObjectives, 'objectives') print('Gurobi found', nSolutions, 'solutions') if parameter_gurobi.retrieve_all_solution: solutions = self.retrieve_solutions(list(range(nSolutions))) else: solutions = self.retrieve_solutions([0]) return solutions def solve_lns(self, parameter_gurobi: ParametersMilp, init_solution: KnapsackSolution, fraction_decision_fixed: float, nb_iteration_max: int): self.model.setParam("TimeLimit", parameter_gurobi.TimeLimit) self.model.setParam("OutputFlag", 0) self.model.modelSense = GRB.MAXIMIZE self.model.setParam(GRB.Param.PoolSolutions, parameter_gurobi.PoolSolutions) self.model.setParam("MIPGapAbs", parameter_gurobi.MIPGapAbs) self.model.setParam("MIPGap", parameter_gurobi.MIPGap) current_solution = init_solution constraints = {} list_solutions = [current_solution] list_objective = [current_solution.value] objective = init_solution.value for k in trange(nb_iteration_max): for c in constraints: self.model.remove(constraints[c]) self.add_init_solution(current_solution) fixed_variable = set( random.sample( self.variable_decision["x"].keys(), int(fraction_decision_fixed * len(self.variable_decision["x"])))) constraints = self.fix_decision(current_solution, fixed_variable) self.model.optimize() nSolutions = self.model.SolCount nObjectives = self.model.NumObj objective = self.model.getObjective().getValue() if parameter_gurobi.retrieve_all_solution: solutions = self.retrieve_solutions(list(range(nSolutions))) else: solutions = self.retrieve_solutions([0]) current_solution = solutions[0] list_solutions += [solutions[0]] list_objective += [solutions[0].value] print("Last obj : ", list_objective[-1]) fig, ax = plt.subplots(1) ax.plot(list_objective) plt.show() def add_init_solution(self, init_solution: KnapsackSolution): for i in self.variable_decision["x"]: self.variable_decision["x"][i].start = init_solution.list_taken[i] self.variable_decision["x"][ i].varhintval = init_solution.list_taken[i] def fix_decision(self, init_solution: KnapsackSolution, fixed_variable_keys): constraints = {} for i in fixed_variable_keys: constraints[i] = self.model.addConstr( self.variable_decision["x"][i] == init_solution.list_taken[i]) return constraints def describe_the_model(self): return str(self.description_variable_description) + "\n" + str( self.description_constraint)
def generate_angle_milp(gurobi_model: grb.Model, input, sin_cos_table: List[Tuple]): """MILP method input: theta, thetadot output: thetadotdot, xdotdot (edited) l_{theta, i}, l_{thatdot,i}, l_{thetadotdot, i}, l_{xdotdot, i}, u_.... sum_{i=1}^k l_{x,i} - l_{x,i}*z_i <= x <= sum_{i=1}^k u_{x,i} - u_{x,i}*z_i, for each variable x sum_{i=1}^k l_{theta,i} - l_{theta,i}*z_i <= theta <= sum_{i=1}^k u_{theta,i} - u_{theta,i}*z_i """ theta = input[2] theta_dot = input[3] k = len(sin_cos_table) zs = [] thetaacc = gurobi_model.addMVar(shape=(1, ), lb=float("-inf"), name="thetaacc") xacc = gurobi_model.addMVar(shape=(1, ), lb=float("-inf"), name="xacc") for i in range(k): z = gurobi_model.addMVar(lb=0, ub=1, shape=(1, ), vtype=grb.GRB.INTEGER, name=f"part_{i}") zs.append(z) gurobi_model.addConstr(k - 1 == sum(zs), name=f"const_milp1") theta_lb = 0 theta_ub = 0 theta_dot_lb = 0 theta_dot_ub = 0 thetaacc_lb = 0 thetaacc_ub = 0 xacc_lb = 0 xacc_ub = 0 for i in range(k): theta_interval, theta_dot_interval, theta_acc_interval, xacc_interval = sin_cos_table[ i] theta_lb += theta_interval[0] - theta_interval[0] * zs[i] theta_ub += theta_interval[1] - theta_interval[1] * zs[i] theta_dot_lb += theta_dot_interval[ 0] - theta_dot_interval[0] * zs[i] theta_dot_ub += theta_dot_interval[ 1] - theta_dot_interval[1] * zs[i] thetaacc_lb += theta_acc_interval[0] - theta_acc_interval[0] * zs[i] thetaacc_ub += theta_acc_interval[1] - theta_acc_interval[1] * zs[i] xacc_lb += xacc_interval[0] - xacc_interval[0] * zs[i] xacc_ub += xacc_interval[1] - xacc_interval[1] * zs[i] # eps = 1e-9 gurobi_model.addConstr(theta >= theta_lb, name=f"theta_guard1") gurobi_model.addConstr(theta <= theta_ub, name=f"theta_guard2") gurobi_model.addConstr(theta_dot >= theta_dot_lb, name=f"theta_dot_guard1") gurobi_model.addConstr(theta_dot <= theta_dot_ub, name=f"theta_dot_guard2") gurobi_model.addConstr(thetaacc >= thetaacc_lb, name=f"thetaacc_guard1") gurobi_model.addConstr(thetaacc <= thetaacc_ub, name=f"thetaacc_guard2") gurobi_model.addConstr(xacc >= xacc_lb, name=f"xacc_guard1") gurobi_model.addConstr(xacc <= xacc_ub, name=f"xacc_guard2") gurobi_model.update() gurobi_model.optimize() if gurobi_model.status == 4: gurobi_model.setParam("DualReductions", 0) gurobi_model.update() gurobi_model.optimize() # assert gurobi_model.status == 2, f"LP wasn't optimally solved. gurobi status {gurobi_model.status}" return thetaacc, xacc
def init_model(self, **kwargs): nb_facilities = self.facility_problem.facility_count nb_customers = self.facility_problem.customer_count use_matrix_indicator_heuristic = kwargs.get("use_matrix_indicator_heuristic", True) if use_matrix_indicator_heuristic: n_shortest = kwargs.get("n_shortest", 10) n_cheapest = kwargs.get("n_cheapest", 10) matrix_fc_indicator, matrix_length = prune_search_space(self.facility_problem, n_cheapest=n_cheapest, n_shortest=n_shortest) else: matrix_fc_indicator, matrix_length = prune_search_space(self.facility_problem, n_cheapest=nb_facilities, n_shortest=nb_facilities) s = Model("facilities") x = {} for f in range(nb_facilities): for c in range(nb_customers): if matrix_fc_indicator[f, c] == 0: x[f, c] = 0 elif matrix_fc_indicator[f, c] == 1: x[f, c] = 1 elif matrix_fc_indicator[f, c] == 2: x[f, c] = s.addVar(vtype=GRB.BINARY, obj=0, name="x_" + str((f, c))) facilities = self.facility_problem.facilities customers = self.facility_problem.customers used = s.addVars(nb_facilities, vtype=GRB.BINARY, name="y") constraints_customer = {} for c in range(nb_customers): constraints_customer[c] = s.addConstr(quicksum([x[f, c] for f in range(nb_facilities)]) == 1) # one facility constraint_capacity = {} for f in range(nb_facilities): s.addConstrs(used[f] >= x[f, c] for c in range(nb_customers)) constraint_capacity[f] = s.addConstr(quicksum([x[f, c] * customers[c].demand for c in range(nb_customers)]) <= facilities[f].capacity) s.update() new_obj_f = LinExpr(0.) new_obj_f += quicksum([facilities[f].setup_cost * used[f] for f in range(nb_facilities)]) new_obj_f += quicksum([matrix_length[f, c] * x[f, c] for f in range(nb_facilities) for c in range(nb_customers)]) s.setObjective(new_obj_f) s.update() s.modelSense = GRB.MINIMIZE s.setParam(GRB.Param.Threads, 4) s.setParam(GRB.Param.PoolSolutions, 10000) s.setParam(GRB.Param.Method, 1) s.setParam("MIPGapAbs", 0.00001) s.setParam("MIPGap", 0.00000001) self.model = s self.variable_decision = {"x": x} self.constraints_dict = {"constraint_customer": constraints_customer, "constraint_capacity": constraint_capacity} self.description_variable_description = {"x": {"shape": (nb_facilities, nb_customers), "type": bool, "descr": "for each facility/customer indicate" " if the pair is active, meaning " "that the customer c is dealt with facility f"}} self.description_constraint = {"Im lazy."} print("Initialized")