def fix_mapping_variables_according_to_integral_solution(self, solution): if not isinstance(solution, solutions.IntegralScenarioSolution): msg = "Expected solutions.IntegralScenarioSolution instance, received {} of type {}".format(solution, type(solution)) raise TypeError(msg) if solution.scenario is not self.scenario: msg = "This method requires that the solution is based on the same scenario as the Modelcreator." raise ClassicMCFError(msg) for req in self.requests: mapping = solution.request_mapping[req] self._fix_embedding_variable(req, mapping) if not mapping.is_embedded: continue for i in req.nodes: for u in req.get_allowed_nodes(i): fix_i_u_mapping_constraint = LinExpr([(1.0, self.var_y[req][i][u])]) name = "{req}_fix_{i}_{u}".format(req=req.name, i=i, u=u) if u == mapping.get_mapping_of_node(i): self.model.addConstr(fix_i_u_mapping_constraint, GRB.EQUAL, 1.0, name=name) else: self.model.addConstr(fix_i_u_mapping_constraint, GRB.EQUAL, 0.0, name=name) for ij in req.edges: i, j = ij for uv in self.substrate.edges: u, v = uv fix_ij_uv_mapping_constraint = LinExpr([(1.0, self.var_z[req][ij][uv])]) name = "{}_fix_{}_{}__{}_{}".format(req.name, i, j, u, v) if uv in mapping.mapping_edges[ij]: self.model.addConstr(fix_ij_uv_mapping_constraint, GRB.EQUAL, 1.0, name=name) else: self.model.addConstr(fix_ij_uv_mapping_constraint, GRB.EQUAL, 0.0, name=name)
def add_node_variables(self): n = self.G.vcount() for i in range(n): for j in range(self.k): self.x[i, j] = self.model.addVar(vtype=GRB.CONTINUOUS) if self.x_coefs: for ((i, c), coef) in self.x_coefs.items(): self.x[i, c].obj = coef self.model.update() for i in range(n): total_assign = LinExpr() for j in range(self.k): total_assign.addTerms(1.0, self.x[i, j]) self.model.addConstr(total_assign == 1.0) for e in self.G.es(): u = min(e.source, e.target) v = max(e.source, e.target) for i in range(self.k): self.model.addConstr(self.y[u, v] >= self.x[u, i] + self.x[v, i] - 1.0) self.model.addConstr(self.x[u, i] >= self.x[v, i] + self.y[u, v] - 1.0) self.model.addConstr(self.x[v, i] >= self.x[u, i] + self.y[u, v] - 1.0) self.model.update()
def constraints_list_of_tuples(model, mylist, sign="="): term_0 = mylist[0] ROWS, COLUMNS = term_0[0].shape[0], term_0[1].shape[1] for row in range(ROWS): for column in range(COLUMNS): expr = LinExpr() for term in mylist: q, qp = term[0].shape[1], term[1].shape[0] if q != qp: raise ValueError(term, "q=%d qp=%d" % (q, qp)) if type(term[1][0, column]) == type(model.addVar()): expr.add( LinExpr([(term[0][row, k], term[1][k, column]) for k in range(q)])) elif type(term[0][row, 0]) == type(model.addVar()): expr.add( LinExpr([(term[1][k, column], term[0][row, k]) for k in range(q)])) else: expr.addConstant( sum([ term[1][k, column] * term[0][row, k] for k in range(q) ])) if sign == "<": model.addConstr(expr <= 0) elif sign == "=": model.addConstr(expr == 0) elif sign == ">=": model.addConstr(expr >= 0) else: raise "sign indefinite"
def create_objective(self): # the original objective of the LP which produced the decomposable fractional solutions objective = LinExpr() for req in self.var_embedding_variable: for fractional_mapping in self.var_embedding_variable[req]: objective.addTerms(req.profit, self.var_embedding_variable[req][fractional_mapping]) self.model.setObjective(objective, GRB.MAXIMIZE)
def funcion_objetivo(model, D, C, T, F, cf_mod, cck_mod, pc_mod): ganancias = LinExpr() for k in range(CTDAD_TIPOS_CLAMSHELLS): for i in range(4): for d in range(8): ganancias += D[k][i][d] * PC_LIST[pc_mod][k][i][d] costo_clamshells = LinExpr() costo_fruta = LinExpr() for k in range(CTDAD_TIPOS_CLAMSHELLS): for i in range(4): for t in range(2): for d in range(28): costo_clamshells += C[k][i][t][d] * CCK_LIST[cck_mod][k] costo_fruta += C[k][i][t][d] * CCD[d] costo_trabajadores = LinExpr() for n in range(54): for m in range(2): for t in range(2): for d in range(28): costo_trabajadores += T[n][m][t][d] * CT[m] costo_frigorifico = LinExpr() for d in range(28): costo_frigorifico += F[d] * CF[cf_mod] fo = ganancias - (costo_clamshells + costo_fruta + costo_trabajadores + costo_frigorifico) model.setObjective(fo, GRB.MAXIMIZE)
def acceptable(model, C): id_r = 1 acc = ['a', 'b', 'c', 'd'] acc_values = [[0.1, 0.25, 0.45, 0.05], [0.2, 0.4, 0.6, 0.15]] for t in range(CTDAD_TURNOS): for d in range(CTDAD_DIAS): restriccion_lr = LinExpr() for k in range(CTDAD_TIPOS_CLAMSHELLS): for i in range(CTDAD_MERCADOS): restriccion_lr += C[k][i][t][d] for x in range(4): restriccion_m = LinExpr() for k in range(CTDAD_TIPOS_CLAMSHELLS): restriccion_m += C[k][x][t][d] model.addConstr( acc_values[0][x] * restriccion_lr <= restriccion_m, name=f"Acceptabilidad_{acc[x]}{id_r}") id_r += 1 model.addConstr( restriccion_m <= acc_values[1][x] * restriccion_lr, name=f"Acceptabilidad_{acc[x]}{id_r}") id_r += 1
def min_trabajadores(model, T, C, qt_mod): id_r_1 = 1 id_r_2 = 1 trab_1 = 'a' trab_2 = 'b' #""" for m in range(CTDAD_TIPOS_TRABAJADORES): for d in range(CTDAD_DIAS): for t in range(CTDAD_TURNOS): #""" if not ((d + 1) % 7 == 0): restriccion_1 = LinExpr() for n in range(CTDAD_TRABAJADORES): restriccion_1 += T[n][m][t][d] model.addConstr(restriccion_1 >= QT_LIST[qt_mod][m], name=f'Min_trabajadores_{trab_1}_{id_r_1}') id_r_1 += 1 #""" #''' restriccion_2_left = LinExpr() for n in range(CTDAD_TRABAJADORES): restriccion_2_left += T[n][m][t][d] restriccion_2_right = LinExpr() for k in range(CTDAD_TIPOS_CLAMSHELLS): for i in range(CTDAD_MERCADOS): restriccion_2_right += C[k][i][t][d] * FM[m] model.addConstr(restriccion_2_left >= restriccion_2_right, name=f'Min_trabajadores_{trab_2}_{id_r_2}') id_r_2 += 1
def build_lp(g, feasible_sol): from gurobipy import LinExpr, GRB, Model #, setParam # We introduce an integer index per node ID. Sometimes we will use this # index, and sometimes the node ID; this makes the code a bit messy. i_nodeid = {i: n for i, n in enumerate(g)} n_nodes = len(i_nodeid) model = Model() # The lower half of the n^2 binary variables, the rest: y_{j,i} = 1-y_{i,j} y = {(i, j): model.addVar(vtype=GRB.BINARY) for i, j in combinations(irange(n_nodes), 2)} model.update() # The triangle inequalities for i, j, k in combinations(irange(n_nodes), 3): lhs = LinExpr([(1, y[(i, j)]), (1, y[(j, k)]), (-1, y[(i, k)])]) model.addConstr(lhs, GRB.LESS_EQUAL, 1.0) lhs = LinExpr([(-1, y[(i, j)]), (-1, y[(j, k)]), (1, y[(i, k)])]) model.addConstr(lhs, GRB.LESS_EQUAL, 0.0) # The objective shift = 0 c = [[0] * n_nodes for _ in irange(n_nodes)] indices = ((i, j) for i, j in product(irange(n_nodes), repeat=2) if g.has_edge(i_nodeid[j], i_nodeid[i])) for j, k in indices: w = g[i_nodeid[k]][i_nodeid[j]]['weight'] if k < j: c[k][j] += w elif k > j: c[j][k] -= w shift += w obj = [(c[i][j], y[(i, j)]) for i, j in combinations(irange(n_nodes), 2)] model.setObjective(LinExpr(obj), GRB.MINIMIZE) model.setAttr('ObjCon', shift) set_start_point(g, model, y, i_nodeid, feasible_sol) model.update() return model, y
def solve_lp_knapsack_gurobi(scores, costs, budget): from gurobipy import Model, LinExpr, GRB n = len(scores) # Create a new model. m = Model("lp_knapsack") # Create variables. for i in range(n): m.addVar(lb=0.0, ub=1.0) m.update() vars = m.getVars() # Set objective. obj = LinExpr() for i in range(n): obj += scores[i] * vars[i] m.setObjective(obj, GRB.MAXIMIZE) # Add constraint. expr = LinExpr() for i in range(n): expr += costs[i] * vars[i] m.addConstr(expr, GRB.LESS_EQUAL, budget) # Optimize. m.optimize() assert m.status == GRB.OPTIMAL x = np.zeros(n) for i in range(n): x[i] = vars[i].x return x
def create_objective(self): objective = LinExpr() for req in self.var_embedding_variable: for fractional_mapping in self.var_embedding_variable[req]: objective.addTerms( req.profit, self.var_embedding_variable[req][fractional_mapping]) self.model.setObjective(objective, GRB.MAXIMIZE)
def plugin_constraint_embed_all_requests(self): for req in self.requests: expr = LinExpr() expr.addTerms(1.0, self.var_embedding_decision[req]) constr_name = construct_name("embed_all_requests", req_name=req.name) self.model.addConstr(expr, GRB.EQUAL, 1.0, name=constr_name)
def polytopic_trajectory_given_modes(x0,list_of_cells,goal,eps=0,order=1): """ Description: Polytopic Trajectory Optimization with the ordered list of polytopes given This is a convex program as mode sequence is already given list_of_cells: each cell has the following attributes: A,B,c, and polytope(H,h) """ model=Model("Fixed Mode Polytopic Trajectory") T=len(list_of_cells) n,m=list_of_cells[0].B.shape q=int(order*n) x=model.addVars(range(T+1),range(n),lb=-GRB.INFINITY,ub=GRB.INFINITY,name="x") u=model.addVars(range(T),range(m),lb=-GRB.INFINITY,ub=GRB.INFINITY,name="u") G=model.addVars(range(T+1),range(n),range(q),lb=-GRB.INFINITY,ub=GRB.INFINITY,name="G") theta=model.addVars(range(T),range(m),range(q),lb=-GRB.INFINITY,ub=GRB.INFINITY,name="theta") model.update() for j in range(n): model.addConstr(x[0,j]<=x0[j,0]+eps) model.addConstr(x[0,j]>=x0[j,0]-eps) for t in range(T): print "adding constraints of t",t cell=list_of_cells[t] A,B,c,p=cell.A,cell.B,cell.c,cell.p for j in range(n): expr_x=LinExpr([(A[j,k],x[t,k]) for k in range(n)]) expr_u=LinExpr([(B[j,k],u[t,k]) for k in range(m)]) model.addConstr(x[t+1,j]==expr_x+expr_u+c[j,0]) for i in range(n): for j in range(q): expr_x=LinExpr([(A[i,k],G[t,k,j]) for k in range(n)]) expr_u=LinExpr([(B[i,k],theta[t,k,j]) for k in range(m)]) model.addConstr(G[t+1,i,j]==expr_x+expr_u) x_t=np.array([x[t,j] for j in range(n)]).reshape(n,1) u_t=np.array([u[t,j] for j in range(m)]).reshape(m,1) G_t=np.array([G[t,i,j] for i in range(n) for j in range(q)]).reshape(n,q) theta_t=np.array([theta[t,i,j] for i in range(m) for j in range(q)]).reshape(m,q) GT=sp.linalg.block_diag(G_t,theta_t) xu=np.vstack((x_t,u_t)) subset_LP(model,xu,GT,Ball(2*q),p) x_T=np.array([x[T,j] for j in range(n)]).reshape(n,1) G_T=np.array([G[T,i,j] for i in range(n) for j in range(q)]).reshape(n,q) z=zonotope(x_T,G_T) subset_zonotopes(model,z,goal) J=LinExpr([(1/(t+1.0),G[t,i,i]) for t in range(T+1) for i in range(n)]) model.setObjective(J) model.write("sadra.lp") model.setParam('TimeLimit', 150) model.optimize() x_num,G_num={},{} for t in range(T+1): x_num[t]=np.array([[x[t,j].X] for j in range(n)]).reshape(n,1) G_num[t]=np.array([[G[t,i,j].X] for i in range(n) for j in range(q)]).reshape(n,q) return (x_num,G_num)
def constraints_Ab_smaller_c(model, A, b, c): delta = {} for row in range(A.shape[0]): lhs = LinExpr() delta[row] = model.addVar(lb=0, obj=1) model.update() for k in range(A.shape[1]): lhs.add(A[row, k] * b[k, 0]) model.addConstr(lhs <= c[row, 0] + delta[row])
def re_verification_tree_extension(s, x, G, i, state_end, factor=0.99): """ This is a method to deal with numerical inaccuracies in high dimensioanl MILPs that are terminated early. Requires solving a linear program. If feasible, the computed control startegy is recomputed. If infeasible, report back, raise a flag, and abort the tree extention Inputs: state_X, state_end Output: flag, u, theta """ model = Model("verifying tree extention") G_dynamic = np.empty((s.n, s.n), dtype='object') theta = np.empty((s.m, s.n), dtype='object') u = np.empty((s.m, 1), dtype='object') x_bar = np.empty((s.n, 1), dtype='object') for row in range(s.n): for column in range(s.n): G_dynamic[row, column] = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY) for row in range(s.m): u[row, 0] = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY) for column in range(s.n): theta[row, column] = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY) for row in range(s.n): x_bar[row, 0] = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY) model.update() for row in range(s.n): for column in range(s.n): AG = LinExpr() for k in range(s.n): AG.add(s.A[i][row, k] * G[k, column]) for k in range(s.m): AG.add(s.B[i][row, k] * theta[k, column]) model.addConstr(G_dynamic[row, column] == AG * factor) for row in range(s.n): Bu = LinExpr() for k in range(s.m): Bu.add(s.B[i][row, k] * u[k, 0]) model.addConstr(x_bar[row, 0] == np.dot(s.A[i], x)[row, 0] + Bu + s.c[i][row, 0]) eps = subset_eps(model, G_dynamic, s.Pi, state_end.polytope.H, state_end.polytope.h, x_bar) subset(model, theta, s.Pi, s.F[i], s.f[i], u) model.setParam("OutputFlag", False) model.optimize() if model.Status == 2: print("eps=", valuation(eps).T) if np.amax(valuation(eps)) > 10**-3: print( "\n-" * 10, "Too large of Epsilon: %d Tree extention failed!" % np.amax(valuation(eps)), "\n-" * 10) return None else: print("Tree extention verified succesuflly!") return (valuation(u), valuation(theta), valuation(eps)) else: print("\n-" * 10, "Infeasible! Tree extention failed!", "\n-" * 10) return None
def _init_LP(self): if self._lp_inited: return logging.debug('Init LP') self.lp = LPModel('estep') self.lp.setAttr("modelSense", 1) # minimzation self.alpha = {} beta2 = {} beta3 = {} # instantiate vars logging.debug('Init LP - create vars') for a in self.author_graph: self.alpha[a] = {} for p in self.parts: self.alpha[a][p] = self.lp.addVar(lb=0.0) for a, b in self.author_graph.edges(): beta2[(a, b)] = self.lp.addVar() beta3[(a, b)] = {} for p in self.parts: beta3[(a, b)][p] = self.lp.addVar(lb=0.0) # integrate added variables into the model self.lp.update() # add constraints once during this init # alphas are indicator vars logging.debug('Init LP - indiv constraints') ones_arr = [1.0] * len(self.parts) for a in self.author_graph: self.lp.addConstr(LinExpr(ones_arr, self.alpha[a].values()), GRB.EQUAL, 1.0) # beta2 is the sum of beta3s logging.debug('Init LP - pair constraints') pt_five_array = [0.5] * len(self.parts) for a, b in self.author_graph.edges(): self.lp.addConstr(LinExpr(pt_five_array, beta3[(a, b)].values()), GRB.EQUAL, beta2[(a, b)]) for p in self.parts: self.lp.addConstr( LinExpr([1.0, -1.0], [self.alpha[a][p], self.alpha[b][p]]), GRB.LESS_EQUAL, beta3[(a, b)][p]) self.lp.addConstr( LinExpr([-1.0, 1.0], [self.alpha[a][p], self.alpha[b][p]]), GRB.LESS_EQUAL, beta3[(a, b)][p]) self.lp.update() # calculate pairwise potentials part of the objective # the optimization is to minimize negated log-likelihood = maximize the log-likelihood logging.debug('Obj func - pair potentials') s = np.log(1 - self.TAU) - np.log(self.TAU) lpcoeffs, lpvars = [], [] for a, b in self.author_graph.edges(): lpcoeffs.append(-self.author_graph[a][b]['weight'] * s) lpvars.append(beta2[(a, b)]) self.objF_pair = LinExpr(list(lpcoeffs), list(lpvars)) self._lp_inited = True logging.debug('Init LP Done')
def check_redundancy_row(H, h, ROW, atol=10**-8): model = Model("Row Redundancy Check") n = H.shape[1] x = np.empty((n, 1), dtype='object') for row in range(n): x[row, 0] = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY) model.update() for row in [r for r in range(H.shape[0]) if r != ROW]: Hx = LinExpr() for column in range(n): Hx.add(H[row, column] * x[column, 0]) model.addConstr(Hx <= h[row, 0]) J = LinExpr() for column in range(n): J.add(H[ROW, column] * x[column, 0]) model.setObjective(J, GRB.MAXIMIZE) model.setParam('OutputFlag', False) model.optimize() if model.Status == 2: if J.getValue() > h[ROW, 0] + atol: return False # It is NOT redundant else: return True # It is redudant else: return False
def create_constraints_flow_preservation_and_induction(self): for req in self.requests: for (i, j) in req.edges: for u in self.substrate.nodes: right_expr = LinExpr() if u in self.var_y[req][i]: right_expr.addTerms(1.0, self.var_y[req][i][u]) if u in self.var_y[req][j]: right_expr.addTerms(-1.0, self.var_y[req][j][u]) ij_mapping_vars = self.var_z[req][(i, j)] left_outgoing = LinExpr([ (1.0, ij_mapping_vars[sedge]) for sedge in self.substrate.out_edges[u] ]) left_incoming = LinExpr([ (1.0, ij_mapping_vars[sedge]) for sedge in self.substrate.in_edges[u] ]) left_expr = LinExpr(left_outgoing - left_incoming) constr_name = modelcreator.construct_name( "flow_pres", req_name=req.name, vedge=(i, j), snode=u ) # Matthias: changed to conform to standard naming self.model.addConstr(left_expr, GRB.EQUAL, right_expr, name=constr_name)
def break_symmetry(self): if self.verbosity > 0: print("Adding symmetry breaking constraints") if not self.x: self.add_node_variables() for i in range(self.k - 1): sym = LinExpr() for j in range(i + 1): sym.addTerms(1.0, self.x[i, j]) self.model.addConstr(sym == 1) self.model.update()
def _build_objective_linear(adj, variables, eigval, eigvec): """ Special case. Build linear objective function for QP. Used if batch size = 1 """ obj = LinExpr() eigvec_sq = np.square(eigvec) n = adj.shape[0] for i in range(n): if eigvec_sq[i] != 0: obj.addTerms(2 * eigval * eigvec_sq[i], variables[i]) return obj
def callback(model, where): if where == GRB.Callback.MIPSOL: sols = model.cbGetSolution([vars[e] for e in edges]) c_edges = [edges[i] for i in range(len(edges)) if sols[i] > 0.5] cycles = cycles_from_edges(c_edges) for cycle in cycles: len_cycle = len(cycle) if len_cycle > k: cycle_vars = [vars[(cycle[i], cycle[(i+1) % len_cycle])] for i in range(len_cycle)] ones = [1.0]*len(cycle_vars) expr = LinExpr() expr.addTerms(ones, cycle_vars) model.cbLazy(expr <= len_cycle - 1)
def point_trajectory_given_modes_and_central_traj(x_traj,list_of_cells,goal,eps=0,scale=[]): """ Description: Point Trajectory Optimization with the ordered list of polytopes given This is a convex program as mode sequence is already given list_of_cells: each cell has the following attributes: A,B,c, and polytope(H,h) """ model=Model("Fixed Mode Polytopic Trajectory") T=len(list_of_cells) n,m=list_of_cells[0].B.shape x=model.addVars(range(T+1),range(n),lb=-GRB.INFINITY,ub=GRB.INFINITY,name="x") u=model.addVars(range(T),range(m),lb=-GRB.INFINITY,ub=GRB.INFINITY,name="u") model.update() if len(scale)==0: scale=np.ones(x_traj[0].shape[0]) print "inside function epsilon is",eps for j in range(n): model.addConstr(x[0,j]<=x_traj[0][j]+eps*scale[j]) model.addConstr(x[0,j]>=x_traj[0][j]-eps*scale[j]) for t in range(T): cell=list_of_cells[t] A,B,c,_p=cell.A,cell.B,cell.c,cell.p for j in range(n): expr_x=LinExpr([(A[j,k],x[t,k]) for k in range(n)]) expr_u=LinExpr([(B[j,k],u[t,k]) for k in range(m)]) model.addConstr(x[t+1,j]==expr_x+expr_u+c[j,0]) x_t=np.array([x[t,j] for j in range(n)]).reshape(n,1) u_t=np.array([u[t,j] for j in range(m)]).reshape(m,1) xu=np.vstack((x_t,u_t)) subset_LP(model,xu,np.zeros((n+m,1)),Ball(1),_p) x_T=np.array([x[T,j] for j in range(n)]).reshape(n,1) z=zonotope(x_T,np.zeros((n,1))) subset_generic(model,z,goal) # Cost function J=QuadExpr() for t in range(T): for i in range(n): J.add(x[t,i]*x[t,i]-x[t,i]*x_traj[t][i]) model.setObjective(J) model.write("polytopic_trajectory.lp") model.setParam('TimeLimit', 150) model.optimize() x_num,u_num={},{} for t in range(T+1): x_num[t]=np.array([[x[t,j].X] for j in range(n)]) for t in range(T): u_num[t]=np.array([[u[t,i].X] for i in range(m) ]) return (x_num,u_num)
def plugin_obj_maximize_task_contingency(self): print(" ..creating objective to maximize Task Contingency") expr = LinExpr() for day in coming_days(self.next_day): for hour in hours_real(day): for tutor in Data().tutor_by_name.keys(): for task in TASKS: if self.past_plan[tutor][task][day][hour] != "": expr.addTerms( 1.0, self.schedule_entry[tutor][day][hour][task]) print(" ..final steps") self.model.setObjective(expr, GRB.MAXIMIZE)
def construct_lp_model(c, A, d): from gurobipy import Model, LinExpr, GRB # A = numpy.array (matrix) # c = numpy.array (vector) # d = numpy.array (vector) k, n = A.shape # Creation of the gurobi model m = Model("sp") # Variables x = list() for i in range(n): x.append(m.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY, name='x_%d' % i)) # Objective Function objExpr = LinExpr() for i in range(n): objExpr.add(x[i], c[i]) m.setObjective(objExpr, GRB.MAXIMIZE) # Constraints expr = {} for j in range(k): expr = LinExpr() for i in range(n): expr.add(x[i], A[j, i]) m.addConstr(expr, GRB.LESS_EQUAL, d[j]) # Update the model to add new entries m.update() return m
def add_node_variables(self): if not self.z: self.add_z_variables() n = self.G.vcount() for i in range(n): for j in range(self.k2 * self.k): self.x[i, j] = self.model.addVar(vtype=GRB.CONTINUOUS) self.model.update() for i in range(n): total_assign = LinExpr() for j in range(self.k2 * self.k): total_assign.addTerms(1.0, self.x[i, j]) self.model.addConstr(total_assign == 1.0) for e in self.G.es(): u = min(e.source, e.target) v = max(e.source, e.target) for c in range(self.k): mod_k_clashes = LinExpr() for j in range(self.k2): mod_k_clashes.addTerms(1.0, self.x[u, c + j * self.k]) mod_k_clashes.addTerms(1.0, self.x[v, c + j * self.k]) self.model.addConstr(self.y[u, v] >= mod_k_clashes - 1.0) for e in self.G.es(): u = min(e.source, e.target) v = max(e.source, e.target) for c in range(self.k2 * self.k): self.model.addConstr(self.z[u, v] >= self.x[u, c] + self.x[v, c] - 1.0) self.model.addConstr(self.x[u, c] >= self.x[v, c] + self.z[u, v] - 1.0) self.model.addConstr(self.x[v, c] >= self.x[u, c] + self.z[u, v] - 1.0)
def create_constraints_compute_edge_load(self): # track edge loads for req in self.requests: for sedge in self.substrate.substrate_edge_resources: expr_terms = [] for vedge in req.edges: vedge_demand = req.get_edge_demand(vedge) expr_terms.append(LinExpr(vedge_demand, self.var_z[req][vedge][sedge])) constr_name = modelcreator.construct_name("compute_request_edge_load", req_name=req.name, sedge=sedge) expr_terms.append(LinExpr(-1.0, self.var_request_load[req][sedge])) expr = gurobipy.quicksum(expr_terms) self.model.addConstr(expr, GRB.EQUAL, 0.0, name=constr_name)
def propagate(x, layers, grb_model, complete): n_outs = len(x[-1]) for layer_idx, layer in enumerate(layers): x[layer_idx] = [] if isinstance(layer, nn.Linear): for i in range(layer.out_features): expr = LinExpr() expr += layer.bias[i] expr += LinExpr( layer.weight[i].detach().cpu().numpy().tolist(), x[layer_idx - 1]) grb_model.update() grb_model.setObjective(expr, GRB.MINIMIZE) grb_model.optimize() lb = grb_model.objVal - EPS grb_model.setObjective(expr, GRB.MAXIMIZE) grb_model.optimize() ub = grb_model.objVal + EPS x[layer_idx] += [ grb_model.addVar(lb=lb, ub=ub, vtype=GRB.CONTINUOUS, name='x_{}_{}'.format(layer_idx, i)) ] grb_model.addConstr(expr, GRB.EQUAL, x[layer_idx][i]) n_outs = layer.out_features elif isinstance(layer, nn.ReLU): for i in range(n_outs): in_lb, in_ub = x[layer_idx - 1][i].lb, x[layer_idx - 1][i].ub x[layer_idx] += [ grb_model.addVar(in_lb, in_ub, vtype=GRB.CONTINUOUS) ] add_relu_constraints(grb_model, in_lb, in_ub, x[layer_idx - 1][i], x[layer_idx][i], complete) else: assert False grb_model.update() return x, n_outs
def run_one_compare(num_variables, num_equations, constraint_coefficent_sample=constraint_coefficent_sample, obj_coefficent_sample=obj_coefficent_sample, constraint_scalar_sample=constraint_scalar_sample): seed(0) gmodel = Model("test") variables = [lp_variable(i, gmodel) for i in range(1, num_variables + 1)] equations_str = [] for i in range(num_equations): cur_equation = [] gurobi_eq = LinExpr() for v in variables: c = round(constraint_coefficent_sample(), 3) cur_equation.append("{}{}".format(c, str(v))) gurobi_eq += c * v.get_gurobi_var() b = round(constraint_scalar_sample(), 3) equations_str.append("{}<={}".format(','.join(cur_equation), b)) gmodel.addConstr(gurobi_eq <= b, '{}'.format(i)) objective_str = '' gurobi_obj = LinExpr() for v in variables: c = round(obj_coefficent_sample(), 3) objective_str += "{}{},".format(c, v) gurobi_obj += c * v.get_gurobi_var() # Remove the last , objective_str = objective_str[:-1] gmodel.setObjective(gurobi_obj, GRB.MAXIMIZE) gmodel.optimize() our_objective, our_assignment = solve_our(equations_str, objective_str) if gmodel.status == GRB.INF_OR_UNBD: gmodel.setParam('DualReductions', 0) gmodel.optimize() print('UNBOUNDED' if gmodel.status == GRB.UNBOUNDED else 'INFEASIBLE') if our_objective == np.inf: assert gmodel.status == GRB.UNBOUNDED elif our_objective is None: assert gmodel.status == GRB.INFEASIBLE else: # IF the solution is not feasible the status would be GRB.INFEASIBLE assert gmodel.status == GRB.OPTIMAL gurobi_objective = gmodel.objVal print(gurobi_objective) for v in variables: np.testing.assert_almost_equal(our_assignment.get(v.index, 0), v.gurobi_var.x) return np.abs(gurobi_objective - our_objective) <= 10 ** -3
def _fix_embedding_variable(self, req, mapping): force_embedding_constraint = LinExpr([(1.0, self.var_embedding_decision[req])]) name = modelcreator.construct_name("force_embedding", req_name=req.name) if mapping.is_embedded: self.model.addConstr(force_embedding_constraint, GRB.EQUAL, 1.0, name=name) else: self.model.addConstr(force_embedding_constraint, GRB.EQUAL, 0.0, name=name)
def add_disjunction_rhs(self, gmodel, conds: List[LinExpr], lhs: Var, greater: bool, cond_name: str): ''' Add all the conditions in conds as a disjunction (using binary variables) :param gmodel: model to add condition to :param conds: list of rhs expressions :param lhs: lhs condition :param greater: if True them lhs >= rhs else lhs <= rhs :param cond_name: name to add in gurobi :return: ''' deltas = [] cond_delta = LinExpr() for cond in conds: deltas.append(gmodel.addVar(vtype=GRB.BINARY)) cond_delta += deltas[-1] if greater: gmodel.addConstr(lhs - 2 * SMALL >= cond - (LARGE * deltas[-1]), name=cond_name) else: # lhs_f, _ = self.get_relu_constraint(gmodel, lhs, -1, -1, False) # gmodel.addConstr(lhs_f <= cond + (LARGE * deltas[-1]), name=cond_name) gmodel.addConstr(lhs + 2 * SMALL <= cond + (LARGE * deltas[-1]), name=cond_name) # gmodel.addConstr(deltas[-1] <= 0) gmodel.addConstr(cond_delta <= len(deltas) - 1, name="{}_deltas".format(cond_name))
def e_step(self): logging.debug('E-Step') if not self._lp_inited: self._init_LP() logging.debug('Obj func - indiv potentials') # individual potentials lpcoeffs, lpvars = [], [] for a in self.author_graph: for p in self.parts: lpcoeffs.append(-self.log_phi(a, p)) lpvars.append(self.alpha[a][p]) objF_indiv = LinExpr(lpcoeffs, lpvars) self.lp.setObjective(objF_indiv + self.objF_pair) # solve the LP logging.debug('Solving the LP') self.lp.optimize() logging.debug('Solving the LP Done') # hard partitions for nodes (authors) for a in self.author_graph: self.partition[a] = np.argmax( [self.alpha[a][p].X for p in self.parts]) logging.debug('E-Step Done')
def subtourelim(mdl,where): if where == GRB.callback.MIPSOL: active_arcs = [] solutions = mdl.cbGetSolution(mdl._x) for i, j in mdl._A: for k in mdl._K: if round(solutions[i, j, k]) == 1: active_arcs.append([i, j, k]) active_arcs = np.vstack(active_arcs) tours = mdl._subtour(mdl._K, active_arcs) # add lazy constraints for k in tours.keys(): if len(tours[k]) > 1: for tour in tours[k]: S = np.unique(tour) expr = LinExpr() for i in S: if i != mdl._V[-1]: for j in S: if j != i and j != mdl._V[0]: expr += mdl._x[i, j, k] # expr = quicksum(mdl._x[i, j, k] for i in S for j in S if j != i if i != mdl._V[-1] or j != mdl._V[0]) mdl.cbLazy(expr <= len(S) - 1)
def two_cycle(A, C, gap): """ Solve high-vertex dense graphs by reduction to weighted matching ILP. """ _ = '*' m = Model() m.modelsense = GRB.MAXIMIZE m.params.mipgap = gap m.params.timelimit = 60 * 60 n = A.shape[0] vars = {} edges = tuplelist() # model as undirected graph for i in range(n): for j in range(i+1, n): if A[i, j] == 1 and A[j, i] == 1: e = (i, j) edges.append(e) w_i = 2 if i in C else 1 w_j = 2 if j in C else 1 w = w_i + w_j var = m.addVar(vtype=GRB.BINARY, obj=w) vars[e] = var m.update() # 2 cycle constraint <=> undirected flow <= 1 for i in range(n): lhs = LinExpr() lhs_vars = [vars[e] for e in chain(edges.select(i, _), edges.select(_, i))] ones = [1.0]*len(lhs_vars) lhs.addTerms(ones, lhs_vars) m.addConstr(lhs <= 1) m.optimize() m.update() cycles = [list(e) for e in edges if vars[e].x == 1.0] return cycles, m.objval
def check_feasability_ILP(exams_to_schedule, period, data, verbose=False): # More precise but by far to slow compared to heuristic r = data['r'] T = data['T'] s = data['s'] z = {} model = Model("RoomFeasability") # z[i,k] = if exam i is written in room k for k in range(r): # print k, period if T[k][period] == 1: for i in exams_to_schedule: z[i, k] = model.addVar(vtype=GRB.BINARY, name="z_%s_%s" % (i, k)) model.update() # Building constraints... # c1: seats for all students for i in exams_to_schedule: expr = LinExpr() for k in range(r): if T[k][period] == 1: expr.addTerms(1, z[i, k]) model.addConstr(expr >= s[i], "c1") # c2: only one exam per room for k in range(r): if T[k][period] == 1: expr = LinExpr() for i in exams_to_schedule: expr.addTerms(1, z[i, k]) model.addConstr(expr <= 1, "c2") model.setObjective(0, GRB.MINIMIZE) if not verbose: model.params.OutputFlag = 0 model.params.heuristics = 0 model.params.PrePasses = 1 model.optimize() # return best room schedule try: return model.objval except GurobiError: logging.warning('check_feasability_ILP: model has no objVal') return None
def _sensitivity_analysis_for_tardiness(z, CT, D): m = Model("model_for_sensitivity_analysis_for_tardiness") m.setParam('OutputFlag', False) # m.params.IntFeasTol = 1e-7 DT = {} TD = {} for j in range(D.project_n): ## Project Tadeness,construction completion time DT[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="DT_%d" % j) TD[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="TD_%d" % j) DT[-1] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="DT_-1") m.update(); #### Add Constraint #### ## Constrain 2: project complete data>due data ## # equation 17 for j in range(D.project_n): m.addConstr(DT[j] - TD[j], GRB.LESS_EQUAL, D.DD[j], name="constraint_2_project_%d" % j) ## Constraint 13 # equation 12 for j in range(D.project_n): m.addConstr(DT[j], GRB.GREATER_EQUAL, CT[j] + D.review_duration[j], name="constraint_13_project_%d" % j) ## Constraint 14 # equation 13 for i in range(-1, D.project_n): for j in range(D.project_n): if i != j: m.addConstr(DT[j], GRB.GREATER_EQUAL, DT[i] - D.M * (1 - z[i, j]) + D.review_duration[j], name="constraint_14_project_%d_project_%d" % (i, j)) m.update() # Set optimization objective - minimize sum of expr = LinExpr() for j in range(D.project_n): expr.add(D.w[j] * TD[j]) m.setObjective(expr, GRB.MINIMIZE) m.update() # m.params.presolve = 1 m.update() m.optimize() # _logger.info("mm binding info:") sj = {} for c in m.getConstrs(): if c.ConstrName.startswith('constraint_13'): j = int(c.ConstrName.split('_')[-1]) # if c.Pi != 0: # sj[j] = 1 # _logger.info('%s binding Pi:%.4g' % (c.ConstrName, c.Pi)) # pass # else: # sj[j] = 0 # _logger.info('%s not binding Pi:%.4g' % (c.ConstrName, c.Pi)) # pass sj[j] = c.Pi return sj
def cycle_milp(A, C, k, gap): n = A.shape[0] t_0 = time.clock() _ = '*' m = Model() m.modelsense = GRB.MAXIMIZE m.params.mipgap = gap cycles = [] vars = [] cycles_grouped = [[] for i in range(n)] vars_grouped = [[] for i in range(n)] print('[%.1f] Generating variables...' % (time.clock() - t_0)) print('i = ', end='') for i in range(n): for cycle in dfs_cycles(i, A, k): w = sum([2 if j in C else 1 for j in cycle]) var = m.addVar(vtype=GRB.BINARY, obj=w) vars.append(var) cycles.append(cycle) cycles_grouped[i].append(cycle) vars_grouped[i].append(var) for j in cycle: if j > i: vars_grouped[j].append(var) cycles_grouped[j].append(cycle) if (i + 1) % 10 == 0: print(i + 1) m.update() print('[%.1f] Generated variables...' % (time.clock() - t_0)) print('[%.1f] Generating constraints...' % (time.clock() - t_0)) for i in range(n): vars_i = vars_grouped[i] lhs = LinExpr() ones = [1.0]*len(vars_i) lhs.addTerms(ones, vars_i) m.addConstr(lhs <= 1.0) print('[%.1f] Generated constraints...' % (time.clock() - t_0)) print('[%.1f] Begin Optimizing %d vertex %d cycle model' % (time.clock() - t_0, n, len(cycles))) m.update() m.optimize() m.update() print('[%.1f] Finished Optimizing' % (time.clock() - t_0)) print('[%.1f] Building cycles...' % (time.clock() - t_0)) final_cycles = [] for i in range(len(vars)): var = vars[i] if var.x == 1.0: cycle = cycles[i] final_cycles.append(cycle) print('[%.1f] Finished building cycles' % (time.clock() - t_0)) return final_cycles, m.objval
def construct_model(self): self.m = Model('mip1.log') # Create model variables self.solution_matrix = {(st, c, se): self.m.addVar(vtype=GRB.BINARY, name='{}_{}_{}'.format(st, c, se)) for st in self.student_ids for c in self.course_ids for se in self.semester_ids} self.m.update() # Constraint #1: Class availability and size for course in self.course_ids: for semester in self.semester_ids: class_size_expr = LinExpr() for student in self.student_ids: class_size_expr.add(self.solution_matrix[student, course, semester]) if not self.is_course_offered(course, semester): self.m.addConstr(class_size_expr, GRB.EQUAL, 0, 'max_size_{}_{}'.format(course, semester)) else: self.m.addConstr(class_size_expr, GRB.LESS_EQUAL, 300, 'max_size_{}_{}'.format(course, semester)) # Constraint #2: No classes with pre-requisites in first semester for student in self.student_ids: for prereq in self.dependencies: first_semester_prereq_expr = LinExpr() first_semester_prereq_expr.add(self.solution_matrix[student, prereq[1], 1]) self.m.addConstr(first_semester_prereq_expr, GRB.EQUAL, 0, 'fs_prereq_{}_{}'.format(student, prereq)) # Constraint #3: Max course load per student per semester for student in self.student_ids: for semester in self.semester_ids: max_load_expr = LinExpr() for course in self.course_ids: max_load_expr.add(self.solution_matrix[student, course, semester]) self.m.addConstr(max_load_expr, GRB.LESS_EQUAL, 2, 'max_load_{}_{}'.format(student, semester)) # Constraint #4: Course demand for student for student in self.student_ids: for course in self.course_ids: if any([self.student_demand[student, course, semester] for semester in self.semester_ids]): demand_expr = LinExpr() for semester in self.semester_ids: demand_expr.add(self.solution_matrix[student, course, semester]) self.m.addConstr(demand_expr, GRB.EQUAL, 1, 'student_demand_{}_{}'.format(student, course)) # Constraint #5: Prerequisite courses for student in self.student_ids: for prereq in self.dependencies: prereq_expr = LinExpr() for semester in sorted(self.semester_ids)[:-1]: prereq_expr.add(self.solution_matrix[student, prereq[0], semester], 1.0) prereq_expr.add(self.solution_matrix[student, prereq[1], semester + 1], -1.0) self.m.addConstr(prereq_expr, GRB.GREATER_EQUAL, 0, 'prereq_{}_{}_{}'.format(student, prereq[0], prereq[1])) # Create the objective objective_expr = LinExpr() for student in self.student_ids: for course in self.course_ids: for semester in self.semester_ids: if self.student_demand[student, course, semester]: objective_expr.add(1 - self.solution_matrix[student, course, semester]) self.m.setObjective(objective_expr, GRB.MINIMIZE)
def build_model(data, n_cliques = 0, verbose = True): # Load Data Format n = data['n'] r = data['r'] p = data['p'] s = data['s'] c = data['c'] h = data['h'] w = data['w'] location = data['location'] conflicts = data['conflicts'] locking_times = data['locking_times'] T = data['T'] similarp = data['similarp'] model = Model("ExaminationScheduling") if verbose: print("Building variables...") # x[i,k,l] = 1 if exam i is at time l in room k x = {} for k in range(r): for l in range(p): if T[k][l] == 1: for i in range(n): if location[k] in w[i]: x[i,k,l] = model.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (i,k,l)) # y[i,l] = 1 if exam i is at time l y = {} for i in range(n): for l in range(p): y[i, l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l)) # integrate new variables model.update() # for i in range(p+5): # for l in range(i-5): # y[i, l].setAttr("BranchPriority", s[i]) # model.update() start = timeit.default_timer() # not very readable but same constraints as in GurbiLinear_v_10: speeded up model building by 2 for small problems (~400 exams) and more for huger problem ~1500 exams if verbose: print("Building constraints...") s_sorted = sorted(range(len(c)), key = lambda k: c[k]) obj = LinExpr() sumconflicts = {} maxrooms = {} for i in range(n): sumconflicts[i] = sum(conflicts[i]) if s[i] <= 50: maxrooms[i] = 1 elif s[i] <= 100: maxrooms[i] = 2 elif s[i] <= 400: maxrooms[i] = 7 elif s[i] <= 700: maxrooms[i] = 9 else: maxrooms[i] = 12 c2 = LinExpr() c4 = LinExpr() for l in range(p): c1 = LinExpr() c1 = LinExpr() c3 = LinExpr() for k in range(r): if T[k][l] == 1 and location[k] in w[i]: # print k, c[k], 1-(1/(pow(2,s_sorted.index(k)))) obj.addTerms( 1-(1/(pow(2,s_sorted.index(k)))) , x[i, k, l]) c1.addTerms(1, x[i,k,l]) c4.addTerms(c[k],x[i,k,l]) model.addConstr(c1 <= maxrooms[i]* y[i,l], "c1a") model.addConstr(c1 >= y[i,l], "C1b") for j in conflicts[i]: c3.addTerms(1,y[j,l]) model.addConstr(c3 <= (1 - y[i,l])*sumconflicts[i], "c3") c2.addTerms(1,y[i,l]) model.addConstr( c2 == 1 , "c2") model.addConstr(c4 >= s[i], "c4") sumrooms = {} for l in range(p): sumrooms[l] = 0 cover_inequalities = LinExpr() for k in range(r): if T[k][l] == 1: sumrooms[l] += 1 c5 = LinExpr() for i in range(n): if location[k] in w[i]: c5.addTerms(1,x[i,k,l]) model.addConstr( c5 <= 1, "c5") cover_inequalities += c5 model.addConstr(cover_inequalities <= sumrooms[l], "cover_inequalities") # Break Symmetry # First only use small rooms in a period if all bigger rooms are already used # TODO Do for every location if similarp[0] >= 0: for i in range(i-1): for l in range(p): model.addConstr(y[i,l] <= quicksum( y[i+1,sim] for sim in similarp), "s1") # for l in range(p): # for index, k in enumerate(s_sorted): # #print k, index # s1 = LinExpr() # if index < len(s_sorted)-1: # if T[k][l] == 1: # for k2 in range(r-index): # if T[s_sorted[index+k2]][l] == 1: # for i in range(n): # # if location[k] in w[i]: # s1.addTerms([1,-1], [x[i,k,l], x[i,s_sorted[index+k2],l]]) # break # model.addConstr( s1 <= 0 , "s1") #if p <= n: # for l in range(p): # model.addConstr( quicksum(y[l,i] for i in range(l)) >= 1, "s1") # for l in range(p-1): # for i in range(n): # model.addConstr( y[i,l] - quicksum(y[i,l+1] for i in range(l,n)) <= 0, "l1") model.setObjective( obj, GRB.MINIMIZE) print timeit.default_timer()-start if verbose: print("All constrained and objective built - OK") if not verbose: model.params.OutputFlag = 0 # Set Parameters #print("Setting Parameters...") # max presolve agressivity #model.params.presolve = 2 # Choosing root method 3= concurrent = run barrier and dual simplex in parallel model.params.method = 3 #model.params.MIPFocus = 1 model.params.OutputFlag = 1 #model.params.MIPFocus = 1 # cuts #model.params.cuts = 0 #model.params.coverCuts = 2 #model.params.CutPasses = 4 # heuristics #model.params.heuristics = 0 #model.params.symmetry = 2 # # Tune the model # model.tune() # if model.tuneResultCount > 0: # # Load the best tuned parameters into the model # model.getTuneResult(0) # # Write tuned parameters to a file # model.write('tune1.prm') # return return(model)
def _objective_function_for_delta_weight(D, delta_weight): m = Model("model_for_supplier_assignment") x = {} q = {} for (r, s, p) in D.supplier_project_shipping: # i resource, j supplier, k project x[r, s, p] = m.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (r, s, p)) q[r, s, p] = m.addVar(vtype=GRB.CONTINUOUS, name="q_%s_%s_%s" % (r, s, p)) AT = {} for j in range(D.project_n): for k in sorted([r for r, p in D.resource_project_demand if p == D.project_list[j]]): AT[j, k] = m.addVar(vtype=GRB.CONTINUOUS, name="AT_%s_%s" % (j, k)) m.update() ## define constraints # constraint 20(3) for (r, s) in D.resource_supplier_capacity: m.addConstr(quicksum(q[r, s, D.project_list[j]] for j in range(D.project_n)), GRB.LESS_EQUAL, D.resource_supplier_capacity[r, s], name="constraint_3_resource_%s_supplier_%s" % (r, s)) # constraint 21(4) 23(6) for (r, p) in D.resource_project_demand: m.addConstr(quicksum(x[r, i, p] for i in D.resource_supplier_list[r]), GRB.EQUAL, 1, name="constraint_6_resource_%s_project_%s" % (r, p)) m.addConstr(quicksum(q[r, i, p] for i in D.resource_supplier_list[r]), GRB.GREATER_EQUAL, D.resource_project_demand[r, p], name="constraint_4_resource_%s_project_%s" % (r, p)) # constraint 22(5) for (i, j, k) in q: # i resource, j supplier, k project m.addConstr(q[i, j, k], GRB.LESS_EQUAL, D.M * x[i, j, k], name="constraint_5_resource_%s_supplier_%s_project_%s" % (i, j, k)) # constraint 7 expr = LinExpr() for (i, j, k) in q: expr = expr + D.c[i, j, k] * q[i, j, k] m.addConstr(expr, GRB.LESS_EQUAL, D.B, name="constraint_7") # constraint 8 for j in range(D.project_n): p = D.project_list[j] project_resources = sorted([r for (r, p_) in D.resource_project_demand.keys() if p_ == p]) for r in project_resources: suppliers = D.resource_supplier_list[r] # print(list(D.supplier_project_shipping.keys())[:10]) # print(D.supplier_project_shipping['NK0g77', 'S1671', 'P1']) # print(list(x.keys())[:10]) # print(x['NK0g77', 'S1671', 'P1']) m.addConstr( quicksum( x[r, s, p] * (D.resource_supplier_release_time[r, s] + D.supplier_project_shipping[r, s, p]) for s in suppliers), GRB.LESS_EQUAL, AT[j, r], name="constraint_8_project_%d_resource_%s_deliver" % (j, r)) m.update() expr = LinExpr() for j in range(D.project_n): for r in sorted([r for (r, p_) in D.resource_project_demand.keys() if p_ == p]): expr.add(delta_weight[_delta_project_idx[j, r]] * AT[j, r]) m.setObjective(expr, GRB.MINIMIZE) m.update() ########################################## m.params.presolve = 1 m.update() # Solve # m.params.presolve=0 m.optimize() print(m.Status) X_ = {} for (i, j, k) in D.supplier_project_shipping: v = m.getVarByName("x_%s_%s_%s" % (i, j, k)) print(v) if v.X == 1: X_[i, j, k] = 1 AT_ = {} for j, r in AT: val = AT[j, r].X if val > 0: AT_[j, r] = val return -_objective_function_for_tardiness(X_, AT_, D),
def _objective_function_for_delta_weight(D, delta_weight, d1, d2): global _time_limit_per_model, _round, _pr_dataset, _tardiness_objective_dataset m = Model("model_for_supplier_assignment") m.setParam('OutputFlag', False) m.params.timelimit = _time_limit_per_model # m.params.IntFeasTol = 1e-7 x = {} q = {} for (r, s, p) in D.supplier_project_shipping: x[r, s, p] = m.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (r, s, p)) q[r, s, p] = m.addVar(vtype=GRB.CONTINUOUS, name="q_%s_%s_%s" % (r, s, p)) AT = {} for j in range(D.project_n): for k in [r for r, p in D.resource_project_demand if p == D.project_list[j]]: AT[j, k] = m.addVar(vtype=GRB.CONTINUOUS, name="AT_%s_%s" % (j, k)) m.update() ## define constraints # equation 2 for (r, s) in D.resource_supplier_capacity: m.addConstr(quicksum(q[r, s, D.project_list[j]] for j in range(D.project_n)), GRB.LESS_EQUAL, D.resource_supplier_capacity[r, s], name="constraint_3_resource_%s_supplier_%s" % (r, s)) # constraint 21(4) 23(6) for (r, p) in D.resource_project_demand: # equation 5 m.addConstr(quicksum(x[r, i, p] for i in D.resource_supplier_list[r]), GRB.EQUAL, 1, name="constraint_6_resource_%s_project_%s" % (r, p)) # equation 3 m.addConstr(quicksum(q[r, i, p] for i in D.resource_supplier_list[r]), GRB.GREATER_EQUAL, D.resource_project_demand[r, p], name="constraint_4_resource_%s_project_%s" % (r, p)) # constraint 22(5) for (i, j, k) in q: # i resource, j supplier, k project # equation 4 m.addConstr(q[i, j, k], GRB.LESS_EQUAL, D.M * x[i, j, k], name="constraint_5_resource_%s_supplier_%s_project_%s" % (i, j, k)) # constraint 7 shipping_cost_expr = LinExpr() for (i, j, k) in q: shipping_cost_expr.addTerms(D.c[i, j, k], q[i, j, k]) # equation 6 m.addConstr(shipping_cost_expr, GRB.LESS_EQUAL, D.B, name="constraint_7") # constraint 8 # equation 26 for j in range(D.project_n): p = D.project_list[j] project_resources = [r for (r, p_) in D.resource_project_demand.keys() if p_ == p] for r in project_resources: suppliers = D.resource_supplier_list[r] m.addConstr( quicksum( x[r, s, p] * (D.resource_supplier_release_time[r, s] + D.supplier_project_shipping[r, s, p]) for s in suppliers), GRB.LESS_EQUAL, AT[j, r], name="constraint_8_project_%d_resource_%s_deliver" % (j, r)) m.update() expr = LinExpr() for j in range(D.project_n): p = D.project_list[j] for r in [r for (r, p_) in D.resource_project_demand.keys() if p_ == p]: expr.add(delta_weight[j, r] * AT[j, r]) m.setObjective(expr, GRB.MINIMIZE) m.update() ########################################## # m.params.presolve = 1 m.update() # Solve # m.params.presolve=0 m.optimize() _exit_if_infeasible(m) m.write(join(_result_output_path, "round_%d_supplier_assign.lp" % _round)) m.write(join(_result_output_path, "round_%d_supplier_assign.sol" % _round)) with open(join(log_output_path, 'shipping_cost.txt'), 'a') as fout: fout.write('shipping cost: %f\n' % shipping_cost_expr.getValue()) _logger.info('shipping cost: %f' % shipping_cost_expr.getValue()) print('status', m.status) # m.write(join(_output_path, 'delta_weight.sol')) # m.write(join(_output_path, 'delta_weight.lp')) X_ = {} for (i, j, k) in D.supplier_project_shipping: v = m.getVarByName("x_%s_%s_%s" % (i, j, k)) if v.X == 1: X_[i, j, k] = 1 AT_ = {} for j, r in AT: val = AT[j, r].X if val > 0: AT_[j, r] = val tardiness_obj_val, skj, sj = _objective_function_for_tardiness(X_, AT_, D) new_delta_weight = {} # delta_weight_keys = list(delta_weight.keys()) # delta_weight_keys.sort(key=lambda x: x[1]) # delta_weight_keys.sort(key=lambda x: x[0]) for j, r in delta_weight.keys(): new_delta_weight[j, r] = delta_weight[j, r] * (1 + d1 * (d2 + sj.get(j, 0)) * skj.get((j, r), 0)) # print('j', type(j), j) # print('r', type(r), r) # print('previous weight', type(delta_weight[j, r]), delta_weight[j, r]) # print('d1', type(d1), d1) # print('d2', type(d2), d2) # print('sj', type(sj.get(j, 0)), sj.get(j, 0)) # print('skj', type(skj.get((j, r))), skj.get((j, r))) # print('new weight', type(new_delta_weight[j, r]), new_delta_weight[j, r]) _logger.info( 'r[%d,%s] = %f *(1+%f*(%f+%f)*%f) = %f' % ( j, r, delta_weight[j, r], d1, d2, sj.get(j, 0), skj.get((j, r), 0), new_delta_weight[j, r])) # new_delta_weight[j, r] = 1 _normalize(new_delta_weight) for j, r in new_delta_weight.keys(): # _logger.info('j:' + str(j)) # _logger.info('r:' + str(r)) # _logger.info(str([_round, j, r, new_delta_weight[j, r]])) _weight_dataset.loc[_weight_dataset.shape[0]] = [_round, j, r, new_delta_weight[j, r]] for j in range(D.project_n): _pr_dataset.loc[_pr_dataset.shape[0]] = [_round, j, sj.get(j, 0)] _tardiness_objective_dataset.loc[_tardiness_objective_dataset.shape[0]] = [_round, tardiness_obj_val] return new_delta_weight
def _sensitivity_for_constraints(AT, j, project, y_, project_activity, M): global _round, _pa_dataset m = Model("SingleProject_%d_for_sensitivity" % j) m.setParam('OutputFlag', False) # m.params.IntFeasTol = 1e-7 ## Project complete data,Project Tadeness,construction completion time CT = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="CT_%d" % j) ## Activity start time ST = {} project_activities = project_activity[project] for row in project_activities.nodes(): ST[row] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="ST_%d_%s" % (j, row)) ## Review sequence z_ij ## move to annealing objective function m.update() ## Constrain 8: activity starting constrain # equation 20 for a in project_activities.nodes(): for r in project_activities.node[a]['resources']: m.addConstr(ST[a], GRB.GREATER_EQUAL, AT[j, r], name="constraint_8_project_%d_activity_%s_resource_%s" % (j, a, r)) ## Constrain 9 activity sequence constrain # equation 21 for row1, row2 in project_activities.edges(): m.addConstr(ST[row1] + project_activities.node[row1]['duration'], GRB.LESS_EQUAL, ST[row2], name="constraint_9_project_%d_activity_%s_activity_%s" % (j, row1, row2)) ## Constrain 10,11 for row1 in project_activities.nodes(): for row2 in project_activities.nodes(): if row1 != row2 and len(list( set(project_activities.node[row1]['rk_resources']).intersection( project_activities.node[row2]['rk_resources']))) > 0: # equation 22 m.addConstr(ST[row1] + project_activities.node[row1]['duration'] - M * ( 1 - _get_y_for_activities(y_, row1, row2)), GRB.LESS_EQUAL, ST[row2], name="constraint_10_project_%d_activity_%s_activity_%s" % (j, row1, row2)) # equation 23 m.addConstr( ST[row2] + project_activities.node[row2]['duration'] - M * _get_y_for_activities(y_, row1, row2), GRB.LESS_EQUAL, ST[row1], name="constraint_11_project_%d_activity_%s_activity_%s" % (j, row1, row2)) # m.addConstr(y[j,row1,row2]+y[j,row2,row1],GRB.LESS_EQUAL,1) ## Constrain 12 # equation 24 for row in project_activities.nodes(): m.addConstr(CT, GRB.GREATER_EQUAL, ST[row] + project_activities.node[row]['duration'], name="constraint_12_project_%d_activity_%s" % (j, row)) m.update() # Set optimization objective - minimize completion time expr = LinExpr() expr.add(CT) m.setObjective(expr, GRB.MINIMIZE) m.update() ########################################## # m.params.presolve = 1 m.update() m.setParam(GRB.Param.Method, 0) m.update() # Solve # m.params.presolve=0 m.optimize() _skja = {} for c in m.getConstrs(): if c.ConstrName.startswith('constraint_8_project'): splits = c.ConstrName.split('_') r = splits[7] if r not in _skja: _skja[r] = [] _skja[r].append(c.Pi) # if c.Pi != 0: # logging.debug('project %d binding resource:%s Pi:%.4g' % (j, splits[-1], c.Pi)) # else: # logging.debug('project %d not binding resource:%s Pi:%.4g' % (j, splits[-1], c.Pi)) _pa_dataset.loc[_pa_dataset.shape[0]] = [_round, j, r, splits[5], c.Pi] _skj = {} for r in _skja: _skj[j, r] = max(_skja[r]) _pa_max_dataset.loc[_pa_max_dataset.shape[0]] = [_round, j, r, max(_skja[r])] return _skj
def __objective_function(self, x, q, p_changed=None): m = Model("Overall_Model") if p_changed is not None: j0 = self.project_list.index(p_changed) CT = self.last_CT CT[j0] = self.optmize_single_project(x, j0, self.project_list, self.project_activity, self.resource_supplier_list, self.resource_supplier_release_time, self.supplier_project_shipping, self.M, self.output_dir) else: CT = {} CT_ASYNC = dict() for j in range(self.project_n): ## solve individual model get Project complete date CT_ASYNC[j] = self.pool.apply_async(HeuristicParallelModel.optmize_single_project, (x, j, self.project_list, self.project_activity, self.resource_supplier_list, self.resource_supplier_release_time, self.supplier_project_shipping, self.M, self.output_dir)) for j in range(self.project_n): CT[j] = CT_ASYNC[j].get() self.last_CT = deepcopy(CT) DT = {} TD = {} for j in range(self.project_n): ## Project Tadeness,construction completion time DT[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(DT%d)" % j) TD[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(TD%d)" % j) DT[-1] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(DT-1)") ## Review Sequence z_ij z = {} for i in range(self.project_n): for j in range(self.project_n): if i != j: z[i, j] = m.addVar(obj=0, vtype=GRB.BINARY, name="(z%d,%d)" % (i, j)) for j in range(self.project_n): z[-1, j] = m.addVar(obj=0, vtype=GRB.BINARY, name="(z%d,%d)" % (-1, j)) m.update(); #### Add Constraint #### ## Constrain 2: project complete data>due data ## for j in range(self.project_n): m.addConstr(DT[j] - TD[j], GRB.LESS_EQUAL, self.DD[j], name="constraint_2_project_%d" % j) ## Constraint 13 for j in range(self.project_n): m.addConstr(DT[j], GRB.GREATER_EQUAL, CT[j] + self.review_duration[j], name="constraint_13_project_%d" % j) ## Constraint 14 for i in range(-1, self.project_n): for j in range(self.project_n): if i != j: m.addConstr(DT[j], GRB.GREATER_EQUAL, DT[i] - self.M * (1 - z[i, j]) + self.review_duration[j], name="constraint_14_project_%d_project_%d" % (i, j)) ## Constrain 15 for j in range(self.project_n): m.addConstr(quicksum(z[i, j] for i in range(-1, self.project_n) if i != j), GRB.EQUAL, 1, name="constraint_15_project_%d" % j) ## Constrain 16 m.addConstr(quicksum(z[-1, j] for j in range(self.project_n)), GRB.EQUAL, 1, name="constraint_16") ## Constrain 17 for i in range(self.project_n): m.addConstr(quicksum(z[i, j] for j in range(self.project_n) if j != i), GRB.LESS_EQUAL, 1, name="constraint_17_project_%d" % i) m.update() # Set optimization objective - minimize sum of expr = LinExpr() for j in range(self.project_n): expr.add(self.w[j] * TD[j]) m.setObjective(expr, GRB.MINIMIZE) m.update() m.params.presolve = 1 m.update() m.optimize() m.write(join(self.output_dir, "heuristic_whole.lp")) m.write(join(self.output_dir, "heuristic_whole.sol")) self.obj_value_trace.append(m.objVal) return m.objVal, argmax([self.w[j] * TD[j].X for j in range(self.project_n)])
def optimize_single_project(AT, j, project_list, project_activity, M): global _time_limit_per_model m = Model("SingleProject_%d" % j) m.params.timelimit = _time_limit_per_model # m.setParam('OutputFlag', False) # m.params.IntFeasTol = 1e-7 #### Create variables #### project = project_list[j] ## Project complete data,Project Tadeness,construction completion time CT = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="CT_%d" % j) ## Activity start time ST = {} project_activities = project_activity[project] for row in project_activities.nodes(): ST[row] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="ST_%d_%s" % (j, row)) ## Review sequence z_ij ## move to annealing objective function # y y = {} for activity_i in project_activities.nodes(): for activity_j in project_activities.nodes(): if activity_i != activity_j and len(list( set(project_activities.node[activity_i]['rk_resources']).intersection( project_activities.node[activity_j]['rk_resources']))) > 0: y[activity_i, activity_j] = m.addVar(obj=0, vtype=GRB.BINARY, name="y_%d_%s_%s" % (j, activity_i, activity_j)) m.update() ## Constrain 8: activity starting constrain # equation 20 for a in project_activities.nodes(): for r in project_activities.node[a]['resources']: m.addConstr(AT[j, r], GRB.LESS_EQUAL, ST[a], name="constraint_8_project_%d_activity_%s_resource_%s" % (j, a, r)) ## Constrain 9 activity sequence constrain # equation 21 for row1, row2 in project_activities.edges(): m.addConstr(ST[row1] + project_activities.node[row1]['duration'], GRB.LESS_EQUAL, ST[row2], name="constraint_9_project_%d_activity_%s_activity_%s" % (j, row1, row2)) ## Constrain 10,11 for row1 in project_activities.nodes(): for row2 in project_activities.nodes(): if row1 != row2 and len(list( set(project_activities.node[row1]['rk_resources']).intersection( project_activities.node[row2]['rk_resources']))) > 0: # equation 22 m.addConstr(ST[row1] + project_activities.node[row1]['duration'] - M * ( 1 - y[row1, row2]), GRB.LESS_EQUAL, ST[row2], name="constraint_10_project_%d_activity_%s_activity_%s" % (j, row1, row2)) # equation 23 m.addConstr( ST[row2] + project_activities.node[row2]['duration'] - M * (y[row1, row2]), GRB.LESS_EQUAL, ST[row1], name="constraint_11_project_%d_activity_%s_activity_%s" % (j, row1, row2)) # m.addConstr(y[j,row1,row2]+y[j,row2,row1],GRB.LESS_EQUAL,1) ## Constrain 12 # equation 24 for row in project_activities.nodes(): m.addConstr(CT, GRB.GREATER_EQUAL, ST[row] + project_activities.node[row]['duration'], name="constraint_12_project_%d_activity_%s" % (j, row)) m.update() # Set optimization objective - minimize completion time expr = LinExpr() expr.add(CT) m.setObjective(expr, GRB.MINIMIZE) m.update() ########################################## # m.params.presolve = 1 m.update() # Solve # m.params.presolve=0 m.optimize() m.write(join(_result_output_path, "round_%d_optimize_single_project_%d.lp" % (_round, j))) m.write(join(_result_output_path, "round_%d_optimize_single_project_%d.sol" % (_round, j))) # _logger.info("project %d with optimalVal %r" % (j, m.objVal)) # m.fixedModel() skj = _sensitivity_for_constraints(AT, j, project, y, project_activity, M) # for c in m.getConstrs(): # if c.ConstrName.startswith('constraint_8_project'): # splits = c.ConstrName.split('_') # if c.Pi == 0: # _logger.info('project %d bind resource:%s Slack:%.4g'%(j, splits[-1],c.Pi)) # break # else: # _logger.info('project %d not bind'%j) _single_project_objective_dataset.loc[_single_project_objective_dataset.shape[0]] = [_round, j, m.objVal] return m.objVal, skj
def build_model(data, n_cliques = 0, verbose = True): # Load Data Format n = data['n'] r = data['r'] p = data['p'] s = data['s'] c = data['c'] h = data['h'] w = data['w'] location = data['location'] conflicts = data['conflicts'] locking_times = data['locking_times'] T = data['T'] model = Model("ExaminationScheduling") if verbose: print("Building variables...") # x[i,k,l] = 1 if exam i is at time l in room k x = {} for k in range(r): for l in range(p): if T[k][l] == 1: for i in range(n): if location[k] in w[i]: x[i,k,l] = model.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (i,k,l)) # y[i,l] = 1 if exam i is at time l y = {} for i in range(n): for l in range(p): y[i, l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l)) # integrate new variables model.update() start = timeit.default_timer() # not very readable but same constraints as in GurbiLinear_v_10: speeded up model building by 2 for small problems (~400 exams) and more for huger problem ~1500 exams if verbose: print("Building constraints...") obj = LinExpr() sumconflicts = {} maxrooms = {} for i in range(n): sumconflicts[i] = sum(conflicts[i]) if s[i] <= 50: maxrooms[i] = 1 elif s[i] <= 100: maxrooms[i] = 2 elif s[i] <= 400: maxrooms[i] = 7 elif s[i] <= 700: maxrooms[i] = 9 else: maxrooms[i] = 12 c2 = LinExpr() c4 = LinExpr() for l in range(p): c1 = LinExpr() c1 = LinExpr() c3 = LinExpr() for k in range(r): if T[k][l] == 1 and location[k] in w[i]: c1.addTerms(1, x[i, k, l]) c4.addTerms(c[k],x[i,k,l]) obj += c1 model.addConstr(c1 <= maxrooms[i]* y[i,l], "c1a") model.addConstr(c1 >= y[i,l], "C1b") for j in conflicts[i]: c3.addTerms(1,y[j,l]) if not conflicts[i]: model.addConstr(c3 <= (1 - y[i,l])*sumconflicts[i], "c3") c2.addTerms(1,y[i,l]) model.addConstr( c2 == 1 , "c2") model.addConstr(c4 >= s[i], "c4") sumrooms = {} for l in range(p): sumrooms[l] = 0 cover_inequalities = LinExpr() for k in range(r): if T[k][l] == 1: sumrooms[l] += 1 c5 = LinExpr() for i in range(n): if location[k] in w[i]: c5.addTerms(1,x[i,k,l]) model.addConstr( c5 <= 1, "c5") cover_inequalities += c5 model.addConstr(cover_inequalities <= sumrooms[l], "cover_inequalities") #lexicographic ordering in all periods for exams and rooms for l in range(p): for i in range(1,n): for k in range(i,r): if T[k][l] == 1: model.addConstr(quicksum( x[i2,k,l] for i2 in range(i, min(r,k+1))) <= quicksum(x[i-1,k2,l] for k2 in range(k-1) if T[k2][l] == 1 )) model.setObjective( obj, GRB.MINIMIZE) print timeit.default_timer()-start if verbose: print("All constrained and objective built - OK") if not verbose: model.params.OutputFlag = 0 model.params.method = 3 #model.params.MIPFocus = 1 model.params.OutputFlag = 1 #model.params.MIPFocus = 1 return(model)
def build_model(data, n_cliques = 0, verbose = True): # Load Data Format n = data['n'] r = data['r'] p = data['p'] s = data['s'] c = data['c'] h = data['h'] w = data['w'] location = data['location'] conflicts = data['conflicts'] locking_times = data['locking_times'] T = data['T'] similarp = data['similarp'] similare = data['similare'] similarr = data['similarr'] model = Model("ExaminationScheduling") if verbose: print("Building variables...") # Calculate Orbits rs = 5 es = 10 orbit = {} for l in range(p): for k in range(r): if k % rs == 0: for i in range(n): if i % es == 0: orbit[i,k,l] = [ (i2,k2,l) for i2 in range(i,min(i+es,n)) for k2 in range(k,min(k+rs,r)) if T[k2][l] == 1 if conflicts[i] <= conflicts[i2] ] # x[i,k,l] = 1 if exam i is at time l in room k x = {} for k in range(r): for l in range(p): if T[k][l] == 1: for i in range(n): if location[k] in w[i]: x[i,k,l] = model.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (i,k,l)) # y[i,l] = 1 if exam i is at time l y = {} for i in range(n): for l in range(p): y[i, l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l)) #Orbit variable for orbital branching o = {} for key in orbit: if orbit[key]: o[key] = model.addVar(vtype=GRB.BINARY, name="o_%s_%s_%s" % (key[0],key[1],key[2])) # integrate new variables model.update() for key in orbit: if orbit[key]: o[key].setAttr("BranchPriority", 1000000) start = timeit.default_timer() # not very readable but same constraints as in GurbiLinear_v_10: speeded up model building by 2 for small problems (~400 exams) and more for huger problem ~1500 exams if verbose: print("Building constraints...") s_sorted = sorted(range(len(c)), key = lambda k: c[k]) obj = LinExpr() sumconflicts = {} maxrooms = {} for i in range(n): sumconflicts[i] = sum(conflicts[i]) if s[i] <= 50: maxrooms[i] = 2 elif s[i] <= 100: maxrooms[i] = 4 elif s[i] <= 400: maxrooms[i] = 9 elif s[i] <= 700: maxrooms[i] = 12 else: maxrooms[i] = 12 c2 = LinExpr() c4 = LinExpr() for l in range(p): c1 = LinExpr() c1 = LinExpr() c3 = LinExpr() for k in range(r): if T[k][l] == 1 and location[k] in w[i]: # print k, c[k], 1-(1/(pow(2,s_sorted.index(k)))) #obj.addTerms( 1-(1/(pow(2,s_sorted.index(k)))) , x[i, k, l]) obj.addTerms(1, x[i,k,l]) c1.addTerms(1, x[i,k,l]) c4.addTerms(c[k],x[i,k,l]) model.addConstr(c1 <= maxrooms[i]* y[i,l], "c1a") model.addConstr(c1 >= y[i,l], "C1b") for j in conflicts[i]: c3.addTerms(1,y[j,l]) if not conflicts[i]: model.addConstr(c3 <= (1 - y[i,l])*sumconflicts[i], "c3") c2.addTerms(1,y[i,l]) model.addConstr( c2 == 1 , "c2") model.addConstr(c4 >= s[i], "c4") sumrooms = {} for l in range(p): sumrooms[l] = 0 cover_inequalities = LinExpr() for k in range(r): if T[k][l] == 1: sumrooms[l] += 1 c5 = LinExpr() for i in range(n): if location[k] in w[i]: c5.addTerms(1,x[i,k,l]) model.addConstr( c5 <= 1, "c5") cover_inequalities += c5 model.addConstr(cover_inequalities <= sumrooms[l], "cover_inequalities") for key in orbit: if orbit[key]: model.addConstr(quicksum( x[i,k,l] for i,k,l in orbit[key] ) <= o[key]*len(orbit[key]), "symmetrie break") # for l in range(p): # print l # for k in range(r): # print k # if T[k][l] == 1: # for i in range(n): # c6 = LinExpr() # for i2 in similare[i]: # for k2 in similarr[k]: # if k2 >= 0: # c6.addTerms(1,x[i2,k,l]) # model.addConstr(c6 <= o[i,k,l]*n, "symmetrie break") # for i in range(p-2): # for l in range(p): # model.addConstr(y[i,l] <= quicksum( y[i+1,sim] for sim in similarp[l]), "s1") model.setObjective( obj, GRB.MINIMIZE) #model.write("CPLEX.mps") print timeit.default_timer()-start if verbose: print("All constrained and objective built - OK") if not verbose: model.params.OutputFlag = 0 # Set Parameters #print("Setting Parameters...") # max presolve agressivity #model.params.presolve = 2 # Choosing root method 3= concurrent = run barrier and dual simplex in parallel #model.params.symmetrie = 2 model.params.method = 3 #model.params.presolve = 0 #model.params.MIPFocus = 1 model.params.OutputFlag = 1 #model.params.MIPFocus = 1 model.params.heuristics = 0 model.params.cuts = 0 return(model)
def __objective_function(self, x, q): m = Model("Overall_Model") CT = {} DT = {} TD = {} #### Add Variable #### for j in range(self.project_n): ## solve individual model get Project complete date CT[j] = self.__optmize_single_project(x, j) ## Project Tadeness,construction completion time DT[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(DT%d)" % j) TD[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(TD%d)" % j) DT[-1] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(DT-1)") ## Review Sequence z_ij z = {} for i in range(self.project_n): for j in range(self.project_n): if i != j: z[i, j] = m.addVar(obj=0, vtype=GRB.BINARY, name="(z%d,%d)" % (i, j)) for j in range(self.project_n): z[-1, j] = m.addVar(obj=0, vtype=GRB.BINARY, name="(z%d,%d)" % (-1, j)) m.update(); #### Add Constraint #### ## Constrain 2: project complete data>due data ## for j in range(self.project_n): m.addConstr(DT[j] - TD[j], GRB.LESS_EQUAL, self.DD[j], name="constraint_2_project_%d" % j) ## Constraint 13 for j in range(self.project_n): m.addConstr(DT[j], GRB.GREATER_EQUAL, CT[j] + self.review_duration[j], name="constraint_13_project_%d" % j) ## Constraint 14 for i in range(-1, self.project_n): for j in range(self.project_n): if i != j: m.addConstr(DT[j], GRB.GREATER_EQUAL, DT[i] - self.M * (1 - z[i, j]) + self.review_duration[j], name="constraint_14_project_%d_project_%d" % (i, j)) ## Constrain 15 for j in range(self.project_n): m.addConstr(quicksum(z[i, j] for i in range(-1, self.project_n) if i != j), GRB.EQUAL, 1, name="constraint_15_project_%d" % j) ## Constrain 16 m.addConstr(quicksum(z[-1, j] for j in range(self.project_n)), GRB.EQUAL, 1, name="constraint_16") ## Constrain 17 for i in range(self.project_n): m.addConstr(quicksum(z[i, j] for j in range(self.project_n) if j != i), GRB.LESS_EQUAL, 1, name="constraint_17_project_%d" % i) m.update() # Set optimization objective - minimize sum of expr = LinExpr() for j in range(self.project_n): expr.add(self.w[j] * TD[j]) m.setObjective(expr, GRB.MINIMIZE) m.update() m.params.presolve = 1 m.update() m.optimize() m.write(join(self.output_dir, "heuristic_whole.lp")) m.write(join(self.output_dir, "heuristic_whole.sol")) print([self.w[j] * TD[j].X for j in range(self.project_n)]) return m.objVal, argmax([self.w[j] * TD[j].X for j in range(self.project_n)])
def lazy_cycle_constraint(A, C, k, gap): """ Lazily generate cycle constraints as potential feasible solutions are generated. """ _ = '*' m = Model() m.modelsense = GRB.MAXIMIZE m.params.mipgap = gap m.params.timelimit = 5 * 60 * 60 m.params.lazyconstraints = 1 n = A.shape[0] edges = tuplelist() vars = {} for i in range(n): for j in range(n): if A[i, j] == 1: e = (i, j) edges.append(e) w = 2 if j in C else 1 var = m.addVar(vtype=GRB.BINARY, obj=w) vars[e] = var m.update() # flow constraints for i in range(n): out_vars = [vars[e] for e in edges.select(i, _)] out_ones = [1.0]*len(out_vars) out_expr = LinExpr() out_expr.addTerms(out_ones, out_vars) in_vars = [vars[e] for e in edges.select(_, i)] in_ones = [1.0]*len(in_vars) in_expr = LinExpr() in_expr.addTerms(in_ones, in_vars) m.addConstr(in_expr <= 1) m.addConstr(out_expr == in_expr) m.update() ith_cycle = 0 def callback(model, where): if where == GRB.Callback.MIPSOL: sols = model.cbGetSolution([vars[e] for e in edges]) c_edges = [edges[i] for i in range(len(edges)) if sols[i] > 0.5] cycles = cycles_from_edges(c_edges) for cycle in cycles: len_cycle = len(cycle) if len_cycle > k: cycle_vars = [vars[(cycle[i], cycle[(i+1) % len_cycle])] for i in range(len_cycle)] ones = [1.0]*len(cycle_vars) expr = LinExpr() expr.addTerms(ones, cycle_vars) model.cbLazy(expr <= len_cycle - 1) m.optimize(callback) m.update() c_edges = [e for e in edges if vars[e].x == 1.0] cycles = cycles_from_edges(c_edges) return cycles, m.objval
def __optmize_single_project(self, x, j): ''' Given the generated x for single project, try to optimize the tardiness of the project. :param x: the assignment of resource supplier to project :param j: index of project :return: ''' m = Model("SingleProject_%d" % j) #### Create variables #### project = self.project_list[j] ## Project complete data,Project Tadeness,construction completion time CT = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(CT%d)" % j) ## Activity start time ST = {} project_activities = self.project_activity[project] # print(project_activities.nodes()) for row in project_activities.nodes(): ST[row] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(ST%d,%s)" % (j, row)) ## Review sequence z_ij ## move to annealing objective function # y y = {} for activity_i in project_activities.nodes(): for activity_j in project_activities.nodes(): # print(project_activities.node[activity_i]) # print(dir(project_activities.node[activity_i])) if activity_i != activity_j and len(list( set(project_activities.node[activity_i]['rk_resources']).intersection( project_activities.node[activity_j]['rk_resources']))) > 0: y[activity_i, activity_j] = m.addVar(obj=0, vtype=GRB.BINARY, name="(y%d,%s,%s)" % (j, activity_i, activity_j)) m.update() #### Create constrains #### ## Constrain 2: project complete data>due data ## move to annealing objective function ## Constrain 3: supplier capacity limit ## move to annealing neighbor & random generator ## Constrain 4,6: project demand require; each project receive from one supplier for each resource ## move to annealing neighbor & random generator ## constrain 5: shipping constrain ## move to annealing neighbor & random generator ## Constrain 7:budget limit ## move to annealing constraint valid ## Constrain 8: activity starting constrain for a in project_activities.nodes(): for r in project_activities.node[a]['resources']: resource_delivered_days = 0 for s in self.resource_supplier_list[r]: resource_delivered_days += x.get((r, s, project), 0) * \ (self.resource_supplier_release_time[r, s] + self.supplier_project_shipping[ r, s, project]) m.addConstr(resource_delivered_days, GRB.LESS_EQUAL, ST[a], name="constraint_8_project_%d_activity_%s_resource_%s" % (j, a, r)) ## Constrain 9 activity sequence constrain for row1, row2 in project_activities.edges(): # print(row1, '#', row2, '#', j) # print(ST) m.addConstr(ST[row1] + project_activities.node[row1]['duration'], GRB.LESS_EQUAL, ST[row2], name="constraint_9_project_%d_activity_%s_activity_%s" % (j, row1, row2)) ## Constrain 10,11 for row1 in project_activities.nodes(): for row2 in project_activities.nodes(): if row1 != row2 and len(list( set(project_activities.node[row1]['rk_resources']).intersection( project_activities.node[row2]['rk_resources']))) > 0: m.addConstr(ST[row1] + project_activities.node[row1]['duration'] - self.M * ( 1 - y[row1, row2]), GRB.LESS_EQUAL, ST[row2], name="constraint_10_project_%d_activity_%s_activity_%s" % (j, row1, row2)) m.addConstr( ST[row2] + project_activities.node[row2]['duration'] - self.M * (y[row1, row2]), GRB.LESS_EQUAL, ST[row1], name="constraint_11_project_%d_activity_%s_activity_%s" % (j, row1, row2)) # m.addConstr(y[j,row1,row2]+y[j,row2,row1],GRB.LESS_EQUAL,1) ## Constrain 12 for row in project_activities.nodes(): # print(project_activities.node[row]['duration']) m.addConstr(CT, GRB.GREATER_EQUAL, ST[row] + project_activities.node[row]['duration'], name="constraint_12_project_%d_activity_%s" % (j, row)) ## Constrain 13 ## move to anealing objective function ## Constrain 14 ## move to anealing objective function ## Constrain 15 ## move to anealing objective function ## Constrain 16 ## move to anealing objective function ## Constrain 17 ## move to anealing objective function m.update() # Set optimization objective - minimize completion time expr = LinExpr() expr.add(CT) m.setObjective(expr, GRB.MINIMIZE) m.update() ########################################## m.params.presolve = 1 m.update() # Solve # m.params.presolve=0 m.optimize() m.write(join(self.output_dir, "heuristic_%d.lp" % j)) m.write(join(self.output_dir, "heuristic_%d.sol" % j)) return m.objVal
def constantino(A, C, k, gap): """ Polynomial-sized CCMcP Edge-Extended Model See Constantino et al. (2013) """ t_0 = time.clock() _ = '*' m = Model() m.modelsense = GRB.MAXIMIZE m.params.mipgap = gap # m.params.timelimit = 60 * 60 # m.params.nodefilestart = 1.0 # m.params.nodefiledir = './.nodefiledir' # m.params.presparsify = 0 # m.params.presolve = 0 n = A.shape[0] vars = {} edges = tuplelist() print('[%.1f] Generating variables...' % (time.clock() - t_0)) # Variables for l in range(n): for i in range(l, n): for j in range(l, n): if A[i, j] == 1: e = (l, i, j) edges.append(e) w = 2 if j in C else 1 var = m.addVar(vtype=GRB.BINARY, obj=w) vars[e] = var if l % 100 == 0 and l != 0: print('[%.1f] l = %d' % (time.clock() - t_0, l)) m.update() print('[%.1f] Generated variables' % (time.clock() - t_0)) print('[%.1f] Adding flow constraints...' % (time.clock() - t_0)) # Constraint (2): Flow in = Flow out for l in range(n): for i in range(l, n): # Flow in lhs_vars = [vars[e] for e in edges.select(l, _, i)] ones = [1.0]*len(lhs_vars) lhs = LinExpr() lhs.addTerms(ones, lhs_vars) # Flow out rhs_vars = [vars[e] for e in edges.select(l, i, _)] ones = [1.0]*len(rhs_vars) rhs = LinExpr() rhs.addTerms(ones, rhs_vars) # Flow in = Flow out m.addConstr(lhs == rhs) if l % 100 == 0 and l != 0: print('[%.1f] l = %d' % (time.clock() - t_0, l)) print('[%.1f] Added flow constraints' % (time.clock() - t_0)) print('[%.1f] Adding cycle vertex constraints...' % (time.clock() - t_0)) # Constraint (3): Use a vertex only once per cycle for i in range(n): c_vars = [vars[e] for e in edges.select(_, i, _)] ones = [1.0]*len(c_vars) expr = LinExpr() expr.addTerms(ones, c_vars) m.addConstr(expr <= 1.0) if i % 100 == 0 and i != 0: print('[%.1f] V_i = %d' % (time.clock() - t_0, i)) print('[%.1f] Added cycle vertex constraints' % (time.clock() - t_0)) print('[%.1f] Adding cycle cardinality constraints...' % (time.clock() - t_0)) # Constraint (4): Limit cardinality of cycles to k for l in range(n): c_vars = [vars[e] for e in edges.select(l, _, _)] ones = [1.0]*len(c_vars) expr = LinExpr() expr.addTerms(ones, c_vars) m.addConstr(expr <= k) if l % 100 == 0 and l != 0: print('[%.1f] l = %d' % (time.clock() - t_0, l)) print('[%.1f] Added cycle cardinality constraints' % (time.clock() - t_0)) print('[%.1f] Adding cycle index constraints...' % (time.clock() - t_0)) # Constraint (5): Cycle index is smallest vertex-index for l in range(n): rhs_vars = [vars[e] for e in edges.select(l, l, _)] ones = [1.0]*len(rhs_vars) rhs = LinExpr() rhs.addTerms(ones, rhs_vars) for i in range(l+1, n): lhs_vars = [vars[e] for e in edges.select(l, i, _)] if len(lhs_vars) > 0: ones = [1.0]*len(lhs_vars) lhs = LinExpr() lhs.addTerms(ones, lhs_vars) m.addConstr(lhs <= rhs) if l % 100 == 0 and l != 0: print('[%.1f] l = %d' % (time.clock() - t_0, l)) print('[%.1f] Added cycle index constraints...' % (time.clock() - t_0)) print('[%.1f] Begin Optimizing %d vertex model' % (time.clock() - t_0, n)) m.optimize() m.update() print('[%.1f] Finished Optimizing' % (time.clock() - t_0)) print('[%.1f] Building cycles...' % (time.clock() - t_0)) cycles = [] for l in range(n): c_edges = [(e[1], e[2]) for e in edges.select(l, _, _) if vars[e].x == 1.0] cycles.extend(cycles_from_edges(c_edges)) print('[%.1f] Finished building cycles' % (time.clock() - t_0)) return cycles, m.objval
def _objective_function_for_tardiness(x, AT, D): global _last_CT, _last_x, _pool m = Model("Overall_Model") CT = {} CT_ASYNC = dict() # project_to_recompute, project_no_recompute = get_project_to_recompute(x, D.project_n, D.project_list) project_suppliers = _get_project_suppliers_map(x, D.project_list) for j in range(D.project_n): p = D.project_list[j] history_CT = _get_CT(p, project_suppliers[p]) if history_CT is None: CT[j] = optmize_single_project(AT, j, D.project_list, D.project_activity, D.M) # CT_ASYNC[j] = _pool.apply_async(optmize_single_project, # (AT, j, D.project_list, D.project_activity, D.M)) else: # logging.info('%s [%s]' % (p, ','.join(sorted(project_suppliers[p])))) CT[j] = history_CT # logging.info('project %s get historical value %f.' % (p, history_CT)) for j in CT_ASYNC: CT[j] = CT_ASYNC[j].get() p = D.project_list[j] _put_CT(p, project_suppliers[p], CT[j]) # _last_CT = deepcopy(CT) # _last_x = deepcopy(x) # if len(project_no_recompute) == D.project_n: # return _tardiness_obj_trace[-1] # self.last_CT = deepcopy(CT) DT = {} TD = {} for j in range(D.project_n): ## Project Tadeness,construction completion time DT[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(DT%d)" % j) TD[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(TD%d)" % j) DT[-1] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(DT-1)") ## Review Sequence z_ij z = {} for i in range(D.project_n): for j in range(D.project_n): if i != j: z[i, j] = m.addVar(obj=0, vtype=GRB.BINARY, name="(z%d,%d)" % (i, j)) for j in range(D.project_n): z[-1, j] = m.addVar(obj=0, vtype=GRB.BINARY, name="(z%d,%d)" % (-1, j)) m.update(); #### Add Constraint #### ## Constrain 2: project complete data>due data ## for j in range(D.project_n): m.addConstr(DT[j] - TD[j], GRB.LESS_EQUAL, D.DD[j], name="constraint_2_project_%d" % j) ## Constraint 13 for j in range(D.project_n): m.addConstr(DT[j], GRB.GREATER_EQUAL, CT[j] + D.review_duration[j], name="constraint_13_project_%d" % j) ## Constraint 14 for i in range(-1, D.project_n): for j in range(D.project_n): if i != j: m.addConstr(DT[j], GRB.GREATER_EQUAL, DT[i] - D.M * (1 - z[i, j]) + D.review_duration[j], name="constraint_14_project_%d_project_%d" % (i, j)) ## Constrain 15 for j in range(D.project_n): m.addConstr(quicksum(z[i, j] for i in range(-1, D.project_n) if i != j), GRB.EQUAL, 1, name="constraint_15_project_%d" % j) ## Constrain 16 m.addConstr(quicksum(z[-1, j] for j in range(D.project_n)), GRB.EQUAL, 1, name="constraint_16") ## Constrain 17 for i in range(D.project_n): m.addConstr(quicksum(z[i, j] for j in range(D.project_n) if j != i), GRB.LESS_EQUAL, 1, name="constraint_17_project_%d" % i) m.update() # Set optimization objective - minimize sum of expr = LinExpr() for j in range(D.project_n): expr.add(D.w[j] * TD[j]) m.setObjective(expr, GRB.MINIMIZE) m.update() m.params.presolve = 1 m.update() m.optimize() # m.write(join(self.output_dir, "heuristic_whole.lp")) # m.write(join(self.output_dir, "heuristic_whole.sol")) # self.obj_value_trace.append(m.objVal) _tardiness_obj_trace.append(m.objVal) # logging.info("Tardiness value:%r" % m.objVal) return m.objVal
def partition(self, k=None, size=None, balance=None, name='partition'): n = self.number_of_nodes() # Create a new model self.model = Model(name) # Create variables # Xi :: Node i is representative of a partition # Xij :: Edge between i and j is cut # 0 => i & j are in the same partition # 1 => i & j are in different partition xi = [self.model.addVar(vtype=GRB.BINARY, name='x'+str(i+1)) for i in range(n)] xij = Bind(self.model, n) # Reinforcement of model # Zij = Xi x Xij zij = [[self.model.addVar(vtype=GRB.BINARY, name='x'+str(i+1)+' x x'+str(i+1)+'.'+str(j+1)) for i in range(j)] for j in range(1, n)] # Integrate new variables self.model.update() # Number of nodes in the partition of node i if balance != None or size != None: wi = [quicksum([xij[i, j] for j in range(n) if j != i]) for i in range(n)] # Set objective # Minimize the weighted sum of Xij obj = LinExpr() for i, j in self.edges_iter(): obj.addTerms(self[i][j]['weight'], xij[i-1, j-1]) self.model.setObjective(obj, GRB.MINIMIZE) # Add partition number # There must be exactly K partitions if k != None: self.model.addConstr(quicksum(xi[i] for i in range(n)) == k) else: self.model.addConstr(quicksum(xi[i] for i in range(n)) >= 2) # Absolute limitation the size of a partition if size != None: for i in range(n): self.model.addConstr((n - wi[i]) <= size) # Relative limit of the size of a partition if balance != None: for i in range(n): self.model.addConstr((n - wi[i]) * k <= n * balance) # Linerarisation of multiplication Xi x Xij for j in range(n-1): for i in range(j+1): self.model.addConstr(zij[j][i] <= xi[i]) self.model.addConstr(zij[j][i] <= 1 - xij[i, j+1]) self.model.addConstr(zij[j][i] >= xi[i] - xij[i, j+1]) # Add triangle inequality for i in range(n): for j in range(i+1, n): for k in range(j+1, n): # xij <= xik + xjk self.model.addConstr(xij[i, j] <= xij[i, k] + xij[j, k]) self.model.addConstr(xij[i, k] <= xij[i, j] + xij[j, k]) self.model.addConstr(xij[j, k] <= xij[i, j] + xij[i, k]) # A node is either a representative, # either in a partition with a smaller node for j in range(n): obj = LinExpr() obj.addTerms(1, xi[j]) for i in range(j): obj.addTerms(1, zij[j-1][i]) self.model.addConstr(obj == 1) # Resolve self.model.optimize() # Compute resultat self.k = 0 for i, v in enumerate(xi): if v.x == 1: self.node[i+1]['partition'] = self.k for j in range(i+1, n): if xij[i, j].x == 0: self.node[j+1]['partition'] = self.k self.k += 1 self.compute()
def optmize_single_project(AT, j, project_list, project_activity, M): m = Model("SingleProject_%d" % j) m.setParam(GRB.Param.Method, 0) m.update() #### Create variables #### project = project_list[j] ## Project complete data,Project Tadeness,construction completion time CT = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(CT%d)" % j) ## Activity start time ST = {} project_activities = project_activity[project] # print(project_activities.nodes()) for row in project_activities.nodes(): ST[row] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(ST%d,%s)" % (j, row)) ## Review sequence z_ij ## move to annealing objective function # y y = {} for activity_i in project_activities.nodes(): for activity_j in project_activities.nodes(): # print(project_activities.node[activity_i]) # print(dir(project_activities.node[activity_i])) if activity_i != activity_j and len(list( set(project_activities.node[activity_i]['rk_resources']).intersection( project_activities.node[activity_j]['rk_resources']))) > 0: y[activity_i, activity_j] = m.addVar(obj=0, vtype=GRB.BINARY, name="(y%d,%s,%s)" % (j, activity_i, activity_j)) m.update() #### Create constrains #### ## Constrain 2: project complete data>due data ## move to annealing objective function ## Constrain 3: supplier capacity limit ## move to annealing neighbor & random generator ## Constrain 4,6: project demand require; each project receive from one supplier for each resource ## move to annealing neighbor & random generator ## constrain 5: shipping constrain ## move to annealing neighbor & random generator ## Constrain 7:budget limit ## move to annealing constraint valid ## Constrain 8: activity starting constrain for a in project_activities.nodes(): for r in project_activities.node[a]['resources']: m.addConstr(AT[j, r], GRB.LESS_EQUAL, ST[a], name="constraint_8_project_%d_activity_%s_resource_%s" % (j, a, r)) ## Constrain 9 activity sequence constrain for row1, row2 in project_activities.edges(): m.addConstr(ST[row1] + project_activities.node[row1]['duration'], GRB.LESS_EQUAL, ST[row2], name="constraint_9_project_%d_activity_%s_activity_%s" % (j, row1, row2)) ## Constrain 10,11 for row1 in project_activities.nodes(): for row2 in project_activities.nodes(): if row1 != row2 and len(list( set(project_activities.node[row1]['rk_resources']).intersection( project_activities.node[row2]['rk_resources']))) > 0: m.addConstr(ST[row1] + project_activities.node[row1]['duration'] - M * ( 1 - y[row1, row2]), GRB.LESS_EQUAL, ST[row2], name="constraint_10_project_%d_activity_%s_activity_%s" % (j, row1, row2)) m.addConstr( ST[row2] + project_activities.node[row2]['duration'] - M * (y[row1, row2]), GRB.LESS_EQUAL, ST[row1], name="constraint_11_project_%d_activity_%s_activity_%s" % (j, row1, row2)) # m.addConstr(y[j,row1,row2]+y[j,row2,row1],GRB.LESS_EQUAL,1) ## Constrain 12 for row in project_activities.nodes(): m.addConstr(CT, GRB.GREATER_EQUAL, ST[row] + project_activities.node[row]['duration'], name="constraint_12_project_%d_activity_%s" % (j, row)) ## Constrain 13 ## move to anealing objective function ## Constrain 14 ## move to anealing objective function ## Constrain 15 ## move to anealing objective function ## Constrain 16 ## move to anealing objective function ## Constrain 17 ## move to anealing objective function m.update() # Set optimization objective - minimize completion time expr = LinExpr() expr.add(CT) m.setObjective(expr, GRB.MINIMIZE) m.update() ########################################## m.params.presolve = 1 m.update() # Solve # m.params.presolve=0 m.optimize() # m.write(join(output_dir, "heuristic_%d.lp" % j)) # m.write(join(output_dir, "heuristic_%d.sol" % j)) # logging.info("project %d with optimalVal %r" % (j, m.objVal)) print(m.status == GRB.OPTIMAL) for c in m.getConstrs(): if c.ConstrName.startswith('constraint_8_project'): c.getAttr(GRB.Attr.SARHSLow) logging.info('%s shadow price (%f,%f)' % (c.ConstrName, c.SARHSLow, c.SARHSUp)) return m.objVal
def build_model(data, n_cliques = 0, verbose = True): # Load Data Format n = data['n'] r = data['r'] p = data['p'] s = data['s'] c = data['c'] h = data['h'] w = data['w'] location = data['location'] conflicts = data['conflicts'] locking_times = data['locking_times'] T = data['T'] model = Model("ExaminationScheduling") if verbose: print("Building variables...") # x[i,k,l] = 1 if exam i is at time l in room k x = {} for k in range(r): for l in range(p): if T[k][l] == 1: for i in range(n): if location[k] in w[i]: x[i,k,l] = model.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (i,k,l)) # y[i,l] = 1 if exam i is at time l y = {} for i in range(n): for l in range(p): y[i, l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l)) # integrate new variables model.update() start = timeit.default_timer() # not very readable but same constraints as in GurbiLinear_v_10: speeded up model building by 2 for small problems (~400 exams) and more for huger problem ~1500 exams if verbose: print("Building constraints...") obj = LinExpr() sumconflicts = {} maxrooms = {} for i in range(n): sumconflicts[i] = sum(conflicts[i]) if s[i] <= 50: maxrooms[i] = 1 elif s[i] <= 100: maxrooms[i] = 2 elif s[i] <= 400: maxrooms[i] = 7 elif s[i] <= 700: maxrooms[i] = 9 else: maxrooms[i] = 12 c2 = LinExpr() c4 = LinExpr() for l in range(p): c1 = LinExpr() c1 = LinExpr() c3 = LinExpr() for k in range(r): if T[k][l] == 1 and location[k] in w[i]: c1.addTerms(1, x[i, k, l]) c4.addTerms(c[k],x[i,k,l]) obj += c1 model.addConstr(c1 <= maxrooms[i]* y[i,l], "c1a") model.addConstr(c1 >= y[i,l], "C1b") for j in conflicts[i]: c3.addTerms(1,y[j,l]) model.addConstr(c3 <= (1 - y[i,l])*sumconflicts[i], "c3") c2.addTerms(1,y[i,l]) model.addConstr( c2 == 1 , "c2") model.addConstr(c4 >= s[i], "c4") sumrooms = {} for l in range(p): sumrooms[l] = 0 cover_inequalities = LinExpr() for k in range(r): if T[k][l] == 1: sumrooms[l] += 1 c5 = LinExpr() for i in range(n): if location[k] in w[i]: c5.addTerms(1,x[i,k,l]) model.addConstr( c5 <= 1, "c5") cover_inequalities += c5 model.addConstr(cover_inequalities <= sumrooms[l], "cover_inequalities") model.setObjective( obj, GRB.MINIMIZE) print timeit.default_timer()-start if verbose: print("All constrained and objective built - OK") if not verbose: model.params.OutputFlag = 0 # Set Parameters #print("Setting Parameters...") # max presolve agressivity #model.params.presolve = 2 # Choosing root method 3= concurrent = run barrier and dual simplex in parallel #model.params.method = 1 #model.params.MIPFocus = 1 model.params.OutputFlag = 1 model.params.Method = 3 # cuts model.params.cuts = 0 model.params.cliqueCuts = 0 model.params.coverCuts = 0 model.params.flowCoverCuts = 0 model.params.FlowPathcuts = 0 model.params.GUBCoverCuts = 0 model.params.impliedCuts = 0 model.params.MIPSepCuts = 0 model.params.MIRCuts = 0 model.params.ModKCuts = 0 model.params.NetworkCuts = 2 model.params.SUBMIPCuts = 0 model.params.ZeroHalfCuts = 0 model.params.TimeLimit = 30 # # Tune the model # model.tune() # if model.tuneResultCount > 0: # # Load the best tuned parameters into the model # model.getTuneResult(0) # # Write tuned parameters to a file # model.write('tune1.prm') # return return(model)
def _objective_function_for_tardiness(x, AT, D): global _last_CT, _last_x, _pool, _time_limit_per_model m = Model("Overall_Model") m.params.timelimit = _time_limit_per_model # m.setParam('OutputFlag', False) # m.params.IntFeasTol = 1e-7 CT = {} # CT_ASYNC = dict() # project_to_recompute, project_no_recompute = get_project_to_recompute(x, D.project_n, D.project_list) project_suppliers = _get_project_suppliers_map(x, D.project_list) critical_project_resource = dict() # for j in range(D.project_n): # p = D.project_list[j] # CT_ASYNC[j] = _pool.apply_async(optimize_single_project, # (AT, j, D.project_list, D.project_activity, D.M)) # # for j in CT_ASYNC: # p = D.project_list[j] # CT[j], skj = CT_ASYNC[j].get() # _put_CT(p, project_suppliers[p], CT[j]) # _put_historical_delta_weight_idx_map(p, project_suppliers[p], skj) # critical_project_resource.update(skj) for j in range(D.project_n): p = D.project_list[j] CT[j], skj = optimize_single_project(AT, j, D.project_list, D.project_activity, D.M) _put_CT(p, project_suppliers[p], CT[j]) _put_historical_delta_weight_idx_map(p, project_suppliers[p], skj) critical_project_resource.update(skj) DT = {} TD = {} for j in range(D.project_n): ## Project Tadeness,construction completion time DT[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="DT_%d" % j) TD[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="TD_%d" % j) DT[-1] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="DT_-1") ## Review Sequence z_ij z = {} for i in range(D.project_n): for j in range(D.project_n): if i != j: z[i, j] = m.addVar(obj=0, vtype=GRB.BINARY, name="z_%d_%d" % (i, j)) for j in range(D.project_n): z[-1, j] = m.addVar(obj=0, vtype=GRB.BINARY, name="z_%d_%d" % (-1, j)) m.update(); #### Add Constraint #### ## Constrain 2: project complete data>due data ## # equation 17 for j in range(D.project_n): m.addConstr(DT[j] - TD[j], GRB.LESS_EQUAL, D.DD[j], name="constraint_2_project_%d" % j) ## Constraint 13 # equation 12 for j in range(D.project_n): m.addConstr(DT[j], GRB.GREATER_EQUAL, CT[j] + D.review_duration[j], name="constraint_13_project_%d" % j) ## Constraint 14 # equation 13 for i in range(-1, D.project_n): for j in range(D.project_n): if i != j: m.addConstr(DT[j], GRB.GREATER_EQUAL, DT[i] - D.M * (1 - z[i, j]) + D.review_duration[j], name="constraint_14_project_%d_project_%d" % (i, j)) ## Constrain 15 # equation 14 for j in range(D.project_n): m.addConstr(quicksum(z[i, j] for i in range(-1, D.project_n) if i != j), GRB.EQUAL, 1, name="constraint_15_project_%d" % j) ## Constrain 16 # equation 15 m.addConstr(quicksum(z[-1, j] for j in range(D.project_n)), GRB.EQUAL, 1, name="constraint_16") ## Constrain 17 # equation 16 for i in range(D.project_n): m.addConstr(quicksum(z[i, j] for j in range(D.project_n) if j != i), GRB.LESS_EQUAL, 1, name="constraint_17_project_%d" % i) m.update() # Set optimization objective - minimize sum of expr = LinExpr() for j in range(D.project_n): expr.add(D.w[j] * TD[j]) m.setObjective(expr, GRB.MINIMIZE) m.update() # m.params.presolve = 1 m.update() m.optimize() m.write(join(_result_output_path, 'round_%d_tardiness.sol' % _round)) m.write(join(_result_output_path, 'round_%d_tardiness.lp' % _round)) z_ = {} for i, j in z: z_[i, j] = z[i, j].X critical_projs = _sensitivity_analysis_for_tardiness(z_, CT, D) _tardiness_obj_trace.append(m.objVal) _gap_trace.append(m.MIPGap) return m.objVal, critical_project_resource, critical_projs