예제 #1
0
    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].inf - theta_interval[0].inf * zs[i]
            theta_ub += theta_interval[0].sup - theta_interval[0].sup * zs[i]
            theta_dot_lb += theta_dot_interval[0].inf - theta_dot_interval[0].inf * zs[i]
            theta_dot_ub += theta_dot_interval[0].sup - theta_dot_interval[0].sup * zs[i]

            thetaacc_lb += theta_acc_interval[0].inf - theta_acc_interval[0].inf * zs[i]
            thetaacc_ub += theta_acc_interval[0].sup - theta_acc_interval[0].sup * zs[i]

            xacc_lb += xacc_interval[0].inf - xacc_interval[0].inf * zs[i]
            xacc_ub += xacc_interval[0].sup - xacc_interval[0].sup * zs[i]

        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()
        # assert gurobi_model.status == 2, "LP wasn't optimally solved"
        return thetaacc, xacc
예제 #2
0
 def optimise(self, templates: np.ndarray, gurobi_model: grb.Model,
              x_prime: tuple):
     results = []
     for template in templates:
         gurobi_model.update()
         gurobi_model.setObjective(
             sum((template[i] * x_prime[i])
                 for i in range(self.env_input_size)), grb.GRB.MAXIMIZE)
         gurobi_model.optimize()
         # print_model(gurobi_model)
         if gurobi_model.status != 2:
             return None
         result = gurobi_model.ObjVal
         results.append(result)
     return np.array(results)
예제 #3
0
 def optimise(templates: np.ndarray, gurobi_model: grb.Model, x_prime: tuple):
     results = []
     for template in templates:
         gurobi_model.update()
         gurobi_model.setObjective(sum((template[i] * x_prime[i]) for i in range(len(template))), grb.GRB.MAXIMIZE)
         gurobi_model.optimize()
         # print_model(gurobi_model)
         if gurobi_model.status == 5:
             result = float("inf")
             results.append(result)
             continue
         if gurobi_model.status == 4 or gurobi_model.status == 3:
             return None
         assert gurobi_model.status == 2, f"gurobi_model.status=={gurobi_model.status}"
         # if gurobi_model.status != 2:
         #     return None
         result = gurobi_model.ObjVal
         results.append(result)
     return np.array(results)
 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"}
예제 #5
0
    def generate_nn_guard(gurobi_model: grb.Model,
                          input,
                          nn: torch.nn.Sequential,
                          action_ego=0,
                          M=1e6):
        gurobi_vars = []
        gurobi_vars.append(input)
        for i, layer in enumerate(nn):

            # print(layer)
            if type(layer) is torch.nn.Linear:
                v = gurobi_model.addMVar(lb=float("-inf"),
                                         shape=(layer.out_features),
                                         name=f"layer_{i}")
                weights: np.ndarray = layer.weight.data.numpy()
                weights.round(6)
                lin_expr = weights @ gurobi_vars[-1]
                if layer.bias is not None:
                    lin_expr = lin_expr + layer.bias.data.numpy()
                gurobi_model.addConstr(v == lin_expr,
                                       name=f"linear_constr_{i}")
                gurobi_vars.append(v)
            elif type(layer) is torch.nn.ReLU:
                v = gurobi_model.addMVar(
                    lb=float("-inf"),
                    shape=gurobi_vars[-1].shape,
                    name=f"layer_{i}")  # same shape as previous
                z = gurobi_model.addMVar(lb=0,
                                         ub=1,
                                         shape=gurobi_vars[-1].shape,
                                         vtype=grb.GRB.INTEGER,
                                         name=f"relu_{i}")
                eps = 0  # 1e-9
                # gurobi_model.addConstr(v == grb.max_(0, gurobi_vars[-1]))
                gurobi_model.addConstr(v >= gurobi_vars[-1],
                                       name=f"relu_constr_1_{i}")
                gurobi_model.addConstr(v <= eps + gurobi_vars[-1] + M * z,
                                       name=f"relu_constr_2_{i}")
                gurobi_model.addConstr(v >= 0, name=f"relu_constr_3_{i}")
                gurobi_model.addConstr(v <= eps + M - M * z,
                                       name=f"relu_constr_4_{i}")
                gurobi_vars.append(v)
                # gurobi_model.update()
                # gurobi_model.optimize()
                # assert gurobi_model.status == 2, "LP wasn't optimally solved"
                """
                y = Relu(x)
                0 <= z <= 1, z is integer
                y >= x
                y <= x + Mz
                y >= 0
                y <= M - Mz"""
        # gurobi_model.update()
        # gurobi_model.optimize()
        # assert gurobi_model.status == 2, "LP wasn't optimally solved"
        # gurobi_model.setObjective(v[action_ego].sum(), grb.GRB.MAXIMIZE)  # maximise the output
        last_layer = gurobi_vars[-1]
        if action_ego == 0:
            gurobi_model.addConstr(last_layer[0] >= last_layer[1],
                                   name="last_layer")
        else:
            gurobi_model.addConstr(last_layer[1] >= last_layer[0],
                                   name="last_layer")
        gurobi_model.update()
        gurobi_model.optimize()
        # assert gurobi_model.status == 2, f"LP wasn't optimally solved, gurobi status {gurobi_model.status}"
        return gurobi_model.status == 2
예제 #6
0
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 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")