class FullModel: def __init__(self, fsp: FacilitySizingProblem): self.fsp = fsp self.m = Model() # Creates the variables self.y = self.m.addVars(fsp.n_facilities, fsp.n_customers, name="y") self.x = self.m.addVars(fsp.n_facilities, name="x") # Creates the objective expr = 0 for i in range(fsp.n_facilities): expr += fsp.fixed_costs[i] * self.x[i] for j in range(fsp.n_customers): expr += fsp.delivery_costs[i][j] * self.y[i, j] self.m.setObjective(expr, GRB.MINIMIZE) # Constraints for i in range(fsp.n_facilities): self.m.addConstr(self.y.sum(i, '*') <= self.x[i]) for j in range(fsp.n_customers): self.m.addConstr(self.y.sum('*', j) >= fsp.demands[j]) self.m.addConstrs(self.x[i] <= self.fsp.capacity[i] for i in range(fsp.n_facilities)) def solve(self): self.m.optimize() def print_solution(self): for i in range(self.fsp.n_facilities): print('%s %g' % (self.x[i].varName, self.x[i].x)) print('Obj: %g' % self.m.objVal)
class MP: def __init__(self): self.m = Model() self.x = self.m.addVar(name="x") self.phi = self.m.addVar(name="phi") # Objective function self.m.setObjective(2 * self.x + self.phi, sense=GRB.MINIMIZE) # Constraints def solve(self): self.m.optimize() def get_sol(self): return self.x.x, self.phi.x def add_feasibility_cuts(self, pi1: float, pi2: float): print(pi1, pi2) self.m.addConstr((pi1 + (4 * pi2)) * self.x >= (pi1 + (2 * pi2))) def add_optimality_cuts(self, pi1: float, pi2: float): self.m.addConstr(self.phi + (pi1 + 4 * pi2) * self.x >= (pi1 + 2 * pi2)) def print_solution(self): print('%s %g' % (self.x.varName, self.x.x)) print('%s %g' % (self.phi.varName, self.phi.x)) print('Obj: %g' % self.m.objVal) def write_model(self): self.m.write("mp.lp")
def defineObjectives(data: DataInstance, model: Model, boolVars, N, posVars): LAG, RAG, TAG, BAG = boolVars L, R, T, B, H, W = posVars maxX = model.addVar(vtype=GRB.INTEGER, name="maxX") maxY = model.addVar(vtype=GRB.INTEGER, name="maxY") for element in range(data.element_count): model.addConstr(maxX >= R[element]) model.addConstr(maxY >= B[element]) OBJECTIVE_GRIDCOUNT = LinExpr(0.0) for element in range(data.element_count): OBJECTIVE_GRIDCOUNT.addTerms([1.0, 1.0], [LAG[element], TAG[element]]) OBJECTIVE_GRIDCOUNT.addTerms([1.0, 1.0], [BAG[element], RAG[element]]) OBJECTIVE_LT = LinExpr(0) for element in range(data.element_count): OBJECTIVE_LT.addTerms([1, 1, 2, 2, -1, -1], [T[element], L[element], B[element], R[element], W[element], H[element]]) Objective = LinExpr(0) Objective.add(OBJECTIVE_GRIDCOUNT, 1) Objective.add(OBJECTIVE_LT, 0.001) # Objective.add(maxX, 10) # Objective.add(maxY, 10) model.addConstr(OBJECTIVE_GRIDCOUNT >= (calculateLowerBound(N))) model.setObjective(Objective, GRB.MINIMIZE) return OBJECTIVE_GRIDCOUNT, OBJECTIVE_LT
class OSP: def __init__(self, x: float): self.m = Model() self.y1 = self.m.addVar(name = "y1") self.y2 = self.m.addVar(name = "y2") # Objective function self.m.setObjective(self.y1 + 3*self.y2, sense=GRB.MINIMIZE) # Constraints self.c1 = self.m.addConstr(2 * self.y1 + self.y2 == 1 - x) self.c2 = self.m.addConstr(-self.y1 + self.y2 == 2 - 4 * x) def solve(self): self.m.optimize() def get_results(self): return self.m.objVal, self.c1.Pi, self.c2.Pi def print_solution(self): print('%s %g' % (self.y1.varName, self.y1.x)) print('%s %g' % (self.y2.varName, self.y2.x)) print('Obj: %g' % self.m.objVal)
class KnapsackProblemModel: def __init__(self,p:KnapsackProblem): self.p = p self.m = Model('knapsack') # Creates the decision variables self.x = self.m.addVars(len(p.rewards),vtype = GRB.BINARY,name = "x") # Creates the objective self.m.setObjective(quicksum([self.p.rewards[i] * self.x[i] for i in range(len(self.p.rewards))]),sense=GRB.MAXIMIZE) # Creates the constraint self.m.addConstr(quicksum([self.p.weights[i] * self.x[i] for i in range(len(self.p.weights))]) <= self.p.capacity) def addCover(self,indices:list,rhs:int): self.m.addConstr(quicksum([self.x[indices[i]] for i in range(len(indices))]) <= rhs) def solve(self): self.m.optimize() def printSolution(self): print("Objective ", self.m.objVal) for v in self.m.getVars(): print('%s %g' % (v.varName, v.x))
def solve_restricted_primal(self, demands, demands_next, p): self.obj = 0. m = Model("multi-unit-auction") # self.m.params.LogToConsole = 0 self.allocation_vars = dict() for agent in self.agents: for i in range(1, self.supply + 1): self.allocation_vars[agent.id, i] = m.addVar(lb=0., ub=1., vtype=GRB.CONTINUOUS, name='x_%s_%s' % (agent.id, i)) m.update() for agent in self.agents: if len(demands[agent.id]) > 0 and len(demands_next[agent.id]) > 0: m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, self.supply + 1)), GRB.EQUAL, 1, name="u_%s_strict" % agent.id) else: m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, self.supply + 1)), GRB.LESS_EQUAL, 1, name="u_%s" % agent.id) for j in range(1, self.supply + 1): if j not in [demand.quantity for demand in demands[agent.id]]: m.addConstr(self.allocation_vars[agent.id, j], GRB.EQUAL, 0, name='x_%s_%s_undemanded' % (agent.id, j)) if p > 0: m.addConstr( quicksum(self.allocation_vars[agent.id, i] * i for i in range(1, self.supply + 1) for agent in self.agents), GRB.EQUAL, self.supply, name="price_strict") else: m.addConstr( quicksum(self.allocation_vars[agent.id, i] * i for i in range(1, self.supply + 1) for agent in self.agents), GRB.LESS_EQUAL, self.supply, name="price") obj_expr = LinExpr() for agent in self.agents: for valuation in agent.valuations: obj_expr.addTerms(valuation.quantity, self.allocation_vars[agent.id, valuation.quantity]) m.setObjective(obj_expr, GRB.MAXIMIZE) m.update() m.optimize() m.write('optimal-lp.lp') if m.status == GRB.OPTIMAL: m.write('optimal-lp.sol') for v in [v for v in m.getVars() if v.x != 0.]: print('%s %g' % (v.varName, v.x)) print '' print 'CONSTRAINTS:' for l in m.getConstrs(): if l.Pi > 0: print('%s %g' % (l.constrName, l.Pi)) print m.getObjective().getValue() return m
class PPSP: def __init__(self,pp:ProcurementProblem,material:int,pi:float): """ Creates an instance of the DW's subproblem for a given material and given pi, the dual variable value corresponding to the complicating constraints in the RMP. :param pp: :param product: :param pi: """ self.pp = pp self.m = Model() self.material = material # The subproblem has only one decision variable self.x = self.m.addVar() # The objective function will be # (c_j - pi A_j)*x, where j = material expr = (self.pp.costs[material] - pi*self.pp.consumption[material]) * self.x self.m.setObjective(expr, GRB.MINIMIZE) # The constraints bind the value of x to a min and max production quantity self.m.addConstr(self.x <= self.pp.max_production[material]) self.m.addConstr(self.x >= self.pp.min_production[material]) def solve(self): """ Solves the subproblem. :return: """ # By setting the OutputFlag to 0 we tell # Gurobi not to print details about the solution of the subproblem. # We do this in order to obtain a more readable output. self.m.setParam(GRB.Param.OutputFlag,0) self.m.optimize() def get_solution(self): """ Retrieves the solution to the subproblem. :return: """ return self.x.x def get_objective(self): """ Retrieves the optimal objective value. :return: """ return self.m.objVal
class Master: def __init__(self, fsp: FacilitySizingProblem): self.fsp = fsp self.m = Model() # Creates the variables self.x = self.m.addVars(fsp.n_facilities, vtype=GRB.CONTINUOUS, name="x") self.phi = self.m.addVar(name="phi") # Creates the objective expr = self.phi + quicksum([ self.fsp.fixed_costs[i] * self.x[i] for i in range(self.fsp.n_facilities) ]) self.m.setObjective(expr, GRB.MINIMIZE) # Creates the constraints self.m.addConstrs(self.x[i] <= self.fsp.capacity[i] for i in range(fsp.n_facilities)) def solve(self): self.m.optimize() def get_solution(self): return [self.x[i].x for i in range(self.fsp.n_facilities)], self.phi.x def add_feasibility_cut(self, dualsCC: list, dualsDC: list): self.m.addConstr( quicksum( [dualsCC[i] * self.x[i] for i in range(self.fsp.n_facilities)]) <= -sum([ dualsDC[j] * self.fsp.demands[j] for j in range(self.fsp.n_customers) ])) print("Added feasibility cut") def add_optimality_cut(self, dualsCC: list, dualsDC: list): self.m.addConstr(self.phi - quicksum( [dualsCC[i] * self.x[i] for i in range(self.fsp.n_facilities)]) >= sum([ dualsDC[j] * self.fsp.demands[j] for j in range(self.fsp.n_customers) ])) print("Added optimality cut") def print_solution(self): for i in range(self.fsp.n_facilities): print('%s %g' % (self.x[i].varName, self.x[i].x)) print('Obj: %g' % self.m.objVal)
class SolverGurobi(Solver): def __init__(self): Solver.__init__(self, GRB.BINARY, GRB.CONTINUOUS, GRB.INTEGER, GRB.OPTIMAL, GRB.INFEASIBLE, GRB.UNBOUNDED, GRB.INTERRUPTED, GRB.SUBOPTIMAL, GRB.EQUAL, GRB.LESS_EQUAL, GRB.GREATER_EQUAL, GRB.MAXIMIZE, GRB.MINIMIZE, GRB.INFINITY) setParam('OutputFlag', 0) setParam('IntFeasTol', 1e-9) self.problem = Model('gurobi_problem') def _add_variable(self, var): if var.var_type == self.BINARY: self.problem.addVar(name=var.name, vtype=var.var_type) else: self.problem.addVar(name=var.name, lb=var.lower_bound, ub=var.upper_bound, vtype=var.var_type) def _del_variable(self, name): self.problem.remove(self.problem.getVarByName(name)) def _add_constraint(self, const): lhs = LinExpr() for elem in const.lhs: var = self.problem.getVarByName(elem.name) lhs.add(var, elem.coefficient) self.problem.addConstr(lhs, const.sense, const.rhs, const.name) def _del_constraint(self, name): self.problem.remove(self.problem.getConstrByName(name)) def update(self): self.problem.update() def _set_objective(self, objective): expr = LinExpr() for elem in objective.expr: var = self.problem.getVarByName(elem.name) expr.add(var, elem.coefficient) self.problem.setObjective(expr, objective.sense) def get_variable_value(self, name): return self.problem.getVarByName(name).x def get_objective_value(self): return self.problem.objVal def get_solution_status(self): return self.problem.status def _optimize(self): self.problem.optimize()
class PPFullModel(): """ Class representing the full model for the procurement problem. """ def __init__(self, pp: ProcurementProblem): self.m = Model() self.pp = pp # Creates the variables self.x = self.m.addVars(self.pp.n_materials, name="x") # Creates the objective # The expression is obtained by multiplying x to the costs dictionary. # See the Gurobi docs for tupledic product here # https://www.gurobi.com/documentation/8.1/refman/py_tupledict_prod.html expr = self.x.prod(self.pp.costs) self.m.setObjective(expr, GRB.MINIMIZE) # Creates the constraints self.m.addConstrs((self.x[i] <= self.pp.max_production[i] for i in range(self.pp.n_materials)), name='max_p') self.m.addConstrs((self.x[i] >= self.pp.min_production[i] for i in range(self.pp.n_materials)), name='min_p') self.m.addConstr(self.x.prod(self.pp.consumption) >= self.pp.demand) def solve(self): """ Solves the problem. :return: """ self.m.optimize() def print_solution(self): """ Prints the solution to the problem. :return: """ for i in range(self.pp.n_materials): print('%s %g' % (self.x[i].varName, self.x[i].x)) print('Obj: %g' % self.m.objVal)
class AlloyProductionModel: """ This class represents the mathematical model for the Alloy Production Problem. """ def __init__(self, p: AlloyProductionProblem): self.p = p self.m = Model('APP') # Creates the decision variables self.materials = list(p.availability.keys()) chemicals = list(p.max_grade.keys()) self.x = self.m.addVars(self.materials, name='x') # Creates the objective function expr = self.x.prod(p.cost) self.m.setObjective(expr, sense=GRB.MINIMIZE) # Creates the constraints # Min content self.m.addConstrs( quicksum([p.content[(k, m)] * self.x[m] for m in self.materials]) >= p.min_grade[k] * self.x.sum('*') for k in chemicals) # Max content self.m.addConstrs( quicksum([p.content[(k, m)] * self.x[m] for m in self.materials]) <= p.max_grade[k] * self.x.sum('*') for k in chemicals) # Availability self.m.addConstrs(self.x[m] <= p.availability[m] for m in self.materials) # Demand self.m.addConstr(self.x.sum('*') >= p.demand) def solve(self): self.m.optimize() def print_solution(self): print("Objective ", self.m.ObjVal) for m in self.materials: print("%s %g " % (self.x[m].varName, self.x[m].x))
class FSP: def __init__(self, flp: FacilityLocationProblem, x: list): self.flp = flp self.m = Model() # Creates the variables y = self.m.addVars(flp.n_facilities, flp.n_customers, name="y") v1 = self.m.addVars(flp.n_facilities, name="v+") v2 = self.m.addVars(flp.n_customers, name="v-") # Creates the objective expr = 0 for i in range(flp.n_facilities): expr += v1[i] for j in range(flp.n_customers): expr += v2[j] self.m.setObjective(expr, GRB.MINIMIZE) # Constraints self.dc = [] self.cc = [] for i in range(flp.n_facilities): print(x[i]) self.cc.append( self.m.addConstr( y.sum(i, '*') - v1[i] <= flp.capacity[i] * x[i])) for j in range(flp.n_customers): self.dc.append( self.m.addConstr(y.sum('*', j) + v2[j] >= flp.demands[j])) def solve(self): self.m.optimize() def getDuals(self): dualsCC = self.m.getAttr(GRB.Attr.Pi, self.cc) dualsDC = self.m.getAttr(GRB.Attr.Pi, self.dc) return self.m.objVal, dualsCC, dualsDC
class FullModel: def __init__(self): self.m = Model() self.x = self.m.addVar(name="x") self.y1 = self.m.addVar(name="y1") self.y2 = self.m.addVar(name="y2") # Objective function self.m.setObjective(2 * self.x + self.y1 + 3 * self.y2, sense=GRB.MINIMIZE) # Constraints self.m.addConstr(2 * self.y1 + self.y2 + self.x == 1) self.m.addConstr(-self.y1 + self.y2 + 4 * self.x == 2) def solve(self): self.m.optimize() def print_solution(self): print('%s %g' % (self.x.varName, self.x.x)) print('%s %g' % (self.y1.varName, self.y1.x)) print('%s %g' % (self.y2.varName, self.y2.x)) print('Obj: %g' % self.m.objVal)
class FSP: def __init__(self, x): self.m = Model() self.y1 = self.m.addVar(name="y1") self.y2 = self.m.addVar(name="y2") self.v1 = self.m.addVar(name="v1") self.v2 = self.m.addVar(name="v2") self.v3 = self.m.addVar(name="v3") self.v4 = self.m.addVar(name="v4") # Objective function self.m.setObjective(self.v1 + self.v2 + self.v3 + self.v4, sense=GRB.MINIMIZE) # Constraints self.c1 = self.m.addConstr(2 * self.y1 + self.y2 + self.v1 - self.v2 == (1 - x)) self.c2 = self.m.addConstr(-self.y1 + self.y2 + self.v3 - self.v4 == (2 - 4 * x)) def solve(self): self.m.optimize() def get_results(self): print(self.m.objVal, self.c1.Pi, self.c2.Pi) return self.m.objVal, self.c1.Pi, self.c2.Pi def print_solution(self): print('%s %g' % (self.y1.varName, self.y1.x)) print('%s %g' % (self.y2.varName, self.y2.x)) print('%s %g' % (self.v1.varName, self.v1.x)) print('%s %g' % (self.v2.varName, self.v2.x)) print('%s %g' % (self.v3.varName, self.v3.x)) print('%s %g' % (self.v4.varName, self.v4.x)) print('Obj: %g' % self.m.objVal)
class OSP: def __init__(self, flp: FacilityLocationProblem, x: list): self.flp = flp self.m = Model() # Creates the variables y = self.m.addVars(flp.n_facilities, flp.n_customers, name="y") # Creates the objective expr = 0 for i in range(flp.n_facilities): for j in range(flp.n_customers): expr += flp.delivery_costs[i][j] * y[i, j] self.m.setObjective(expr, GRB.MINIMIZE) # Constraints self.dc = [] self.cc = [] for i in range(flp.n_facilities): self.cc.append( self.m.addConstr(y.sum(i, '*') <= flp.capacity[i] * x[i])) for j in range(flp.n_customers): self.dc.append(self.m.addConstr(y.sum('*', j) >= flp.demands[j])) def solve(self): self.m.optimize() def getResults(self): dualsCC = self.m.getAttr(GRB.Attr.Pi, self.cc) dualsDC = self.m.getAttr(GRB.Attr.Pi, self.dc) return self.m.objVal, dualsCC, dualsDC def write(self): self.m.write("subproblem.lp")
def _balancing(self, flow_graph, sinks, frontier, demands): configure_gurobi() model = Model() xij = {i: {} for i in frontier} for node in frontier: congestion = sum(flow_graph[node][neighbor] for neighbor in flow_graph[node]) for neighbor in flow_graph[node]: assert neighbor in sinks xij[node][neighbor] = model.addVar(vtype=GRB.CONTINUOUS, name=f"x_{node}_{neighbor}") model.addConstr(xij[node][neighbor] >= 0) model.addConstr(quicksum(xij[node][neighbor] for neighbor in flow_graph[node]) == congestion) sink_predecessors = {i: [] for i in sinks} for node in frontier: for neighbor in flow_graph[node]: sink_predecessors[neighbor].append(node) bj = {} for node in sinks: bj[node] = model.addVar(vtype=GRB.CONTINUOUS, name=f"b_{node}") model.addConstr(bj[node] == quicksum(xij[pred][node] for pred in sink_predecessors[node]) + demands[node]) model.setObjective(quicksum(bj[node] * bj[node] for node in sinks), GRB.MINIMIZE) model.optimize() any_edge_deleted = False for node in frontier: to_delete = [] for neighbor in flow_graph[node]: flow = xij[node][neighbor].X if flow < EPS: to_delete.append(neighbor) any_edge_deleted = True else: flow_graph[node][neighbor] = flow for neighbor in to_delete: del flow_graph[node][neighbor] return any_edge_deleted
class RMP(): def __init__(self, pp: ProcurementProblem): """ Builds an instance of the DW's RMP for the Procurement Problem. :param pp: """ # Builds an instance of the model self.m = Model() self.pp = pp # In the following list it will store all columns added to RMP during the DW algorithm self.columns = [] # Initially there is no variable, # but we will add them here # as we generate them self.u = [] # Creates an empty objective self.m.setObjective(0, GRB.MINIMIZE) # Creates the complicating constraints self.compc = self.m.addConstr(0, GRB.GREATER_EQUAL, self.pp.demand, "cc") # Creates the convexity constraints self.convc = self.m.addConstr(0, GRB.EQUAL, 1) def addColumn(self, solution: tuple): """ Receives the x_i solutions to the subproblems as a tuple and i) stores the solution (necessary for calculating the final x solution) ii) generates a combined column ii) adds it to RMP. """ self.columns.append(solution) # We calculate the cost of the combined column and its lhs term in the complicating constraints (we call it w) cost = 0 w = 0 for i in range(self.pp.n_materials): # Since we add combined columns, for each material we add the cost and the consumption. cost += self.pp.costs[i] * solution[i] w += self.pp.consumption[i] * solution[i] # We pass the coefficient of the constraint in which it appears. # It appears with coefficient w in the complicating constraints # and with coefficient 1 in the convexity constraints. # Read the docs here https://www.gurobi.com/documentation/8.1/refman/py_column2.html c = Column([w, 1], [self.compc, self.convc]) # Calculates the index of the new variable index = len(self.u) + 1 # Adds the new variable starting from the column created. # Read the docs here https://www.gurobi.com/documentation/8.1/refman/py_model_addvar.html self.u.append( self.m.addVar(lb=0.0, ub=GRB.INFINITY, obj=cost, vtype=GRB.CONTINUOUS, name=("u" + str(index)), column=c)) def solve(self): self.m.optimize() def print(self, file_name): """ Prints the current problem to file in a human-readable format. :param file_name: the name of the file where the problem should be printed. :return: """ self.m.write(str(file_name) + ".lp") def get_objective(self): return self.m.objVal def get_pi(self): # Read here for how to access the attributes of a constraint # https://www.gurobi.com/documentation/8.1/refman/attributes.html#sec:Attributes return self.compc.Pi def get_sigma(self): # Read here for how to access the attributes of a constraint # https://www.gurobi.com/documentation/8.1/refman/attributes.html#sec:Attributes return self.convc.Pi def print_u_solution(self): """ Prints the solution to RMP and its objective value. :return: """ for i in range(len(self.u)): print('%s %g' % (self.u[i].varName, self.u[i].x)) print('Obj: %g' % self.m.objVal) def print_x_solution(self): """ Calculates and prints the x solution from the u solution, as well as its objective value. :return: """ x = [0 for i in range(self.pp.n_materials)] for i in range(len(self.columns)): print(self.columns[i]) print(self.u[i].x) for m in range(self.pp.n_materials): x[m] = x[m] + self.columns[i][m] * self.u[i].x for m in range(self.pp.n_materials): print("x_" + str(m) + "=" + str(x[m])) print('Obj: %g' % self.m.objVal)
class PCST: def __init__(self, network): self.lp = Model('PCST') self.network = network def initialise(self): # Initialise variables for n in self.network.nodes.values(): n.var = self.lp.addVar(vtype=GRB.BINARY, name=n.id) for e in self.network.edges.values(): e.var = self.lp.addVar(vtype=GRB.BINARY, name=e.id) # Update variables self.lp.update() # Root restriction lhs = LinExpr() for root_out in self.network.out_edges(self.network.root.id): lhs.addTerms(1, root_out.var) self.lp.addConstr(lhs, GRB.EQUAL, 1) # Income constraints for n in self.network.nodes.values(): lhs = LinExpr() for e in self.network.in_edges(n.id): lhs.addTerms(1, e.var) self.lp.addConstr(lhs, GRB.EQUAL, LinExpr(n.var)) # Reversibility constraint for e in self.network.edges.values(): if e.inverse is not None: lhs = LinExpr([1, 1], [e.var, self.network.get_edge(e.inverse).var]) self.lp.addConstr(lhs, GRB.LESS_EQUAL, self.network.get_node(e.source).var) self.lp.addConstr(lhs, GRB.LESS_EQUAL, self.network.get_node(e.target).var) for n in self.network.nodes.values(): if n.type == Type.LEAF or n.type == Type.LEAF_TERMINAL: for in_edge in self.network.in_edges(n.id): source = self.network.get_node(in_edge.source) if source.type != Type.ROOT: print n.id, in_edge.source self.lp.addConstr(source.var, GRB.LESS_EQUAL, n.var) def objective_function(self, beta=1): # Set objective function obj = LinExpr() for e in self.network.edges.values(): obj.addTerms(e.value, e.var) for n in self.network.nodes.values(): if n.type == Type.NORMAL: obj.addTerms(-n.value * beta, n.var) self.lp.setObjective(obj, GRB.MINIMIZE) def optimise(self): self.lp.optimize() return self.get_solution() def edge_sensitivity_analysis(self, solution): scores = {} for e in solution.edges.values(): edge_constraint = self.lp.addConstr(self.network.get_edge(e.id).var, GRB.EQUAL, 0) scores[e.id] = self.optimise() self.lp.remove(edge_constraint) print '\n[INFO] Edge sensivity analysis done! ' + str(len(solution.edges)) + ' edges analysed.' return scores def get_solution(self): edges = dict((e.id, Edge(e.source, e.target, self.lp.getVarByName(e.id).x)) for e in self.network.edges.values() if self.lp.getVarByName(e.id).x > 0.9999) obj_val = self.lp.objVal return Solution(edges, obj_val) def get_obj_value(self): return self.lp.objVal def print_solution(self): for v in self.lp.getVars(): print v.varName, v.x print 'Obj:', self.lp.objVal
lp.addVar(vtype=GRB.BINARY, name=v) # Initialise edges variables for edge in in_edges: lp.addVar(vtype=GRB.BINARY, name=edge) for edge in out_edges: lp.addVar(vtype=GRB.BINARY, name=edge) # Update variables lp.update() # Initialise constraints for site in sites: lhs = LinExpr([(1, lp.getVarByName(edge)) for edge in in_edges if edge.endswith(site)]) lp.addConstr(lhs, GRB.EQUAL, lp.getVarByName(site)) for site in sites: for out_edge in out_edges: if out_edge.startswith(site): lp.addConstr(lp.getVarByName(out_edge), GRB.EQUAL, lp.getVarByName(site)) for kinase in kinases: for in_edge in in_edges: if in_edge.startswith(kinase): lp.addConstr(lp.getVarByName(kinase), GRB.GREATER_EQUAL, lp.getVarByName(in_edge)) for substrate in substrates: for out_edge in out_edges: if out_edge.endswith(substrate): lp.addConstr(lp.getVarByName(substrate), GRB.GREATER_EQUAL, lp.getVarByName(out_edge))
# Model m = Model('textile') # Decision variables xa = m.addVar(0, GRB.INFINITY, vtype=GRB.CONTINUOUS, name="xa") xb = m.addVar(0, GRB.INFINITY, vtype=GRB.CONTINUOUS, name="xb") yw = m.addVar(0, GRB.INFINITY, vtype=GRB.CONTINUOUS, name="yw") yl = m.addVar(0, GRB.INFINITY, vtype=GRB.CONTINUOUS, name="yl") yh = m.addVar(0, GRB.INFINITY, vtype=GRB.CONTINUOUS, name="yh") # Objective function m.setObjective(60 * xa + 65 * xb - 3 * yw - 3 * yl - 10 * yh, sense=GRB.MAXIMIZE) # Constraints m.addConstr(0.3 * xa + 0.5 * xb - yw, sense=GRB.LESS_EQUAL, rhs=0) m.addConstr(6 * xa + 5 * xb <= yl) m.addConstr(3 * xa + 5 * xb <= yh) m.addConstr(yw <= 20) m.addConstr(yl <= 300) m.addConstr(yh <= 200) m.optimize() print('Objective value: %g' % m.objVal) print('%s %g' % (xa.varName, xa.x)) print('%s %g' % (xb.varName, xb.x)) print('%s %g' % (yw.varName, yw.x)) print('%s %g' % (yl.varName, yl.x)) print('%s %g' % (yh.varName, yh.x))
class BendersSolver: def __init__(self, supply, agents, approximator, log): """ :param b: b of LP. If n=len(agents) then the first n values are 1./alpha and n+1 value is supply/alpha. :param agents: List of agents. """ # Setting up master problem self.m = Model("master-problem") self.m.params.LogToConsole = 0 # noinspection PyArgumentList,PyArgumentList,PyArgumentList self.z = self.m.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY, name="z") self.approximator = approximator self.agents = agents self.log = log self.allocations = {'X0': Allocation()} self.b = [(1. / self.approximator.gap) for i in range(0, len(self.agents))] self.b.append(supply / self.approximator.gap) # noinspection PyArgumentList,PyArgumentList,PyArgumentList self.price_var = self.m.addVar(lb=-GRB.INFINITY, ub=0, name="price") self.utility_vars = dict() for agent in self.agents: # noinspection PyArgumentList,PyArgumentList,PyArgumentList self.utility_vars[agent.id] = self.m.addVar(lb=-GRB.INFINITY, ub=0, name="u_%s" % agent.id) self.m.update() # Initial constraints for empty allocation self.add_benders_cut(Allocation(), "X0") self.old_price_constraint = 0. self.add_price_constraint(0.) self.m.setObjective(self.z, GRB.MAXIMIZE) self.price_changed = False self.give_second_chance = True self.old_z = 0. self.old_utilities = dict() @property def price(self): """ :return: Returns current price (positive). """ try: return math.fabs(self.price_var.x) except GurobiError: return None @property def utilities(self): """ :return: Returns current utilities (positive): dict(agent_id: utility) """ return dict((v[0], math.fabs(v[1].x)) for v in self.utility_vars.iteritems()) @property def objective(self): try: return self.z.x except GurobiError: return 0. def solve(self): while self.iterate(): pass return self.allocations def iterate(self): """ Performs one iteration of the Bender Auction. Optimizes current master problem, requests an approximate \ allocation based on current prices and utilities, calculates phi with current optimal values of master problem \ and then compares this with current z value. :return: False if auction is done and True if a Bender's cut has been added and the auction continues. """ iteration = len(self.allocations) self.log.log('') self.log.log('######## ITERATION %s ########' % iteration) self.optimize() no_change = self.old_z == self.objective and all( [any(old_utility == utility for old_utility in self.old_utilities) for utility in self.utilities]) self.log.log("no change ... %s" % no_change) self.old_z = self.objective self.old_utilities = self.utilities # allocation := X allocation = self.approximator.approximate(self.price, self.utilities) # first_term - second_term = w*b - (c + wA) * X # first_term is w*b first_term = sum([-w * b for w, b in zip(self.utilities.values() + [self.price], self.b)]) # second_term is (c + wA) * X second_term = 0 for assignment in allocation.assignments: # for each x_ij which is 1 we generate c + wA which is (for MUA): v_i(j) + price * j + u_i second_term += self.price * assignment.quantity second_term += -self.utilities[assignment.agent_id] second_term += assignment.valuation phi = first_term - second_term self.log.log('phi = %s - %s = %s' % (first_term, second_term, phi)) # check if phi with current result of master-problem is z (with tolerance) if math.fabs(phi - self.z.x) < epsilon or iteration > iteration_abort_threshold: self.remove_bad_cuts() self.set_allocation_probabilities() self.print_results() return False else: self.give_second_chance = True # otherwise continue and add cut based on this iteration's allocation allocation_name = 'X%s' % iteration self.allocations[allocation_name] = allocation self.add_benders_cut(allocation, allocation_name) self.set_allocation_probabilities() return True def add_price_constraint(self, new_price=None): if True: return None try: self.m.remove(self.m.getConstrByName("price_constraint")) except GurobiError: pass if new_price != None: self.old_price_constraint = new_price else: self.old_price_constraint -= .5 self.log.log(self.old_price_constraint) self.m.addConstr(self.price_var, GRB.EQUAL, self.old_price_constraint, name="price_constraint") def print_results(self): """ Prints results in console. """ self.log.log('') self.log.log('####### SUMMARY #######') self.log.log('') self.m.write("master-program.lp") for item in self.allocations.iteritems(): if item[1].probability > 0: # noinspection PyArgumentList self.log.log('%s (%s)' % (item[0], item[1].probability)) item[1].print_me(self.log) self.log.log('') if self.price_changed: self.log.log('Price has decreased at some point.') self.log.log('%s iterations needed' % len(self.allocations)) self.log.log('E[Social welfare] is %s' % -self.z.x) def optimize(self): """ Optimizes current master-problem and outputs optimal values and dual variables """ # for observation we save the current price current_price = self.price if self.price else 0. self.m.optimize() if current_price > self.price: self.price_changed = True for v in [v for v in self.m.getVars() if v.x != 0.]: self.log.log('%s %g' % (v.varName, v.x)) for l in self.m.getConstrs(): if l.Pi > 0: self.log.log('%s %g' % (l.constrName, l.Pi)) def remove_bad_cuts(self): for l in self.m.getConstrs(): if l.Pi == 0: self.m.remove(l) def add_benders_cut(self, allocation, name): """ Adds another cut z <= wb - (c + wA) * X. :param allocation: Allocation as list of Assignment. :param name: Name for new constraint. """ # wb part of cut expr = LinExpr(self.b, self.utility_vars.values() + [self.price_var]) for assignment in allocation.assignments: # c expr.addConstant(-assignment.valuation) # if w=(u, p) then this is the uA part (for columns where X is 1) expr.addTerms(-1, self.utility_vars[assignment.agent_id]) # if w=(u, p) then this is the pA part (for columns where X is 1) expr.addTerms(-assignment.quantity, self.price_var) # we get v_i(j) + u_i + j * price summed over all i,j where x_ij = 1 self.m.addConstr(self.z, GRB.LESS_EQUAL, expr, name=name) def set_allocation_probabilities(self): for item in self.allocations.iteritems(): # noinspection PyArgumentList constraint = self.m.getConstrByName(item[0]) item[1].probability = constraint.pi if constraint else 0
# Model m = Model('ref') # Decision variables b = m.addVars(months, lb=0, ub=max_buy, vtype=GRB.CONTINUOUS, name="b") s = m.addVars(months, lb=0, ub=max_sell, vtype=GRB.CONTINUOUS, name="s") k = m.addVars(months, lb=0, ub=storage_capacity, vtype=GRB.CONTINUOUS, name="k") print(s) # Objective function expr = 0 for i in months: expr = expr + price[i] * s[i] - cost[i] * b[i] - storage_cost * k[i] m.setObjective(expr, sense=GRB.MAXIMIZE) # Constraints for i in months: if i == 8: m.addConstr(k[i] - b[i] + s[i] == current_stock) else: m.addConstr(k[i] - k[i - 1] - b[i] + s[i] == 0) m.optimize() print('Objective value: %g' % m.objVal) for v in m.getVars(): print('%s %g' % (v.varName, v.x))
# Create the model object m = Model('diet_problem') # Create the variables xa = m.addVar(0, GRB.INFINITY, vtype=GRB.CONTINUOUS, name="xa") xb = m.addVar(0, GRB.INFINITY, vtype=GRB.CONTINUOUS, name="xb") # a different way to create a non-negative continuous variable xc = m.addVar(name="xc") xd = m.addVar(0, GRB.INFINITY, name="xd") xe = m.addVar(name="xe") # Create the objective function expr = 8 * xa + 10 * xb + 3 * xc + 20 * xd + 15 * xe m.setObjective(expr, sense=GRB.MINIMIZE) # Create the constraints. We will use different ways of adding a constraint expr = 0.4 * xa + 1.2 * xb + 0.6 * xc + 0.6 * xd + 12.2 * xe m.addConstr(lhs=expr, sense=GRB.GREATER_EQUAL, rhs=70) m.addConstr(6 * xa + 10 * xb + 3 * xc + 1 * xd + 0 * xe >= 50) m.addConstr(0.4 * xa + 0.6 * xb + 0.4 * xc + 0.2 * xd + 2.6 * xe, GRB.GREATER_EQUAL, 12) m.optimize() print('Objective value: %g' % m.objVal) print('%s %g' % (xa.varName, xa.x)) print('%s %g' % (xb.varName, xb.x)) print('%s %g' % (xc.varName, xc.x)) print('%s %g' % (xd.varName, xd.x)) print('%s %g' % (xe.varName, xe.x))
class OptimalSolver: def __init__(self, supply, agents, gap, restriced=False): print '' print 'Optimal Solver:' self.m = Model("multi-unit-auction") self.m.params.LogToConsole = 0 self.allocation_vars = dict() for agent in agents: for i in range(1, supply + 1): self.allocation_vars[agent.id, i] = self.m.addVar(lb=0., ub=1., vtype=GRB.CONTINUOUS, name='x_%s_%s' % (agent.id, i)) self.m.update() for agent in agents: self.m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, supply + 1)), GRB.LESS_EQUAL, 1, name="u_%s" % agent.id) if restriced: for valuation in agent.valuations: if valuation.valuation > 0: self.m.addConstr(self.allocation_vars[agent.id, valuation.quantity] >= epsilon, name="not_zero_%s_%s" % (agent.id, valuation.quantity)) self.m.addConstr(quicksum(self.allocation_vars[agent.id, i]*i for i in range(1, supply + 1) for agent in agents), GRB.LESS_EQUAL, supply, name="price") obj_expr = LinExpr() for agent in agents: for valuation in agent.valuations: obj_expr.addTerms(valuation.valuation, self.allocation_vars[agent.id, valuation.quantity]) self.m.setObjective(obj_expr, GRB.MAXIMIZE) self.m.update() self.m.optimize() # # for agent in agents: # for i in range(1, supply + 1): # self.allocation_vars[agent.id, i] = self.m.addVar(vtype=GRB.CONTINUOUS, lb=0, # name='x_%s_%s' % (agent.id, i)) # # self.m.update() # # self.m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, supply + 1) for agent in agents), # GRB.LESS_EQUAL, supply / gap, name="price") # for agent in agents: # for i in range(1, supply): # self.m.addConstr(self.allocation_vars[agent.id, i + 1] - self.allocation_vars[agent.id, i], # GRB.LESS_EQUAL, 0, name="chain_%s_%s" % (agent.id, i)) # self.m.addConstr(self.allocation_vars[agent.id, i], GRB.LESS_EQUAL, 1. / gap, # name="p_%s_%s" % (agent.id, i)) # self.m.addConstr(self.allocation_vars[agent.id, supply], GRB.GREATER_EQUAL, 0, name="greater_%s" % agent.id) # self.m.addConstr(self.allocation_vars[agent.id, 1], GRB.LESS_EQUAL, 1. / gap, name="u_%s" % agent.id) # # # m.addConstr(x11 + 2*x12 + 3*x13 + 4*x14 + x21 + 2*x22 + 3*x23 + 4*x24, GRB.LESS_EQUAL, 4, name="p_an") # # obj_expr = LinExpr() # for agent in agents: # prev_val = None # for valuation in agent.valuations: # try: # prev_val = next(val for val in agent.valuations if val.quantity == valuation.quantity - 1) # except StopIteration: # pass # marginal_value = valuation.valuation - (prev_val.valuation if prev_val else 0) # obj_expr.addTerms(marginal_value, self.allocation_vars[agent.id, valuation.quantity]) # self.m.setObjective(obj_expr, GRB.MAXIMIZE) # # self.m.optimize() for v in [v for v in self.m.getVars() if v.x != 0.]: print('%s %g' % (v.varName, v.x)) print '' print 'CONSTRAINTS:' for l in self.m.getConstrs(): if l.Pi > 0: print('%s %g' % (l.constrName, l.Pi)) print self.m.getObjective().getValue() # print 'Optimal solution:' # for v in self.m.getVars(): # print('%s %g' % (v.varName, v.x)) # for l in self.m.getConstrs(): # if l.Pi > 0: # print('%s %g' % (l.constrName, l.Pi)) print 'OPT social welfare %s | %s/%s=%s' % ( self.m.getObjective().getValue(), self.m.getObjective().getValue(), gap, self.m.getObjective().getValue() / gap) self.m.write('optimal-lp.lp') self.m.write('optimal-lp.sol')
__author__ = 'Usiel' m = Model("play") x11 = m.addVar(vtype=GRB.CONTINUOUS, name="x11", lb=0) x12 = m.addVar(vtype=GRB.CONTINUOUS, name="x12") x13 = m.addVar(vtype=GRB.CONTINUOUS, name="x13") x14 = m.addVar(vtype=GRB.CONTINUOUS, name="x14") x21 = m.addVar(vtype=GRB.CONTINUOUS, name="x21") x22 = m.addVar(vtype=GRB.CONTINUOUS, name="x22") x23 = m.addVar(vtype=GRB.CONTINUOUS, name="x23") x24 = m.addVar(vtype=GRB.CONTINUOUS, name="x24") m.update() m.addConstr(x11 + x12 + x13 + x14 + x21 + x22 + x23 + x24, GRB.LESS_EQUAL, 2, name="all") m.addConstr(x12, GRB.LESS_EQUAL, x11, name="c11") m.addConstr(x13, GRB.LESS_EQUAL, x12, name="c12") m.addConstr(x14, GRB.LESS_EQUAL, x13, name="c13") m.addConstr(x22, GRB.LESS_EQUAL, x21, name="c21") m.addConstr(x23, GRB.LESS_EQUAL, x22, name="c22") m.addConstr(x24, GRB.LESS_EQUAL, x23, name="c23") m.addConstr(x14, GRB.GREATER_EQUAL, 0, name="11") m.addConstr(x24, GRB.GREATER_EQUAL, 0, name="12") m.addConstr(x11, GRB.LESS_EQUAL, .5, name="u1") m.addConstr(x21, GRB.LESS_EQUAL, .5, name="u2") #m.addConstr(x11 + 2*x12 + 3*x13 + 4*x14 + x21 + 2*x22 + 3*x23 + 4*x24, GRB.LESS_EQUAL, 4, name="p_an") m.setObjective(x11 * 6 + x12 * 0 + x13 * 0 + x14 * 3 + x21 * 1 + x22 * 3 + x23 * 0 + x24 * 2, GRB.MAXIMIZE)
def setConstraints(data: DataInstance, model: Model, relVars, boolVars, vVars, elemVars, posVars, N): L, R, T, B, H, W = posVars ABOVE, LEFT = relVars LAG, RAG, TAG, BAG = boolVars vLAG, vRAG, vTAG, vBAG = vVars elemAtLAG, elemAtRAG, elemAtTAG, elemAtBAG = elemVars # Known Position constraints X Y HORIZONTAL_TOLERANCE = data.canvasWidth * FLEXIBILITY_VALUE VERTICAL_TOLERANCE = data.canvasWidth * FLEXIBILITY_VALUE for element in range(data.element_count): print("At element ", element, "with lock = ", data.elements[element].isLocked) if data.elements[element].isLocked: if data.elements[element].X is not None and data.elements[element].X >= 0: model.addConstr(L[element] == data.elements[element].X, "PrespecifiedXOfElement(", element, ")") if data.elements[element].Y is not None and data.elements[element].Y >= 0: model.addConstr(T[element] == data.elements[element].Y, "PrespecifiedYOfElement(", element, ")") else: if data.elements[element].X is not None and data.elements[element].X >= 0: model.addConstr(L[element] >= data.elements[element].X - HORIZONTAL_TOLERANCE, "PrespecifiedXminOfElement(", element, ")") model.addConstr(L[element] <= data.elements[element].X + HORIZONTAL_TOLERANCE, "PrespecifiedXmaxOfElement(", element, ")") if data.elements[element].Y is not None and data.elements[element].Y >= 0: model.addConstr(T[element] >= data.elements[element].Y - VERTICAL_TOLERANCE, "PrespecifiedYminOfElement(", element, ")") model.addConstr(T[element] <= data.elements[element].Y + VERTICAL_TOLERANCE, "PrespecifiedYmaxOfElement(", element, ")") if data.elements[element].aspectRatio is not None and data.elements[element].aspectRatio > 0.001: model.addConstr(W[element] == data.elements[element].aspectRatio * H[element], "PrespecifiedAspectRatioOfElement(", element, ")") # Known Position constraints TOP BOTTOM LEFT RIGHT coeffsForAbsolutePositionExpression = [] varsForAbsolutePositionExpression = [] for element in range(data.element_count): for other in range(data.element_count): if element != other: if data.elements[element].verticalPreference is not None: if data.elements[element].verticalPreference.lower() == "top": varsForAbsolutePositionExpression.append(ABOVE[other, element]) coeffsForAbsolutePositionExpression.append(1.0) if data.elements[element].verticalPreference.lower() == "bottom": varsForAbsolutePositionExpression.append(ABOVE[element, other]) coeffsForAbsolutePositionExpression.append(1.0) if data.elements[element].horizontalPreference is not None: if data.elements[element].horizontalPreference.lower() == "left": varsForAbsolutePositionExpression.append(LEFT[other, element]) coeffsForAbsolutePositionExpression.append(1.0) if data.elements[element].horizontalPreference.lower() == "right": varsForAbsolutePositionExpression.append(LEFT[element, other]) coeffsForAbsolutePositionExpression.append(1.0) expression = LinExpr(coeffsForAbsolutePositionExpression, varsForAbsolutePositionExpression) model.addConstr(expression == 0, "Disable non-permitted based on prespecified") # Height/Width/L/R/T/B Summation Sanity for element in range(N): model.addConstr(W[element] + L[element] == R[element], "R-L=W(" + str(element) + ")") model.addConstr(H[element] + T[element] == B[element], "B-T=H(" + str(element) + ")") # MinMax limits of Left-Above interactions for element in range(N): for otherElement in range(N): if element > otherElement: model.addConstr( ABOVE[element, otherElement] + ABOVE[otherElement, element] + LEFT[element, otherElement] + LEFT[ otherElement, element] >= 1, "NoOverlap(" + str(element) + str(otherElement) + ")") model.addConstr( ABOVE[element, otherElement] + ABOVE[otherElement, element] + LEFT[element, otherElement] + LEFT[ otherElement, element] <= 2, "UpperLimOfQuadrants(" + str(element) + str(otherElement) + ")") model.addConstr(ABOVE[element, otherElement] + ABOVE[otherElement, element] <= 1, "Anti-symmetryABOVE(" + str(element) + str(otherElement) + ")") model.addConstr(LEFT[element, otherElement] + LEFT[otherElement, element] <= 1, "Anti-symmetryLEFT(" + str(element) + str(otherElement) + ")") # Interconnect L-R-LEFT and T-B-ABOVE for element in range(N): for otherElement in range(N): if element != otherElement: model.addConstr( R[element] + data.elementXPadding <= L[otherElement] + (1 - LEFT[element, otherElement]) * ( data.canvasWidth + data.elementXPadding), (str(element) + "(ToLeftOf)" + str(otherElement))) model.addConstr( B[element] + data.elementYPadding <= T[otherElement] + (1 - ABOVE[element, otherElement]) * ( data.canvasHeight + data.elementYPadding), (str(element) + "(Above)" + str(otherElement))) model.addConstr( (L[otherElement] - R[element] - data.elementXPadding) <= data.canvasWidth * LEFT[ element, otherElement] , (str(element) + "(ConverseOfToLeftOf)" + str(otherElement))) model.addConstr( (T[otherElement] - B[element] - data.elementYPadding) <= data.canvasHeight * ABOVE[ element, otherElement] , (str(element) + "(ConverseOfAboveOf)" + str(otherElement))) # One Alignment-group for every edge of every element for element in range(N): coeffsForLAG = [] coeffsForRAG = [] coeffsForTAG = [] coeffsForBAG = [] varsForLAG = [] varsForRAG = [] varsForTAG = [] varsForBAG = [] for alignmentGroupIndex in range(data.element_count): varsForLAG.append(elemAtLAG[element, alignmentGroupIndex]) coeffsForLAG.append(1) varsForRAG.append(elemAtRAG[element, alignmentGroupIndex]) coeffsForRAG.append(1) varsForTAG.append(elemAtTAG[element, alignmentGroupIndex]) coeffsForTAG.append(1) varsForBAG.append(elemAtBAG[element, alignmentGroupIndex]) coeffsForBAG.append(1) model.addConstr(LinExpr(coeffsForLAG, varsForLAG) == 1, "OneLAGForElement[" + str(element) + "]") model.addConstr(LinExpr(coeffsForTAG, varsForTAG) == 1, "OneTAGForElement[" + str(element) + "]") model.addConstr(LinExpr(coeffsForBAG, varsForBAG) == 1, "OneBAGForElement[" + str(element) + "]") model.addConstr(LinExpr(coeffsForRAG, varsForRAG) == 1, "OneRAGForElement[" + str(element) + "]") # Symmetry breaking and sequencing of alignment groups # for alignmentGroupIndex in range(data.N): # if(alignmentGroupIndex >= 1): # print() # gurobi.addConstr(LAG[alignmentGroupIndex] <= LAG[alignmentGroupIndex-1], "SymmBreakLAG["+str(alignmentGroupIndex)+ "]") # gurobi.addConstr(TAG[alignmentGroupIndex] <= TAG[alignmentGroupIndex-1], "SymmBreakTAG["+str(alignmentGroupIndex)+ "]") # gurobi.addConstr(RAG[alignmentGroupIndex] <= RAG[alignmentGroupIndex-1], "SymmBreakRAG["+str(alignmentGroupIndex)+ "]") # gurobi.addConstr(BAG[alignmentGroupIndex] <= BAG[alignmentGroupIndex-1], "SymmBreakBAG["+str(alignmentGroupIndex)+ "]") # gurobi.addConstr(vLAG[alignmentGroupIndex] >= vLAG[alignmentGroupIndex-1]+1, "ProgressiveIndexLAG["+str(alignmentGroupIndex)+"]") # gurobi.addConstr(vTAG[alignmentGroupIndex] >= vTAG[alignmentGroupIndex-1]+1, "ProgressiveIndexTAG["+str(alignmentGroupIndex)+"]") # gurobi.addConstr(vRAG[alignmentGroupIndex] >= vRAG[alignmentGroupIndex-1]+1, "ProgressiveIndexRAG["+str(alignmentGroupIndex)+"]") # gurobi.addConstr(vBAG[alignmentGroupIndex] >= vBAG[alignmentGroupIndex-1]+1, "ProgressiveIndexBAG["+str(alignmentGroupIndex)+"]") # Assign alignment groups to elements only if groups are enabled for alignmentGroupIndex in range(data.element_count): for element in range(N): model.addConstr(elemAtLAG[element, alignmentGroupIndex] <= LAG[alignmentGroupIndex]) model.addConstr(elemAtRAG[element, alignmentGroupIndex] <= RAG[alignmentGroupIndex]) model.addConstr(elemAtTAG[element, alignmentGroupIndex] <= TAG[alignmentGroupIndex]) model.addConstr(elemAtBAG[element, alignmentGroupIndex] <= BAG[alignmentGroupIndex]) # Correlate alignment groups value with element edge if assigned for alignmentGroupIndex in range(data.element_count): for element in range(N): model.addConstr(L[element] <= vLAG[alignmentGroupIndex] + data.canvasWidth * ( 1 - elemAtLAG[element, alignmentGroupIndex]), "MinsideConnectL[" + str(element) + "]ToLAG[" + str(alignmentGroupIndex) + "]") model.addConstr(R[element] <= vRAG[alignmentGroupIndex] + data.canvasWidth * ( 1 - elemAtRAG[element, alignmentGroupIndex]), "MinsideConnectR[" + str(element) + "]ToRAG[" + str(alignmentGroupIndex) + "]") model.addConstr(T[element] <= vTAG[alignmentGroupIndex] + data.canvasHeight * ( 1 - elemAtTAG[element, alignmentGroupIndex]), "MinsideConnectT[" + str(element) + "]ToTAG[" + str(alignmentGroupIndex) + "]") model.addConstr(B[element] <= vBAG[alignmentGroupIndex] + data.canvasHeight * ( 1 - elemAtBAG[element, alignmentGroupIndex]), "MinsideConnectB[" + str(element) + "]ToBAG[" + str(alignmentGroupIndex) + "]") model.addConstr(L[element] >= vLAG[alignmentGroupIndex] - data.canvasWidth * ( 1 - elemAtLAG[element, alignmentGroupIndex]), "MaxsideConnectL[" + str(element) + "]ToLAG[" + str(alignmentGroupIndex) + "]") model.addConstr(R[element] >= vRAG[alignmentGroupIndex] - data.canvasWidth * ( 1 - elemAtRAG[element, alignmentGroupIndex]), "MaxsideConnectR[" + str(element) + "]ToRAG[" + str(alignmentGroupIndex) + "]") model.addConstr(T[element] >= vTAG[alignmentGroupIndex] - data.canvasHeight * ( 1 - elemAtTAG[element, alignmentGroupIndex]), "MaxsideConnectT[" + str(element) + "]ToTAG[" + str(alignmentGroupIndex) + "]") model.addConstr(B[element] >= vBAG[alignmentGroupIndex] - data.canvasHeight * ( 1 - elemAtBAG[element, alignmentGroupIndex]), "MaxsideConnectB[" + str(element) + "]ToBAG[" + str(alignmentGroupIndex) + "]")
def Build_LDR_Model(self): """ LDR for location-inventpry problem is only feasible when all affine coefficients equal to 0, which violates from what we want. For more info about how to design a reasonable prepositioning network, see: http://web.hec.ca/pages/erick.delage/LRC_TRO.pdf The above paper assume support set is a convex polyhedron characterized by linear constraints. """ m, n = self.m, self.n f, h = self.f, self.h mu, sigma = self.mu, self.sigma roads = self.roads INF = float('inf') f_ks, K = self.ldr_params['f_k'], len(self.ldr_params['f_k']) # declare model ldr_model = Model() # decision variables I = ldr_model.addVars(m, vtype=GRB.CONTINUOUS, lb=0.0, name='I') Z = ldr_model.addVars(m, vtype=GRB.BINARY, lb=0.0, name='Z') t = ldr_model.addVars(n, vtype=GRB.CONTINUOUS, lb=-INF, name='t') gamma = ldr_model.addVar(lb=-INF, vtype=GRB.CONTINUOUS, name='gamma') s = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=0.0, name='s') phi = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=0.0, name='phi') psi = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=-INF, name='psi') xi = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=-INF, name='xi') eta = ldr_model.addVars(n, K, vtype=GRB.CONTINUOUS, lb=0.0, name='eta') tau = ldr_model.addVars(n, K, vtype=GRB.CONTINUOUS, lb=-INF, name='tau') theta = ldr_model.addVars(n, K, vtype=GRB.CONTINUOUS, lb=-INF, name='theta') w = ldr_model.addVars(m, K, vtype=GRB.CONTINUOUS, lb=0.0, name='w') lambd = ldr_model.addVars(m, K, vtype=GRB.CONTINUOUS, lb=-INF, name='lambda') delta = ldr_model.addVars(m, K, vtype=GRB.CONTINUOUS, lb=-INF, name='delta') alpha_0 = ldr_model.addVars(roads, vtype=GRB.CONTINUOUS, lb=-INF, name='alpha_0') alpha = ldr_model.addVars(roads, n, vtype=GRB.CONTINUOUS, lb=-INF, name='alpha') beta = ldr_model.addVars(roads, K, vtype=GRB.CONTINUOUS, lb=-INF, name='beta') # objective function obj1 = quicksum([f[i]*Z[i] for i in range(m)]) obj2 = quicksum([h[i]*I[i] for i in range(m)]) obj3 = quicksum([mu[i]*t[i] for i in range(m)]) obj4 = quicksum(s[k]*matmul(matmul(f_k, sigma), f_k) for k, f_k in enumerate(f_ks)) obj5 = gamma ldr_model.setObjective(obj1 + obj2 + obj3 + obj4 + obj5) ldr_model.modelSense = GRB.MINIMIZE # constraint # c1 ldr_model.addConstr(gamma + alpha_0.sum() >= 1/2*(phi.sum() - psi.sum()), name='c1') # c2 ldr_model.addConstrs((1/2*(phi[k]+psi[k]) == beta.sum('*', '*', k) + s[k]*len(roads) for k in range(K)), name='c2') # c3 a_star_star = [alpha.sum('*', '*', l) for l in range(n)] ldr_model.addConstrs((xi[k]*f_ks[k][l] <= t[l]+a_star_star[l]-1 for k in range(K) for l in range(n)), name='c3') # c4 ldr_model.addConstrs((-alpha_0.sum('*', j) >= 1/2*(eta.sum(j, '*')-tau.sum(j, '*')) for j in range(n)), name='c4') # c5 ldr_model.addConstrs((-1/2*(eta[j, k]+tau[j, k]) == beta.sum('*', j, k) for k in range(K) for j in range(n)), name='c5') # c6 for j in range(n): a_star_j = [alpha.sum('*', j, l) if l != j else alpha.sum('*', j, l)-1 for l in range(n)] for k, f_k in enumerate(f_ks): ldr_model.addConstrs(-theta[j, k]*f_k[l] >= a_star_j[l] for l in range(n)) # c7 ldr_model.addConstrs((I[i]-alpha_0.sum(i, '*') >= 1/2*(w.sum(i, '*')-lambd.sum(i, '*')) for i in range(m)), name='c7') # c8 ldr_model.addConstrs((-1/2*(w[i, k]+lambd[i, k]) == beta.sum(i, '*', k) for i in range(m) for k in range(K)), name='c8') # c9 for i in range(m): a_i_star = [alpha.sum(i, '*', l) for l in range(n)] for k, f_k in enumerate(f_ks): ldr_model.addConstrs(-delta[i, k]*f_k[l] >= a_i_star[l] for l in range(n)) # c10 I,Z ldr_model.addConstrs(I[i] <= 10000*Z[i] for i in range(m)) # c11 ldr_model.addConstrs(phi[k]*phi[k] >= psi[k]*psi[k] + xi[k]*xi[k] for k in range(K)) ldr_model.addConstrs(eta[i, k]*eta[i, k] >= tau[i, k]*tau[i, k] + theta[i, k]*theta[i, k] for k in range(K) for i in range(m)) ldr_model.addConstrs(w[i, k]*w[i, k] >= lambd[i, k]*lambd[i, k] + delta[i, k]*delta[i, k] for k in range(K) for i in range(m)) # update ldr_model.update() ldr_model.optimize() # print(I) # print(Z) # print(alpha_0) # print(alpha) # print(beta) # print(ldr_model.ObjVal) self.model = ldr_model
from gurobipy.gurobipy import GRB, Model, GurobiError try: # Create model m = Model('test') # Create variables x = m.addVar(vtype=GRB.BINARY, name='x') y = m.addVar(vtype=GRB.BINARY, name='y') z = m.addVar(vtype=GRB.BINARY, name='z') # Integrate new variables m.update() # Set objective function m.setObjective(x + y + 2 * z, GRB.MAXIMIZE) # Add constraints m.addConstr(x + 2 * y + 3 * z <= 4, 'c0') m.addConstr(x + y >= 1, 'c1') m.optimize() for v in m.getVars(): print v.varName, v.x print 'Obj:', m.objVal except GurobiError: print 'Error reported'