Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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")
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
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()
Exemplo n.º 10
0
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)
Exemplo n.º 11
0
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))
Exemplo n.º 12
0
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
Exemplo n.º 13
0
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)
Exemplo n.º 14
0
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)
Exemplo n.º 15
0
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")
Exemplo n.º 16
0
    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
Exemplo n.º 17
0
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)
Exemplo n.º 18
0
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
Exemplo n.º 19
0
    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))
Exemplo n.º 20
0
# 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
Exemplo n.º 22
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))
Exemplo n.º 23
0
# 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)

Exemplo n.º 26
0
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) + "]")
Exemplo n.º 27
0
    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'