Exemple #1
0
def split_polyhedron_milp(template, boundaries, chosen_dimension,
                          decision_point):
    '''splits the polyhedron in 2 based on the dimension and the decision point using the milp model'''
    gurobi_model = grb.Model()
    gurobi_model.setParam('OutputFlag', False)
    split_template = template[chosen_dimension]
    input = generate_input_region(gurobi_model, template, boundaries,
                                  len(split_template))
    gurobi_model.update()
    gurobi_model.optimize()
    assert gurobi_model.status == 2, "LP wasn't optimally solved"
    gurobi_model.addConstr(
        sum((split_template[i] * input[i])
            for i in range(len(split_template))) >= decision_point)
    split1 = optimise(template, gurobi_model, input)
    assert split1 is not None
    gurobi_model = grb.Model()
    gurobi_model.setParam('OutputFlag', False)
    split_template = template[chosen_dimension]
    input = generate_input_region(gurobi_model, template, boundaries,
                                  len(split_template))
    gurobi_model.update()
    gurobi_model.optimize()
    assert gurobi_model.status == 2, "LP wasn't optimally solved"
    gurobi_model.addConstr(
        sum((split_template[i] * input[i])
            for i in range(len(split_template))) <= decision_point)
    split2 = optimise(template, gurobi_model, input)
    assert split2 is not None
    return split1, split2
Exemple #2
0
    def bellman_solver(self, state1):
        obx = state1["Sbar"] - (self.model_trainer.sim.beta * state1["Sbar"] *
                                state1["Ibar"] / self.model_trainer.sim.N)
        w = 1 / self.model_trainer.sim.N + self.theta[self.model_trainer.sim.
                                                      nc:]
        m = gp.Model("bellman solver")
        x = m.addMVar(shape=self.model_trainer.sim.nc,
                      vtype=GRB.INTEGER,
                      name="x")

        m.setObjective(w @ x, GRB.MAXIMIZE)

        A = np.ones(self.model_trainer.sim.nc)

        # Build rhs vector
        rhs = np.array([self.model_trainer.NVac])

        # Add constraints
        m.addConstr(A @ x <= rhs, name="c")
        m.addConstr(0 <= x)
        m.addConstr(x <= obx)

        m.optimize()

        return x.X
Exemple #3
0
    def make_base_model(self,
                        add_gpr=True,
                        genes="continuous",
                        bounds="weak",
                        **kwargs):
        model = gp.Model()
        n = self.S.shape[1]
        for i in range(n):
            model.addVar(lb=self.lb[i], ub=self.ub[i], name=self.rxns[i])
        model.update()

        v = get_vars_by_name(model, self.rxns, "MVar")
        model.setObjective(self.c @ v, GRB.MAXIMIZE)
        model.addConstr(self.S @ v == self.b, name="Sv=b")
        model.update()

        if add_gpr:
            if genes == "continuous" and bounds == "weak":
                add_gprs_cnf_weak_(self, model, **kwargs)
            # elif genes == "continuous" and bounds == "strong":
            #     # FALCON
            # elif genes == "discrete" and bounds == "weak":
            #     # CNF with binary variables
            # elif genes == "discrete" and bounds == "strong":
            #     # SR-FBA

            g = get_vars_by_name(model, self.genes, "MVar")
        else:
            g = None

        return model, v, g
Exemple #4
0
 def standard_op():
     gurobi_model = grb.Model()
     gurobi_model.setParam('OutputFlag', output_flag)
     input = self.generate_input_region(gurobi_model, template, x,
                                        self.env_input_size)
     z = self.apply_dynamic(input, gurobi_model, self.env_input_size)
     return gurobi_model, z, input
Exemple #5
0
 def post_milp(self, x, nn, output_flag, t, template):
     """milp method"""
     post = []
     for chosen_action in range(2):
         gurobi_model = grb.Model()
         gurobi_model.setParam('OutputFlag', output_flag)
         gurobi_model.setParam('Threads', 2)
         input = Experiment.generate_input_region(gurobi_model, template, x,
                                                  self.env_input_size)
         max_theta, min_theta, max_theta_dot, min_theta_dot = self.get_theta_bounds(
             gurobi_model, input)
         sin_cos_table = self.get_sin_cos_table(max_theta,
                                                min_theta,
                                                max_theta_dot,
                                                min_theta_dot,
                                                action=chosen_action)
         feasible_action = CartpoleExperiment.generate_nn_guard(
             gurobi_model, input, nn, action_ego=chosen_action)
         if feasible_action:
             thetaacc, xacc = CartpoleExperiment.generate_angle_milp(
                 gurobi_model, input, sin_cos_table)
             # apply dynamic
             x_prime = self.apply_dynamic(
                 input,
                 gurobi_model,
                 thetaacc=thetaacc,
                 xacc=xacc,
                 env_input_size=self.env_input_size)
             gurobi_model.update()
             gurobi_model.optimize()
             found_successor, x_prime_results = self.h_repr_to_plot(
                 gurobi_model, template, x_prime)
             if found_successor:
                 post.append(tuple(x_prime_results))
     return post
Exemple #6
0
 def find_important_dimensions(self, poly1, poly2):
     '''assuming check_contained(poly1,poly2) returns true, we are interested in the halfspaces that matters
     poly1 = root, poly2 = candidate
     '''
     # #Binary Space Partitioning
     gurobi_model = grb.Model()
     gurobi_model.setParam('OutputFlag', self.output_flag)
     input1 = Experiment.generate_input_region(gurobi_model, self.analysis_template, poly1, self.env_input_size)
     relevant_directions = []
     for j, template in enumerate(self.analysis_template):
         multiplication = 0
         for i in range(self.env_input_size):
             multiplication += template[i] * input1[i]
         previous_constraint = gurobi_model.getConstrByName("check_contained_constraint")
         if previous_constraint is not None:
             gurobi_model.remove(previous_constraint)
             gurobi_model.update()
         gurobi_model.addConstr(multiplication <= poly2[j], name=f"check_contained_constraint")
         gurobi_model.update()
         x_results = self.optimise(self.analysis_template, gurobi_model, input1)
         if np.allclose(np.array(poly1), x_results) is False:
             vertices = np.stack(self.pypoman_compute_polytope_vertices(self.analysis_template, np.array(x_results)))
             samples = polytope.sample(1000, self.analysis_template, x_results)
             from scipy.spatial import ConvexHull
             hull = ConvexHull(samples)
             volume = hull.volume  # estimated volume
             relevant_directions.append((j, volume))
     return relevant_directions
Exemple #7
0
    def post_milp(self, x, x_label, nn, output_flag, t, template) -> List[Experiment.SuccessorInfo]:
        """milp method"""
        ranges_probs = self.create_range_bounds_model(template, x, self.env_input_size, nn)
        post = []
        for chosen_action in range(2):
            gurobi_model = grb.Model()
            gurobi_model.setParam('OutputFlag', output_flag)
            gurobi_model.setParam('DualReductions', 0)
            input = generate_input_region(gurobi_model, template, x, self.env_input_size)
            x_prime = StoppingCarExperimentProbabilistic.apply_dynamic(input, gurobi_model, action=chosen_action, env_input_size=self.env_input_size)
            gurobi_model.update()
            gurobi_model.optimize()
            x_prime_results = optimise(template, gurobi_model, x_prime)
            if x_prime_results is None:
                assert x_prime_results is not None
            successor_info = Experiment.SuccessorInfo()
            successor_info.successor = tuple(x_prime_results)
            successor_info.parent = x
            successor_info.parent_lbl = x_label
            successor_info.t = t + 1
            successor_info.action = "policy"  # chosen_action
            successor_info.lb = ranges_probs[chosen_action][0]
            successor_info.ub = ranges_probs[chosen_action][1]
            post.append(successor_info)

        return post
Exemple #8
0
    def build(self):

        try:
            model = grb.Model("facility_location_sub_problem")

            facility_customer_pair_to_column \
                = build_transport_columns(self.data, model)

            facility_to_supply_constraint \
                = build_supply_constraints(self.data, model, facility_customer_pair_to_column, dict())

            customer_to_demand_constraint \
                = build_demand_constraints(self.data, model, facility_customer_pair_to_column)

            model.setParam(grb.GRB.Param.InfUnbdInfo, 1)
            model.update()
            return SubProblem(model,
                              facility_customer_pair_to_column,
                              facility_to_supply_constraint,
                              customer_to_demand_constraint)

        except grb.GurobiError as ex:
            logging.exception("Gurobi %r" % ex)
        except Exception as ex:
            logging.exception(ex)
        return None
    def __init__(self, data: InputData):
        self.data = data

        self.model = grb.Model("facility_location_single_model")

        self.facility_name_to_column: Dict[str, grb.Var] = None
        self.facility_customer_to_column: Dict[Tuple[str, str], grb.Var] = None
Exemple #10
0
def make_base_model(tiger):
    model = gp.Model()
    n = tiger.S.shape[1]
    v = model.addMVar(shape=n, lb=tiger.lb, ub=tiger.ub, name="v")
    model.setObjective(tiger.c @ v, GRB.MAXIMIZE)
    model.addConstr(tiger.S @ v == tiger.b, name="Sv=b")
    model.update()
    return model, v
Exemple #11
0
 def generate_root_polytope(self, input_boundaries):
     gurobi_model = grb.Model()
     gurobi_model.setParam('OutputFlag', self.output_flag)
     input = Experiment.generate_input_region(gurobi_model, self.input_template, input_boundaries, self.env_input_size)
     x_results = self.optimise(self.analysis_template, gurobi_model, input)
     if x_results is None:
         print("Model unsatisfiable")
         return None
     root = tuple(x_results)
     return root
Exemple #12
0
 def post_milp(self, x, x_label, nn, output_flag, t, template):
     """milp method"""
     post = []
     for chosen_action in range(2):
         gurobi_model = grb.Model()
         gurobi_model.setParam('OutputFlag', output_flag)
         input = generate_input_region(gurobi_model, template, x,
                                       self.env_input_size)
         # gurobi_model.addConstr(input[0] >= 0, name=f"input_base_constr1")
         # gurobi_model.addConstr(input[1] >= 0, name=f"input_base_constr2")
         # gurobi_model.addConstr(input[2] >= 20, name=f"input_base_constr3")
         observation = gurobi_model.addMVar(shape=(2, ),
                                            lb=float("-inf"),
                                            ub=float("inf"),
                                            name="observation")
         gurobi_model.addConstr(
             observation[1] <= input[0] - input[1] + self.input_epsilon / 2,
             name=f"obs_constr21")
         gurobi_model.addConstr(
             observation[1] >= input[0] - input[1] - self.input_epsilon / 2,
             name=f"obs_constr22")
         gurobi_model.addConstr(observation[0] <= self.v_lead - input[2] +
                                self.input_epsilon / 2,
                                name=f"obs_constr11")
         gurobi_model.addConstr(observation[0] >= self.v_lead - input[2] -
                                self.input_epsilon / 2,
                                name=f"obs_constr12")
         # gurobi_model.addConstr(input[3] <= self.max_speed, name=f"v_constr_input")
         # gurobi_model.addConstr(input[3] >= -self.max_speed, name=f"v_constr_input")
         feasible_action = Experiment.generate_nn_guard(
             gurobi_model, observation, nn, action_ego=chosen_action)
         # feasible_action = Experiment.generate_nn_guard(gurobi_model, input, nn, action_ego=chosen_action)
         if feasible_action:
             # apply dynamic
             x_prime = StoppingCarExperiment.apply_dynamic(
                 input,
                 gurobi_model,
                 action=chosen_action,
                 env_input_size=self.env_input_size)
             gurobi_model.update()
             gurobi_model.optimize()
             found_successor, x_prime_results = self.h_repr_to_plot(
                 gurobi_model, template, x_prime)
             if found_successor:
                 # post.append((tuple(x_prime_results),(x, x_label)))
                 successor_info = Experiment.SuccessorInfo()
                 successor_info.successor = tuple(x_prime_results)
                 successor_info.parent = x
                 successor_info.parent_lbl = x_label
                 successor_info.t = t + 1
                 successor_info.action = "policy"  # chosen_action
                 # successor_info.lb = ranges_probs[chosen_action][0]
                 # successor_info.ub = ranges_probs[chosen_action][1]
                 post.append(successor_info)
     return post
Exemple #13
0
 def check_contained(self, poly1, poly2):
     gurobi_model = grb.Model()
     gurobi_model.setParam('OutputFlag', self.output_flag)
     input1 = Experiment.generate_input_region(gurobi_model, self.analysis_template, poly1, self.env_input_size)
     Experiment.generate_region_constraints(gurobi_model, self.analysis_template, input1, poly2, self.env_input_size, eps=1e-5)  # use epsilon to prevent single points
     x_results = self.optimise(self.analysis_template, gurobi_model, input1)
     if x_results is None:
         # not contained
         return False
     else:
         return True
Exemple #14
0
def make_dual_model(tiger):
    model = gp.Model()
    n = tiger.S.shape[1]
    m = tiger.S.shape[0]
    yS = model.addMVar(shape=m, lb=-GRB.INFINITY, name="yS")
    yL = model.addMVar(shape=n, lb=-GRB.INFINITY, ub=0.0, name="yL")
    yU = model.addMVar(shape=n, name="yU")
    model.addConstr(tiger.S.T @ yS + np.eye(n) @ yL +
                    np.eye(n) @ yU == tiger.c)
    model.setObjective(tiger.b @ yS + tiger.lb @ yL + tiger.ub @ yU)
    model.update()
    return model, (yS, yL, yU)
Exemple #15
0
 def post_milp(self, x, x_label, nn, output_flag, t, template):
     """milp method"""
     ranges_probs = self.create_range_bounds_model(template, x,
                                                   self.env_input_size, nn)
     post = []
     # for split_angle in itertools.product([True, False], repeat=2):  # split successor if theta is within safe_angle
     for chosen_action in range(self.n_actions):
         # if (chosen_action == 2 or chosen_action == 1) and x_label == 1:  # skip actions when battery is dead
         #     continue
         gurobi_model = grb.Model()
         gurobi_model.setParam('OutputFlag', output_flag)
         gurobi_model.setParam('Threads', 2)
         input = generate_input_region(gurobi_model, template, x,
                                       self.env_input_size)
         max_theta, min_theta, max_theta_dot, min_theta_dot = self.get_theta_bounds(
             gurobi_model, input)
         # feasible_action = PendulumExperiment.generate_nn_guard(gurobi_model, input, nn, action_ego=chosen_action, M=1e03)
         # if feasible_action:  # performs action 2 automatically when battery is dead
         sin_cos_table = self.get_sin_cos_table(max_theta,
                                                min_theta,
                                                max_theta_dot,
                                                min_theta_dot,
                                                action=chosen_action)
         # for normalisation_split in [True,False]:
         newthdot, newtheta = PendulumExperiment.generate_angle_milp(
             gurobi_model, input, sin_cos_table)
         # gurobi_model.addConstr(newtheta >)
         # apply dynamic
         x_prime = self.apply_dynamic(input,
                                      gurobi_model,
                                      newthdot=newthdot,
                                      newtheta=newtheta,
                                      env_input_size=self.env_input_size,
                                      action=chosen_action)
         # for i, (A, b) in enumerate(self.angle_split):
         #     Experiment.generate_region_constraints(gurobi_model, A, x_prime, b, self.env_input_size, invert=not split_angle[i])
         gurobi_model.update()
         gurobi_model.optimize()
         if gurobi_model.status != 2:
             continue
         found_successor, x_prime_results = self.h_repr_to_plot(
             gurobi_model, template, x_prime)
         if found_successor:
             successor_info = Experiment.SuccessorInfo()
             successor_info.successor = tuple(x_prime_results)
             successor_info.parent = x
             successor_info.parent_lbl = x_label
             successor_info.t = t + 1
             successor_info.action = "policy"  # chosen_action
             successor_info.lb = ranges_probs[chosen_action][0]
             successor_info.ub = ranges_probs[chosen_action][1]
             post.append(successor_info)
     return post
Exemple #16
0
 def post_milp2(self, x, nn, output_flag, t, template):
     """milp method for a simple guard that keeps distance at 20 metres"""
     post = []
     for chosen_action in range(2):
         gurobi_model = grb.Model()
         gurobi_model.setParam('OutputFlag', output_flag)
         input = generate_input_region(gurobi_model, template, x,
                                       self.env_input_size)
         observation = gurobi_model.addMVar(shape=(2, ),
                                            lb=float("-inf"),
                                            ub=float("inf"),
                                            name="input")
         gurobi_model.addConstr(
             observation[1] <= input[0] - input[1] + self.input_epsilon / 2,
             name=f"obs_constr21")
         gurobi_model.addConstr(
             observation[1] >= input[0] - input[1] - self.input_epsilon / 2,
             name=f"obs_constr22")
         gurobi_model.addConstr(observation[0] <= self.v_lead - input[2] +
                                self.input_epsilon / 2,
                                name=f"obs_constr11")
         gurobi_model.addConstr(observation[0] >= self.v_lead - input[2] -
                                self.input_epsilon / 2,
                                name=f"obs_constr12")
         if chosen_action == 0:
             gurobi_model.addConstr(input[0] - input[1] <= 20)
             gurobi_model.update()
             gurobi_model.optimize()
             feasible_action = gurobi_model.status == 2 or gurobi_model.status == 5
         else:
             gurobi_model.addConstr(input[0] - input[1] >= 20)
             gurobi_model.update()
             gurobi_model.optimize()
             feasible_action = gurobi_model.status == 2 or gurobi_model.status == 5
         # feasible_action = Experiment.generate_nn_guard(gurobi_model, observation, nn, action_ego=chosen_action)
         # feasible_action = Experiment.generate_nn_guard(gurobi_model, input, nn, action_ego=chosen_action)
         # gurobi_model.addConstr(input[3] <= self.max_speed, name=f"v_constr_input")
         # gurobi_model.addConstr(input[3] >= -self.max_speed, name=f"v_constr_input")
         if feasible_action:
             # apply dynamic
             x_prime = StoppingCarExperiment.apply_dynamic(
                 input,
                 gurobi_model,
                 action=chosen_action,
                 env_input_size=self.env_input_size)
             gurobi_model.update()
             gurobi_model.optimize()
             found_successor, x_prime_results = self.h_repr_to_plot(
                 gurobi_model, template, x_prime)
             if found_successor:
                 post.append(tuple(x_prime_results))
     return post
Exemple #17
0
    def post_milp(self, x, nn, output_flag, t, template):
        """milp method"""
        post = []
        for chosen_action in range(2):
            observable_template = self.observable_templates[chosen_action]
            observable_result = self.observable_results[chosen_action]
            gurobi_model = grb.Model()
            gurobi_model.setParam('OutputFlag', output_flag)
            gurobi_model.setParam('Threads', 2)
            input = Experiment.generate_input_region(gurobi_model, template, x,
                                                     self.env_input_size)
            observation = gurobi_model.addMVar(shape=(2, ),
                                               lb=float("-inf"),
                                               ub=float("inf"),
                                               name="input")
            gurobi_model.addConstr(
                observation[1] <= input[0] - input[1] + self.input_epsilon / 2,
                name=f"obs_constr21")
            gurobi_model.addConstr(
                observation[1] >= input[0] - input[1] - self.input_epsilon / 2,
                name=f"obs_constr22")
            gurobi_model.addConstr(
                observation[0] <= input[2] - input[3] + self.input_epsilon / 2,
                name=f"obs_constr11")
            gurobi_model.addConstr(
                observation[0] >= input[2] - input[3] - self.input_epsilon / 2,
                name=f"obs_constr12")
            # feasible_action = Experiment.generate_nn_guard(gurobi_model, observation, nn, action_ego=chosen_action)
            # feasible_action = Experiment.generate_nn_guard(gurobi_model, input, nn, action_ego=chosen_action)

            Experiment.generate_region_constraints(gurobi_model,
                                                   observable_template,
                                                   observation,
                                                   observable_result, 2)
            gurobi_model.optimize()
            feasible_action = gurobi_model.status == 2
            if feasible_action:
                # apply dynamic
                # x_prime_results = self.optimise(template, gurobi_model, input)  # h representation
                # x_prime = Experiment.generate_input_region(gurobi_model, template, x_prime_results, self.env_input_size)
                x_second = StoppingCarExperiment.apply_dynamic(
                    input,
                    gurobi_model,
                    action=chosen_action,
                    env_input_size=self.env_input_size)
                gurobi_model.update()
                gurobi_model.optimize()
                found_successor, x_second_results = self.h_repr_to_plot(
                    gurobi_model, template, x_second)
                if found_successor:
                    post.append(tuple(x_second_results))
        return post
Exemple #18
0
 def post_milp(self, x, x_label, nn, output_flag, t,
               template) -> List[Experiment.SuccessorInfo]:
     """milp method"""
     ranges_probs = self.create_range_bounds_model(template, x,
                                                   self.env_input_size, nn)
     post = []
     for chosen_action in range(2):
         gurobi_model = grb.Model()
         gurobi_model.setParam('OutputFlag', output_flag)
         gurobi_model.setParam('DualReductions', 0)
         input = generate_input_region(gurobi_model, template, x,
                                       self.env_input_size)
         observation = gurobi_model.addMVar(shape=(2, ),
                                            lb=float("-inf"),
                                            ub=float("inf"),
                                            name="input")
         gurobi_model.addConstr(
             observation[1] <= input[0] - input[1] + self.input_epsilon / 2,
             name=f"obs_constr21")
         gurobi_model.addConstr(
             observation[1] >= input[0] - input[1] - self.input_epsilon / 2,
             name=f"obs_constr22")
         gurobi_model.addConstr(observation[0] <= self.v_lead - input[2] +
                                self.input_epsilon / 2,
                                name=f"obs_constr11")
         gurobi_model.addConstr(observation[0] >= self.v_lead - input[2] -
                                self.input_epsilon / 2,
                                name=f"obs_constr12")
         feasible_action = Experiment.generate_nn_guard(
             gurobi_model, observation, nn, action_ego=chosen_action)
         if feasible_action:
             x_prime = StoppingCarExperiment.apply_dynamic(
                 input,
                 gurobi_model,
                 action=chosen_action,
                 env_input_size=self.env_input_size)
             gurobi_model.update()
             gurobi_model.optimize()
             found_successor, x_prime_results = self.h_repr_to_plot(
                 gurobi_model, template, x_prime)
             if found_successor:
                 successor_info = Experiment.SuccessorInfo()
                 successor_info.successor = tuple(x_prime_results)
                 successor_info.parent = x
                 successor_info.parent_lbl = x_label
                 successor_info.t = t + 1
                 successor_info.action = "policy"  # chosen_action
                 successor_info.lb = ranges_probs[chosen_action][0]
                 successor_info.ub = ranges_probs[chosen_action][1]
                 post.append(successor_info)
     return post
 def assign_label(self, x_prime, parent, parent_lbl) -> int:
     for A, b in self.unsafe_zone:
         gurobi_model = grb.Model()
         gurobi_model.setParam('OutputFlag', False)
         input = gurobi_model.addMVar(shape=(self.env_input_size, ),
                                      lb=float("-inf"),
                                      name="input")
         generate_region_constraints(gurobi_model, self.analysis_template,
                                     input, x_prime, self.env_input_size)
         generate_region_constraints(gurobi_model, A, input, b,
                                     self.env_input_size)
         gurobi_model.update()
         gurobi_model.optimize()
         if gurobi_model.status == 2:
             return parent_lbl + 1  # still balancing
     return 0  # unsafe count up to 20
Exemple #20
0
 def create_range_bounds_model(self, template, x, env_input_size, nn, round=-1):
     gurobi_model = grb.Model()
     gurobi_model.setParam('OutputFlag', False)
     input = Experiment.generate_input_region(gurobi_model, template, x, env_input_size)
     gurobi_model.update()
     gurobi_model.optimize()
     assert gurobi_model.status == 2, "LP wasn't optimally solved"
     observation = self.get_observation_variable(input, gurobi_model)  # get the observation from the input
     ranges = Experiment.get_range_bounds(observation, nn, gurobi_model)
     if self.use_softmax:
         ranges_probs = unroll_methods.softmax_interval(ranges)
     else:
         ranges_probs = ranges
     if round >= 0:
         pass
         # todo round the probabilities
     return ranges_probs
Exemple #21
0
 def check_unsafe(self, template, bnds):
     for A, b in self.unsafe_zone:
         gurobi_model = grb.Model()
         gurobi_model.setParam('OutputFlag', False)
         input = gurobi_model.addMVar(shape=(self.env_input_size, ),
                                      lb=float("-inf"),
                                      name="input")
         Experiment.generate_region_constraints(gurobi_model, template,
                                                input, bnds,
                                                self.env_input_size)
         Experiment.generate_region_constraints(gurobi_model, A, input, b,
                                                self.env_input_size)
         gurobi_model.update()
         gurobi_model.optimize()
         if gurobi_model.status == 2:
             return True
     return False
Exemple #22
0
 def generate_nn_polyhedral_guard(self, nn, chosen_action, output_flag):
     gurobi_model = grb.Model()
     gurobi_model.setParam('OutputFlag', output_flag)
     gurobi_model.setParam('Threads', 2)
     observation = gurobi_model.addMVar(shape=(2, ),
                                        lb=float("-inf"),
                                        ub=float("inf"),
                                        name="observation")
     Experiment.generate_nn_guard(gurobi_model,
                                  observation,
                                  nn,
                                  action_ego=chosen_action)
     observable_template = Experiment.octagon(2)
     self.env_input_size = 2
     observable_result = self.optimise(observable_template, gurobi_model,
                                       observation)
     self.env_input_size = 6
     return observable_template, observable_result
Exemple #23
0
    def post_milp(self, x, x_label, nn, output_flag, t, template):
        post = []
        for unsafe_check in [True, False]:
            for chosen_action in range(self.n_actions):
                gurobi_model = grb.Model()
                gurobi_model.setParam('OutputFlag', output_flag)
                gurobi_model.setParam('Threads', 2)
                gurobi_model.params.NonConvex = 2
                input = generate_input_region(gurobi_model, template, x,
                                              self.env_input_size)

                feasible_action = WaterTankExperiment.generate_nn_guard(
                    gurobi_model, input, nn, action_ego=chosen_action)
                if feasible_action:
                    # apply dynamic
                    x_prime = self.apply_dynamic(
                        input,
                        gurobi_model,
                        chosen_action,
                        env_input_size=self.env_input_size)
                    for A, b in self.unsafe_zone:  # splits the input based on the decision boundary of the ltl property
                        if unsafe_check:
                            generate_region_constraints(
                                gurobi_model, A, x_prime, b,
                                self.env_input_size)
                        else:
                            generate_region_constraints(gurobi_model,
                                                        A,
                                                        x_prime,
                                                        b,
                                                        self.env_input_size,
                                                        invert=True)
                    gurobi_model.update()
                    gurobi_model.optimize()
                    found_successor, x_prime_results = self.h_repr_to_plot(
                        gurobi_model, template, x_prime)
                    if found_successor:
                        post.append((tuple(x_prime_results), (x, x_label)))
        return post
 def additional_seen(self):
     # adds an element that captures all the states where battery is <=0
     gurobi_model = grb.Model()
     gurobi_model.setParam('OutputFlag', self.output_flag)
     additional = [
         self.safe_angle, self.safe_angle,
         float("inf"),
         float("inf"),
         float("inf"),
         float("inf"),
         float("inf"),
         float("inf")
     ]
     input = generate_input_region(gurobi_model,
                                   Experiment.octagon(self.env_input_size),
                                   additional, self.env_input_size)
     x_results = optimise(self.analysis_template, gurobi_model, input)
     if x_results is None:
         print("Model unsatisfiable")
         return None
     root = tuple(x_results)
     return [(root, 0)]
Exemple #25
0
    def show_sampleplot2d(self):
        '''Generates a plot from the probability of encountering an unsafe state from a sample of points'''
        root = self.generate_root_polytope()

        # convert to intervals
        gurobi_model = grb.Model()
        gurobi_model.setParam('OutputFlag', self.output_flag)
        input = generate_input_region(gurobi_model, self.input_template, self.input_boundaries, self.env_input_size)
        x_results = optimise(self.input_template, gurobi_model, input)
        if x_results is None:
            print("Model unsatisfiable")
            return None
        root2d = tuple(x_results)

        # samples = polytope.sample(1000, self.analysis_template, np.array(root))
        even_samples = self.generate_spaced_samples((-root2d[3], root2d[2]), (-root2d[1], root2d[0]))
        samples = list(even_samples)
        nn = self.get_nn_fn()
        t_max = 200
        n_trajectories = 500
        probabilities = []
        proc_ids = []
        with StandardProgressBar(prefix="Preparing AbstractStepWorkers ", max_value=len(samples)) as bar:
            while len(samples) != 0 or len(proc_ids) != 0:
                while len(proc_ids) < self.n_workers and len(samples) != 0:
                    sample = samples.pop(0) - np.array([28, 0])
                    proc_ids.append(sample_trajectory.remote(sample, nn, t_max, n_trajectories))
                    bar.update(bar.value + 1)
                ready_ids, proc_ids = ray.wait(proc_ids, num_returns=len(proc_ids), timeout=0.5)
                if len(ready_ids) != 0:
                    results_list = ray.get(ready_ids)
                    for result in results_list:
                        n_failures = result
                        probabilities.append(n_failures / n_trajectories)
                        # bar.update(len(probabilities))
        print(probabilities)
 def __init__(self, data: InputData):
     self.data = data
     self.name_to_column = dict()
     self.model = grb.Model("facility_location_master_problem")
     self.aux_var_name = 'z'
    def init_model(self, **args):
        self.model = gurobi.Model("Gantt")
        self.ressource_id_usage = {
            k:
            {i: {}
             for i in range(len(self.rcpsp_model.calendar_details[k]))}
            for k in self.rcpsp_model.calendar_details.keys()
        }
        variables_per_task = {}
        variables_per_individual = {}
        constraints_ressource_need = {}

        for task in self.jobs:
            start = self.rcpsp_schedule[task]["start_time"]
            end = self.rcpsp_schedule[task]["end_time"]
            for k in self.ressource_id_usage:  # typically worker
                needed_ressource = (self.rcpsp_model.mode_details[task][
                    self.modes_dict[task]][k] > 0)
                if needed_ressource:
                    for individual in self.ressource_id_usage[k]:
                        available = all([
                            self.rcpsp_model.calendar_details[k][individual]
                            [time] for time in range(start, end)
                        ])
                        if available:
                            key_variable = (k, individual, task)
                            self.ressource_id_usage[k][individual][
                                task] = self.model.addVar(
                                    name=str(key_variable),
                                    vtype=gurobi.GRB.BINARY)
                            if task not in variables_per_task:
                                variables_per_task[task] = set()
                            if k not in variables_per_individual:
                                variables_per_individual[k] = {}
                            if individual not in variables_per_individual[k]:
                                variables_per_individual[k][individual] = set()
                            variables_per_task[task].add(key_variable)
                            variables_per_individual[k][individual].add(
                                key_variable)
                    ressource_needed = self.rcpsp_model.mode_details[task][
                        self.modes_dict[task]][k]
                    if k not in constraints_ressource_need:
                        constraints_ressource_need[k] = {}
                    constraints_ressource_need[k][task] = self.model.addConstr(
                        gurobi.quicksum([
                            self.ressource_id_usage[k][key[1]][key[2]]
                            for key in variables_per_task[task] if key[0] == k
                        ]) == ressource_needed,
                        name="ressource_" + str(k) + "_" + str(task),
                    )
        overlaps_constraints = {}

        for i in range(len(self.cliques)):
            tasks = set(self.cliques[i])
            for k in variables_per_individual:
                for individual in variables_per_individual[k]:
                    keys_variable = [
                        variable
                        for variable in variables_per_individual[k][individual]
                        if variable[2] in tasks
                    ]
                    if len(keys_variable) > 0:
                        overlaps_constraints[(
                            i, k, individual
                        )] = self.model.addConstr(
                            gurobi.quicksum([
                                self.ressource_id_usage[key[0]][key[1]][key[2]]
                                for key in keys_variable
                            ]) <= 1)
 def before_start(self):
     self.internal_model = grb.Model()
Exemple #29
0
    def init_model(self, **args):
        greedy_start = args.get("greedy_start", True)
        start_solution = args.get("start_solution", None)
        max_horizon = args.get("max_horizon", None)
        verbose = args.get("verbose", False)
        if start_solution is None:
            if greedy_start:
                if verbose:
                    print("Computing greedy solution")
                if isinstance(self.rcpsp_model, RCPSPModelCalendar):
                    greedy_solver = PileSolverRCPSP_Calendar(self.rcpsp_model)
                else:
                    greedy_solver = PileSolverRCPSP(self.rcpsp_model)
                store_solution = greedy_solver.solve(
                    greedy_choice=GreedyChoice.MOST_SUCCESSORS
                )
                self.start_solution = store_solution.get_best_solution_fit()[0]
                makespan = self.rcpsp_model.evaluate(self.start_solution)["makespan"]
            else:
                if verbose:
                    print("Get dummy solution")
                solution = self.rcpsp_model.get_dummy_solution()
                self.start_solution = solution
                makespan = self.rcpsp_model.evaluate(solution)["makespan"]
        else:
            self.start_solution = start_solution
            makespan = self.rcpsp_model.evaluate(start_solution)["makespan"]

        # p = [0, 3, 2, 5, 4, 2, 3, 4, 2, 4, 6, 0]
        sorted_tasks = sorted(self.rcpsp_model.mode_details.keys())
        p = [
            int(
                max(
                    [
                        self.rcpsp_model.mode_details[key][mode]["duration"]
                        for mode in self.rcpsp_model.mode_details[key]
                    ]
                )
            )
            for key in sorted_tasks
        ]
        # c = [6, 8]
        c = [x for x in self.rcpsp_model.resources.values()]
        renewable = {
            r: self.rcpsp_model.resources[r]
            for r in self.rcpsp_model.resources
            if r not in self.rcpsp_model.non_renewable_resources
        }
        non_renewable = {
            r: self.rcpsp_model.resources[r]
            for r in self.rcpsp_model.non_renewable_resources
        }
        # print('c: ', c)
        # S = [[0, 1], [0, 2], [0, 3], [1, 4], [1, 5], [2, 9], [2, 10], [3, 8], [4, 6],
        #      [4, 7], [5, 9], [5, 10], [6, 8], [6, 9], [7, 8], [8, 11], [9, 11], [10, 11]]
        S = []
        print("successors: ", self.rcpsp_model.successors)
        for task in sorted_tasks:
            for suc in self.rcpsp_model.successors[task]:
                S.append([task, suc])
        # print('S: ', S)
        (R, self.J, self.T) = (range(len(c)), range(len(p)), list(range(sum(p))))
        # we have a better self.T to limit the number of variables :
        if self.start_solution.rcpsp_schedule_feasible:
            self.T = list(range(int(makespan + 1)))
        if max_horizon is not None:
            self.T = list(range(max_horizon + 1))
            print("Hey")
            print(self.T)
        # model = Model()
        self.model = gurobi.Model("MRCPSP")
        self.x: Dict[gurobi.Var] = {}
        last_task = max(self.rcpsp_model.mode_details.keys())
        variable_per_task = {}
        keys_for_t = {}
        for task in sorted_tasks:
            if task not in variable_per_task:
                variable_per_task[task] = []
            for mode in self.rcpsp_model.mode_details[task]:
                for t in self.T:
                    self.x[(task, mode, t)] = self.model.addVar(
                        name="x({},{}, {})".format(task, mode, t),
                        vtype=gurobi.GRB.BINARY,
                    )
                    for tt in range(
                        t, t + self.rcpsp_model.mode_details[task][mode]["duration"]
                    ):
                        if tt not in keys_for_t:
                            keys_for_t[tt] = set()
                        keys_for_t[tt].add((task, mode, t))
                    variable_per_task[task] += [(task, mode, t)]
        self.model.update()
        self.model.setObjective(
            gurobi.quicksum(
                self.x[key] * key[2] for key in variable_per_task[last_task]
            )
        )
        self.model.addConstrs(
            gurobi.quicksum(self.x[key] for key in variable_per_task[j]) == 1
            for j in variable_per_task
        )

        if isinstance(self.rcpsp_model, RCPSPModelCalendar):
            renewable_quantity = {r: renewable[r] for r in renewable}
        else:
            renewable_quantity = {r: [renewable[r]] * len(self.T) for r in renewable}

        if isinstance(self.rcpsp_model, RCPSPModelCalendar):
            non_renewable_quantity = {r: non_renewable[r] for r in non_renewable}
        else:
            non_renewable_quantity = {
                r: [non_renewable[r]] * len(self.T) for r in non_renewable
            }

        # for r, t in product(renewable, self.T):
        #    self.model.addConstr(gurobi.quicksum(int(self.rcpsp_model.mode_details[key[0]][key[1]][r]) * self.x[key]
        #                                          for key in keys_for_t[t])
        #                          <= renewable_quantity[r][t])
        #    print(r, t)

        self.model.addConstrs(
            gurobi.quicksum(
                int(self.rcpsp_model.mode_details[key[0]][key[1]][r]) * self.x[key]
                for key in keys_for_t[t]
            )
            <= renewable_quantity[r][t]
            for (r, t) in product(renewable, self.T)
        )

        self.model.addConstrs(
            gurobi.quicksum(
                int(self.rcpsp_model.mode_details[key[0]][key[1]][r]) * self.x[key]
                for key in self.x
            )
            <= non_renewable_quantity[r][0]
            for r in non_renewable
        )
        self.model.update()
        durations = {
            j: self.model.addVar(name="duration_" + str(j), vtype=gurobi.GRB.INTEGER)
            for j in variable_per_task
        }
        self.durations = durations
        self.variable_per_task = variable_per_task
        self.model.addConstrs(
            gurobi.quicksum(
                self.rcpsp_model.mode_details[key[0]][key[1]]["duration"] * self.x[key]
                for key in variable_per_task[j]
            )
            == durations[j]
            for j in variable_per_task
        )
        self.model.addConstrs(
            gurobi.quicksum(
                [key[2] * self.x[key] for key in variable_per_task[s]]
                + [-key[2] * self.x[key] for key in variable_per_task[j]]
            )
            >= durations[j]
            for (j, s) in S
        )

        start = []
        self.starts = {}
        for task in sorted_tasks:
            self.starts[task] = self.model.addVar(
                name="start({})".format(task),
                vtype=gurobi.GRB.INTEGER,
                lb=0,
                ub=self.T[-1],
            )
            self.starts[task].start = self.start_solution.rcpsp_schedule[task][
                "start_time"
            ]
            self.model.addConstr(
                gurobi.quicksum(
                    [self.x[key] * key[2] for key in variable_per_task[task]]
                )
                == self.starts[task]
            )
        for j in self.start_solution.rcpsp_schedule:
            start_time_j = self.start_solution.rcpsp_schedule[j]["start_time"]
            mode_j = (
                1
                if j == 1 or j == self.rcpsp_model.n_jobs + 2
                else self.start_solution.rcpsp_modes[j - 2]
            )
            start += [
                (
                    self.durations[j],
                    self.rcpsp_model.mode_details[j][mode_j]["duration"],
                )
            ]
            for k in self.variable_per_task[j]:
                task, mode, time = k
                if start_time_j == time and mode == mode_j:
                    start += [(self.x[k], 1)]
                    self.x[k].start = 1
                else:
                    start += [(self.x[k], 0)]
                    self.x[k].start = 0

        # self.model.start = start
        p_s: Union[PartialSolution, None] = args.get("partial_solution", None)
        self.constraints_partial_solutions = []
        self.model.update()
        if p_s is not None:
            constraints = []
            if p_s.start_times is not None:
                constraints = self.model.addConstrs(
                    gurobi.quicksum(
                        [
                            self.x[k]
                            for k in self.variable_per_task[task]
                            if k[2] == p_s.start_times[task]
                        ]
                    )
                    == 1
                    for task in p_s.start_times
                )
            if p_s.partial_permutation is not None:
                for t1, t2 in zip(
                    p_s.partial_permutation[:-1], p_s.partial_permutation[1:]
                ):
                    constraints += [
                        self.model.addConstr(
                            gurobi.quicksum(
                                [key[2] * self.x[key] for key in variable_per_task[t1]]
                                + [
                                    -key[2] * self.x[key]
                                    for key in variable_per_task[t2]
                                ]
                            )
                            <= 0
                        )
                    ]
            if p_s.list_partial_order is not None:
                for l in p_s.list_partial_order:
                    for t1, t2 in zip(l[:-1], l[1:]):
                        constraints += [
                            self.model.addConstr(
                                gurobi.quicksum(
                                    [
                                        key[2] * self.x[key]
                                        for key in variable_per_task[t1]
                                    ]
                                    + [
                                        -key[2] * self.x[key]
                                        for key in variable_per_task[t2]
                                    ]
                                )
                                <= 0
                            )
                        ]
            if p_s.start_at_end is not None:
                for i, j in p_s.start_at_end:
                    constraints += [
                        self.model.addConstr(
                            self.starts[j] == self.starts[i] + durations[i]
                        )
                    ]
            if p_s.start_together is not None:
                for i, j in p_s.start_together:
                    constraints += [
                        self.model.addConstr(self.starts[j] == self.starts[i])
                    ]
            if p_s.start_after_nunit is not None:
                for t1, t2, delta in p_s.start_after_nunit:
                    constraints += [
                        self.model.addConstr(self.starts[t2] >= self.starts[t1] + delta)
                    ]
            if p_s.start_at_end_plus_offset is not None:
                for t1, t2, delta in p_s.start_at_end_plus_offset:
                    constraints += [
                        self.model.addConstr(
                            self.starts[t2] >= self.starts[t1] + delta + durations[t1]
                        )
                    ]
            self.constraints_partial_solutions = constraints
            print("Partial solution constraints : ", self.constraints_partial_solutions)
            self.model.update()
    def post_milp(self, x, nn, output_flag, t, template):
        post = []
        observable_template_action1 = self.observable_templates[1]
        observable_result_action1 = self.observable_results[1]
        observable_template_action0 = self.observable_templates[0]
        observable_result_action0 = self.observable_results[0]

        def standard_op():
            gurobi_model = grb.Model()
            gurobi_model.setParam('OutputFlag', output_flag)
            input = self.generate_input_region(gurobi_model, template, x,
                                               self.env_input_size)
            z = self.apply_dynamic(input, gurobi_model, self.env_input_size)
            return gurobi_model, z, input

        # case 0
        gurobi_model, z, input = standard_op()
        feasible0 = self.generate_guard(gurobi_model, z, case=0)  # bounce
        if feasible0:  # action is irrelevant in this case
            # apply dynamic
            x_prime_results = self.optimise(template, gurobi_model, z)
            gurobi_model = grb.Model()
            gurobi_model.setParam('OutputFlag', output_flag)
            input2 = self.generate_input_region(gurobi_model, template,
                                                x_prime_results,
                                                self.env_input_size)
            x_second = self.apply_dynamic2(input2,
                                           gurobi_model,
                                           case=0,
                                           env_input_size=self.env_input_size)
            found_successor, x_second_results = self.h_repr_to_plot(
                gurobi_model, template, x_second)
            if found_successor:
                post.append(tuple(x_second_results))

        # case 1 : ball going down and hit
        gurobi_model, z, input = standard_op()
        feasible11 = self.generate_guard(gurobi_model, z, case=1)
        if feasible11:
            Experiment.generate_region_constraints(
                gurobi_model, observable_template_action1, input,
                observable_result_action1, 2)
            gurobi_model.optimize()
            feasible12 = gurobi_model.status == 2
            # feasible12 = self.generate_nn_guard(gurobi_model, input, nn, action_ego=1)  # check for action =1 over input (not z!)
            if feasible12:
                # apply dynamic
                x_prime_results = self.optimise(template, gurobi_model, z)
                gurobi_model = grb.Model()
                gurobi_model.setParam('OutputFlag', output_flag)
                input2 = self.generate_input_region(gurobi_model, template,
                                                    x_prime_results,
                                                    self.env_input_size)
                x_second = self.apply_dynamic2(
                    input2,
                    gurobi_model,
                    case=1,
                    env_input_size=self.env_input_size)
                found_successor, x_second_results = self.h_repr_to_plot(
                    gurobi_model, template, x_second)
                if found_successor:
                    post.append(tuple(x_second_results))
        # case 2 : ball going up and hit
        gurobi_model, z, input = standard_op()
        feasible21 = self.generate_guard(gurobi_model, z, case=2)
        if feasible21:
            Experiment.generate_region_constraints(
                gurobi_model, observable_template_action1, input,
                observable_result_action1, 2)
            gurobi_model.optimize()
            feasible22 = gurobi_model.status == 2
            # feasible22 = self.generate_nn_guard(gurobi_model, input, nn, action_ego=1)  # check for action =1 over input (not z!)
            if feasible22:
                # apply dynamic
                x_prime_results = self.optimise(template, gurobi_model, z)
                gurobi_model = grb.Model()
                gurobi_model.setParam('OutputFlag', output_flag)
                input2 = self.generate_input_region(gurobi_model, template,
                                                    x_prime_results,
                                                    self.env_input_size)
                x_second = self.apply_dynamic2(
                    input2,
                    gurobi_model,
                    case=2,
                    env_input_size=self.env_input_size)
                found_successor, x_second_results = self.h_repr_to_plot(
                    gurobi_model, template, x_second)
                if found_successor:
                    post.append(tuple(x_second_results))
        # case 1 alt : ball going down and NO hit
        gurobi_model, z, input = standard_op()
        feasible11_alt = self.generate_guard(gurobi_model, z, case=1)
        if feasible11_alt:
            Experiment.generate_region_constraints(
                gurobi_model, observable_template_action0, input,
                observable_result_action0, 2)
            gurobi_model.optimize()
            feasible12_alt = gurobi_model.status == 2
            # feasible12_alt = self.generate_nn_guard(gurobi_model, input, nn, action_ego=0)  # check for action = 0 over input (not z!)
            if feasible12_alt:
                # apply dynamic
                x_prime_results = self.optimise(template, gurobi_model, z)
                gurobi_model = grb.Model()
                gurobi_model.setParam('OutputFlag', output_flag)
                input2 = self.generate_input_region(gurobi_model, template,
                                                    x_prime_results,
                                                    self.env_input_size)
                x_second = self.apply_dynamic2(
                    input2,
                    gurobi_model,
                    case=3,
                    env_input_size=self.env_input_size)
                found_successor, x_second_results = self.h_repr_to_plot(
                    gurobi_model, template, x_second)

                if found_successor:
                    post.append(tuple(x_second_results))
        # case 2 alt : ball going up and NO hit
        gurobi_model, z, input = standard_op()
        feasible21_alt = self.generate_guard(gurobi_model, z, case=2)
        if feasible21_alt:
            Experiment.generate_region_constraints(
                gurobi_model, observable_template_action0, input,
                observable_result_action0, 2)
            gurobi_model.optimize()
            feasible22_alt = gurobi_model.status == 2
            # feasible22_alt = self.generate_nn_guard(gurobi_model, input, nn, action_ego=0)  # check for action = 0 over input (not z!)
            if feasible22_alt:
                # apply dynamic
                x_prime_results = self.optimise(template, gurobi_model, z)
                gurobi_model = grb.Model()
                gurobi_model.setParam('OutputFlag', output_flag)
                input2 = self.generate_input_region(gurobi_model, template,
                                                    x_prime_results,
                                                    self.env_input_size)
                x_second = self.apply_dynamic2(
                    input2,
                    gurobi_model,
                    case=3,
                    env_input_size=self.env_input_size)
                found_successor, x_second_results = self.h_repr_to_plot(
                    gurobi_model, template, x_second)
                if found_successor:
                    post.append(tuple(x_second_results))
        # case 3 : ball out of reach and not bounce
        gurobi_model, z, input = standard_op()
        feasible3 = self.generate_guard(gurobi_model, z,
                                        case=3)  # out of reach
        if feasible3:  # action is irrelevant in this case
            # apply dynamic
            x_prime_results = self.optimise(template, gurobi_model, z)
            gurobi_model = grb.Model()
            gurobi_model.setParam('OutputFlag', output_flag)
            input2 = self.generate_input_region(gurobi_model, template,
                                                x_prime_results,
                                                self.env_input_size)
            x_second = self.apply_dynamic2(input2,
                                           gurobi_model,
                                           case=3,
                                           env_input_size=self.env_input_size)
            found_successor, x_second_results = self.h_repr_to_plot(
                gurobi_model, template, x_second)
            if found_successor:
                post.append(tuple(x_second_results))

        return post