class Backup(object):
    """ Class object for normal-based backup network model.

    Parameters
    ----------
    nodes: set of nodes
    links: set of links
    capacity: capacities per link based based on random failures 
    mean: mean for failure random variable
    std: standard deviation for failure random variable
    invstd: inverse of Phi-normal distribution for (1-epsilon)

    
    Returns
    -------
    solution: set of capacity assigned per backup link. 
    
    """
    # Private model object
    __model = []
    
    # Private model variables
    __BackupCapacity = {}
    __bBackupLink = {}
    __ValidLink = {}
        
    # Private model parameters
    __links = []
    __nodes = []
    __capacity = []
    __mean = []
    __std = []
    __invstd = 1
    
    def __init__(self,nodes,links,capacity,mean,std,invstd):
        '''
        Constructor
        '''
        self.__links = links
        self.__nodes = nodes
        self.__capacity = capacity
        self.__mean = mean
        self.__std = std
        self.__invstd = invstd
        
        self.__loadModel()
                
    def __loadModel(self):
                
        # Create optimization model
        self.__model = Model('Backup')
    
        # Auxiliary variables for SOCP reformulation
        U = {}
        R = {}
      
        # Create variables
        for i,j in self.__links:
            self.__BackupCapacity[i,j] = self.__model.addVar(lb=0, obj=1, name='Backup_Capacity[%s,%s]' % (i, j))
        self.__model.update()
         
        for i,j in self.__links:
            for s,d in self.__links:
                self.__bBackupLink[i,j,s,d] = self.__model.addVar(vtype=GRB.BINARY,obj=1,name='Backup_Link[%s,%s,%s,%s]' % (i, j, s, d))
        self.__model.update()
        
        for i,j in self.__links:
            U[i,j] = self.__model.addVar(obj=1,name='U[%s,%s]' % (i, j))
        self.__model.update()
        
        for i,j in self.__links:
            for s,d in self.__links:
                R[i,j,s,d] = self.__model.addVar(obj=1,name='R[%s,%s,%s,%s]' % (i,j,s,d))
        self.__model.update()
        
        self.__model.modelSense = GRB.MINIMIZE
        #m.setObjective(quicksum([fixedCosts[p]*open[p] for p in plants]))
        self.__model.setObjective(quicksum(self.__BackupCapacity[i,j] for i,j in self.__links))
        self.__model.update()
        
           
        #------------------------------------------------------------------------#
        #                    Constraints definition                              #
        #                                                                        #
        #                                                                        #
        #------------------------------------------------------------------------#
         
        # Link capacity constraints
        for i,j in self.__links:
            self.__model.addConstr(self.__BackupCapacity[i,j] >= quicksum(self.__mean[s,d]*self.__bBackupLink[i,j,s,d] for (s,d) in self.__links) + U[i,j]*self.__invstd,'[CONST]Link_Cap_%s_%s' % (i, j))
        self.__model.update()
            
        # SCOP Reformulation Constraints
        for i,j in self.__links:
            self.__model.addConstr(quicksum(R[i,j,s,d]*R[i,j,s,d] for (s,d) in self.__links) <= U[i,j]*U[i,j],'[CONST]SCOP1[%s][%s]' % (i, j))
        self.__model.update()
            
        # SCOP Reformulation Constraints    
        for i,j in self.__links:
            for s,d in self.__links:
                self.__model.addConstr(self.__std[s,d]*self.__bBackupLink[i,j,s,d] == R[i,j,s,d],'[CONST]SCOP2[%s][%s][%s][%s]' % (i, j,s,d))
        self.__model.update()
        
        for i in self.__nodes:
            for s,d in self.__links:
                # Flow conservation constraints
                if i == s:
                    self.__model.addConstr(quicksum(self.__bBackupLink[i,j,s,d] for i,j in self.__links.select(i,'*')) - 
                                           quicksum(self.__bBackupLink[j,i,s,d] for j,i in self.__links.select('*',i)) == 1,'Flow1[%s,%s,%s,%s]' % (i,j,s, d))
                # Flow conservation constraints
                elif i == d:
                    self.__model.addConstr(quicksum(self.__bBackupLink[i,j,s,d] for i,j in self.__links.select(i,'*')) - 
                                           quicksum(self.__bBackupLink[j,i,s,d] for j,i in self.__links.select('*',i)) == -1,'Flow2[%s,%s,%s,%s]' % (i,j,s, d))
                # Flow conservation constraints
                else:    
                    self.__model.addConstr(quicksum(self.__bBackupLink[i,j,s,d] for i,j in self.__links.select(i,'*')) - 
                                           quicksum(self.__bBackupLink[j,i,s,d] for j,i in self.__links.select('*',i)) == 0,'Flow3[%s,%s,%s,%s]' % (i,j,s, d))
        self.__model.update()
                
        
    def optimize(self,MipGap, TimeLimit):
        
        self.__model.write('backup.lp')
        
        if MipGap != None:
            self.__model.params.timeLimit = TimeLimit
        if TimeLimit != None:
            self.__model.params.MIPGap = MipGap
         
        # Compute optimal solution
        self.__model.optimize()
        
        # Print solution
        if self.__model.status == GRB.Status.OPTIMAL:
            solution = self.__model.getAttr('x', self.__BackupCapacity)
            for i,j in self.__links:
                if solution[i,j] > 0:
                    print('%s -> %s: %g' % (i, j, solution[i,j]))
            
        else:
            print('Optimal value not found!\n')
            solution = []
            
        return solution;    
    
    def reset(self):
        '''
        Reset model solution
        '''
        self.__model.reset()
Пример #2
0
def create_problem(cobra_model, objective_sense="maximize"):
    lp = Model("cobra")
    lp.Params.OutputFlag = 0

    if objective_sense == 'maximize':
        objective_sign = -1.0
    elif objective_sense == 'minimize':
        objective_sign = 1.0
    else:
        raise ValueError("objective_sense must be 'maximize' or 'minimize'")

    # create metabolites/constraints
    metabolite_constraints = {}
    for metabolite in cobra_model.metabolites:
        metabolite_constraints[metabolite] = \
            lp.addConstr(0.0, sense_dict[metabolite._constraint_sense],
            metabolite._bound, metabolite.id)
    lp.update()

    # create reactions/variables along with S matrix
    for j, reaction in enumerate(cobra_model.reactions):
        constraints = [metabolite_constraints[i] \
            for i in reaction._metabolites]
        stoichiometry = reaction._metabolites.values()
        lp.addVar(
            lb=float(reaction.lower_bound),
            ub=float(reaction.upper_bound),
            obj=objective_sign * reaction.objective_coefficient,
            name=reaction.id,
            vtype=variable_kind_dict[reaction.variable_kind],
            column=Column(stoichiometry, constraints))
    lp.update()
    return lp
Пример #3
0
class MainProblem:
    def __init__(self):
        self.model = Model("main_problem")

        self.x_1 = self.model.addVar(lb=0, name="x_1")
        self.x_2 = self.model.addVar(lb=0, name="x_2")
        self.x_3 = self.model.addVar(lb=0, name="x_3")
        self.x_4 = self.model.addVar(lb=0, name="x_4")
        self.x_5 = self.model.addVar(lb=0, name="x_5")

        self.model.addConstr(self.x_1 + self.x_4 + self.x_5 <= 3)
        self.model.addConstr(2 * self.x_2 + 3 * self.x_4 <= 12)
        self.model.addConstr(self.x_3 - 7 * self.x_5 <= -16)
        self.model.addConstr(-self.x_4 + self.x_5 <= 2)

        self.x_hat_4 = None
        self.x_hat_5 = None

        self.model.setObjective(
            -2 * self.x_1 - self.x_2 + self.x_3 + 3 * self.x_4 - 3 * self.x_5,
            GRB.MINIMIZE,
        )

    def solve(self):
        self.model.optimize()

        return self.model.objVal
Пример #4
0
def build_model(plants, warehouses, capacity, demand, fixed_costs, trans_costs):
    # decision variables
    m = Model("facility")
    is_open = []
    for p in plants:
        is_open.append(m.addVar(vtype=GRB.BINARY,
                                name="is_open[{}]".format(p)))
    trans_qty = []
    for w in warehouses:
        trans_qty.append([])
        for p in plants:
            trans_qty[w].append(m.addVar(vtype=GRB.CONTINUOUS,
                                         name="trans_qty[{}.{}]".format(p, w),
                                         lb=0.0))
    m.update()
    # objective function
    m.setObjective(quicksum(fixed_costs[p] * is_open[p]
                            for p in plants) +
                   quicksum(trans_costs[w][p] * trans_qty[w][p]
                            for w in warehouses
                            for p in plants),
                   GRB.MINIMIZE)
    # constraints
    for p in plants:
        m.addConstr(quicksum(trans_qty[w][p] for w in warehouses) <= capacity[p] * is_open[p],
                    "Capacity({})".format(p))
    for w in warehouses:
        m.addConstr(quicksum(trans_qty[w][p] for p in plants) == demand[w],
                    "Demand({})".format(w))
    m.update()
    return m
Пример #5
0
class MasterProblem:
    def __init__(self):
        self.model = Model("benders_master_problem")

        self.x_4 = self.model.addVar(lb=0, name="x_4")
        self.x_5 = self.model.addVar(lb=0, name="x_5")

        self.phi = self.model.addVar(lb=-100 * 100 * 100, name="phi")

        self.model.addConstr(-self.x_4 + self.x_5 <= 2)

        self.model.setObjective(
            3 * self.x_4 - 3 * self.x_5 + self.phi,
            GRB.MINIMIZE,
        )

    def add_cut(self, lhs, pi_1, pi_2):
        self.model.addConstr(
            lhs <= self.phi - self.x_4 * pi_1 - self.x_5 * pi_2, name="cut")

    def solve(self):
        self.model.optimize()

        return (
            self.model.objVal,
            self.x_4.x,
            self.x_5.x,
        )
Пример #6
0
def solve_lp_knapsack_gurobi(scores, costs, budget):
    from gurobipy import Model, LinExpr, GRB

    n = len(scores)

    # Create a new model.
    m = Model("lp_knapsack")

    # Create variables.
    for i in range(n):
        m.addVar(lb=0.0, ub=1.0)
    m.update()
    vars = m.getVars()

    # Set objective.
    obj = LinExpr()
    for i in range(n):
        obj += scores[i] * vars[i]
    m.setObjective(obj, GRB.MAXIMIZE)

    # Add constraint.
    expr = LinExpr()
    for i in range(n):
        expr += costs[i] * vars[i]
    m.addConstr(expr, GRB.LESS_EQUAL, budget)

    # Optimize.
    m.optimize()
    assert m.status == GRB.OPTIMAL
    x = np.zeros(n)
    for i in range(n):
        x[i] = vars[i].x

    return x
Пример #7
0
def create_problem(cobra_model, objective_sense="maximize"):
    lp = Model("cobra")
    lp.Params.OutputFlag = 0

    if objective_sense == "maximize":
        objective_sign = -1.0
    elif objective_sense == "minimize":
        objective_sign = 1.0
    else:
        raise ValueError("objective_sense must be 'maximize' or 'minimize'")

    # create metabolites/constraints
    metabolite_constraints = {}
    for metabolite in cobra_model.metabolites:
        metabolite_constraints[metabolite] = lp.addConstr(
            0.0, sense_dict[metabolite._constraint_sense], metabolite._bound, metabolite.id
        )
    lp.update()

    # create reactions/variables along with S matrix
    for j, reaction in enumerate(cobra_model.reactions):
        constraints = [metabolite_constraints[i] for i in reaction._metabolites]
        stoichiometry = reaction._metabolites.values()
        lp.addVar(
            lb=float(reaction.lower_bound),
            ub=float(reaction.upper_bound),
            obj=objective_sign * reaction.objective_coefficient,
            name=reaction.id,
            vtype=variable_kind_dict[reaction.variable_kind],
            column=Column(stoichiometry, constraints),
        )
    lp.update()
    return lp
Пример #8
0
def solve_optimal_gurobi(matrix):
    """
    Solves a given tsp instance optimal using the python gurobi solver interface.
    
    Returns a list of indices. The result list has a cardinality
    of the length of the matrix.
    """
    model = Model()
    model.Params.OutputFlag = 0
    n = len(matrix); N = list(range(n))
    # Create variables
    x = [[model.addVar(vtype=GRB.BINARY, ub=1.0, lb=0.0, name='x{}{}'.format(i,j)) for j in N] for i in range(n)]
    u = [ model.addVar(vtype=GRB.CONTINUOUS, name='u{}'.format(i))  for i in N] # miller tucker vars
    model.update()
    # Set objective
    sum_tour_length = [x[i][j] * matrix[i][j] for i in N for j in N]
    model.setObjective(quicksum(sum_tour_length), GRB.MINIMIZE)
    # Constraints for assignment problem:
    [model.addConstr(quicksum([x[i][j] for j in range(n)]) == 1)   for i in N]
    [model.addConstr(quicksum([x[i][j] for i in range(n)]) == 1)   for j in N]
    # Constraints for subtour elimination:
    [model.addConstr(2 <= u[i] <= n) for i in N[1:]]
    [model.addConstr(u[i] - u[j] + 1 <= (n-1)*(1-x[i][j]))   for i in N[1:] for j in N[1:]]
    model.update()
    #model.write('gurobi.lp')
    model.optimize()
    if model.status == GRB.Status.OPTIMAL:
        return __grb_retrieve_tour(model, x)
Пример #9
0
class WheatSubProblem:
    def __init__(self, cfg: Config):
        self.cfg = cfg

        # model.ModelSense is minimization by default
        self.model = Model("wheat_sub_problem")

        self.x_1 = self.model.addVar(ub=self.cfg.area, name="x_1")

        probability = 1 / len(self.cfg.scenarios)
        for index, scenario in enumerate(self.cfg.scenarios):
            self._variables_constraint(index, scenario, probability)

    def _variables_constraint(self, index, scenario, probability):
        y_11 = self.model.addVar(name=f"y_11_{index}",
                                 obj=self.cfg.wheat.buy_price * probability)
        y_12 = self.model.addVar(name=f"y_12_{index}",
                                 obj=-self.cfg.wheat.sell_price * probability)

        self.model.addConstr(
            self.cfg.wheat.requirement <=
            self.x_1 * self.cfg.wheat.produce_rate *
            (1 + scenario) + y_11 - y_12,
            name="wheat_produce_constraint",
        )

    def solve(self, _lambda):
        self.x_1.obj = _lambda + self.cfg.wheat.plant_cost
        self.model.optimize()

        return (
            self.model.objVal,
            self.x_1.x,
        )
def solve(budget, buses, lines, u, c, b, S, D):
    m = Model('inhibit')
    w, v, y = {}, {}, {}
    for i in buses:
        w[i] = m.addVar(vtype=GRB.BINARY, name="w_%s" % i)
    for i, j in lines:
        v[i, j] = m.addVar(vtype=GRB.BINARY, name='v_%s_%s' % (i, j))
        y[i, j] = m.addVar(vtype=GRB.BINARY, name='y_%s_%s' % (i, j))
    m.update()

    for i, j in lines:
        m.addConstr(w[i] - w[j] <= v[i, j] + y[i, j],
                    'balance1_%s_%s' % (i, j))
        m.addConstr(w[j] - w[i] <= v[i, j] + y[i, j],
                    'balance2_%s_%s' % (i, j))
    m.addConstr(
        quicksum(c[i, j] * y[i, j] for i, j in lines) <= budget, 'budget')

    m.setObjective(
        quicksum(u[i, j] * v[i, j] for i, j in lines) +
        quicksum(b[i] * (1 - w[i]) for i in S) - quicksum(b[i] * w[i]
                                                          for i in D))

    m.setParam('OutputFlag', 0)
    m.optimize()
    m.write('gurobi.lp')
    return w, v, y, m
Пример #11
0
def solve_lp_knapsack_gurobi(scores, costs, budget):
    from gurobipy import Model, LinExpr, GRB

    n = len(scores)

    # Create a new model.
    m = Model("lp_knapsack")

    # Create variables.
    for i in range(n):
        m.addVar(lb=0.0, ub=1.0)
    m.update()
    vars = m.getVars()

    # Set objective.
    obj = LinExpr()
    for i in range(n):
        obj += scores[i] * vars[i]
    m.setObjective(obj, GRB.MAXIMIZE)

    # Add constraint.
    expr = LinExpr()
    for i in range(n):
        expr += costs[i] * vars[i]
    m.addConstr(expr, GRB.LESS_EQUAL, budget)

    # Optimize.
    m.optimize()
    assert m.status == GRB.OPTIMAL
    x = np.zeros(n)
    for i in range(n):
        x[i] = vars[i].x

    return x
Пример #12
0
def calculate_sample_weights(pred, c, D, prev_sample_weights=None):
    # Dual problem
    tree_count = len(pred)
    sample_count = len(c)

    m = Model("sample_weight_optimiser")
    sample_weights = [
        m.addVar(vtype=GRB.CONTINUOUS,
                 name="sample_weights " + str(i),
                 ub=D if D > 0 else 1) for i in range(sample_count)
    ]

    # Set sample weights to given value
    if prev_sample_weights is not None:
        for i in range(min(len(prev_sample_weights), len(sample_weights))):
            sample_weights[i].setAttr("Start", prev_sample_weights[i])

    gamma = m.addVar(vtype=GRB.CONTINUOUS, name="gamma", lb=float("-inf"))

    m.setObjective(gamma, GRB.MINIMIZE)

    m.addConstr(quicksum(sample_weights) == 1, name="weights = 1")
    for t in range(tree_count):
        m.addConstr(quicksum([
            c[i] * sample_weights[i] * pred[t][i] for i in range(sample_count)
        ]) <= gamma,
                    name="Constraint on tree " + str(t))

    m.setParam("LogToConsole", 0)
    m.optimize()

    return [w.X for w in sample_weights], gamma.X
Пример #13
0
    def compute_plane(self, batch, row, col, candidates, candidate_flows,
                      is_lower):

        model = Model()

        model.setParam('OutputFlag', False)
        model.setParam('NumericFocus', 2)

        a = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY)
        b = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY)
        c = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY)

        differences = list()

        for candidate, flow in zip(candidates, candidate_flows):
            (x, y), z = flow[batch, row, col], candidate[batch, row, col]
            x, y, z = x.item(), y.item(), z.item()

            if is_lower:
                model.addConstr(a + b * x + c * y <= z)
                differences.append(z - a + b * x + c * y)

            else:
                model.addConstr(a + b * x + c * y >= z)
                differences.append(a + b * x + c * y - z)

        model.setObjective(quicksum(differences), sense=GRB.MINIMIZE)
        model.optimize()

        if model.status != GRB.OPTIMAL:
            raise ValueError('Gurobi: objective not optimal')

        return a.x, b.x, c.x
Пример #14
0
def add_set_flag(
    m: gModel,
    label: str,
    x_var: gVar,
    A: Sequence[Sequence[float]],
    b: Sequence[float],
    K: float,
) -> gVar:
    if len(A) == 1:
        delta = m.addVar(vtype=g.GRB.BINARY, name=label)
        deltas = [delta]
    else:
        deltas = [
            m.addVar(vtype=g.GRB.BINARY, name=delta_label(label, i))
            for i in range(len(A))
        ]
        delta = m.addVar(vtype=g.GRB.BINARY, name=label)

    for i in range(len(A)):
        m.addConstr(
            g.quicksum(A[i][j] * x_var[j]
                       for j in range(len(x_var))) - deltas[i] * K <= b[i])
        m.addConstr(
            g.quicksum(A[i][j] * x_var[j] for j in range(len(x_var))) +
            (1 - deltas[i]) * K >= b[i])
    if len(A) > 1:
        for i in range(len(A)):
            m.addConstr(delta >= deltas[i])
        m.addConstr(delta <= g.quicksum(deltas))

    return delta
Пример #15
0
def q2():
    from gurobipy import Model, GRB, quicksum, LinExpr
    import numpy
    from functions import open_data

    # Creation of the model
    m = Model('LR')

    # Your code goes here
    x, y = open_data()
    N, n = len(x), len(x[0])

    # The following example is here to help you build the model (you must adapt it !!!) 
    # Define decision variables
    var = [] # w, b, z
    for i in range(n):
        var.append(m.addVar(lb = -GRB.INFINITY, vtype=GRB.CONTINUOUS, name = 'w_{}'.format(i), obj = 1))
    var.append(m.addVar(lb = -GRB.INFINITY, vtype=GRB.CONTINUOUS, name = 'b'.format(i), obj = 1))
    for i in range(N):
        var.append(m.addVar(lb = 0, vtype=GRB.CONTINUOUS, name = 'z_{}'.format(i), obj = 1))
    #m.update()

    # Constraints 
    expr={}
    for j in range(N):
        expr = LinExpr()
        for i in range(n):
            expr += -var[i]*x[j][i]
        expr += -var[n]
        expr += -var[n+1+j]
        m.addConstr(expr, GRB.LESS_EQUAL, -y[j])

        expr = LinExpr()
        for i in range(n):
            expr.add(var[i], x[j][i])
        expr += var[n]
        expr += -var[n+1+j]
        m.addConstr(expr, GRB.LESS_EQUAL, y[j])

    # Define objective function:
    obj=LinExpr()
    for i in range(N):
        obj += var[n+1+i]
    m.setObjective(obj, GRB.MINIMIZE)

    m.update()
    m.optimize()
    m.write('q2.lp')

    # Your code goes here

    #if m.status == GRB.Status.OPTIMAL:
    z = m.objVal
    b = var[n].x
    w = [v.x for v in var[:n]]
    
    #print([v.x for v in var[n+1:]])
    return ([z, b, w])
Пример #16
0
def re_verification_tree_extension(s, x, G, i, state_end, factor=0.99):
    """
    This is a method to deal with numerical inaccuracies in high dimensioanl MILPs that are terminated early.
    Requires solving a linear program. If feasible, the computed control startegy is recomputed. 
    If infeasible, report back, raise a flag, and abort the tree extention
    Inputs: state_X, state_end
    Output: flag, u, theta
    """
    model = Model("verifying tree extention")
    G_dynamic = np.empty((s.n, s.n), dtype='object')
    theta = np.empty((s.m, s.n), dtype='object')
    u = np.empty((s.m, 1), dtype='object')
    x_bar = np.empty((s.n, 1), dtype='object')
    for row in range(s.n):
        for column in range(s.n):
            G_dynamic[row, column] = model.addVar(lb=-GRB.INFINITY,
                                                  ub=GRB.INFINITY)
    for row in range(s.m):
        u[row, 0] = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY)
        for column in range(s.n):
            theta[row, column] = model.addVar(lb=-GRB.INFINITY,
                                              ub=GRB.INFINITY)
    for row in range(s.n):
        x_bar[row, 0] = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY)
    model.update()
    for row in range(s.n):
        for column in range(s.n):
            AG = LinExpr()
            for k in range(s.n):
                AG.add(s.A[i][row, k] * G[k, column])
            for k in range(s.m):
                AG.add(s.B[i][row, k] * theta[k, column])
            model.addConstr(G_dynamic[row, column] == AG * factor)
    for row in range(s.n):
        Bu = LinExpr()
        for k in range(s.m):
            Bu.add(s.B[i][row, k] * u[k, 0])
        model.addConstr(x_bar[row, 0] == np.dot(s.A[i], x)[row, 0] + Bu +
                        s.c[i][row, 0])
    eps = subset_eps(model, G_dynamic, s.Pi, state_end.polytope.H,
                     state_end.polytope.h, x_bar)
    subset(model, theta, s.Pi, s.F[i], s.f[i], u)
    model.setParam("OutputFlag", False)
    model.optimize()
    if model.Status == 2:
        print("eps=", valuation(eps).T)
        if np.amax(valuation(eps)) > 10**-3:
            print(
                "\n-" * 10, "Too large of Epsilon: %d Tree extention failed!" %
                np.amax(valuation(eps)), "\n-" * 10)
            return None
        else:
            print("Tree extention verified succesuflly!")
            return (valuation(u), valuation(theta), valuation(eps))
    else:
        print("\n-" * 10, "Infeasible! Tree extention failed!", "\n-" * 10)
        return None
Пример #17
0
    def repair(self):
        this = self
        data_size = self.instance.size()

        def get_cj(j, x_vars):
            x_list = [x_vars[i][j] for i in xrange(data_size)]
            multi_list = list()
            for k in xrange(data_size):
                if k not in self.neighbor_map[j]:
                    continue
                for i in xrange(data_size):
                    multi_list.append(x_vars[i][k])
            return quicksum(x_list) + quicksum(multi_list)

        def build_objective(x_vars):
            result = list()
            for i, record1 in enumerate(this.instance.data):
                for j, record2 in enumerate(this.instance.data):
                    result.append(record1.distance(record2) * x_vars[i][j])
            return result

        try:
            m = Model('mip1')
            x = list()
            y = list()
            for i, record in enumerate(self.instance.data):
                variables = [m.addVar(vtype=GRB.BINARY, name='x_%d_%d' % (i, j)) for j in xrange(data_size)]
                x.append(variables)
                y.append(m.addVar(vtype=GRB.BINARY, name='y_%d' % i))
                m.addConstr(quicksum(x[i]) == 1, name='sum_%d' % i)
            for j, record in enumerate(self.instance.data):
                c_j = get_cj(j, x)
                m.addConstr(c_j - self.k * y[j] >= 0, name='constr_1_%d' % j)
                m.addConstr(y[j] * data_size - c_j >= 1 - self.k, name='constr_2_%d' % j)
                m.addConstr(y[j] +
                            quicksum([y[i] if i in self.neighbor_map[j] else 0 for i in xrange(data_size)]) -
                            quicksum([x[k][j] for k in xrange(data_size)]) / float(data_size)
                            >= 0, name='constr_3_%d' % j)
            m.setObjective(quicksum(build_objective(x)))

            print '---- Begin to solve the ILP ----'
            m.optimize()
            repair_result = list()
            for v in m.getVars():
                if v.varName.startswith('x') and v.x == 1:
                    _, record_id, candidate_id = v.varName.split('_')
                    repair_result.append((int(record_id), int(candidate_id)))
            print('Obj: %g' % m.objVal)
            return repair_result

        except GurobiError as e:
            print('Error code ' + str(e.errno) + ": " + str(e))

        except AttributeError:
            import traceback;
            traceback.print_exc()
            print('Encountered an attribute error')
Пример #18
0
def VRPSol(n, K, C, Ps, Ds, d, F, TimeLimit):
    m = Model()
    m.setParam(GRB.Param.TimeLimit, TimeLimit)
    # Create variables
    x = {}
    for i in Ps:
        for j in Ps:
            if i != j :
                x[i,j] = m.addVar(obj=F(Ps[i], Ps[j]), vtype=GRB.BINARY,
                                  name='x'+str(i)+'_'+str(j))
    # Create Miller variables (subtour elimination)
    u = {}
    for i in Ds:
        if i != d:
            u[i] = m.addVar(obj=0.0, vtype=GRB.CONTINUOUS,
                            lb=Ds[i], ub=C, name='u'+str(i))
            
    m.update()
    # Add outdegree constraint
    for j in Ps:
        if j != d:
            Ls = list(filter(lambda z: z!=j, Ps))
            m.addConstr(quicksum(x[i,j] for i in Ls) == 1)
    # Add indegree constraint
    for i in Ps:
        if i != d:
            Ls = filter(lambda z: z!=i, Ps)
            m.addConstr(quicksum(x[i,j] for j in Ls) == 1)
    # Number of vehicles
    Ls = list(filter(lambda z: z!=d, Ps))                   
    m.addConstr(quicksum(x[i,d] for i in Ls) == K)
    m.addConstr(quicksum(x[d,j] for j in Ls) == K)
    # Subtour elimination constraints
    for i in Ls:
        for j in Ls:
            if i != j:
                m.addConstr( u[i] - u[j] +C*x[i,j] <= C - Ds[j] )

    m.update()

    # Solve the model
    m.optimize()
    solution = m.getAttr('x', x)
    selected = [(i,j) for (i,j) in solution if solution[i,j] > 0.5]

    # Xs = [p for p in Ps.values()]
    # Ws = [w for w in Ds.values()]
    
    # for i,j in selected:
    #     DisegnaSegmento(Ps[i], Ps[j])
    # plt.scatter([i for i,j in Xs[1:]], [j for i,j in Xs[1:]], 
    #             s=Ws[1:], alpha=0.3, cmap='viridis')
    # plt.plot([Xs[0][0]], [Xs[0][1]], marker='s', color='red', alpha=0.5)
    # plt.axis('square')
    # plt.axis('off')
    
    return m.objVal, selected
Пример #19
0
def markovitz_dro_wasserstein(data,
                              delta_param,
                              alpha_param,
                              wasserstein_norm=1):
    '''
    Model from Blanchet et al. 2017
    DRO Markovitz reformulation from Wasserstein distance.
    '''

    r = np.mean(data, axis=0)
    cov = np.cov(data, rowvar=False)
    k = len(r)
    n = len(data)
    m = Model('opt_profolio')
    m.params.OutputFlag = 0
    m.params.NumericFocus = 3
    x = m.addVars(k, lb=0, ub=1, vtype=GRB.CONTINUOUS, name='x')
    norm_p = m.addVar(lb=0, ub=1, vtype=GRB.CONTINUOUS, name='norm')
    p_SD = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name='p_var')
    m.update()

    sqrt_delta = np.sqrt(delta_param)
    m.addConstr((x.sum() == 1), 'portfolio_ctr')
    m.addConstr(
        (quicksum(x[j] * r[j]
                  for j in range(k)) >= alpha_param - sqrt_delta * norm_p),
        'return_ctr')
    m.addConstr((p_SD * p_SD >= quicksum(cov[i, j] * x[i] * x[j]
                                         for i in range(k)
                                         for j in range(k))), 'SD_def')
    objfun = p_SD * p_SD + 2 * p_SD * sqrt_delta * norm_p + delta_param * norm_p * norm_p
    m.setObjective(objfun, GRB.MINIMIZE)

    if wasserstein_norm == 1:
        regularizer_norm = 'inf'
        m.addConstrs((norm_p >= x[j] for j in range(k)), 'norm_def')
    elif wasserstein_norm == 2:
        regularizer_norm = 2
        m.addConstr((norm_p * norm_p >=
                     (quicksum(x[j] * x[j] for j in range(k)))), 'norm_def')
    elif wasserstein_norm == 'inf':
        regularizer_norm = 1
        #Note: this works since x>=0
        m.addConstr((norm_p == (quicksum(x[j] for j in range(k)))), 'norm_def')
    else:
        raise 'wasserstain norm should be 1,2, or inf'

    m.optimize()
    x_sol = np.array([x[j].X for j in range(k)])
    p_mean = r.dot(x_sol)
    p_var = x_sol.dot(cov.dot(x_sol))
    #print(x_sol, p_mean, p_var)
    #print('norms' , np.linalg.norm(x_sol) , norm_p.X)

    return x_sol, p_mean, p_var
Пример #20
0
def fair_l1_solution(old_solutions, num_patients):

    solutions = process_solutions(old_solutions)
    num_solutions = len(solutions)

    patient_to_solutions = [[] for _ in range(num_patients)]
    for s, solution in enumerate(solutions):
        for p in solution:
            patient_to_solutions[p].append(s)

    model = Model()
    model.params.OutputFlag = 0

    solution_probs = [
        model.addVar(lb=0.0, ub=1.0, vtype=GRB.CONTINUOUS)
        for _ in range(num_solutions)
    ]
    model.addConstr(quicksum(solution_probs), GRB.EQUAL, 1.0)

    patient_probs = [
        model.addVar(lb=0.0, ub=1.0, vtype=GRB.CONTINUOUS)
        for _ in range(num_patients)
    ]

    for i in range(num_patients):
        expr = quicksum(solution_probs[j] for j in patient_to_solutions[i])
        model.addConstr(patient_probs[i], GRB.EQUAL, expr)

    m = model.addVar(lb=0.0, ub=1.0, vtype=GRB.CONTINUOUS)
    model.addConstr(quicksum(patient_probs), GRB.EQUAL, num_patients * m)

    distance_to_mean = [
        model.addVar(lb=0.0, ub=1.0, vtype=GRB.CONTINUOUS)
        for _ in range(num_patients)
    ]
    for i in range(num_patients):
        model.addConstr(distance_to_mean[i], GRB.GREATER_EQUAL,
                        patient_probs[i] - m)
        model.addConstr(distance_to_mean[i], GRB.GREATER_EQUAL,
                        m - patient_probs[i])

    model.setObjective(quicksum(distance_to_mean), GRB.MINIMIZE)
    model.optimize()

    #return [solution_probs[i].x for i in range(num_solutions)]

    if (model.status == GRB.Status.OPTIMAL):
        solution_prob_dict = {}
        for i in range(num_solutions):
            solution_prob_dict[i] = solution_probs[i].x

        return solution_prob_dict
    else:
        return {}
Пример #21
0
def fair_maxmin_solution(solutions, num_patients):
    model = Model('maximin_fair')
    model.params.outputflag = 0
    solutions = process_solutions(solutions)
    solution_size = len(solutions)
    solution_dict = {}

    dict_array = []
    solution_vars = []
    for i in range(solution_size):
        p = model.addVar(lb=0, ub=1, vtype=GRB.CONTINUOUS)
        solution_dict[i] = p
        solution_vars.append(p)
    solution_exprt = quicksum(solution_vars)
    model.addConstr(solution_exprt, GRB.EQUAL, 1.0)

    node_prob_dict = {}
    for i in range(solution_size):
        for item in solutions[i]:
            if int(item) in node_prob_dict.keys():
                node_prob_dict[int(item)].append(i)
            else:
                node_prob_dict[int(item)] = [i]

    y = model.addVar(lb=0, ub=1.0, vtype=GRB.CONTINUOUS)

    for key, value in node_prob_dict.items():
        tmp = []
        for solution in value:
            tmp.append(solution_dict[solution])
        expr = quicksum(tmp)
        #expr_constant = float(len(value))
        model.addConstr(expr, GRB.GREATER_EQUAL, y)

    model.update()

    model.setObjective(y, GRB.MAXIMIZE)

    model.update()

    try:
        model.optimize()
    except e:
        print(e)

    if (model.status == GRB.Status.OPTIMAL):
        solution_prob_dict = {}
        for key, value in solution_dict.items():
            solution_prob_dict[key] = value.x

        return solution_prob_dict
    else:
        return {}
Пример #22
0
class MasterProblem:
    def __init__(self):
        self.model = Model("benders_master_problem")

        self.x_1 = self.model.addVar(lb=0, name="x_1", vtype=GRB.BINARY)
        self.x_2 = self.model.addVar(lb=0, name="x_2", vtype=GRB.BINARY)

        self.phi = self.model.addVar(lb=-100, name="phi")

        self.model.addConstr(self.x_1 + self.x_2 <= 1)

        self.model.setObjective(
            3 * self.x_1 + 5 * self.x_2 + self.phi,
            GRB.MINIMIZE,
        )

    def add_cut(self, lhs, x_hat_1, x_hat_2):
        if x_hat_1 == 1 and x_hat_2 == 0:
            self.model.addConstr(
                lhs + BIG_M * (self.x_1 - 1) - BIG_M * (self.x_2) <= self.phi,
                name="cut",
            )
        if x_hat_1 == 0 and x_hat_2 == 1:
            self.model.addConstr(
                lhs - BIG_M * (self.x_1) + BIG_M * (self.x_2 - 1) <= self.phi,
                name="cut",
            )
        if x_hat_1 == 0 and x_hat_2 == 0:
            self.model.addConstr(
                lhs - BIG_M * (self.x_1) - BIG_M * (self.x_2) <= self.phi,
                name="cut",
            )
        if x_hat_1 == 1 and x_hat_2 == 1:
            self.model.addConstr(
                lhs + BIG_M * (self.x_1 - 1) + BIG_M *
                (self.x_2 - 1) <= self.phi,
                name="cut",
            )

    def solve(self):
        self.model.optimize()
        print()
        print(f"PHI: {self.phi.x}")
        print(f"X_1: {self.x_1.x}")
        print(f"X_2: {self.x_2.x}")
        print()

        return (
            self.model.objVal,
            self.x_1.x,
            self.x_2.x,
        )
Пример #23
0
def mip_gurobipy(x, y0, n, m, N):

    from gurobipy import Model, GRB, quicksum

    # set big M
    M = 100

    # generate model
    model = Model('linear regression_mip')

    # variables
    r = [
        model.addVar(name='r({})'.format(i), vtype=GRB.CONTINUOUS)
        for i in range(n)
    ]
    t = [
        model.addVar(name='t({})'.format(i), vtype=GRB.CONTINUOUS)
        for i in range(n)
    ]
    q = [
        model.addVar(name='q({})'.format(i), vtype=GRB.BINARY)
        for i in range(n)
    ]
    b = [
        model.addVar(name='b({})'.format(j), lb=-inf, vtype=GRB.CONTINUOUS)
        for j in range(m)
    ]

    # objective
    model.setObjective(quicksum(r[i] - t[i] for i in range(n)), GRB.MINIMIZE)

    # constraints
    for i in range(n):
        model.addConstr(r[i] >= y0[i] - quicksum(x[j, i] * b[j]
                                                 for j in range(m)))
        model.addConstr(r[i] >= quicksum(x[j, i] * b[j]
                                         for j in range(m)) - y0[i])
        model.addConstr(t[i] <= M * (1 - q[i]))
        model.addConstr(t[i] <= r[i])
    model.addConstr(quicksum(q[i] for i in range(n)) >= N)

    # optimize
    model.optimize()

    # get results
    r_sol = [r[i].x for i in range(n)]
    q_sol = [round(q[i].x) for i in range(n)]
    b_sol = [b[j].x for j in range(m)]
    t_sol = [t[i].x for i in range(n)]

    return r_sol, q_sol, b_sol
Пример #24
0
class MasterProblem:
    """
    Benders's master problem.
    In each iteration a new cut will be added into this.
    """
    def __init__(self, cfg: Config):
        self.model = Model("benders_master_porblem")
        self.cfg = cfg

        self.x_1 = self.model.addVar(vtype=GRB.CONTINUOUS, lb=0, name="x_1")
        self.x_2 = self.model.addVar(vtype=GRB.CONTINUOUS, lb=0, name="x_2")
        self.x_3 = self.model.addVar(vtype=GRB.CONTINUOUS, lb=0, name="x_3")

        self.phi = self.model.addVar(vtype=GRB.CONTINUOUS,
                                     lb=-100 * 100 * 100,
                                     name="phi")

        self.model.addConstr(self.x_1 + self.x_2 + self.x_3 <= cfg.area,
                             name="area_constraint")

        self.model.setObjective(
            self.x_1 * cfg.wheat.plant_cost + self.x_2 * cfg.corn.plant_cost +
            self.x_3 * cfg.beet.plant_cost + self.phi,
            GRB.MINIMIZE,
        )

    def add_cut(self, lhs, pi_1, pi_2, pi_3):
        """
        add_cut adds new cuts to master problem based
        on given dual values and constant.
        these parameters come from the sub problem
        optimal solution in each benders iteration.
        """
        self.model.addConstr(
            lhs <=
            self.phi - self.x_1 * pi_1 - self.x_2 * pi_2 - self.x_3 * pi_3,
            name="cut",
        )

    def solve(self):
        """
        solve solves master problem and returns the optimal solution
        """
        self.model.optimize()

        return (
            self.model.objVal,
            self.x_1.x,
            self.x_2.x,
            self.x_3.x,
        )
Пример #25
0
def build_gurobi_model(case):
    G, B = case.G, case.B
    P = real(case.demands)
    Q = imag(case.demands)
    branches = case.branch_list
    n = len(case.demands)
    vhat = case.vhat
    s2 = 2**.5
    gens = {bus: gen.v for bus, gen in case.gens.items()}
    del gens[0]

    m = GurobiModel("jabr")
    u = [m.addVar(name='u_%d' % i) for i in range(n)]
    R = {(i, j): m.addVar(name='R_%d_%d' % (i, j)) for i, j in branches}
    I = {(i, j): m.addVar(lb=-GRB.INFINITY, name='I_%d_%d' % (i, j))
         for i, j in branches}
    for i, j in branches:
        R[j, i] = R[i, j]
        I[j, i] = I[i, j]
    m.update()
    m.addConstr(u[0] == vhat * vhat / s2, 'u0')
    for gen, v in gens.iteritems():
        m.addConstr(u[gen] == v * v / s2, 'u%d' % gen)
    for i, j in branches:
        m.addQConstr(2 * u[i] * u[j] >= R[i, j] * R[i, j] + I[i, j] * I[i, j],
                     'cone_%d_%d' % (i, j))
    k = lambda i: (j for j in B[i, :].nonzero()[1])
    s = lambda i, j: 1 if i < j else -1
    for i in range(1, n):
        m.addConstr(
            -s2 * u[i] * G[i, :].sum() +
            quicksum(G[i, j] * R[i, j] + B[i, j] * s(i, j) * I[i, j]
                     for j in k(i)) == P[i], 'real_flow_%d_%d' % (i, j))
        if i in gens:
            continue
        m.addConstr(
            s2 * u[i] * B[i, :].sum() +
            quicksum(-B[i, j] * R[i, j] + G[i, j] * s(i, j) * I[i, j]
                     for j in k(i)) == Q[i], 'reac_flow_%d_%d' % (i, j))
    m.setObjective(quicksum(R[i, j] for i, j in branches), sense=GRB.MAXIMIZE)
    m.params.outputFlag = 0
    #m.params.barQCPConvTol = 5e-10
    m.optimize()
    if m.status != 2:
        raise ValueError("gurobi failed to converge: %s (check log)" %
                         m.status)
    u_opt = [x.getAttr('x') for x in u]
    R_opt = {(i, j): x.getAttr('x') for (i, j), x in R.items()}
    I_opt = {(i, j): x.getAttr('x') for (i, j), x in I.items()}
    return u_opt, R_opt, I_opt
Пример #26
0
    def generateInstance(self):

        def euc_dist(bor, sh):
            dx = bor["x_coord"] - sh["x_coord"]
            dy = bor["y_coord"] - sh["y_coord"]
            return math.sqrt(dx * dx + dy * dy)

        model = Model('FireSolver')

        # Generate variables
        x = {}
        for bor in self.boroughs:
            # New firehouses
            for fh in self.new_firehouses + self.old_firehouses:
                name = "x_" + fh["loc_id"] + "_" + bor["loc_id"]
                x[bor["loc_id"], fh["loc_id"]] = model.addVar(name=name, vtype ="b", obj=self.cost_coef * euc_dist(bor, fh))

        # Open variables
        openfh = {}
        for fh in self.new_firehouses:
            openfh[fh["loc_id"]] = model.addVar(name = "open_" + fh["loc_id"], vtype ="b", obj=fh["construction_cost"])

        # Close variables
        closefh = {}
        for fh in self.old_firehouses:
            closefh[fh["loc_id"]] = model.addVar(name = "close_" + fh["loc_id"], vtype ="b", obj=fh["destruction_cost"])

        model.modelSense = GRB.MINIMIZE
        model.update()

        # Constraints: one firehouse / borough
        for bor in self.boroughs:
            model.addConstr(quicksum(x[key] for key in x if key[0] == bor["loc_id"]) == 1)

        # capacity of firehouses
        for fh in self.new_firehouses:
            model.addConstr(quicksum(x[key] for key in x if key[1] == fh["loc_id"]) <= self.capacity * openfh[fh["loc_id"]])

        # If it is not removed, the initial assignment needs to be respected
        for fh in self.old_firehouses:
            for bor in self.boroughs:
                if bor["currently_protected_by"] == fh["loc_id"]:
                    model.addConstr(x[bor["loc_id"], fh["loc_id"]] == 1 - closefh[fh["loc_id"]])
                else:
                    model.addConstr(x[bor["loc_id"], fh["loc_id"]] == 0)
        
        # solve it
        model.optimize()

        self.model = model
Пример #27
0
def build_ilp(g, eqs, forbidden, simple_cycles, match):
    m = Model()
    m.setAttr('ModelSense', GRB.MAXIMIZE)
    edges = sorted(g.edges(eqs))
    # y: is edge e in the matching? The worth of each allowed match is 1.
    obj_coeff = {e: (1 if e not in forbidden else 0) for e in edges}
    y = {e: m.addVar(vtype=GRB.BINARY, obj=obj_coeff[e]) for e in edges}
    m.update()
    # An equation is matched at most once
    for eq in eqs:
        add_matched_at_most_once_con(m, y, g.edges(eq))
    # A variable is matched at most once
    set_eqs = set(eqs)
    vrs = sorted(v for v in g if v not in set_eqs)
    for v in vrs:
        add_matched_at_most_once_con(m, y, list(
            (eq, v) for v, eq in g.edges(v)))
    #
    break_each_cycle_at_least_once(eqs, m, y, simple_cycles)
    #
    set_lower_bound_if_any(g, eqs, m, y)
    #
    # Set feasible solution from the matching, if any
    if match is not None:
        match = set(match)
        for edge, var in iteritems(y):
            var.setAttr('Start', 1 if edge in match else 0)
    return m, y
Пример #28
0
    def createInstance(self):

        model = Model()
        modelVars = {}

        # x variables are assigned.
        for i in range(self.m):
            for j in range(self.n):
                Vname = 'x_{}_{}'.format(i, j)
                modelVars[Vname] = model.addVar(vtype=GRB.BINARY, name=Vname)

        # Term 2: Objective Function
        obj = quicksum(self.v[j] * modelVars['x_{}_{}'.format(i, j)]
                       for i in range(self.m) for j in range(self.n))

        # Term 3: Each job is assigned to at most 1 machine.
        model.addConstrs(
            quicksum(modelVars['x_{}_{}'.format(i, j)]
                     for i in range(self.m)) <= 1 for j in range(self.n))

        # Term 4: Allows the assignment of at most R resources to a machine.
        model.addConstrs(
            quicksum(modelVars['x_{}_{}'.format(i, j)] * self.r[j]
                     for j in self.J[h]) <= self.R for i in range(self.m)
            for h in range(1, self.k + 1))

        # Term 5: Implicit in varaible definition.

        # Objective Function is set.
        model._vars = modelVars
        model.setObjective(obj, GRB.MAXIMIZE)

        #print(model.getAttr('ModelSense') == GRB.MINIMIZE)

        return model
Пример #29
0
    def gurobi_qp(self, qp):
        n = qp.H.shape[1]
        model = Model()
        x = {
            i: model.addVar(
                vtype=GRB.CONTINUOUS,
                name='x_%d' % i,
                lb=qp.lb,
                ub=qp.ub)
            for i in range(n)
        }
        model.update()  
        obj = QuadExpr()
        rows, cols = qp.H.nonzero()
        for i, j in zip(rows, cols):
            obj += 0.5 * x[i] * qp.H[i, j] * x[j]
        for i in range(n):
            obj += qp.f[i] * x[i]
        model.setObjective(obj, GRB.MINIMIZE)
        if qp.A is not None:
            A_nonzero_rows = get_nonzero_rows(qp.A)
            for i, row in A_nonzero_rows.items():
                model.addConstr(quicksum(qp.A[i, j] * x[j] for j in row) <= qp.b[i])

        if qp.Aeq is not None:
            A_nonzero_rows = get_nonzero_rows(qp.Aeq)
            for i, row in A_nonzero_rows.items():
                model.addConstr(quicksum(qp.Aeq[i, j] * x[j] for j in row) == qp.beq[i])
        model.optimize()
        self.solution = empty(n)
        for i in range(n):
            self.solution[i] = model.getVarByName('x_%d' % i).x
Пример #30
0
def sample_from_polytope(polytope):
    """
        A random point in H,h
    """
    model=Model("Polytope Sampling")
    n=polytope.H.shape[1]
    alpha=np.random.random((n,1))-0.5
    theta=model.addVar(lb=-GRB.INFINITY,ub=GRB.INFINITY)
    model.update()
    Hx_Anchor=np.dot(polytope.H,polytope.anchor)
    H_alpha=np.dot(polytope.H,alpha)
    for row in range(polytope.H.shape[0]):
        model.addConstr(H_alpha[row,0]*theta+Hx_Anchor[row,0]<=polytope.h[row])
    model.setObjective(theta,GRB.MINIMIZE)
    model.setParam('OutputFlag',False)
    model.optimize()
    theta_min=theta.X
    model.reset()
    model.setObjective(theta,GRB.MAXIMIZE)
    model.optimize()
    theta_max=theta.X
    c=rand()
    x_sample=(polytope.anchor+alpha*theta_min)*c+(polytope.anchor+alpha*theta_max)*(1-c)
    polytope.anchor=x_sample
    return x_sample
Пример #31
0
def construct_lp_model(c, A, d):
    from gurobipy import Model, LinExpr, GRB

    # A = numpy.array (matrix)
    # c = numpy.array (vector)
    # d = numpy.array (vector)

    k, n = A.shape

    # Creation of the gurobi model
    m = Model("sp")

    # Variables
    x = list()
    for i in range(n):
        x.append(m.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY, name='x_%d' % i))

    # Objective Function
    objExpr = LinExpr()
    for i in range(n):
        objExpr.add(x[i], c[i])
    m.setObjective(objExpr, GRB.MAXIMIZE)

    # Constraints
    expr = {}
    for j in range(k):
        expr = LinExpr()
        for i in range(n):
            expr.add(x[i], A[j, i])
        m.addConstr(expr, GRB.LESS_EQUAL, d[j])

    # Update the model to add new entries
    m.update()
    return m
Пример #32
0
    def _construct_smore_lp(self, G, edge_to_paths, num_total_paths):
        m = Model('min-edge-util')

        # Create variables: one for each path
        path_vars = m.addVars(num_total_paths,
                              vtype=GRB.CONTINUOUS,
                              lb=0.0,
                              ub=1.0,
                              name='f')
        max_link_util_var = m.addVar(vtype=GRB.CONTINUOUS, lb=0.0, name='z')
        m.update()
        m.setObjective(max_link_util_var, GRB.MINIMIZE)

        # Add demand constraints
        for k, d_k, path_ids in self.commodities:
            m.addConstr(quicksum(path_vars[p] for p in path_ids) == 1)

        # Add edge util constraints
        for u, v, c_e in G.edges.data('capacity'):
            paths = edge_to_paths[(u, v)]
            constr_vars = [
                path_vars[p] * self.commodities[self._path_to_commod[p]][-2]
                for p in paths
            ]
            m.addConstr(quicksum(constr_vars) / c_e <= max_link_util_var)

        return LpSolver(m, None, self.DEBUG, self.VERBOSE, self.out)
Пример #33
0
def max_return(r, risk_threshold, cvar_alpha=0.95):

    r_bar = np.mean(r, axis=0)
    cov = np.cov(r, rowvar=False)
    n = len(r)
    k = len(r[0])
    m = Model('opt_profolio')
    m.params.OutputFlag = 0
    m.params.NumericFocus = 3
    x = m.addVars(k, lb=0, ub=1, vtype=GRB.CONTINUOUS, name='x')
    z = m.addVars(n, lb=0, vtype=GRB.CONTINUOUS, name='z')
    eta = m.addVar(lb=-GRB.INFINITY, vtype=GRB.CONTINUOUS, name='eta')
    m.update()

    #Portfolio contraint
    m.addConstr((x.sum() == 1), 'portfolio_ctr')
    #Risk constraint
    m.addConstr(
        (eta + (1.0 / (n * (1 - cvar_alpha))) * z.sum() <= risk_threshold),
        'cvar_ctr')
    #CVaR linearlization
    m.addConstrs((z[i] >= quicksum(-r[i, j] * x[j] for j in range(k)) - eta
                  for i in range(n)), 'cvar_linear')

    m.setObjective(quicksum(r_bar[j] * x[j] for j in range(k)), GRB.MAXIMIZE)
    m.update()

    m.optimize()
    x_sol = np.array([x[j].X for j in range(k)])
    p_mean = r_bar.dot(x_sol)
    p_var = x_sol.dot(cov.dot(x_sol))
    cvar_loss = (eta + (1.0 / (n * (1 - cvar_alpha))) * z.sum()).getValue()
    #print(m.status, eta.X, (-1+(1+eta.X)**365), cvar_loss , (-1+(1+cvar_loss)**365))
    return x_sol, p_mean, p_var
Пример #34
0
def check_redundancy_row(H, h, ROW, atol=10**-8):
    model = Model("Row Redundancy Check")
    n = H.shape[1]
    x = np.empty((n, 1), dtype='object')
    for row in range(n):
        x[row, 0] = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY)
    model.update()
    for row in [r for r in range(H.shape[0]) if r != ROW]:
        Hx = LinExpr()
        for column in range(n):
            Hx.add(H[row, column] * x[column, 0])
        model.addConstr(Hx <= h[row, 0])
    J = LinExpr()
    for column in range(n):
        J.add(H[ROW, column] * x[column, 0])
    model.setObjective(J, GRB.MAXIMIZE)
    model.setParam('OutputFlag', False)
    model.optimize()
    if model.Status == 2:
        if J.getValue() > h[ROW, 0] + atol:
            return False  # It is NOT redundant
        else:
            return True  # It is redudant
    else:
        return False
Пример #35
0
def ilp(costMatrix):

    #Invalid_Connections : -1
    if costMatrix.shape==(0,0):
        return []


    dist_mat=numpy.copy(costMatrix)
    dist_mat[costMatrix==-1]=10e10

    size_x   = dist_mat.shape[0]
    size_y   = dist_mat.shape[1]
    size_min = int(numpy.amin([size_x,size_y]))
    from gurobipy import Model, quicksum, GRB


    m=Model("mip1")
    COS,VAR={},{}

    for i in range(size_x):
        x_cos, x_var = [],[]
        for j in range(size_y):
            COS[i,j]=dist_mat[i,j]
            VAR[i,j]=m.addVar(vtype='B',name="["+str(i)+","+str(j)+"]")
    m.update()


    # Set objective
    m.setObjective( quicksum(\
            COS[x,y]*VAR[x,y]
            for x in range(size_x) \
            for y in range(size_y) \
            ),GRB.MINIMIZE)


    # Constrains HORIZONTAL
    for i in range(size_x):
        m.addConstr( quicksum\
                (VAR[i,y] for y in range(size_y)) <= 1)

    # Constrains VERTICAL
    for i in range(size_y):
        m.addConstr( quicksum\
                (VAR[x,i] for x in range(size_x)) <= 1)

    m.addConstr(quicksum(\
            VAR[x,y] for x in range(size_x) for y in range(size_y)) == int(size_min))

    m.setParam("OutputFlag",False)
    m.optimize()
    res=numpy.zeros(dist_mat.shape,dtype=bool)
    for i in range(size_x):
        for j in range(size_y):
            res[i,j]=VAR[i,j].x

    binMatrix = numpy.zeros( costMatrix.shape,dtype=bool )
    binMatrix[res==1]=1
    binMatrix[costMatrix==-1]=0
    return binMatrix
Пример #36
0
def build_gurobi_model(case):
    G, B = case.G, case.B
    P = real(case.demands)
    Q = imag(case.demands)
    branches = case.branch_list
    n = len(case.demands)
    vhat = case.vhat
    s2 = 2**.5
    gens = {bus: gen.v for bus, gen in case.gens.items()}
    del gens[0]

    m = GurobiModel("jabr")
    u = [m.addVar(name='u_%d'%i) for i in range(n)]
    R = {(i, j): m.addVar(name='R_%d_%d' % (i, j)) for i, j in branches}
    I = {(i, j): m.addVar(lb=-GRB.INFINITY, name='I_%d_%d' % (i, j)) for i, j in branches}
    for i, j in branches:
        R[j, i] = R[i, j]
        I[j, i] = I[i, j]
    m.update()
    m.addConstr(u[0] == vhat*vhat/s2, 'u0')
    for gen, v in gens.iteritems():
        m.addConstr(u[gen] == v*v/s2, 'u%d' % gen)
    for i, j in branches:
        m.addQConstr(2*u[i]*u[j] >= R[i,j]*R[i,j] + I[i,j]*I[i,j], 'cone_%d_%d' % (i, j))
    k = lambda i: (j for j in B[i, :].nonzero()[1])
    s = lambda i, j: 1 if i < j else -1
    for i in range(1, n):
        m.addConstr(-s2*u[i]*G[i, :].sum() + quicksum(G[i,j]*R[i,j] + B[i,j]*s(i,j)*I[i,j] for j in k(i)) == P[i],
                    'real_flow_%d_%d' % (i, j))
        if i in gens:
            continue
        m.addConstr(s2*u[i]*B[i, :].sum() + quicksum(-B[i,j]*R[i,j] + G[i,j]*s(i,j)*I[i,j] for j in k(i)) == Q[i],
                    'reac_flow_%d_%d' % (i, j))
    m.setObjective(quicksum(R[i,j] for i, j in branches), sense=GRB.MAXIMIZE)
    m.params.outputFlag = 0
    #m.params.barQCPConvTol = 5e-10
    m.optimize()
    if m.status != 2:
        raise ValueError("gurobi failed to converge: %s (check log)" % m.status)
    u_opt = [x.getAttr('x') for x in u]
    R_opt = {(i, j): x.getAttr('x') for (i, j), x in R.items()}
    I_opt = {(i, j): x.getAttr('x') for (i, j), x in I.items()}
    return u_opt, R_opt, I_opt
Пример #37
0
def create_problem(cobra_model, quadratic_component=None, **kwargs):
    """Solver-specific method for constructing a solver problem from
    a cobra.Model.  This can be tuned for performance using kwargs


    """
    lp = Model("")

    the_parameters = parameter_defaults
    if kwargs:
        the_parameters = parameter_defaults.copy()
        the_parameters.update(kwargs)

    # Set verbosity first to quiet infos on parameter changes
    if "verbose" in the_parameters:
        set_parameter(lp, "verbose", the_parameters["verbose"])
    for k, v in iteritems(the_parameters):
        set_parameter(lp, k, v)


    # Create variables
    #TODO:  Speed this up
    variable_list = [lp.addVar(_float(x.lower_bound),
                               _float(x.upper_bound),
                               float(x.objective_coefficient),
                               variable_kind_dict[x.variable_kind],
                               str(i))
                     for i, x in enumerate(cobra_model.reactions)]
    reaction_to_variable = dict(zip(cobra_model.reactions,
                                    variable_list))
    # Integrate new variables
    lp.update()

    #Constraints are based on mass balance
    #Construct the lin expression lists and then add
    #TODO: Speed this up as it takes about .18 seconds
    #HERE
    for i, the_metabolite in enumerate(cobra_model.metabolites):
        constraint_coefficients = []
        constraint_variables = []
        for the_reaction in the_metabolite._reaction:
            constraint_coefficients.append(_float(the_reaction._metabolites[the_metabolite]))
            constraint_variables.append(reaction_to_variable[the_reaction])
        #Add the metabolite to the problem
        lp.addConstr(LinExpr(constraint_coefficients, constraint_variables),
                     sense_dict[the_metabolite._constraint_sense.upper()],
                     the_metabolite._bound,
                     str(i))

    # Set objective to quadratic program
    if quadratic_component is not None:
        set_quadratic_objective(lp, quadratic_component)

    lp.update()
    return(lp)
Пример #38
0
    def global_model(N, k_choices, distance_matrix):

        if k_choices >= N:
            raise ValueError("k_choices must be less than N")

        model = Model("distance1")
        trajectories = range(N)

        distance_matrix = np.array(
            distance_matrix / distance_matrix.max(), dtype=np.float64)

        dm = distance_matrix ** 2

        y, x = {}, {}
        for i in trajectories:
            y[i] = model.addVar(vtype="B", obj=0, name="y[%s]" % i)
            for j in range(i + 1, N):
                x[i, j] = model.addVar(
                    vtype="B", obj=1.0, name="x[%s,%s]" % (i, j))
        model.update()

        model.setObjective(quicksum([x[i, j] * dm[j][i]
                                     for i in trajectories
                                     for j in range(i + 1, N)]))

        # Add constraints to the model
        model.addConstr(quicksum([y[i]
                                  for i in trajectories]) <= k_choices, "27")

        for i in trajectories:
            for j in range(i + 1, N):
                model.addConstr(x[i, j] <= y[i], "28-%s-%s" % (i, j))
                model.addConstr(x[i, j] <= y[j], "29-%s-%s" % (i, j))
                model.addConstr(y[i] + y[j] <= 1 + x[i, j],
                                "30-%s-%s" % (i, j))

        model.addConstr(quicksum([x[i, j] for i in trajectories
                                  for j in range(i + 1, N)])
                        <= nchoosek(k_choices, 2), "Cut_1")
        model.update()
        return model
def find_feasible_start(n_colors, h, statespace, conflicts, verbose=False):
    
    model = Model("TimeFeasibility")
    p = len(h)
    y = {}
    # y[i,k] = if color i gets slot l
    for i in range(n_colors):
        for l in range(p):
            y[i,l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l))

    model.update()

    # Building constraints...    
    
    # c1: all get one
    for i in range(n_colors):
        model.addConstr( quicksum([ y[i, l] for l in range(p) ]) == 1, "c1")

    # c2: each slot needs to be used tops once
    for l in range(p):
        model.addConstr( quicksum([ y[i, l] for i in range(n_colors) ]) <= 1, "c2")    

    ### c3: statespace constraints
    for i in range(n_colors):
        #print l, h[l], i, [s for s in statespace]
        model.addConstr( quicksum([ y[i, l] for l in range(p) if h[l] not in statespace[i] ]) == 0, "c3")    
    
    # objective: minimize conflicts
    #obj = quicksum([ y[i,l] * y[j,l] for l in range(p) for i in range(n_colors) for j in range(i+1, n_colors) ]) 
    obj = quicksum([ sum(y[i,l] for i in range(n_colors)) for l in range(p)  ]) 
    #obj = 0
    model.setObjective(obj, GRB.MINIMIZE)
    
    if not verbose:
        model.params.OutputFlag = 0
    
    model.optimize()

    # return best room schedule
    color_schedule = []
    if model.status == GRB.INFEASIBLE:
        return color_schedule
                    
    for i in range(n_colors):
        for l in range(p):
            v = model.getVarByName("y_%s_%s" % (i,l)) 
            if v.x == 1:
                color_schedule.append(h[l])
                break
            
    return color_schedule
def check_feasability_ILP(exams_to_schedule, period, data, verbose=False):
    # More precise but by far to slow compared to heuristic
    r = data['r']
    T = data['T']
    s = data['s']
    z = {}

    model = Model("RoomFeasability")

    # z[i,k] = if exam i is written in room k
    for k in range(r):
        # print k, period
        if T[k][period] == 1:
            for i in exams_to_schedule:
                z[i, k] = model.addVar(vtype=GRB.BINARY, name="z_%s_%s" % (i, k))

    model.update()

    # Building constraints...

    # c1: seats for all students
    for i in exams_to_schedule:
        expr = LinExpr()
        for k in range(r):
            if T[k][period] == 1:
                expr.addTerms(1, z[i, k])
        model.addConstr(expr >= s[i], "c1")

    # c2: only one exam per room
    for k in range(r):
        if T[k][period] == 1:
            expr = LinExpr()
            for i in exams_to_schedule:
                expr.addTerms(1, z[i, k])
            model.addConstr(expr <= 1, "c2")

    model.setObjective(0, GRB.MINIMIZE)
    if not verbose:
        model.params.OutputFlag = 0

    model.params.heuristics = 0
    model.params.PrePasses = 1

    model.optimize()

    # return best room schedule
    try:
        return model.objval
    except GurobiError:
        logging.warning('check_feasability_ILP: model has no objVal')
        return None
def solve(budget, buses, lines, u, c, b, S, D):
    m = Model('inhibit')
    w, v, y = {}, {}, {}
    for i in buses:
        w[i] = m.addVar(vtype=GRB.BINARY, name="w_%s" % i)
    for i, j in lines:
        v[i, j] = m.addVar(vtype=GRB.BINARY, name='v_%s_%s' % (i, j))
        y[i, j] = m.addVar(vtype=GRB.BINARY, name='y_%s_%s' % (i, j))
    m.update()

    for i, j in lines:
        m.addConstr(w[i]-w[j] <= v[i, j] + y[i, j], 'balance1_%s_%s' % (i, j))
        m.addConstr(w[j]-w[i] <= v[i, j] + y[i, j], 'balance2_%s_%s' % (i, j))
    m.addConstr(quicksum(c[i, j]*y[i, j] for i, j in lines) <= budget, 'budget')
        
    m.setObjective(quicksum(u[i, j]*v[i, j] for i, j in lines) +
                   quicksum(b[i]*(1-w[i]) for i in S) -
                   quicksum(b[i]*w[i] for i in D))
    
    m.setParam('OutputFlag', 0)
    m.optimize()
    m.write('gurobi.lp')
    return w, v, y, m
    def _cut(self, model, val_func, cut_func):
        '''Returns true if a cut was added to the master'''
        problem = self.problem
        theta = self.theta
        x = self.x

        # Create subproblem.
        sub = Model()

        # y[ip,iq,s,c] = 1 if images ip & iq have a shared path through stage
        #                s by running command c during s, 0 otherwise
        y = {}
        for (ip, iq), cmds in problem.shared_cmds.items():
            for s, c in product(problem.shared_stages[ip, iq], cmds):
                y[ip,iq,s,c] = sub.addVar(name='y[%s,%s,%s,%s]' % (ip,iq,s,c))

        sub.update()

        # Find shared paths among image pairs.
        constraints = defaultdict(list)
        for (ip, iq), cmds in problem.shared_cmds.items():
            for s in problem.shared_stages[ip,iq]:
                for c in cmds:
                    constraints[ip,s,c].append(sub.addConstr(y[ip,iq,s,c] <= val_func(model, x[ip,s,c])))
                    constraints[iq,s,c].append(sub.addConstr(y[ip,iq,s,c] <= val_func(model, x[iq,s,c])))
                if s > 1:
                    sub.addConstr(sum(y[ip,iq,s,c] for c in cmds) <= sum(y[ip,iq,s-1,c] for c in cmds))

        sub.setObjective(
            -sum(problem.commands[c] * y[ip,iq,s,c] for ip,iq,s,c in y),
            GRB.MINIMIZE
        )
        sub.optimize()

        # Add the dual prices for each variable
        pi = defaultdict(float)
        for isp, cons in constraints.iteritems():
            for c in cons:
                pi[isp] += c.pi

        # Detect optimality
        if val_func(model, theta) >= sub.objVal:
            return False # no cuts to add

        # Optimality cut
        cut_func(model, theta >= sum(pi[isp]*x[isp] for isp in pi if pi[isp]))
        return True
Пример #43
0
def two_cycle(A, C, gap):
    """
    Solve high-vertex dense graphs by reduction to
    weighted matching ILP.
    """
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    m.params.timelimit = 60 * 60

    n = A.shape[0]
    vars = {}
    edges = tuplelist()

    # model as undirected graph
    for i in range(n):
        for j in range(i+1, n):
            if A[i, j] == 1 and A[j, i] == 1:
                e = (i, j)
                edges.append(e)
                w_i = 2 if i in C else 1
                w_j = 2 if j in C else 1
                w = w_i + w_j
                var = m.addVar(vtype=GRB.BINARY, obj=w)
                vars[e] = var

    m.update()

    # 2 cycle constraint <=> undirected flow <= 1
    for i in range(n):
        lhs = LinExpr()
        lhs_vars = [vars[e] for e in chain(edges.select(i, _), edges.select(_, i))]
        ones = [1.0]*len(lhs_vars)
        lhs.addTerms(ones, lhs_vars)

        m.addConstr(lhs <= 1)

    m.optimize()
    m.update()

    cycles = [list(e) for e in edges if vars[e].x == 1.0]
    return cycles, m.objval
def build_model(data, n_cliques = 0, verbose = True):
    
    # Load Data Format
    n = data['n']
    r = data['r']
    p = data['p']
    s = data['s']
    c = data['c']
    h = data['h']
    w = data['w']
    location = data['location']
    conflicts = data['conflicts']
    locking_times = data['locking_times']
    T = data['T']
    similarp = data['similarp']
    
    model = Model("ExaminationScheduling")
    
    
    if verbose:
        print("Building variables...")
    
    # x[i,k,l] = 1 if exam i is at time l in room k
    x = {}
    for k in range(r):
        for l in range(p):
            if T[k][l] == 1:
                for i in range(n):
                    if location[k] in w[i]:
                        x[i,k,l] = model.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (i,k,l))
    
    # y[i,l] = 1 if exam i is at time l
    y = {}
    for i in range(n):
        for l in range(p):
            y[i, l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l))    

    # integrate new variables
    model.update() 

    # for i in range(p+5):
    #     for l in range(i-5):
    #         y[i, l].setAttr("BranchPriority", s[i])

    # model.update() 


    start = timeit.default_timer()

    # not very readable but same constraints as in GurbiLinear_v_10: speeded up model building by 2 for small problems (~400 exams) and more for huger problem ~1500 exams
    if verbose:
        print("Building constraints...")    
    
    s_sorted = sorted(range(len(c)), key = lambda k: c[k])
    
    obj = LinExpr()
    sumconflicts = {}
    maxrooms = {}
    for i in range(n):
        sumconflicts[i] = sum(conflicts[i])
        if s[i] <= 50:
            maxrooms[i] = 1
        elif s[i] <= 100:
            maxrooms[i] = 2
        elif s[i] <= 400:
            maxrooms[i] = 7
        elif s[i] <= 700:
            maxrooms[i] = 9
        else:
            maxrooms[i] = 12
        c2 = LinExpr()
        c4 = LinExpr()
        for l in range(p):
            c1 = LinExpr()
            c1 = LinExpr()
            c3 = LinExpr()
            for k in range(r):
                if T[k][l] == 1 and location[k] in w[i]:
                    # print k, c[k], 1-(1/(pow(2,s_sorted.index(k))))
                    obj.addTerms( 1-(1/(pow(2,s_sorted.index(k)))) , x[i, k, l])
                    c1.addTerms(1, x[i,k,l])
                    c4.addTerms(c[k],x[i,k,l])
            model.addConstr(c1 <= maxrooms[i]* y[i,l], "c1a")
            model.addConstr(c1 >= y[i,l], "C1b")

            for j in conflicts[i]:
                c3.addTerms(1,y[j,l])
            model.addConstr(c3 <= (1 - y[i,l])*sumconflicts[i], "c3")

            c2.addTerms(1,y[i,l])
        model.addConstr( c2 == 1 , "c2")
        model.addConstr(c4 >= s[i], "c4")

    sumrooms = {}
    for l in range(p):
        sumrooms[l] = 0
        cover_inequalities = LinExpr()
        for k in range(r):   
            if T[k][l] == 1:
                sumrooms[l] += 1
                c5 = LinExpr()
                for i in range(n):
                    if location[k] in w[i]:
                        c5.addTerms(1,x[i,k,l])
                model.addConstr( c5 <= 1, "c5")  
                cover_inequalities += c5
        model.addConstr(cover_inequalities <= sumrooms[l], "cover_inequalities")


    # Break Symmetry
    # First only use small rooms in a period if all bigger rooms are already used
    # TODO Do for every location 


    if similarp[0] >= 0:
        for i in range(i-1):
            for l in range(p):
                model.addConstr(y[i,l] <= quicksum( y[i+1,sim] for sim in similarp), "s1")



    # for l in range(p):
    #     for index, k in enumerate(s_sorted):
    #         #print k, index
    #         s1 = LinExpr()
    #         if index < len(s_sorted)-1:
    #             if T[k][l] == 1:
    #                 for k2 in range(r-index):
    #                     if T[s_sorted[index+k2]][l] == 1:
    #                         for i in range(n):
    #                         #    if location[k] in w[i]:
    #                             s1.addTerms([1,-1], [x[i,k,l], x[i,s_sorted[index+k2],l]])
    #                         break
    #         model.addConstr( s1 <= 0 , "s1")

    #if p <= n:
    #    for l in range(p):
    #        model.addConstr( quicksum(y[l,i] for i in range(l)) >= 1, "s1")

    # for l in range(p-1):
    #     for i in range(n):
    #         model.addConstr( y[i,l] - quicksum(y[i,l+1] for i in range(l,n)) <= 0, "l1")



    model.setObjective( obj, GRB.MINIMIZE)

    print timeit.default_timer()-start
 
    

    if verbose:
        print("All constrained and objective built - OK")

    

    if not verbose:
        model.params.OutputFlag = 0
    
    # Set Parameters
    #print("Setting Parameters...")
 
    # max presolve agressivity
    #model.params.presolve = 2
    # Choosing root method 3= concurrent = run barrier and dual simplex in parallel
    model.params.method = 3
    #model.params.MIPFocus = 1

    model.params.OutputFlag = 1
    #model.params.MIPFocus = 1


    # cuts
    #model.params.cuts = 0
    #model.params.coverCuts = 2
    #model.params.CutPasses = 4

    # heuristics
    #model.params.heuristics = 0

    #model.params.symmetry = 2



    # # Tune the model
    # model.tune()

    # if model.tuneResultCount > 0:

    #     # Load the best tuned parameters into the model
    #     model.getTuneResult(0)

    #     # Write tuned parameters to a file
    #     model.write('tune1.prm')

    # return
    return(model)
Пример #45
0
def cycle_milp(A, C, k, gap):
    n = A.shape[0]
    t_0 = time.clock()
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap

    cycles = []
    vars = []
    cycles_grouped = [[] for i in range(n)]
    vars_grouped = [[] for i in range(n)]

    print('[%.1f] Generating variables...' % (time.clock() - t_0))

    print('i = ', end='')
    for i in range(n):
        for cycle in dfs_cycles(i, A, k):
            w = sum([2 if j in C else 1 for j in cycle])
            var = m.addVar(vtype=GRB.BINARY, obj=w)
            vars.append(var)
            cycles.append(cycle)
            cycles_grouped[i].append(cycle)
            vars_grouped[i].append(var)
            for j in cycle:
                if j > i:
                    vars_grouped[j].append(var)
                    cycles_grouped[j].append(cycle)
        if (i + 1) % 10 == 0:
            print(i + 1)

    m.update()

    print('[%.1f] Generated variables...' % (time.clock() - t_0))
    print('[%.1f] Generating constraints...' % (time.clock() - t_0))

    for i in range(n):
        vars_i = vars_grouped[i]
        lhs = LinExpr()
        ones = [1.0]*len(vars_i)
        lhs.addTerms(ones, vars_i)
        m.addConstr(lhs <= 1.0)

    print('[%.1f] Generated constraints...' % (time.clock() - t_0))
    print('[%.1f] Begin Optimizing %d vertex %d cycle model' % (time.clock() - t_0, n, len(cycles)))

    m.update()
    m.optimize()
    m.update()

    print('[%.1f] Finished Optimizing' % (time.clock() - t_0))
    print('[%.1f] Building cycles...' % (time.clock() - t_0))

    final_cycles = []

    for i in range(len(vars)):
        var = vars[i]
        if var.x == 1.0:
            cycle = cycles[i]
            final_cycles.append(cycle)

    print('[%.1f] Finished building cycles' % (time.clock() - t_0))
    return final_cycles, m.objval
class BFPBackupNetwork_Continuous(object):
    """ Class object for buffered failure probability-based model.

    Parameters
    ----------
    Gamma: importance sampling vector
    Nodes: set of nodes
    Links: set of links
    Capacity: capacities per link based based on random failures 
    Survivability: desired survivabiliy factor (epsilon)
    K: number of random scenarios
    
    Returns
    -------
    BackupCapacity: set of capacity per backup link. 
    BackupRoutes: set of backup links
    
    """

    # Private model object
    model = []

    # Private model variables
    BackupCapacity = {}
    bBackupLink = {}
    z0 = {}
    z = {}

    def __init__(self):
        """
        Constructor
        """

    def LoadModel(self, Gamma, Nodes, Links, Capacity, Survivability, NumSamples):
        """ Load model.
    
        Parameters
        ----------
        Gamma : importance sampling vector
        
        """
        self.Links = tuplelist(Links)
        self.Capacity = Capacity

        # Create optimization model
        self.model = Model("Backup")

        # Create variables
        for i, j in self.Links:
            self.BackupCapacity[i, j] = self.model.addVar(
                vtype=GRB.CONTINUOUS, lb=0, name="Backup_Capacity[%s,%s]" % (i, j)
            )
            # self.BackupCapacity[i,j] = self.model.addVar(lb=0, name='Backup_Capacity[%s,%s]' % (i, j))
        self.model.update()

        for i, j in self.Links:
            for s, d in self.Links:
                self.bBackupLink[i, j, s, d] = self.model.addVar(
                    vtype=GRB.BINARY, name="Backup_Link[%s,%s,%s,%s]" % (i, j, s, d)
                )
        self.model.update()

        for i, j in self.Links:
            for k in range(NumSamples):
                self.z[k, i, j] = self.model.addVar(lb=0, name="z[%s][%s][%s]" % (k, i, j))
        self.model.update()

        for i, j in self.Links:
            self.z0[i, j] = self.model.addVar(lb=-GRB.INFINITY, name="z0[%s][%s]" % (i, j))
        self.model.update()

        self.model.modelSense = GRB.MINIMIZE

        self.model.setObjective(quicksum(self.BackupCapacity[i, j] for i, j in self.Links))
        self.model.update()

        # ------------------------------------------------------------------------#
        #                    Constraints definition                              #
        #                                                                        #
        #                                                                        #
        # ------------------------------------------------------------------------#

        # Buffer probability I
        for i, j in self.Links:
            self.model.addConstr(
                self.z0[i, j]
                + 1 / (NumSamples * Survivability) * quicksum(self.z[k, i, j] for (k) in range(NumSamples))
                <= 0,
                "[CONST]Buffer_Prob_I[%s][%s]" % (i, j),
            )
        self.model.update()

        # Link capacity constraints
        for i, j in self.Links:
            for k in range(NumSamples):
                if Gamma == None:
                    self.model.addConstr(
                        (
                            quicksum(self.bBackupLink[i, j, s, d] * Capacity[k, s, d] for s, d in self.Links)
                            - self.BackupCapacity[i, j]
                            - self.z0[i, j]
                        )
                        <= self.z[k, i, j],
                        "[CONST]Buffer_Prob_II[%s][%s][%s]" % (k, i, j),
                    )
                else:
                    self.model.addConstr(
                        (
                            quicksum(self.bBackupLink[i, j, s, d] * Capacity[k, s, d] for s, d in self.Links)
                            - self.BackupCapacity[i, j]
                            - self.z0[i, j]
                        )
                        * Gamma[k]
                        <= self.z[k, i, j],
                        "[CONST]Buffer_Prob_II[%s][%s][%s]" % (k, i, j),
                    )
        self.model.update()

        # Link capacity constraints
        for i, j in self.Links:
            for k in range(NumSamples):
                self.model.addConstr(self.z[k, i, j] >= 0, "[CONST]Buffer_Prob_III[%s][%s][%s]" % (k, i, j))
        self.model.update()

        for i in Nodes:
            for s, d in self.Links:
                # Flow conservation constraints
                if i == s:
                    self.model.addConstr(
                        quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*"))
                        - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i))
                        == 1,
                        "Flow1[%s,%s,%s]" % (i, s, d),
                    )
                # Flow conservation constraints
                elif i == d:
                    self.model.addConstr(
                        quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*"))
                        - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i))
                        == -1,
                        "Flow2[%s,%s,%s]" % (i, s, d),
                    )
                # Flow conservation constraints
                else:
                    self.model.addConstr(
                        quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*"))
                        - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i))
                        == 0,
                        "Flow3[%s,%s,%s]" % (i, s, d),
                    )
        self.model.update()

    def Optimize(self, MipGap=None, TimeLimit=None, LogLevel=None):
        """ Optimize the defined  model.
    
        Parameters
        ----------
        MipGap : desired gap
        TimeLimit : time limit
        LogLevel: log level 1 for printing all optimal variables and None otherwise
        
        Returns
        -------
        BackupCapacity: The total capacity assigned per backup link
        BackupRoutes: The set of selected backup links 
           A tuple list with all paths for edge (s,d) that uses (i,j).
    
        """
        self.model.write("bpbackup.lp")

        if MipGap != None:
            self.model.params.MIPGap = MipGap
        if TimeLimit != None:
            self.model.params.timeLimit = TimeLimit
        # Compute optimal solution
        self.model.optimize()

        # Print solution
        if self.model.status == GRB.Status.OPTIMAL:

            if LogLevel == 1:
                for v in self.model.getVars():
                    print("%s %g" % (v.varName, v.x))

            self.BackupCapacitySolution = self.model.getAttr("x", self.BackupCapacity)
            self.BackupRoutesSolution = self.model.getAttr("x", self.bBackupLink)

            self.BackupLinksSolution = {}
            self.HatBackupCapacity = {}
            for link in self.BackupCapacitySolution:
                if self.BackupCapacitySolution[link] < 1 and self.BackupCapacitySolution[link] > 0.001:
                    self.HatBackupCapacity[link] = math.ceil(self.BackupCapacitySolution[link])
                else:
                    self.HatBackupCapacity[link] = math.floor(self.BackupCapacitySolution[link])
                if self.HatBackupCapacity[link] > 0:
                    if len(self.BackupLinksSolution) == 0:
                        self.BackupLinksSolution = [link]
                    else:
                        self.BackupLinksSolution = self.BackupLinksSolution + [link]
        else:
            print("Optimal value not found!\n")
            self.BackupCapacitySolution = []
            self.BackupRoutesSolution = {}
            self.BackupLinksSolution = {}

        return self.BackupCapacitySolution, self.BackupRoutesSolution, self.BackupLinksSolution, self.HatBackupCapacity

    def SaveBakupNetwork(self, file_name):
        """Save the optimal backup network to the file ``file_name``."""

        data = {
            "links": [i for i in self.BackupCapacitySolution],
            "capacities": [self.BackupCapacitySolution[i] for i in self.BackupCapacitySolution],
            "routes": [i for i in self.BackupRoutesSolution],
            "status": [self.BackupRoutesSolution[i] for i in self.BackupRoutesSolution],
        }
        f = open(file_name, "w")
        json.dump(data, f)
        f.close()

    def LoadBackupNetwork(self, file_name):
        """Load a backup network from the file ``file_name``.  
        Returns the backup network solution saved in the file. 
      
        """
        f = open(file_name, "r")
        data = json.load(f)
        f.close()

        self.BackupCapacitySolution = {}
        self.BackupRoutesSolution = {}
        self.BackupLinksSolution = {}

        links = [i for i in data["links"]]
        capacities = [i for i in data["capacities"]]
        routes = [i for i in data["routes"]]
        status = [i for i in data["status"]]

        IndexAux = 0
        for i, j in links:
            self.BackupCapacitySolution[i, j] = capacities[IndexAux]
            IndexAux = IndexAux + 1

        self.HatBackupCapacity = {}
        for link in self.BackupCapacitySolution:
            if self.BackupCapacitySolution[link] < 1 and self.BackupCapacitySolution[link] > 0.001:
                self.HatBackupCapacity[link] = math.ceil(self.BackupCapacitySolution[link])
            else:
                self.HatBackupCapacity[link] = math.floor(self.BackupCapacitySolution[link])
            if self.HatBackupCapacity[link] > 0:
                if len(self.BackupLinksSolution) == 0:
                    self.BackupLinksSolution = [link]
                else:
                    self.BackupLinksSolution = self.BackupLinksSolution + [link]

        IndexAux = 0
        for i, j, s, d in routes:
            self.BackupRoutesSolution[i, j, s, d] = status[IndexAux]
            IndexAux = IndexAux + 1

        return self.BackupCapacitySolution, self.BackupRoutesSolution, self.BackupLinksSolution, self.HatBackupCapacity

    def ResetModel(self):
        """
        Reset model solution.
        """
        self.BackupCapacity = {}
        self.bBackupLink = {}
        self.z0 = {}
        self.z = {}
        if self.model:
            self.model.reset()
Пример #47
0
class SolveSC1GuMIP:
    """
    Solve the initial marking problem optimally using Guroby (it must be install).
    
    The computation time can be quite long for big instances.
    """

    def __init__(self, dataflow, verbose, lp_filename):
        """
        Constructor
        """
        self.dataflow = dataflow
        self.verbose = verbose
        self.lp_filename = lp_filename

        self.col_v = {}  # dict use for storing gamma's variable column
        self.col_m0 = {}  # dict use for storing bds's variable column
        self.col_fm0 = {}  # dict use for storing FM0's variable column
        
    def compute_initial_marking(self):
        """launch the computation. This function return the objective value of the MILP problem
        
        The initial marking of the graph in parameter is modify.
        """
        self.__init_prob()  # Modify parameters
        self.__create_col()  # Add Col on prob
        self.__create_row()  # Add Row (constraint) on prob
        self.__create_obj()  # Add objectif function
        self.__solve_prob()  # Launch the solver and set preload of the graph
        del self.prob  # Del prob
        return self.Z  # Return the total amount find by the solver

    def __init_prob(self):  # Modify parameters
        logging.info("Generating initial marking problem")
        self.prob = Model("SC1_MIP")

        # Gurobi parameters:
        if not self.verbose:
            self.prob.params.OutputFlag = 0
            try:
                os.remove("gurobi.log")
            except OSError:
                pass
        self.prob.params.Threads = 2
        self.prob.params.intfeastol = 0.000001

    def __create_col(self):  # Add Col on prob
        # Create column bds (M0)
        for arc in self.dataflow.get_arc_list():
            self.__add_col_m0(arc)

        # Create column bds (FM0)
        for arc in self.dataflow.get_arc_list():
            self.__add_col_fm0(arc)

        # Create column lambda (v)
        for task in self.dataflow.get_task_list():
            phase_count = self.__get_range_phases(task)
            for i in xrange(phase_count):
                self.__add_col_v(str(task) + "/" + str(i))

        # Integrate new variables
        self.prob.update()

    def __create_row(self):  # Add Row (constraint) on prob
        # BEGUIN FILL ROW
        ########################################################################
        #                       Constraint FM0*step - M0 = 0                   #
        ########################################################################
        for arc in self.dataflow.get_arc_list():
            if not self.dataflow.is_arc_reentrant(arc):
                arc_gcd = self.dataflow.get_gcd(arc)
                self.__add_frow(arc, arc_gcd)

        ########################################################################
        #                       Constraint u-u'+M0 >= W1+1                     #
        ########################################################################
        for arc in self.dataflow.get_arc_list():
            source = self.dataflow.get_source(arc)
            target = self.dataflow.get_target(arc)
            if not self.dataflow.is_arc_reentrant(arc):
                range_source = self.__get_range_phases(source)
                range_target = self.__get_range_phases(target)
                prod_list = self.__get_prod_rate_list(arc)
                cons_list = self.__get_cons_rate_list(arc)
                if self.dataflow.is_pcg:
                    threshold_list = self.__get_threshold_list(arc)
                arc_gcd = self.dataflow.get_gcd(arc)

                pred_prod = 0
                for sourcePhase in xrange(range_source):  # source/prod/out normaux
                    if sourcePhase > 0:
                        pred_prod += prod_list[sourcePhase - 1]

                    pred_cons = 0
                    cons = 0
                    for targetPhase in xrange(range_target):  # target/cons/in normaux
                        cons += cons_list[targetPhase]
                        if targetPhase > 0:
                            pred_cons += cons_list[targetPhase - 1]

                        w = cons - pred_prod - arc_gcd
                        if self.dataflow.is_pcg:
                            w += pred_cons + threshold_list[targetPhase] - cons

                        str_v1 = str(source) + "/" + str(sourcePhase)
                        str_v2 = str(target) + "/" + str(targetPhase)

                        self.__add_row(str_v1, str_v2, arc, w)
        # END FILL ROW

    def __create_obj(self):
        obj = QuadExpr()

        for arc in self.dataflow.get_arc_list():
            obj += self.col_m0[arc]
        self.prob.setObjective(obj, GRB.MINIMIZE)

    def __solve_prob(self):  # Launch the solver and set preload of the graph
        logging.info("loading matrix ...")
        self.prob.update()

        if self.lp_filename is not None:
            problem_location = str(self.prob.write(self.lp_filename))
            logging.info("Writing problem: " + str(problem_location))

        logging.info("solving problem ...")
        self.prob.optimize()
        logging.info("Integer solving done !")

        self.Z = self.prob.objVal

        for arc in self.dataflow.get_arc_list():
            if not self.dataflow.is_arc_reentrant(arc):
                self.dataflow.set_initial_marking(arc, int(self.col_m0[arc].x))

        logging.info("SC1 MIP Mem tot (no reentrant): " + str(self.Z))

    # Add a variable lamda
    def __add_col_v(self, name):
        var = self.prob.addVar(vtype=GRB.CONTINUOUS, name=name)
        self.col_v[name] = var

    # Add a variable M0
    def __add_col_m0(self, arc):
        var = self.prob.addVar(lb=0, vtype=GRB.INTEGER)
        self.col_m0[arc] = var

    # Add a variable FM0
    def __add_col_fm0(self, arc):
        var = self.prob.addVar(lb=0, vtype=GRB.INTEGER)
        self.col_fm0[arc] = var

    # Add a constraint: lambda1 - lambda2 + M0 > W1
    def __add_row(self, str_v1, str_v2, arc, w):
        expr = LinExpr()
        if not self.dataflow.is_arc_reentrant(arc):
            expr += self.col_v[str_v1]
            expr -= self.col_v[str_v2]
        expr += self.col_m0[arc]

        self.prob.addConstr(expr, GRB.GREATER_EQUAL, w + 0.00001)

    # Add a constraint: FM0*step = M0
    def __add_frow(self, arc, step):
        expr = LinExpr()
        expr += self.col_fm0[arc]*float(step)
        expr -= self.col_m0[arc]
        self.prob.addConstr(expr, GRB.EQUAL, 0)

    def __get_range_phases(self, task):
        if self.dataflow.is_sdf:
            return 1
        range_task = self.dataflow.get_phase_count(task)
        if self.dataflow.is_pcg:
            range_task += self.dataflow.get_ini_phase_count(task)
        return range_task

    def __get_prod_rate_list(self, arc):
        if self.dataflow.is_sdf:
            return [self.dataflow.get_prod_rate(arc)]
        prod_list = self.dataflow.get_prod_rate_list(arc)
        if self.dataflow.is_pcg:
            prod_list = self.dataflow.get_ini_prod_rate_list(arc) + prod_list
        return prod_list

    def __get_cons_rate_list(self, arc):
        if self.dataflow.is_sdf:
            return [self.dataflow.get_cons_rate(arc)]
        cons_list = self.dataflow.get_cons_rate_list(arc)
        if self.dataflow.is_pcg:
            cons_list = self.dataflow.get_ini_cons_rate_list(arc) + cons_list
        return cons_list

    def __get_threshold_list(self, arc):
        return self.dataflow.get_ini_threshold_list(arc) + self.dataflow.get_threshold_list(arc)
    [ 8,  9,  5]
]
a = [
    [ 5,  7,  2],
    [14,  8,  7],
    [10,  6, 12],
    [ 8,  4, 15],
    [ 6, 12,  5]
]
 
# x[i][j] = 1 if i is assigned to j
x = []
for i in range(len(c)):
    x_i = []
    for j in c[i]:
        x_i.append(model.addVar(vtype=GRB.BINARY))
    x.append(x_i)
 
# As stated, the GAP has these following constraints. We dualize these into
# penalties instead, using variables so we can easily extract their values.
penalties = [model.addVar() for _ in x]
model.update()
 
# Dualized constraints: sum j: x_ij <= 1 for all i
for p, x_i in zip(penalties, x):
    model.addConstr(p == 1 - sum(x_i))
 
# sum i: a_ij * x_ij <= b[j] for all j
for j in range(len(b)):
    model.addConstr(sum(a[i][j] * x[i][j] for i in range(len(x))) <= b[j])
 
Пример #49
0
    def __objective_function(self, x, q):
        m = Model("Overall_Model")

        CT = {}
        DT = {}
        TD = {}

        #### Add Variable ####

        for j in range(self.project_n):
            ## solve individual model get Project complete date
            CT[j] = self.__optmize_single_project(x, j)

            ## Project Tadeness,construction completion time
            DT[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(DT%d)" % j)
            TD[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(TD%d)" % j)

        DT[-1] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(DT-1)")

        ## Review Sequence z_ij
        z = {}
        for i in range(self.project_n):
            for j in range(self.project_n):
                if i != j:
                    z[i, j] = m.addVar(obj=0, vtype=GRB.BINARY, name="(z%d,%d)" % (i, j))

        for j in range(self.project_n):
            z[-1, j] = m.addVar(obj=0, vtype=GRB.BINARY, name="(z%d,%d)" % (-1, j))
        m.update();

        #### Add Constraint ####
        ## Constrain 2: project complete data>due data ##
        for j in range(self.project_n):
            m.addConstr(DT[j] - TD[j], GRB.LESS_EQUAL, self.DD[j], name="constraint_2_project_%d" % j)

        ## Constraint 13
        for j in range(self.project_n):
            m.addConstr(DT[j], GRB.GREATER_EQUAL, CT[j] + self.review_duration[j], name="constraint_13_project_%d" % j)

        ## Constraint 14
        for i in range(-1, self.project_n):
            for j in range(self.project_n):
                if i != j:
                    m.addConstr(DT[j], GRB.GREATER_EQUAL, DT[i] - self.M * (1 - z[i, j]) + self.review_duration[j],
                                name="constraint_14_project_%d_project_%d" % (i, j))

        ## Constrain 15
        for j in range(self.project_n):
            m.addConstr(quicksum(z[i, j] for i in range(-1, self.project_n) if i != j), GRB.EQUAL, 1,
                        name="constraint_15_project_%d" % j)

        ## Constrain 16
        m.addConstr(quicksum(z[-1, j] for j in range(self.project_n)), GRB.EQUAL, 1, name="constraint_16")

        ## Constrain 17
        for i in range(self.project_n):
            m.addConstr(quicksum(z[i, j] for j in range(self.project_n) if j != i), GRB.LESS_EQUAL, 1,
                        name="constraint_17_project_%d" % i)
        m.update()

        # Set optimization objective - minimize sum of
        expr = LinExpr()
        for j in range(self.project_n):
            expr.add(self.w[j] * TD[j])
        m.setObjective(expr, GRB.MINIMIZE)
        m.update()

        m.params.presolve = 1
        m.update()

        m.optimize()
        m.write(join(self.output_dir, "heuristic_whole.lp"))
        m.write(join(self.output_dir, "heuristic_whole.sol"))
        print([self.w[j] * TD[j].X for j in range(self.project_n)])
        return m.objVal, argmax([self.w[j] * TD[j].X for j in range(self.project_n)])
def build_model(data, n_cliques = 0, verbose = True):
    
    # Load Data Format
    n = data['n']
    r = data['r']
    p = data['p']
    s = data['s']
    c = data['c']
    h = data['h']
    w = data['w']
    location = data['location']
    conflicts = data['conflicts']
    locking_times = data['locking_times']
    T = data['T']
    
    model = Model("ExaminationScheduling")
    
    
    if verbose:
        print("Building variables...")
    
    # x[i,k,l] = 1 if exam i is at time l in room k
    x = {}
    for k in range(r):
        for l in range(p):
            if T[k][l] == 1:
                for i in range(n):
                    if location[k] in w[i]:
                        x[i,k,l] = model.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (i,k,l))
    
    # y[i,l] = 1 if exam i is at time l
    y = {}
    for i in range(n):
        for l in range(p):
            y[i, l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l))
    

    # integrate new variables
    model.update() 

    start = timeit.default_timer()

    # not very readable but same constraints as in GurbiLinear_v_10: speeded up model building by 2 for small problems (~400 exams) and more for huger problem ~1500 exams
    if verbose:
        print("Building constraints...")    
    
    obj = LinExpr()
    sumconflicts = {}
    maxrooms = {}
    for i in range(n):
        sumconflicts[i] = sum(conflicts[i])
        if s[i] <= 50:
            maxrooms[i] = 1
        elif s[i] <= 100:
            maxrooms[i] = 2
        elif s[i] <= 400:
            maxrooms[i] = 7
        elif s[i] <= 700:
            maxrooms[i] = 9
        else:
            maxrooms[i] = 12
        c2 = LinExpr()
        c4 = LinExpr()
        for l in range(p):
            c1 = LinExpr()
            c1 = LinExpr()
            c3 = LinExpr()
            for k in range(r):
                if T[k][l] == 1 and location[k] in w[i]:
                    c1.addTerms(1, x[i, k, l])
                    c4.addTerms(c[k],x[i,k,l])
            obj += c1
            model.addConstr(c1 <= maxrooms[i]* y[i,l], "c1a")
            model.addConstr(c1 >= y[i,l], "C1b")

            for j in conflicts[i]:
                c3.addTerms(1,y[j,l])
            model.addConstr(c3 <= (1 - y[i,l])*sumconflicts[i], "c3")

            c2.addTerms(1,y[i,l])
        model.addConstr( c2 == 1 , "c2")
        model.addConstr(c4 >= s[i], "c4")

    sumrooms = {}
    for l in range(p):
        sumrooms[l] = 0
        cover_inequalities = LinExpr()
        for k in range(r):   
            if T[k][l] == 1:
                sumrooms[l] += 1
                c5 = LinExpr()
                for i in range(n):
                    if location[k] in w[i]:
                        c5.addTerms(1,x[i,k,l])
                model.addConstr( c5 <= 1, "c5")  
                cover_inequalities += c5
        model.addConstr(cover_inequalities <= sumrooms[l], "cover_inequalities")


    model.setObjective( obj, GRB.MINIMIZE)

    print timeit.default_timer()-start
 
    

    if verbose:
        print("All constrained and objective built - OK")

    

    if not verbose:
        model.params.OutputFlag = 0
    
    # Set Parameters
    #print("Setting Parameters...")
 
    # max presolve agressivity
    #model.params.presolve = 2
    # Choosing root method 3= concurrent = run barrier and dual simplex in parallel
    #model.params.method = 1
    #model.params.MIPFocus = 1

    model.params.OutputFlag = 1
    model.params.Method = 3


    # cuts
    model.params.cuts = 0
    model.params.cliqueCuts = 0
    model.params.coverCuts = 0
    model.params.flowCoverCuts = 0
    model.params.FlowPathcuts = 0
    model.params.GUBCoverCuts = 0
    model.params.impliedCuts = 0
    model.params.MIPSepCuts = 0
    model.params.MIRCuts = 0
    model.params.ModKCuts = 0
    model.params.NetworkCuts = 2
    model.params.SUBMIPCuts = 0
    model.params.ZeroHalfCuts = 0

    model.params.TimeLimit = 30



    # # Tune the model
    # model.tune()

    # if model.tuneResultCount > 0:

    #     # Load the best tuned parameters into the model
    #     model.getTuneResult(0)

    #     # Write tuned parameters to a file
    #     model.write('tune1.prm')

    # return
    return(model)
Пример #51
0
    def __optmize_single_project(self, x, j):
        '''
        Given the generated x for single project, try to optimize the tardiness of the project.
        :param x: the assignment of resource supplier to project
        :param j: index of project
        :return:
        '''
        m = Model("SingleProject_%d" % j)

        #### Create variables ####
        project = self.project_list[j]

        ## Project complete data,Project Tadeness,construction completion time
        CT = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(CT%d)" % j)

        ## Activity start time
        ST = {}
        project_activities = self.project_activity[project]
        # print(project_activities.nodes())
        for row in project_activities.nodes():
            ST[row] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(ST%d,%s)" % (j, row))

        ## Review sequence z_ij
        ## move to annealing objective function

        # y
        y = {}
        for activity_i in project_activities.nodes():
            for activity_j in project_activities.nodes():
                # print(project_activities.node[activity_i])
                # print(dir(project_activities.node[activity_i]))
                if activity_i != activity_j and len(list(
                        set(project_activities.node[activity_i]['rk_resources']).intersection(
                            project_activities.node[activity_j]['rk_resources']))) > 0:
                    y[activity_i, activity_j] = m.addVar(obj=0, vtype=GRB.BINARY,
                                                         name="(y%d,%s,%s)" % (j, activity_i, activity_j))
        m.update()

        #### Create constrains ####
        ## Constrain 2: project complete data>due data
        ## move to annealing objective function

        ## Constrain 3: supplier capacity limit
        ## move to annealing neighbor & random generator

        ## Constrain 4,6: project demand require; each project receive from one supplier for each resource
        ## move to annealing neighbor & random generator

        ## constrain 5: shipping constrain
        ## move to annealing neighbor & random generator

        ## Constrain 7:budget limit
        ## move to annealing constraint valid

        ## Constrain 8: activity starting constrain
        for a in project_activities.nodes():
            for r in project_activities.node[a]['resources']:
                resource_delivered_days = 0
                for s in self.resource_supplier_list[r]:
                    resource_delivered_days += x.get((r, s, project), 0) * \
                                               (self.resource_supplier_release_time[r, s] +
                                                self.supplier_project_shipping[
                                                    r, s, project])
                m.addConstr(resource_delivered_days, GRB.LESS_EQUAL, ST[a],
                            name="constraint_8_project_%d_activity_%s_resource_%s" % (j, a, r))

        ## Constrain 9 activity sequence constrain
        for row1, row2 in project_activities.edges():
            # print(row1, '#', row2, '#', j)
            # print(ST)
            m.addConstr(ST[row1] + project_activities.node[row1]['duration'], GRB.LESS_EQUAL,
                        ST[row2], name="constraint_9_project_%d_activity_%s_activity_%s" % (j, row1, row2))

        ## Constrain 10,11
        for row1 in project_activities.nodes():
            for row2 in project_activities.nodes():
                if row1 != row2 and len(list(
                        set(project_activities.node[row1]['rk_resources']).intersection(
                            project_activities.node[row2]['rk_resources']))) > 0:
                    m.addConstr(ST[row1] + project_activities.node[row1]['duration'] - self.M * (
                        1 - y[row1, row2]), GRB.LESS_EQUAL, ST[row2],
                                name="constraint_10_project_%d_activity_%s_activity_%s" % (j, row1, row2))
                    m.addConstr(
                        ST[row2] + project_activities.node[row2]['duration'] - self.M * (y[row1, row2]),
                        GRB.LESS_EQUAL, ST[row1],
                        name="constraint_11_project_%d_activity_%s_activity_%s" % (j, row1, row2))
                    # m.addConstr(y[j,row1,row2]+y[j,row2,row1],GRB.LESS_EQUAL,1)

        ## Constrain 12
        for row in project_activities.nodes():
            # print(project_activities.node[row]['duration'])
            m.addConstr(CT, GRB.GREATER_EQUAL, ST[row] + project_activities.node[row]['duration'],
                        name="constraint_12_project_%d_activity_%s" % (j, row))

        ## Constrain 13
        ## move to anealing objective function

        ## Constrain 14
        ## move to anealing objective function

        ## Constrain 15
        ## move to anealing objective function

        ## Constrain 16
        ## move to anealing objective function

        ## Constrain 17
        ## move to anealing objective function

        m.update()

        # Set optimization objective - minimize completion time
        expr = LinExpr()
        expr.add(CT)
        m.setObjective(expr, GRB.MINIMIZE)
        m.update()
        ##########################################
        m.params.presolve = 1
        m.update()
        # Solve
        # m.params.presolve=0
        m.optimize()
        m.write(join(self.output_dir, "heuristic_%d.lp" % j))
        m.write(join(self.output_dir, "heuristic_%d.sol" % j))
        return m.objVal
Пример #52
0
def lazy_cycle_constraint(A, C, k, gap):
    """
    Lazily generate cycle constraints as potential feasible solutions
    are generated.
    """
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    m.params.timelimit = 5 * 60 * 60
    m.params.lazyconstraints = 1

    n = A.shape[0]
    edges = tuplelist()
    vars = {}

    for i in range(n):
        for j in range(n):
            if A[i, j] == 1:
                e = (i, j)
                edges.append(e)
                w = 2 if j in C else 1
                var = m.addVar(vtype=GRB.BINARY, obj=w)
                vars[e] = var

    m.update()

    # flow constraints
    for i in range(n):
        out_vars = [vars[e] for e in edges.select(i, _)]
        out_ones = [1.0]*len(out_vars)
        out_expr = LinExpr()
        out_expr.addTerms(out_ones, out_vars)

        in_vars = [vars[e] for e in edges.select(_, i)]
        in_ones = [1.0]*len(in_vars)
        in_expr = LinExpr()
        in_expr.addTerms(in_ones, in_vars)

        m.addConstr(in_expr <= 1)
        m.addConstr(out_expr == in_expr)

    m.update()

    ith_cycle = 0

    def callback(model, where):
        if where == GRB.Callback.MIPSOL:
            sols = model.cbGetSolution([vars[e] for e in edges])
            c_edges = [edges[i] for i in range(len(edges)) if sols[i] > 0.5]
            cycles = cycles_from_edges(c_edges)
            for cycle in cycles:
                len_cycle = len(cycle)
                if len_cycle > k:
                    cycle_vars = [vars[(cycle[i], cycle[(i+1) % len_cycle])] for i in range(len_cycle)]
                    ones = [1.0]*len(cycle_vars)
                    expr = LinExpr()
                    expr.addTerms(ones, cycle_vars)
                    model.cbLazy(expr <= len_cycle - 1)

    m.optimize(callback)
    m.update()

    c_edges = [e for e in edges if vars[e].x == 1.0]
    cycles = cycles_from_edges(c_edges)

    return cycles, m.objval
Пример #53
0
def gurobi(wanted_parts, available_parts, stores, shipping_cost=10.0):
  from gurobipy import Model, GRB, LinExpr

  kf1 = lambda x: (x['item_id'], x['wanted_color_id'])
  kf2 = lambda x: (x['ItemID'], x['ColorID'])

  available_by_store = utils.groupby(available_parts, lambda x: x['store_id'])
  store_by_id = dict( (s['store_id'], s) for s in stores )

  m = Model()

  store_variables     = {}  # store id to variable indicating store is used
  quantity_variables  = []  # list of all lot variables + metadata

  # for every store
  for (store_id, inventory) in available_by_store.iteritems():

    # a variable for if anything was bought from this store. if 1, then pay
    # shipping cost and all store inventory is available; if 0, then don't pay
    # for shipping and every lot in it has 0 quantity available
    store_variables[store_id] = m.addVar(0.0, 1.0, shipping_cost, GRB.BINARY,
                                         "use-store=%s" % (store_id,))

    for lot in inventory:
      store_id = lot['store_id']
      quantity = lot['quantity_available']
      unit_cost= lot['cost_per_unit']
      item_id  = lot['item_id']
      color_id = lot['color_id']

      # a variable for how much to buy of this lot
      v = m.addVar(0.0, quantity, unit_cost, GRB.CONTINUOUS,
                   "quantity-store=%s-item=%s-color=%s" % (store_id, item_id, color_id))

      # keep a list of all lots
      quantity_variables.append({
        'store_id': store_id,
        'item_id': lot['item_id'],
        'wanted_color_id': lot['wanted_color_id'],
        'color_id': lot['color_id'],
        'variable': v,
        'quantity_available': quantity,
        'cost_per_unit': unit_cost
      })

  # actually put the variables into the model
  m.update()

  # for every lot in every store
  for lot in quantity_variables:
    use_store = store_variables[lot['store_id']]
    quantity  = lot['quantity_available']
    unit_cost = lot['cost_per_unit']
    v         = lot['variable']

    # a constraint for how much can be bought
    m.addConstr(LinExpr([1.0, -1 * quantity], [v, use_store]),
                GRB.LESS_EQUAL, 0.0,
                "maxquantity-store=%s-item=%s-color-%d" % (lot['store_id'], lot['item_id'], lot['color_id']))

  # for every wanted lot
  variables_by_id = utils.groupby(quantity_variables, kf1)
  for lot in wanted_parts:
    # a constraint saying amount bought >= wanted amount
    variables = map(lambda x: x['variable'], variables_by_id[kf2(lot)])
    constants = len(variables) * [1.0]
    m.addConstr(LinExpr(constants, variables),
                GRB.GREATER_EQUAL, lot['Qty'],
                "wantedamount-item=%s-color=%s" % (lot['ItemID'], lot['ColorID']))

  # for every store
  variables_by_store = utils.groupby(quantity_variables, lambda x: x['store_id'])
  for (store_id, variables) in variables_by_store.iteritems():
    use_store         = store_variables[store_id]
    minimum_purchase  = store_by_id[store_id]['minimum_buy']

    # a constraint saying "if I purchased from this store, I bought the minimum amount or more"
    constants = [v['cost_per_unit'] for v in variables] + [-1 * minimum_purchase]
    variables = [v['variable'] for v in variables] + [use_store]
    m.addConstr(LinExpr(constants, variables),
                GRB.GREATER_EQUAL, 0.0,
                "minbuy-store=%d" % (store_id,))

  # minimize sum of costs of items bought + shipping costs
  m.setParam(GRB.param.MIPGap, 0.01)  # stop when duality gap <= 1%
  m.optimize()

  # get results
  if m.ObjVal < float('inf'):
    result = []
    for lot in quantity_variables:
      # get variable out
      v = lot['variable']
      del lot['variable']

      # lot variables are continuous, so they might not actually be integral.
      # If they're not, check that they're "almost" integral, so we can just
      # round. Otherwise, print this warning.  According to theory the optimal
      # solution is for all continuous variables to be integral.
      if v.X != int(v.X) and abs(v.X - round(v.X)) > 1e-3:
        print 'Uh oh. Variable %s has value %f. This is a little close for comfort.' % (v.VarName, v.X)

      # save quantity to buy if it's > 0
      lot['quantity'] = int(round(v.X))
      if lot['quantity'] > 0:
        result.append(lot)

    cost = sum(e['quantity'] * e['cost_per_unit'] for e in result)
    store_ids = list(set(e['store_id'] for e in result))
    return [{
      'cost': cost,
      'allocation': result,
      'store_ids': store_ids
    }]
  else:
    print 'No solution :('
    return []
Пример #54
0
def constantino(A, C, k, gap):
    """
    Polynomial-sized CCMcP Edge-Extended Model
    See Constantino et al. (2013)
    """
    t_0 = time.clock()
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    # m.params.timelimit = 60 * 60
    # m.params.nodefilestart = 1.0
    # m.params.nodefiledir = './.nodefiledir'
    # m.params.presparsify = 0
    # m.params.presolve = 0

    n = A.shape[0]
    vars = {}
    edges = tuplelist()

    print('[%.1f] Generating variables...' % (time.clock() - t_0))

    # Variables
    for l in range(n):
        for i in range(l, n):
            for j in range(l, n):
                if A[i, j] == 1:
                    e = (l, i, j)
                    edges.append(e)
                    w = 2 if j in C else 1
                    var = m.addVar(vtype=GRB.BINARY, obj=w)
                    vars[e] = var

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    m.update()

    print('[%.1f] Generated variables' % (time.clock() - t_0))
    print('[%.1f] Adding flow constraints...' % (time.clock() - t_0))

    # Constraint (2): Flow in = Flow out
    for l in range(n):
        for i in range(l, n):
            # Flow in
            lhs_vars = [vars[e] for e in edges.select(l, _, i)]
            ones = [1.0]*len(lhs_vars)
            lhs = LinExpr()
            lhs.addTerms(ones, lhs_vars)

            # Flow out
            rhs_vars = [vars[e] for e in edges.select(l, i, _)]
            ones = [1.0]*len(rhs_vars)
            rhs = LinExpr()
            rhs.addTerms(ones, rhs_vars)

            # Flow in = Flow out
            m.addConstr(lhs == rhs)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added flow constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle vertex constraints...' % (time.clock() - t_0))

    # Constraint (3): Use a vertex only once per cycle
    for i in range(n):
        c_vars = [vars[e] for e in edges.select(_, i, _)]
        ones = [1.0]*len(c_vars)
        expr = LinExpr()
        expr.addTerms(ones, c_vars)
        m.addConstr(expr <= 1.0)

        if i % 100 == 0 and i != 0:
            print('[%.1f] V_i = %d' % (time.clock() - t_0, i))

    print('[%.1f] Added cycle vertex constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle cardinality constraints...' % (time.clock() - t_0))

    # Constraint (4): Limit cardinality of cycles to k
    for l in range(n):
        c_vars = [vars[e] for e in edges.select(l, _, _)]
        ones = [1.0]*len(c_vars)
        expr = LinExpr()
        expr.addTerms(ones, c_vars)
        m.addConstr(expr <= k)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added cycle cardinality constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle index constraints...' % (time.clock() - t_0))

    # Constraint (5): Cycle index is smallest vertex-index
    for l in range(n):
        rhs_vars = [vars[e] for e in edges.select(l, l, _)]
        ones = [1.0]*len(rhs_vars)
        rhs = LinExpr()
        rhs.addTerms(ones, rhs_vars)

        for i in range(l+1, n):
            lhs_vars = [vars[e] for e in edges.select(l, i, _)]
            if len(lhs_vars) > 0:
                ones = [1.0]*len(lhs_vars)
                lhs = LinExpr()
                lhs.addTerms(ones, lhs_vars)

                m.addConstr(lhs <= rhs)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added cycle index constraints...' % (time.clock() - t_0))
    print('[%.1f] Begin Optimizing %d vertex model' % (time.clock() - t_0, n))

    m.optimize()
    m.update()

    print('[%.1f] Finished Optimizing' % (time.clock() - t_0))
    print('[%.1f] Building cycles...' % (time.clock() - t_0))

    cycles = []
    for l in range(n):
        c_edges = [(e[1], e[2]) for e in edges.select(l, _, _) if vars[e].x == 1.0]
        cycles.extend(cycles_from_edges(c_edges))

    print('[%.1f] Finished building cycles' % (time.clock() - t_0))

    return cycles, m.objval
Пример #55
0
def _optimize_gurobi(cobra_model, new_objective=None, objective_sense='maximize',
                    min_norm=0, the_problem=None,
                    tolerance_optimality=1e-6, tolerance_feasibility=1e-6,
                    tolerance_barrier=None, tolerance_integer=1e-9, error_reporting=None,
                    print_solver_time=False, copy_problem=False, lp_method=0,
                    relax_b=None, quad_precision=False, quadratic_component=None,
                    reuse_basis=True, lp_parallel=None, update_problem_reaction_bounds=True):
    """Uses the gurobi (http://gurobi.com) optimizer to perform an optimization on cobra_model
    for the objective_coefficients in cobra_model._objective_coefficients based
    on objective sense.

    cobra_model: A cobra.Model object

    new_objective: Reaction, String, or Integer referring to a reaction in
    cobra_model.reactions to set as the objective.  Currently, only supports single
    objective coeffients.  Will expand to include mixed objectives.

    objective_sense: 'maximize' or 'minimize'

    min_norm: not implemented

    the_problem: None or a problem object for the specific solver that can be used to hot
    start the next solution.

    tolerance_optimality: Solver tolerance for optimality.

    tolerance_feasibility: Solver tolerance for feasibility.

    quad_precision: Boolean.  Whether or not to used quad precision in calculations

    error_reporting: None or True to disable or enable printing errors encountered
    when trying to find the optimal solution.
    
    print_solver_time: False or True.  Indicates if the time to calculate the solution
    should be displayed.


    quadratic_component: None or 
          scipy.sparse.dok of dim(len(cobra_model.reactions),len(cobra_model.reactions))
         If not None:
          Solves quadratic programming problems for cobra_models of the form:
          minimize: 0.5 * x' * quadratic_component * x + cobra_model._objective_coefficients' * x
          such that,
            cobra_model._lower_bounds <= x <= cobra_model._upper_bounds
            cobra_model._S * x (cobra_model._constraint_sense) cobra_model._b

            NOTE: When solving quadratic problems it may be necessary to disable quad_precision
            and use lp_method = 0 for gurobi.

    reuse_basis: Boolean.  If True and the_problem is a model object for the solver,
    attempt to hot start the solution.

    update_problem_reaction_bounds: Boolean.  Set to True if you're providing the_problem
    and you've modified reaction bounds on your cobra_model since creating the_problem.  Only
    necessary for CPLEX
    
    lp_parallel: Not implemented

    lp.optimize() with Salmonella model:
         cold start: 0.063 seconds
         hot start: 0.057 seconds (Slow due to copying the LP)
         

    """
    if relax_b is not None:
        raise Exception('Need to reimplement constraint relaxation')
    from numpy import array, nan, zeros
    #TODO: speed this up
    if objective_sense == 'maximize':
        objective_sense = -1
    else:
        objective_sense = 1
    from gurobipy import Model, LinExpr, GRB, QuadExpr
    sense_dict = {'E': GRB.EQUAL,
                  'L': GRB.LESS_EQUAL,
                  'G': GRB.GREATER_EQUAL}
    from cobra.flux_analysis.objective import update_objective
    from cobra.solvers.legacy import status_dict, variable_kind_dict

    variable_kind_dict = eval(variable_kind_dict['gurobi'])
    status_dict = eval(status_dict['gurobi'])

    #Update objectives if they are new.
    if new_objective and new_objective != 'update problem':
       update_objective(cobra_model, new_objective)
    #Create a new problem
    if not the_problem or the_problem in ['return', 'setup'] or \
           not isinstance(the_problem, Model):
        lp = Model("cobra")
        lp.Params.OutputFlag = 0
        lp.Params.LogFile = ''
        # Create variables
        #TODO:  Speed this up 
        variable_list = [lp.addVar(lb=float(x.lower_bound),
                                   ub=float(x.upper_bound),
                                   obj=objective_sense*float(x.objective_coefficient),
                                   name=x.id,
                                   vtype=variable_kind_dict[x.variable_kind])
                         for x in cobra_model.reactions]
        reaction_to_variable = dict(zip(cobra_model.reactions,
                                        variable_list))
        # Integrate new variables
        lp.update()
        #Set objective to quadratic program
        if quadratic_component is not None:
            if not hasattr(quadratic_component, 'todok'):
                raise Exception('quadratic component must be a scipy.sparse type array')

            quadratic_objective = QuadExpr()
            for (index_0, index_1), the_value in quadratic_component.todok().items():
                quadratic_objective.addTerms(the_value,
                                       variable_list[index_0],
                                       variable_list[index_1])
            lp.setObjective(quadratic_objective, sense=objective_sense)
        #Constraints are based on mass balance
        #Construct the lin expression lists and then add
        #TODO: Speed this up as it takes about .18 seconds
        #HERE
        for the_metabolite in cobra_model.metabolites:
            constraint_coefficients = []
            constraint_variables = []
            for the_reaction in the_metabolite._reaction:
                constraint_coefficients.append(the_reaction._metabolites[the_metabolite])
                constraint_variables.append(reaction_to_variable[the_reaction])
            #Add the metabolite to the problem
            lp.addConstr(LinExpr(constraint_coefficients, constraint_variables),
                         sense_dict[the_metabolite._constraint_sense.upper()],
                         the_metabolite._bound,
                         the_metabolite.id)
    else:
        #When reusing the basis only assume that the objective coefficients or bounds can change
        if copy_problem:
            lp = the_problem.copy()
        else:
            lp = the_problem
        if not reuse_basis:
            lp.reset()
        for the_variable, the_reaction in zip(lp.getVars(),
                                              cobra_model.reactions):
            the_variable.lb = float(the_reaction.lower_bound)
            the_variable.ub = float(the_reaction.upper_bound)
            the_variable.obj = float(objective_sense*the_reaction.objective_coefficient)

    
    if the_problem == 'setup':
        return lp
    if print_solver_time:
        start_time = time()
    lp.update()
    lp.setParam("FeasibilityTol", tolerance_feasibility)
    lp.setParam("OptimalityTol", tolerance_optimality) 
    if tolerance_barrier:
        lp.setParam("BarConvTol", tolerance_barrier)

    if quad_precision:
            lp.setParam("Quad", 1)
    lp.setParam("Method", lp_method)

    #Different methods to try if lp_method fails
    the_methods = [0, 2, 1]
    if lp_method in the_methods:
        the_methods.remove(lp_method)
    if not isinstance(the_problem, Model):
        lp.optimize()
        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            #Try to find a solution using a different method
            lp.setParam("MarkowitzTol", 1e-2)
            for lp_method in the_methods:
                lp.setParam("Method", lp_method)
                lp.optimize()
                if status_dict[lp.status] == 'optimal':
                    break
    else:
        lp.setParam("TimeLimit", 0.6)
        lp.optimize()
        lp.setParam("TimeLimit", "default")
        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            lp.setParam("MarkowitzTol", 1e-2)
            #Try to find a solution using a different method
            for lp_method in the_methods:
                lp.setParam("Method", lp_method)
                lp.optimize()
                if status_dict[lp.status] == 'optimal':
                    break
                
            if status_dict[lp.status] != 'optimal':
                lp = optimize_gurobi(cobra_model, new_objective=new_objective, objective_sense=objective_sense,
                                     min_norm=min_norm, the_problem=None, 
                                     print_solver_time=print_solver_time)['the_problem']


    if print_solver_time:
        print 'optimize time: %f'%(time() - start_time)
    x_dict = {}
    y_dict = {}
    y = None
    if lp.status in status_dict:
        status = status_dict[lp.status]
    else:
        status = 'failed'
    if status == 'optimal':
        objective_value = objective_sense*lp.ObjVal
        [x_dict.update({v.VarName: v.X}) for v in lp.getVars()]
        x = array([x_dict[v.id] for v in cobra_model.reactions])
        if lp.isMIP:
            y = y_dict = None #MIP's don't have duals
        else:
            [y_dict.update({c.ConstrName: c.Pi})
             for c in lp.getConstrs()]
            y = array([y_dict[v.id] for v in cobra_model.metabolites])
    else:
        y = y_dict = x = x_dict = None
        objective_value = None
        if error_reporting:
            print 'gurobi failed: %s'%lp.status  
    the_solution = Solution(objective_value, x=x, x_dict=x_dict,
                            y=y, y_dict=y_dict,
                            status=status)
    solution = {'the_problem': lp, 'the_solution': the_solution}
    return solution
def build_model(data, n_cliques = 0, verbose = True):
    
    # Load Data Format
    n = data['n']
    r = data['r']
    p = data['p']
    s = data['s']
    c = data['c']
    h = data['h']
    w = data['w']
    location = data['location']
    conflicts = data['conflicts']
    locking_times = data['locking_times']
    T = data['T']
    
    model = Model("ExaminationScheduling")
    
    
    if verbose:
        print("Building variables...")
    
    # x[i,k,l] = 1 if exam i is at time l in room k
    x = {}
    for k in range(r):
        for l in range(p):
            if T[k][l] == 1:
                for i in range(n):
                    if location[k] in w[i]:
                        x[i,k,l] = model.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (i,k,l))
    
    # y[i,l] = 1 if exam i is at time l
    y = {}
    for i in range(n):
        for l in range(p):
            y[i, l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l))
    

    # integrate new variables
    model.update() 

    start = timeit.default_timer()
    # adding constraints as found in MidTerm.pdf
    if verbose:
        print("Building constraints...")    
    
    if verbose:
        print("c1: connecting variables x and y")
    for i in range(n):
        for l in range(p):
            model.addConstr( quicksum([ x[i, k, l] for k in range(r) if T[k][l] == 1 and location[k] in w[i] ]) <= 12 * y[i, l], "c1a")
            model.addConstr( quicksum([ x[i, k, l] for k in range(r) if T[k][l] == 1 and location[k] in w[i] ]) >= y[i, l], "c1b")
            
    if verbose:
        print("c2: each exam at exactly one time")
    for i in range(n):
        model.addConstr( quicksum([ y[i, l] for l in range(p) ]) == 1 , "c2")

    """
    Idea:   -instead of saving a conflict Matrix, save Cliques of exams that cannot be written at the same time
            -then instead of saying of one exam is written in a given period all conflicts cannot be written in the same period we could say
            -for all exams in a given clique only one can be written
    """
    
    if verbose:
        print("c3: avoid conflicts")
    for i in range(n):
        for l in range(p):
            # careful!! Big M changed!
            model.addConstr(quicksum([ y[j,l] for j in conflicts[i] ]) <= (1 - y[i, l]) * sum(conflicts[i]), "c3")
    
    if verbose:
        print("c4: seats for all students")
    for i in range(n):
        model.addConstr( quicksum([ x[i, k, l] * c[k] for k in range(r) for l in range(p) if T[k][l] == 1 and location[k] in w[i] ]) >= s[i], "c4")
    
    if verbose:
        print("c5: only one exam per room per period")
    for k in range(r):
        for l in range(p):
            if T[k][l] == 1:
                model.addConstr( quicksum([ x[i, k, l] for i in range(n) if location[k] in w[i] ]) <= 1, "c5")    
    

    if verbose:
        print("All constrained built - OK")

    

    # objective: minimize number of used rooms
    if verbose:
        print("Building Objective...")
    obj1 = quicksum([ x[i,k,l] for i,k,l in itertools.product(range(n), range(r), range(p)) if T[k][l] == 1 and location[k] in w[i]]) 

    model.setObjective( obj1, GRB.MINIMIZE)

    print timeit.default_timer()-start

    if not verbose:
        model.params.OutputFlag = 0
    
    # Set Parameters
    #print("Setting Parameters...")
 
    # max presolve agressivity
    #model.params.presolve = 2
    # Choosing root method 3= concurrent = run barrier and dual simplex in parallel
    #model.params.method = 1
    #model.params.MIPFocus = 1
    #model.params.cuts = 0
    model.params.OutputFlag = 1


    # # Tune the model
    # model.tune()

    # if model.tuneResultCount > 0:

    #     # Load the best tuned parameters into the model
    #     model.getTuneResult(0)

    #     # Write tuned parameters to a file
    #     model.write('tune1.prm')

    # return
    return(model)
Пример #57
0
class GurobiSolver(Solver):
    """ Implements the solver interface using gurobipy. """

    def __init__(self):
        Solver.__init__(self)
        self.problem = GurobiModel()
        

    def __getstate__(self):
        tmp_file = tempfile.mktemp(suffix=".lp")
        self.problem.update()
        self.problem.write(tmp_file)
        cplex_form = open(tmp_file).read()
        repr_dict = {'var_ids': self.var_ids, 'constr_ids': self.constr_ids, 'cplex_form': cplex_form}
        return repr_dict

    def __setstate__(self, repr_dict):
        tmp_file = tempfile.mktemp(suffix=".lp")
        open(tmp_file, 'w').write(repr_dict['cplex_form'])
        self.problem = read(tmp_file)
        self.var_ids = repr_dict['var_ids']
        self.constr_ids = repr_dict['constr_ids']

            
    def add_variable(self, var_id, lb=None, ub=None, vartype=VarType.CONTINUOUS, persistent=True, update_problem=True):
        """ Add a variable to the current problem.
        
        Arguments:
            var_id : str -- variable identifier
            lb : float -- lower bound
            ub : float -- upper bound
            vartype : VarType -- variable type (default: CONTINUOUS)
            persistent : bool -- if the variable should be reused for multiple calls (default: true)
            update_problem : bool -- update problem immediately (default: True)
        """
        lb = lb if lb is not None else -GRB.INFINITY
        ub = ub if ub is not None else GRB.INFINITY
        
        map_types = {VarType.BINARY: GRB.BINARY,
                     VarType.INTEGER: GRB.INTEGER,
                     VarType.CONTINUOUS: GRB.CONTINUOUS}

        if var_id in self.var_ids:
            var = self.problem.getVarByName(var_id)
            var.setAttr('lb', lb)
            var.setAttr('ub', ub)
            var.setAttr('vtype', map_types[vartype])
        else:
            self.problem.addVar(name=var_id, lb=lb, ub=ub, vtype=map_types[vartype])
            self.var_ids.append(var_id)
            
        if not persistent:
            self.temp_vars.add(var_id)
        
        if update_problem:
            self.problem.update()

    def add_constraint(self, constr_id, lhs, sense='=', rhs=0, persistent=True, update_problem=True):
        """ Add a variable to the current problem.
        
        Arguments:
            constr_id : str -- constraint identifier
            lhs : list [of (str, float)] -- variables and respective coefficients
            sense : {'<', '=', '>'} -- default '='
            rhs : float -- right-hand side of equation (default: 0)
            persistent : bool -- if the variable should be reused for multiple calls (default: True)
            update_problem : bool -- update problem immediately (default: True)
        """

        grb_sense = {'=': GRB.EQUAL,
                     '<': GRB.LESS_EQUAL,
                     '>': GRB.GREATER_EQUAL}

        if constr_id in self.constr_ids:
            constr = self.problem.getConstrByName(constr_id)
            self.problem.remove(constr)

        expr = quicksum([coeff * self.problem.getVarByName(r_id) for r_id, coeff in lhs if coeff])
        self.problem.addConstr(expr, grb_sense[sense], rhs, constr_id)
        self.constr_ids.append(constr_id)
            
        if not persistent:
            self.temp_constrs.add(constr_id)

        if update_problem:
            self.problem.update()
                                
    def remove_variable(self, var_id):
        """ Remove a variable from the current problem.
        
        Arguments:
            var_id : str -- variable identifier
        """
        if var_id in self.var_ids:
            self.problem.remove(self.problem.getVarByName(var_id))
            self.var_ids.remove(var_id)
    
    def remove_constraint(self, constr_id):
        """ Remove a constraint from the current problem.
        
        Arguments:
            constr_id : str -- constraint identifier
        """
        if constr_id in self.constr_ids:
            self.problem.remove(self.problem.getConstrByName(constr_id))
            self.constr_ids.remove(constr_id)
    
    def update(self):
        """ Update internal structure. Used for efficient lazy updating. """
        self.problem.update()

        
    def solve_lp(self, objective, model=None, constraints=None, get_shadow_prices=False, get_reduced_costs=False):
        """ Solve an LP optimization problem.

        Arguments:
            objective : dict (of str to float) -- reaction ids in the objective function and respective
                        coefficients, the sense is maximization by default
            model : ConstraintBasedModel -- model (optional, leave blank to reuse previous model structure)
            constraints : dict (of str to (float, float)) -- environmental or additional constraints (optional)
            get_shadow_prices : bool -- return shadow price information if available (optional, default: False)
            get_reduced_costs : bool -- return reduced costs information if available (optional, default: False)
        Returns:
            Solution
        """

        return self._generic_solve(None, objective, GRB.MAXIMIZE, model, constraints, get_shadow_prices,
                                   get_reduced_costs)

    def solve_qp(self, quad_obj, lin_obj, model=None, constraints=None, get_shadow_prices=False,
                 get_reduced_costs=False):
        """ Solve an LP optimization problem.

        Arguments:
            quad_obj : dict (of (str, str) to float) -- map reaction pairs to respective coefficients
            lin_obj : dict (of str to float) -- map single reaction ids to respective linear coefficients
            model : ConstraintBasedModel -- model (optional, leave blank to reuse previous model structure)
            constraints : dict (of str to (float, float)) -- overriding constraints (optional)
            get_shadow_prices : bool -- return shadow price information if available (default: False)
            get_reduced_costs : bool -- return reduced costs information if available (default: False)

        Returns:
            Solution
        """


        return self._generic_solve(quad_obj, lin_obj, GRB.MINIMIZE, model, constraints, get_shadow_prices,
                                   get_reduced_costs)

    def _generic_solve(self, quad_obj, lin_obj, sense, model=None, constraints=None, get_shadow_prices=False,
                       get_reduced_costs=False):

        if model:
            self.build_problem(model)

        problem = self.problem

        if constraints:
            old_constraints = {}
            for r_id, (lb, ub) in constraints.items():
                lpvar = problem.getVarByName(r_id)
                old_constraints[r_id] = (lpvar.lb, lpvar.ub)
                lpvar.lb = lb if lb is not None else -GRB.INFINITY
                lpvar.ub = ub if ub is not None else GRB.INFINITY
            problem.update()

        #create objective function
        quad_obj_expr = [q * problem.getVarByName(r_id1) * problem.getVarByName(r_id2)
                         for (r_id1, r_id2), q in quad_obj.items() if q] if quad_obj else []

        lin_obj_expr = [f * problem.getVarByName(r_id)
                        for r_id, f in lin_obj.items() if f] if lin_obj else []

        obj_expr = quicksum(quad_obj_expr + lin_obj_expr)

        problem.setObjective(obj_expr, sense)
        problem.update()

#        from datetime import datetime
#        self.problem.write("problem_{}.lp".format(str(datetime.now())))
        
        #run the optimization
        problem.optimize()

        status = status_mapping[problem.status] if problem.status in status_mapping else Status.UNKNOWN
        message = str(problem.status)

        if status == Status.OPTIMAL:
            fobj = problem.ObjVal
            values = OrderedDict([(r_id, problem.getVarByName(r_id).X) for r_id in self.var_ids])

            #if metabolite is disconnected no constraint will exist
            shadow_prices = OrderedDict([(m_id, problem.getConstrByName(m_id).Pi)
                                         for m_id in self.constr_ids
                                         if problem.getConstrByName(m_id)]) if get_shadow_prices else None

            reduced_costs = OrderedDict([(r_id, problem.getVarByName(r_id).RC)
                                         for r_id in self.var_ids]) if get_reduced_costs else None

            solution = Solution(status, message, fobj, values, shadow_prices, reduced_costs)
        else:
            solution = Solution(status, message)

        #reset old constraints because temporary constraints should not be persistent
        if constraints:
            for r_id, (lb, ub) in old_constraints.items():
                lpvar = problem.getVarByName(r_id)
                lpvar.lb, lpvar.ub = lb, ub
            problem.update()

        return solution
Пример #58
0
def tsp_gurobi(edges):
    """
    Modeled using GUROBI python example.
    """
    from gurobipy import Model, GRB, quicksum

    edges = populate_edge_weights(edges)
    incoming, outgoing, nodes = node_to_edge(edges)
    idx = dict((n, i) for i, n in enumerate(nodes))
    nedges = len(edges)
    n = len(nodes)

    m = Model()

    step = lambda x: "u_{0}".format(x)
    # Create variables
    vars = {}
    for i, (a, b, w) in enumerate(edges):
        vars[i] = m.addVar(obj=w, vtype=GRB.BINARY, name=str(i))
    for u in nodes[1:]:
        u = step(u)
        vars[u] = m.addVar(obj=0, vtype=GRB.INTEGER, name=u)
    m.update()

    # Bounds for step variables
    for u in nodes[1:]:
        u = step(u)
        vars[u].lb = 1
        vars[u].ub = n - 1

    # Add degree constraint
    for v in nodes:
        incoming_edges = incoming[v]
        outgoing_edges = outgoing[v]
        m.addConstr(quicksum(vars[x] for x in incoming_edges) == 1)
        m.addConstr(quicksum(vars[x] for x in outgoing_edges) == 1)

    # Subtour elimination
    edge_store = dict(((idx[a], idx[b]), i) for i, (a, b, w) in enumerate(edges))

    # Given a list of edges, finds the shortest subtour
    def subtour(s_edges):
        visited = [False] * n
        cycles = []
        lengths = []
        selected = [[] for i in range(n)]
        for x, y in s_edges:
            selected[x].append(y)
        while True:
            current = visited.index(False)
            thiscycle = [current]
            while True:
                visited[current] = True
                neighbors = [x for x in selected[current] if not visited[x]]
                if len(neighbors) == 0:
                    break
                current = neighbors[0]
                thiscycle.append(current)
            cycles.append(thiscycle)
            lengths.append(len(thiscycle))
            if sum(lengths) == n:
                break
        return cycles[lengths.index(min(lengths))]

    def subtourelim(model, where):
        if where != GRB.callback.MIPSOL:
            return
        selected = []
        # make a list of edges selected in the solution
        sol = model.cbGetSolution([model._vars[i] for i in range(nedges)])
        selected = [edges[i] for i, x in enumerate(sol) if x > .5]
        selected = [(idx[a], idx[b]) for a, b, w in selected]
        # find the shortest cycle in the selected edge list
        tour = subtour(selected)
        if len(tour) == n:
            return
        # add a subtour elimination constraint
        c = tour
        incident = [edge_store[a, b] for a, b in pairwise(c + [c[0]])]
        model.cbLazy(quicksum(model._vars[x] for x in incident) <= len(tour) - 1)

    m.update()

    m._vars = vars
    m.params.LazyConstraints = 1
    m.optimize(subtourelim)

    selected = [v.varName for v in m.getVars() if v.x > .5]
    selected = [int(x) for x in selected if x[:2] != "u_"]
    results = sorted(x for i, x in enumerate(edges) if i in selected) \
                    if selected else None
    return results
Пример #59
0
    def run_algorithm(self):

        old_M = self.M
        old_items = [i.copy() for i in self.items]
        map_name_to_old_item = dict()
        for i in old_items:
            map_name_to_old_item[i.name] = i
        self.scale_items_by_cost()

        from gurobipy import Model, GRB
        model = Model("NP-Hard")

        print("Setting Model Parameters")
        # set timeout
        model.setParam('TimeLimit', 1600)
        model.setParam('MIPFocus', 3)
        model.setParam('PrePasses', 1)
        model.setParam('Heuristics', 0.01)
        model.setParam('Method', 0)

        map_name_to_item = dict()
        map_name_to_cost = dict()
        map_name_to_weight = dict()
        map_name_to_profit = dict()
        map_class_to_name = dict()
        
        item_names = list()

        print("Preprocessing data for model...")

        for item in self.items:
            item_names.append(item.name)
            map_name_to_item[item.name] = item
            map_name_to_cost[item.name] = item.cost
            map_name_to_weight[item.name] = item.weight
            map_name_to_profit[item.name] = item.profit
            if item.classNumber not in map_class_to_name:
                map_class_to_name[item.classNumber] = list()
            map_class_to_name[item.classNumber].append(item.name)

        class_numbers = list(map_class_to_name.keys())

        print("Setting model variables...")
        # binary variables =1, if use>0
        items = model.addVars(item_names, vtype=GRB.BINARY, name="items")
        classes = model.addVars(class_numbers, vtype=GRB.BINARY, name="class numbers")

        print("Setting model objective...")
        # maximize profit
        objective = items.prod(map_name_to_profit)
        model.setObjective(objective, GRB.MAXIMIZE)

        # constraints
        print("Setting model constraints")
        model.addConstr(items.prod(map_name_to_weight) <= self.P,"weight capacity")
        model.addConstr(items.prod(map_name_to_cost) <= self.M,"cost capacity")
        
        # if any item from a class is chosen, that class variable has to be a binary of 1
        for num in class_numbers:
            model.addGenConstrOr(classes[num], [items[x] for x in map_class_to_name[num]] ,name="class count")

        for c in self.raw_constraints:
            count = model.addVar()
            for n in c:
                if n in classes:
                    count += classes[n]
            model.addConstr(count <= 1, name="constraint")

        print("Start optimizing...")
        model.optimize()
        print("Done! ")

        # Status checking
        status = model.Status
        if status == GRB.Status.INF_OR_UNBD or \
           status == GRB.Status.INFEASIBLE  or \
           status == GRB.Status.UNBOUNDED:
            print('The model cannot be solved because it is infeasible or unbounded')

        if status != GRB.Status.OPTIMAL:
            print('Optimization was stopped with status ' + str(status))
            Problem = True

        try:
            model.write("mps_model/" + self.filename + ".sol")
        except Exception as e:
            pass

        print("Generating solution file...")
        # Display solution
        solution_names = list()
        for i, v in enumerate(items):
            try:
                if items[v].X > 0.9:
                    solution_names.append(item_names[i])
            except Exception as e:
                pass

        self.M = old_M
        self.items = old_items
        solution = [map_name_to_old_item[i] for i in solution_names]
        return solution