def generate_nn_guard(gurobi_model: grb.Model, input, nn: torch.nn.Sequential, action_ego=0, M=1e2): gurobi_model.setParam("DualReductions", 0) gurobi_vars = [] gurobi_vars.append(input) for i, layer in enumerate(nn): # print(layer) if type(layer) is torch.nn.Linear: v = gurobi_model.addMVar(lb=float("-inf"), shape=(int(layer.out_features)), name=f"layer_{i}") lin_expr = layer.weight.data.numpy() @ gurobi_vars[-1] if layer.bias is not None: lin_expr = lin_expr + layer.bias.data.numpy() gurobi_model.addConstr(v == lin_expr, name=f"linear_constr_{i}") gurobi_vars.append(v) gurobi_model.update() gurobi_model.optimize() assert gurobi_model.status == 2, "LP wasn't optimally solved" elif type(layer) is torch.nn.ReLU: v = gurobi_model.addMVar(lb=float("-inf"), shape=gurobi_vars[-1].shape, name=f"layer_{i}") # same shape as previous z = gurobi_model.addMVar(shape=gurobi_vars[-1].shape, vtype=grb.GRB.BINARY, name=f"relu_{i}") # lb=0, ub=1, gurobi_model.addConstr(v >= gurobi_vars[-1], name=f"relu_constr_1_{i}") gurobi_model.addConstr(v <= gurobi_vars[-1] + M * z, name=f"relu_constr_2_{i}") gurobi_model.addConstr(v >= 0, name=f"relu_constr_3_{i}") gurobi_model.addConstr(v <= M - M * z, name=f"relu_constr_4_{i}") gurobi_vars.append(v) gurobi_model.update() gurobi_model.optimize() assert gurobi_model.status == 2, "LP wasn't optimally solved" """ y = Relu(x) 0 <= z <= 1, z is integer y >= x y <= x + Mz y >= 0 y <= M - Mz""" # gurobi_model.update() # gurobi_model.optimize() # assert gurobi_model.status == 2, "LP wasn't optimally solved" # gurobi_model.setObjective(v[action_ego].sum(), grb.GRB.MAXIMIZE) # maximise the output last_layer = gurobi_vars[-1] for i in range(last_layer.shape[0]): if i == action_ego: continue gurobi_model.addConstr(last_layer[action_ego] >= last_layer[i], name="last_layer") # if action_ego == 0: # gurobi_model.addConstr(last_layer[0] >= last_layer[1], name="last_layer") # else: # gurobi_model.addConstr(last_layer[1] >= last_layer[0], name="last_layer") gurobi_model.update() gurobi_model.optimize() # assert gurobi_model.status == 2, "LP wasn't optimally solved" return gurobi_model.status == 2 or gurobi_model.status == 5
def gurobi_solve_qp(P, q, G=None, h=None, A=None, b=None, initvals=None, verbose: bool = False) -> Optional[ndarray]: """ Solve a Quadratic Program defined as: .. math:: \\begin{split}\\begin{array}{ll} \\mbox{minimize} & \\frac{1}{2} x^T P x + q^T x \\\\ \\mbox{subject to} & G x \\leq h \\\\ & A x = h \\end{array}\\end{split} using `Gurobi <http://www.gurobi.com/>`_. Parameters ---------- P : array, shape=(n, n) Primal quadratic cost matrix. q : array, shape=(n,) Primal quadratic cost vector. G : array, shape=(m, n) Linear inequality constraint matrix. h : array, shape=(m,) Linear inequality constraint vector. A : array, shape=(meq, n), optional Linear equality constraint matrix. b : array, shape=(meq,), optional Linear equality constraint vector. initvals : array, shape=(n,), optional Warm-start guess vector (not used). verbose : bool, optional Set to `True` to print out extra information. Returns ------- x : array, shape=(n,) Solution to the QP, if found, otherwise ``None``. """ if initvals is not None: warn("Gurobi: warm-start values given but they will be ignored") model = Model() if not verbose: # optionally turn off solver output model.setParam("OutputFlag", 0) num_vars = P.shape[0] x = model.addMVar(num_vars, lb=-GRB.INFINITY, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS) if A is not None: # include equality constraints model.addMConstr(A, x, GRB.EQUAL, b) if G is not None: # include inequality constraints model.addMConstr(G, x, GRB.LESS_EQUAL, h) objective = 0.5 * (x @ P @ x) + q @ x model.setObjective(objective, sense=GRB.MINIMIZE) model.optimize() status = model.status if status not in (GRB.OPTIMAL, GRB.SUBOPTIMAL): return None return array(x.X)
# examples/python directory. # # This example requires the pandas (>= 0.20.3), NumPy, and Matplotlib # Python packages, which are part of the SciPy ecosystem for # mathematics, science, and engineering (http://scipy.org). These # packages aren't included in all Python distributions, but are # included by default with Anaconda Python. from active_set_method.utils import generate_random_instance from gurobipy import GRB, Model import numpy as np n = 5000 q, p, x = generate_random_instance(n) m = Model('portfolio') A = np.ones(n) x = m.addMVar(n, lb=0.0) m.setObjective(x @ q @ x + 2 * p @ x, GRB.MINIMIZE) m.addConstr(A @ x == 1) m.optimize() count = 0 temp = np.zeros(n) for i in range(n): if x[i].x > 1e-4: temp[i] = x[i].x x = temp.copy() shit = np.vstack((x, y)) gurobi_obj = .5 * x @ q @ x + p @ x
for f in range(F): for j in range(J): t[k, f, j] = random.randrange(10, 20 + 1) build_time_end = time.time() #print("-"*30) #print(f"D={D}\nr={r}\nR={R}\nC={C}\np={p}\nt={t}") #inicio modelagem model_time_start = time.time() mdl = Model('papel') if real_values: x = mdl.addMVar(p.shape, vtype=GRB.CONTINUOUS) y = mdl.addMVar(t.shape, vtype=GRB.CONTINUOUS) else: x = mdl.addMVar(p.shape, vtype=GRB.INTEGER) y = mdl.addMVar(t.shape, vtype=GRB.INTEGER) mdl.modelSense = GRB.MINIMIZE mdl.setParam('TimeLimit', 30 * 60) mdl.setObjective( sum(p[k, l, f] * x[k, l, f] for k in range(P) for l in range(L) for f in range(F)) + sum(t[k, f, j] * y[k, f, j] for k in range(P) for l in range(L) for j in range(J))) mdl.addConstrs( sum(x[k, l, f] for l in range(L)
def generate_nn_guard_continuous(gurobi_model: grb.Model, input, nn: torch.nn.Sequential): gurobi_vars = [] gurobi_vars.append(input) for i, layer in enumerate(nn): # print(layer) if type(layer) is torch.nn.Linear: v = gurobi_model.addMVar(lb=float("-inf"), shape=(int(layer.out_features)), name=f"layer_{i}") lin_expr = layer.weight.data.numpy() @ gurobi_vars[-1] if layer.bias is not None: lin_expr = lin_expr + layer.bias.data.numpy() gurobi_model.addConstr(v == lin_expr, name=f"linear_constr_{i}") gurobi_vars.append(v) elif type(layer) is torch.nn.ReLU: v = gurobi_model.addMVar(lb=float("-inf"), shape=gurobi_vars[-1].shape, name=f"layer_{i}") # same shape as previous z = gurobi_model.addMVar(lb=0, ub=1, shape=gurobi_vars[-1].shape, vtype=grb.GRB.INTEGER, name=f"relu_{i}") M = 1e3 # gurobi_model.addConstr(v == grb.max_(0, gurobi_vars[-1])) gurobi_model.addConstr(v >= gurobi_vars[-1], name=f"relu_constr_1_{i}") gurobi_model.addConstr(v <= gurobi_vars[-1] + M * z, name=f"relu_constr_2_{i}") gurobi_model.addConstr(v >= 0, name=f"relu_constr_3_{i}") gurobi_model.addConstr(v <= M - M * z, name=f"relu_constr_4_{i}") gurobi_vars.append(v) # gurobi_model.update() # gurobi_model.optimize() # assert gurobi_model.status == 2, "LP wasn't optimally solved" """ y = Relu(x) 0 <= z <= 1, z is integer y >= x y <= x + Mz y >= 0 y <= M - Mz""" elif type(layer) is torch.nn.Hardtanh: layerTanh: torch.nn.Hardtanh = layer min_val = layerTanh.min_val max_val = layerTanh.max_val M = 10e3 v1 = gurobi_model.addMVar(lb=float("-inf"), shape=gurobi_vars[-1].shape, name=f"layer_{i}") # same shape as previous z1 = gurobi_model.addMVar(lb=0, ub=1, shape=gurobi_vars[-1].shape, vtype=grb.GRB.INTEGER, name=f"hardtanh1_{i}") z2 = gurobi_model.addMVar(lb=0, ub=1, shape=gurobi_vars[-1].shape, vtype=grb.GRB.INTEGER, name=f"hardtanh2_{i}") gurobi_model.addConstr(v1 >= gurobi_vars[-1], name=f"hardtanh1_constr_1_{i}") gurobi_model.addConstr(v1 <= gurobi_vars[-1] + M * z1, name=f"hardtanh1_constr_2_{i}") gurobi_model.addConstr(v1 >= min_val, name=f"hardtanh1_constr_3_{i}") gurobi_model.addConstr(v1 <= min_val + M - M * z1, name=f"hardtanh1_constr_4_{i}") gurobi_vars.append(v1) v2 = gurobi_model.addMVar(lb=float("-inf"), shape=gurobi_vars[-1].shape, name=f"layer_{i}") # same shape as previous gurobi_model.addConstr(v2 <= gurobi_vars[-1], name=f"hardtanh2_constr_1_{i}") gurobi_model.addConstr(v2 >= gurobi_vars[-1] - M * z2, name=f"hardtanh2_constr_2_{i}") gurobi_model.addConstr(v2 <= max_val, name=f"hardtanh2_constr_3_{i}") gurobi_model.addConstr(v2 >= max_val - M + M * z2, name=f"hardtanh2_constr_4_{i}") gurobi_vars.append(v2) else: raise Exception("Unrecognised layer") gurobi_model.update() gurobi_model.optimize() assert gurobi_model.status == 2, "LP wasn't optimally solved" last_layer = gurobi_vars[-1] gurobi_model.setObjective(last_layer[0].sum(), grb.GRB.MAXIMIZE) # maximise the output gurobi_model.update() gurobi_model.optimize() assert gurobi_model.status == 2, "LP wasn't optimally solved" max_val = gurobi_model.ObjVal gurobi_model.setObjective(last_layer[0].sum(), grb.GRB.MINIMIZE) # maximise the output gurobi_model.update() gurobi_model.optimize() assert gurobi_model.status == 2, "LP wasn't optimally solved" min_val = gurobi_model.ObjVal return last_layer, max_val, min_val