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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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
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
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
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
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)]
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()
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