Example #1
0
    def _initialize_model(self):

        problem = Model()
        problem.setParam('OutputFlag', False)

        # edges from source to reviewers, capacity controls maximum reviewer load
        self._source_vars = problem.addVars(self.numrev, vtype=GRB.CONTINUOUS, lb=0.0,
                                            ub=self.ability, name='reviewers')

        # edges from papers to sink, capacity controls a number of reviewers per paper
        self._sink_vars = problem.addVars(self.numpapers, vtype=GRB.CONTINUOUS, lb=0.0,
                                          ub=self.demand, name='papers')

        # edges between reviewers and papers. Initially capacities are set to 0 (no edge is added in the network)
        self._mix_vars = problem.addVars(self.numrev, self.numpapers, vtype=GRB.CONTINUOUS,
                                         lb=0.0, ub=0.0, name='assignment')
        problem.update()

        # flow balance equations for reviewers' nodes
        self._balance_reviewers = problem.addConstrs((self._source_vars[i] == self._mix_vars.sum(i, '*')
                                                      for i in range(self.numrev)))

        # flow balance equations for papers' nodes
        self._balance_papers = problem.addConstrs((self._sink_vars[i] == self._mix_vars.sum('*', i)
                                                   for i in range(self.numpapers)))
        problem.update()

        self._problem = problem
Example #2
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
Example #3
0
def initialize_model(cost_matrix, cutoff, model=None):
    #Add dummy detection
    cost_matrix = np.insert(cost_matrix,
                            0,
                            np.ones(cost_matrix.shape[0]) * cutoff,
                            axis=1)
    M, N = cost_matrix.shape
    if model is None:
        model = Model()
    else:
        model.remove(model.getVars())
        model.remove(model.getConstrs())
    model.setParam('OutputFlag', False)
    # y = []
    # for i in range(M):
    #     y.append([])
    #     for j in range(N):
    #         y[i].append(m.addVar(vtype=GRB.BINARY, name = 'y_%d%d'%(i,j)))
    y = model.addVars(M, N, vtype=GRB.BINARY, name='y')
    model.setObjective(
        quicksum(
            quicksum([y[i, j] * cost_matrix[i][j] for j in range(N)])
            for i in range(M)), GRB.MINIMIZE)
    # for i in range(M):
    model.addConstrs(
        (quicksum(y[i, j] for j in range(N)) == 1 for i in range(M)),
        name='constraint for track')
    # for j in range(1,N):
    model.addConstrs(
        (quicksum(y[i, j] for i in range(M)) <= 1 for j in range(1, N)),
        name='constraint for detection')
    y = list(y.values())
    return model, M, N, y
def solve():
    model = Model("Enigma Riddle Binary Program")
    letters = {"E", "N", "I", "G", "M", "A"}
    digits = range(1, 10)
    # x[i, j] == 1 => Letter i uses digit j
    x = model.addVars(letters, digits, vtype=GRB.BINARY)
    # Final value for first word
    b = model.addVar(vtype=GRB.INTEGER)
    first_word = "ENIGMA"
    second_word = "IGMAEN"

    # Constraints for the enigma-igmaen numbers
    model.addConstr(
        quicksum(
            quicksum(10**(len(first_word) - 1 - i) * j * x[first_word[i], j]
                     for j in digits) for i in range(len(first_word))) == b)
    model.addConstr(
        quicksum(
            quicksum(10**(len(second_word) - 1 - i) * j * x[second_word[i], j]
                     for j in digits)
            for i in range(len(second_word))) == b * 1.2)

    # Conflict constraint, different letters have different digits
    model.addConstrs(x[i_1, j] + x[i_2, j] <= 1 for i_1 in letters
                     for i_2 in letters for j in digits if i_1 != i_2)

    # Exactly one digit has to be used per letter
    model.addConstrs(quicksum(x[i, j] for j in digits) == 1 for i in letters)

    model.optimize()
    return model
Example #5
0
def solve():
    model = Model("Enigma Riddle Binary Program")
    letters = {"E", "N", "I", "G", "M", "A"}
    digits = range(1, 10)
    # x[i, j] == 1 => Letter i uses digit j
    x = model.addVars(letters,
                      digits,
                      vtype=GRB.BINARY,
                      name=(f"x[{l},{d}]" for l in letters for d in digits))
    # Final value for first word
    first_word = "ENIGMA"
    second_word = "IGMAEN"
    factor = 1.2

    # Constraint for the enigma-igmaen numbers
    model.addConstr(factor * quicksum(
        quicksum(10**(len(first_word) - 1 - i) * j * x[first_word[i], j]
                 for j in digits)
        for i in range(len(first_word))) - quicksum(
            quicksum(10**(len(second_word) - 1 - i) * j * x[second_word[i], j]
                     for j in digits) for i in range(len(second_word))) == 0)

    # Conflict constraint, different letters have different digits
    model.addConstrs(quicksum(x[i, j] for i in letters) <= 1 for j in digits)

    # Exactly one digit has to be used per letter
    model.addConstrs(quicksum(x[i, j] for j in digits) == 1 for i in letters)

    model.optimize()
    return model
 def stage_prob_builder(t):
     model = Model('CapExp%i' % t)  # Create a model
     x = model.addVars(data.I, vtype=GRB.CONTINUOUS, lb=0, ub=data.b, obj=1, name='x')
     x0 = model.addVars(data.I, vtype=GRB.CONTINUOUS, lb=0, ub=data.b, obj=0, name='x0')
     d = model.addVars(data.J, vtype=GRB.CONTINUOUS, lb=0, ub=0, obj=0, name='d')
     model.update()
     if t == 0:
         # y = model.addVars(data.I, lb=0, ub=1, obj=5, vtype=GRB.BINARY, name='y')
         # model.addConstrs((x[i] <= data.b * y[i] for i in data.I), 'logic_open')
         model.addConstr(sum(x[i] for i in data.I), GRB.LESS_EQUAL, data.b, 'globalCap')
         model.update()
     else:
         y = model.addVars(data.I, data.J, lb=0, obj=data.c, vtype=GRB.CONTINUOUS, name='y')
         s = model.addVars(data.J, lb=0, obj=data.rho, vtype=GRB.CONTINUOUS, name='s')
         model.update()
         '''Capacity constraints'''
         model.addConstrs((sum(y[i, j] for j in data.J) <= x0[i] for i in data.I), 'CapCtr')
         '''Recourse constraint, subcontracting '''
         model.addConstrs((sum(y[i, j] for i in data.I) + s[j] >= d[j] for j in data.J), 'RecCtr')
         model.update()
     
     in_states = [var.VarName for var in x0.values()]
     out_states = [var.VarName for var in x.values()]
     rhs_vars = [var.VarName for var in d.values()]
     return model, in_states, out_states, rhs_vars
Example #7
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
Example #8
0
class mip_model(object):
    def __init__(self, samples, delta=1.0):
        self.n_nodes = samples.n_nodes
        self.n_samples = samples.n_samples
        self.delta = delta

        self.B = samples.B
        self.T = samples.T
        self.F = samples.F

        self.model = Model('DPSL')
        self.create_model()

    def create_model(self):
        self.U = self.model.addVars(self.n_nodes,
                                    self.n_samples,
                               name='U', lb=0, ub=1,
                               vtype=GRB.CONTINUOUS)
        self.M = self.model.addVars(self.n_nodes,
                               name='M', lb=0, ub=1,
                               vtype=GRB.CONTINUOUS)

        self.y = self.model.addVars(self.n_nodes,
                                    self.n_samples,
                               name='y', lb=0, ub=1,
                               vtype=GRB.CONTINUOUS)

        self.z = self.model.addVars(self.n_nodes,
                                    self.n_nodes,
                                    self.n_samples,
                               name='z', lb=0, ub=1,
                               vtype=GRB.CONTINUOUS)


        self.model.addConstrs((self.y[i, n] >= -1 + self.M[i]
                                          + self.B[i, n]
                                          - self.U[i, n])
                              for i in range(self.n_nodes)
                              for n in range(self.n_samples))

        self.model.addConstrs((self.z[i, j, n] >= -2 + self.T[i, j, n]
                                             + self.F[i, j, n]
                                             + self.U[j, n]
                                             - self.U[i, n])
                              for i in range(self.n_nodes)
                              for j in range(self.n_nodes)
                              for n in range(self.n_samples)
                              if i != j)

        cost_expr = 2 * self.M.sum() - (5 / self.n_samples) * self.U.sum()
        dist_expr = self.y.sum() + self.z.sum() + self.U.sum()

        self.model.setObjective(cost_expr + self.delta * dist_expr,
                                GRB.MINIMIZE)
    def solve(self):
        self.model.optimize()
        for i in range(self.n_nodes):
            print(self.M[i].x)
Example #9
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
def optimize_pareto(Bw, h, ju_s, ju_l, jn_s, jn_l):
    # create a model
    m = Model('Pareto')
    # create decision variables
    x = m.addVars(an, an, vtype=GRB.BINARY, name='x')
    y = m.addVars(an, dc, vtype=GRB.BINARY, name='y')

    ######### add constraints ##########
    m.addConstrs((x[i, j] == x[j, i] for i in an for j in an),
                 'symmetric constraint')
    # Two service areas cant use the same stateful functions when x[i,j] = 0
    m.addConstrs((y[i, t] + y[j, t] <= x[i, j] + 1 for i in an for j in an
                  for t in dc), 'x = 0 constraint')
    # Two service areas use the same stateful functions when x[i,j] = 1
    m.addConstrs(((y[i, t] - y[j, t] <= 1 - x[i, j]) for i in an for j in an
                  for t in dc), 'x = 1 constraint')
    # Each should be at least managed by one dc
    m.addConstrs((sum(y[i, t] for t in dc) == 1 for i in an),
                 'one dc for access node')
    # high availability constraint
    m.addConstr(
        sum((1 - x[i, j]) for i in an for j in an if i != j) >= 1, 'ha')
    # maximum state transfer frequency
    m.addConstr(
        sum(h * (1 - x[i, j]) for i in an for j in an if i != j) <= jn_s - 1,
        'max state transfer constraint')
    # maximum latency constraint
    m.addConstr(
        sum(y[i, t] * C[i, t] * (Sd / Bw + Lw + Wg) for i in an
            for t in dc) <= jn_l, 'latency maximum constraint')

    ######## Objective function #########
    m.setObjective((sum(y[i, t] * C[i, t] * (Sd / Bw + Lw + Wg) for i in an
                        for t in dc) - ju_l) / (jn_l - ju_l) +
                   (sum(h * (1 - x[i, j]) for i in an
                        for j in an if i != j) - ju_s) / (jn_s - ju_s),
                   GRB.MINIMIZE)

    m.optimize()

    ######## Calculate performance metrics #########
    # latency
    latency = sum(C[i, t] * getattr(y[i, t], 'X') * (Sd / Bw + Lw + Wg)
                  for i in an for t in dc)

    # state transfer frequency
    state_transfer = sum(h * (1 - getattr(x[i, j], 'X')) for i in an
                         for j in an if i != j)

    # total cost
    cost = latency + state_transfer

    # number of functions
    num_func = M_dc - sum(
        prod(1 - getattr(y[i, t], 'X') for i in an) for t in dc)

    # total metrics
    total_metrics = [Bw, h, state_transfer, latency, num_func, cost]

    return total_metrics
def optimize_latency(Bw, h):
    # create a model
    m = Model('latency')
    # create decision variables
    x = m.addVars(an, an, vtype=GRB.BINARY, name='x')
    y = m.addVars(an, dc, vtype=GRB.BINARY, name='y')

    ######### add constraints ##########
    # x is symmetric
    m.addConstrs((x[i, j] == x[j, i] for i in an for j in an),
                 'symmetric constraint')
    # Two service areas cant use the same stateful functions when x[i,j] = 0
    m.addConstrs((y[i, t] + y[j, t] <= x[i, j] + 1 for i in an for j in an
                  for t in dc), 'x = 0 constraint')
    # Two service areas use the same stateful functions when x[i,j] = 1
    m.addConstrs(((y[i, t] - y[j, t] <= 1 - x[i, j]) for i in an for j in an
                  for t in dc), 'x = 1 constraint')
    # One access node connects to only one dc
    m.addConstrs((sum(y[i, t] for t in dc) == 1 for i in an),
                 'one dc for access node')
    # high availability constraint
    m.addConstr(
        sum((1 - x[i, j]) for i in an for j in an if i != j) >= 1, 'ha')
    # maximum state transfer frequency
    m.addConstr(
        sum(h * (1 - x[i, j]) for i in an for j in an if i != j) <= State_max,
        'max state transfer constraint')

    ######## Objective function #########
    # Optimize latency budget
    m.setObjective(
        sum(y[i, t] * C[i, t] * (Sd / Bw + Lw + Wg) for i in an for t in dc),
        GRB.MINIMIZE)

    m.optimize()

    ######## Calculate performance metrics #########
    # latency
    latency = sum(C[i, t] * (Sd / Bw + Lw + Wg) * getattr(y[i, t], 'X')
                  for i in an for t in dc)

    # state transfer frequency
    state_transfer = sum(h * (1 - getattr(x[i, j], 'X')) for i in an
                         for j in an if i != j)

    # number of function
    num_func = M_dc - sum(
        prod(1 - getattr(y[i, t], 'X') for i in an) for t in dc)

    # total cost
    cost = latency + state_transfer

    # total metrics
    total_metrics = [Bw, h, state_transfer, latency, num_func, cost]

    # utopia point, nadir point
    worst_state = state_transfer
    best_latency = latency

    return total_metrics, worst_state, best_latency
Example #12
0
def RCI_controller(sys, x):
    """
    Based on zonotopes
    """
    model = Model("Controller")
    q = sys.phi.shape[1]
    zeta = tupledict_to_array(
        model.addVars(range(q), [0], lb=-1, ub=1, name="zeta"))
    zeta_abs = tupledict_to_array(
        model.addVars(range(q), [0], lb=0, ub=1, name="zeta_abs", obj=1))
    model.update()
    constraints_list_of_tuples(model, [(-np.eye(sys.n), x), (sys.phi, zeta)])
    model.addConstrs(zeta_abs[i, 0] >= zeta[i, 0] for i in range(q))
    model.addConstrs(zeta_abs[i, 0] >= -zeta[i, 0] for i in range(q))
    model.setParam('OutputFlag', False)
    model.optimize()
    zeta_n = np.array([zeta[i, 0].X for i in range(q)]).reshape(q, 1)
    print zeta_n.T
    return np.dot(sys.theta, zeta_n)
Example #13
0
def solve():
    model = Model("Enigma Riddle")
    letters = {"E", "N", "I", "G", "M", "A"}
    digits = range(1, 10)
    x = model.addVars(letters, digits, vtype=GRB.BINARY)
    y = model.addVars(letters, vtype=GRB.INTEGER)
    # Stay in digit range
    for i in letters:
        model.addRange(y[i], 1, 9, f"digitRange{i}")
    # Final value for first word
    b = model.addVar(vtype=GRB.INTEGER)
    first_word = "ENIGMA"
    second_word = "IGMAEN"

    # Constraint for the enigma-igmaen numbers
    model.addConstr(quicksum(10 ** (len(first_word) - 1 - i) * y[first_word[i]] for i in range(len(first_word))) == b)
    model.addConstr(
        quicksum(10 ** (len(second_word) - 1 - i) * y[second_word[i]] for i in range(len(second_word))) == b * 1.2)

    # Conflict constraint
    model.addConstrs(x[i_1, j] + x[i_2, j] <= 1 for i_1 in letters for i_2 in letters for j in digits if i_1 != i_2)

    # Linking constraint
    model.addConstrs(j * x[i, j] <= y[i] for i in letters for j in digits)

    # Exactly one digit has to be packed
    model.addConstrs(quicksum(x[i, j] for j in digits) == 1 for i in letters)

    model.optimize()
    return model
  def _create_model(self, city_ids, map_points):
    depot_id = city_ids[0]
    city_num = len(city_ids)
    ## prepare the index for decision variables
    # index of network flow
    cities = tuple(city_ids)
    # index of MTZ constraint
    MTZ_u = tuple(city_ids[1:])
    # connecting arcs of the cities
    cityArcs = [(i,j) for i in cities for j in cities if i != j]
    
    ## parameters model (dictionary)
    # 1. distance map
    distances_map = self.calculate_distances(city_ids, map_points)

    ## create model
    m = Model('TSP')
    ## create decision variables
    # 1. choice of arcs between cities
    x = m.addVars(cityArcs, vtype=GRB.BINARY, name='route')    
    # 2. for expression of non-subtour: [2,N]
    u = m.addVars(MTZ_u, name='MTZ_u')
    
    ## create objective: minimum route distance
    m.setObjective(quicksum([x[i,j]*distances_map[(i,j)] for (i,j) in cityArcs]), GRB.MINIMIZE) # TOTRY
    ## create constraints
    # 1. MTZ formulation
    m.addConstrs((u[i]-u[j]+city_num*x[i,j] <= city_num-1 for (i,j) in cityArcs if (i>depot_id and j>depot_id)),'MTZ formulation')
    m.addConstrs((u[i]>=0 and u[i]<=city_num-1 for i in MTZ_u), 'MTZ compensation')
    # 2. Network flow
    m.addConstrs((quicksum([x[i,j] for j in cities if i!=j])==1 for i in cities), 'Network flow1')
    m.addConstrs((quicksum([x[i,j] for i in cities if i!=j])==1 for j in cities), 'Network flow2')

    return m, x
Example #15
0
def TWTgurobi():
  jobs = tuple(range(1,5))
  jobPairs = [(i,j) for i in jobs for j in jobs if i < j]
  # job_id as keys and weight as content
  weight = dict(zip(jobs, (4,3,4,5)))
  duration = dict(zip(jobs, (12,8,15,9)))
  deadline = dict(zip(jobs, (16,26,25,27)))
  # Big M for modeling
  M = sum(duration.values())

  try:
    m = Model('TWTexample')
    x = m.addVars(jobPairs, vtype=GRB.BINARY, name='x')
    startTime = m.addVars(jobs, name='startTime')
    tardiness = m.addVars(jobs, name='tardiness')
    m.setObjective(quicksum([weight[j]*tardiness[j] for j in jobs]), GRB.MINIMIZE)
    m.addConstrs((startTime[j] >= startTime[i]+duration[i]-M*(1-x[i,j]) for(i,j) in jobPairs), 'NoOverplap1')
    m.addConstrs((startTime[i] >= startTime[j]+duration[j]-M*x[i,j] for(i,j) in jobPairs), 'NoOverplap2')    
    m.addConstrs((tardiness[j] >= startTime[j]+duration[j]-deadline[j] for j in jobs), 'Deadline')
    m.optimize()
    if m.status == GRB.Status.INF_OR_UNBD:
      m.setParam(GRB.Param.DualReductions, 0)
      m.optimize()
    if m.status == GRB.Status.OPTIMAL:
      for v in m.getVars():
        print('%s:\t%g' %(v.varName, v.x))
      print('Objective:\t%g' % m.objVal)
    else:
      statstr = StatusDict[m.status]
      print('Optimization was stopped with status %s' %statstr)
  except GurobiError as e:
    print('Error code '+str(e.errno)+': '+str(e))
Example #16
0
def rocket():
    from gurobipy import Model, GRB
    # Set up data
    Mass = [
        70, 90, 100, 110, 120, 130, 150, 180, 210, 220, 250, 280, 340, 350, 400
    ]
    P = range(len(Mass))

    # A, B, C, D
    Sections = ["A", "B", "C", "D"]
    S = range(len(Sections))

    m = Model('Rocket Payload')
    X = m.addVars(P, S, vtype=GRB.BINARY, name='X')
    Y = m.addVars(P, S, name='Y', obj=1)

    m.addConstrs(Y[p, s] == X[p, s] * Mass[p] for p, s in X.keys())

    m.addConstrs(Y.sum('*', s) <= 1000 for s in S)
    m.addConstrs(X.sum('*', s) >= 3 for s in S)

    m.addConstr(Y.sum('*', 0) == Y.sum('*', 3))
    m.addConstr(Y.sum('*', 1) == Y.sum('*', 2))

    m.setAttr(GRB.Attr.ModelSense, GRB.MAXIMIZE)
    m.optimize()
Example #17
0
    def _create_model(self, city_ids, map_points):
        depot_id = city_ids[0]
        city_num = len(city_ids)
        ## prepare the index for decision variables
        # index of network flow
        cities = tuple(city_ids)

        # connecting arcs of the cities
        cityArcs = [(i, j) for i in cities for j in cities if i != j]

        ## parameters model (dictionary)
        # 1. distance map
        distances_map = self.calculate_distances(city_ids, map_points)

        ## create model
        m = Model('TSP')
        ## create decision variables
        # 1. choice of arcs between cities
        x = m.addVars(cityArcs, vtype=GRB.BINARY, name='route')
        m._x = x
        m._cities = cities
        m._cityArcs = cityArcs
        ## create objective: minimum route distance
        m.setObjective(
            quicksum([x[i, j] * distances_map[(i, j)] for (i, j) in cityArcs]),
            GRB.MINIMIZE)  # TOTRY
        ## create constraints
        # 1. Network flow
        m.addConstrs((quicksum([x[i, j] for j in cities if i != j]) == 1
                      for i in cities), 'Network flow1')
        m.addConstrs((quicksum([x[i, j] for i in cities if i != j]) == 1
                      for j in cities), 'Network flow2')
        for (i, j) in cityArcs:
            if (i, j) in init_solution:
                x[i, j].start = 1
        return m, x
Example #18
0
def tpms_assignment(papload, revload, similarity):
    problem = Model()
    problem.setParam('OutputFlag', False)
    numrev = similarity.shape[0]
    numpap = similarity.shape[1]
    source_vars = problem.addVars(numrev, vtype=GRB.CONTINUOUS, lb=0, ub=revload, name='reviewers')
    sink_vars = problem.addVars(numpap, vtype=GRB.CONTINUOUS, lb=0,
                                          ub=papload, name='papers')
    mix_vars = problem.addVars(numrev, numpap, vtype=GRB.CONTINUOUS,
                                         lb=0.0, ub=1.0, name='assignment')
                    
    #Reviewer flow constraints
    balance_reviewers = problem.addConstrs((source_vars[i] == mix_vars.sum(i, '*') for i in range(numrev)))

    # avoid COIs
    #avoid_cois = problem.addConstrs((mix_vars[i][j] == 0 for i in range(numrev) for j in range(numpap) if similarity[i,j] < -0.5))

    #Paper flow constraints
    balance_papers = problem.addConstrs((sink_vars[j] == mix_vars.sum('*', j) for j in range(numpap)))
        
    #Objective
    problem.setObjective(sum([sum([mix_vars[rev, pap] * similarity[rev, pap] 
                                   for pap in range(numpap)])
                              for rev in range(numrev)]),
                         GRB.MAXIMIZE)
    problem.optimize()
    if problem.status != 2:
        raise Exception('An error occured')
    #The rest is a constructun of the assignment dict
    assignment = {rev : [] for rev in range(numrev)}
    for pap in range(numpap):
        for rev in range(numrev):
            if mix_vars[rev, pap].X == 1:
                assignment[rev] += [pap]
        
    return(assignment)
Example #19
0
def TWTgurobi():
    # TWT Problem Data
    jobs = tuple([i + 1 for i in range(4)])
    jobPairs = [(i, j) for i in jobs for j in jobs if i < j]
    weight = dict(zip(jobs, (4, 5, 3, 5)))
    duration = dict(zip(jobs, (12, 8, 15, 9)))
    deadline = dict(zip(jobs, (16, 26, 25, 27)))
    M = sum(duration.values())

    try:
        # Create a new model
        m = Model('TWTexample')

        # Create variables
        # x[(i,j)] = 1 if i << j, else j >> i
        x = m.addVars(jobPairs, vtype=GRB.BINARY, name='x')
        startTime = m.addVars(jobs, name='startTime')
        tardiness = m.addVars(jobs, name='tardiness')

        # Set objective function
        m.setObjective(quicksum([weight[j] * tardiness[j] for j in jobs]),
                       GRB.MINIMIZE)

        # Add constraints
        m.addConstrs(
            (startTime[j] >= startTime[i] + duration[i] - M * (1 - x[(i, j)])
             for (i, j) in jobPairs), 'NoOverlap1')
        m.addConstrs(
            (startTime[i] >= startTime[j] + duration[j] - M * x[(i, j)]
             for (i, j) in jobPairs), 'NoOverlap2')
        m.addConstrs((tardiness[j] >= startTime[j] + duration[j] - deadline[j]
                      for j in jobs), 'Deadline')

        # Solve model
        m.optimize()
        if m.status == GRB.Status.INF_OR_UNBD:
            # Disable dual reductions to determine solve status
            m.setParam(GRB.Param.DualReductions, 0)
            m.optimize()

        # Display solution
        if m.status == GRB.Status.OPTIMAL:
            for v in m.getVars():
                print('%s:\t%g' % (v.varName, v.x))
            print('Objective:\t%g' % m.objVal)
        else:
            statstr = StatusDict[m.status]
            print('Optimization was stopped with status %s' % statstr)

    except GurobiError as e:
        print('Error code ' + str(e.errno) + ": " + str(e))
Example #20
0
def _run_econstraint_gurobi(mdl: GurobiModel,
                            objectives: List[LinExpr],
                            payoff_table,
                            g: Dict[int, int] = None,
                            solution_extractor: Callable = None) -> NoReturn:
    p = len(objectives)
    s = mdl.addVars([k for k in range(1, p)], name='s')
    lb = {k: min(payoff_table[h, k] for h in range(p)) for k in range(1, p)}
    r = {
        k: max(payoff_table[h, k] for h in range(p)) - min(payoff_table[h, k]
                                                           for h in range(p))
        for k in range(1, p)
    }
    logger.debug('r: %s', r)
    epsilon = 1e-3
    mdl.setObjective(objectives[0] + epsilon * quicksum(s[k] / r[k]
                                                        for k in range(1, p)),
                     sense=GRB.MAXIMIZE)
    if g is None:
        g = {k: 3 for k in range(1, p)}  # default number of grid
        logger.warning('Using default grid g=3')
    i = {k: 0 for k in range(1, p)}
    while True:
        e = {k: lb[k] + (i[k] * r[k]) / g[k] for k in range(1, p)}
        logger.info(f'i: {i}, e: {e}')
        constraints = mdl.addConstrs(objectives[k] - s[k] == e[k]
                                     for k in range(1, p))
        mdl.optimize()
        if mdl.SolCount > 0:
            solution_extractor()
            logger.info('feasible')
        else:
            logger.info('not feasible')
        mdl.remove(constraints)
        if all(i[k] == g[k] for k in range(1, p)):
            break
        else:
            for k in range(1, p):
                if i[k] == g[k]:
                    i[k] = 0
                else:
                    i[k] += 1
                    break
Example #21
0
def polytopic_trajectory(system,x0,list_of_goal_polytopes,T,eps=0.1,order=1):
    """
    Description: Polytopic Trajectory Optimization
    """
    model=Model("Point Trajectory Optimization")
    q=int(order*system.n)
    x=model.addVars(range(T+1),range(system.n),lb=-GRB.INFINITY,ub=GRB.INFINITY,name="x")
    u=model.addVars(range(T),range(system.m),lb=-GRB.INFINITY,ub=GRB.INFINITY,name="u")
    G=model.addVars(range(T+1),range(n),range(q),lb=-GRB.INFINITY,ub=GRB.INFINITY,name="G")
    theta=model.addVars(range(T),range(m),range(q),lb=-GRB.INFINITY,ub=GRB.INFINITY,name="theta")
    ##
    x_PWA=model.addVars([(t,n,i,j) for t in range(T+1) for n in system.list_of_sum_indices \
                         for i in system.list_of_modes[n] for j in range(system.n)],lb=-GRB.INFINITY,ub=GRB.INFINITY,name="x_pwa")
    u_PWA=model.addVars([(t,n,i,j) for t in range(T) for n in system.list_of_sum_indices \
                         for i in system.list_of_modes[n] for j in range(system.m)],lb=-GRB.INFINITY,ub=GRB.INFINITY,name="u_pwa")
    G_PWA=model.addVars([(t,n,i,row,column) for t in range(T+1) for n in system.list_of_sum_indices \
                         for i in system.list_of_modes[n] for row in range(system.n) for column in range(q)],\
                        lb=-GRB.INFINITY,ub=GRB.INFINITY,name="G_pwa")
    theta_PWA=model.addVars([(t,n,i,row,column) for t in range(T+1) for n in system.list_of_sum_indices \
                         for i in system.list_of_modes[n] for row in range(system.m) for column in range(q)],\
                        lb=-GRB.INFINITY,ub=GRB.INFINITY,name="theta_pwa")
    delta_PWA=model.addVars([(t,n,i) for t in range(T) for n in system.list_of_sum_indices \
                             for i in system.list_of_modes[n]],vtype=GRB.BINARY,name="delta_pwa")
    model.update()
    for j in range(n):
        model.addConstr(x[0,j]<=x0[j,0]+eps*system.scale[j])
        model.addConstr(x[0,j]>=x0[j,0]-eps*system.scale[j])
    
    # Convexhull Dynamics and Constraints
    model.addConstrs(x[t,j]==x_PWA.sum(t,n,"*",j) for t in range(T+1) for j in range(system.n)\
                     for n in system.list_of_sum_indices)
    model.addConstrs(u[t,j]==u_PWA.sum(t,n,"*",j) for t in range(T) for j in range(system.m)\
                     for n in system.list_of_sum_indices)   
    model.addConstrs(G[t,row,column]==G_PWA.sum(t,n,"*",row,column) for t in range(T) for row in range(system.n)\
                     for column in range(q) for n in system.list_of_sum_indices) 
    model.addConstrs(G[t,row,column]==G_PWA.sum(t,n,"*",row,column) for t in range(T) for row in range(system.n)\
                     for column in range(q) for n in system.list_of_sum_indices) 
    raise NotImplementedError    
Example #22
0
def vrproutes(n, xc, yc, cost_func):
    rnd = np.random
    rnd.seed(0)
    plt.plot(xc[0], yc[0], c='r', marker='s')
    plt.scatter(xc[1:], yc[1:], c='b')
    N = [i for i in range(1, n + 1)]
    V = [0] + N
    A = [(i, j) for i in V for j in V if i != j]
    # c = {(i, j): np.hypot(xc[i]-xc[j], yc[i]-yc[j]) for i, j in A}
    c = {(i, j): cost_func(i, j) for i, j in A}
    print(c)
    Q = 20
    q = {i: rnd.randint(1, 10) for i in N}

    mdl = Model('CVRP')

    x = mdl.addVars(A, vtype=GRB.BINARY)
    u = mdl.addVars(N, vtype=GRB.CONTINUOUS)

    mdl.modelSense = GRB.MINIMIZE
    mdl.params.LogToConsole = False
    mdl.setObjective(quicksum(x[i, j] * c[i, j] for i, j in A))

    mdl.addConstrs(quicksum(x[i, j] for j in V if j != i) == 1 for i in N)
    mdl.addConstrs(quicksum(x[i, j] for i in V if i != j) == 1 for j in N)
    mdl.addConstrs((x[i, j] == 1) >> (u[i] + q[j] == u[j]) for i, j in A
                   if i != 0 and j != 0)
    mdl.addConstrs(u[i] >= q[i] for i in N)
    mdl.addConstrs(u[i] <= Q for i in N)

    mdl.Params.MIPGap = 0.001
    mdl.Params.TimeLimit = 60  # seconds
    mdl.optimize()

    active_arcs = [a for a in A if x[a].x > 0.5]
    return active_arcs
def Distribution_Matching(D):
    mean = np.mean(D)
    moment = [np.var(D), stats.skew(D),
              stats.kurtosis(D)]

    N = len(D)
    T1 = range(N)
    K = range(len(moment))
    #number of moments

    W = np.array([0.5, 0.35, 0.15])
    Omega = np.random.uniform(0, 1, (1, N))
    osum = np.sum(Omega)
    Omega = [i / osum for i in Omega[0]]
    # Gurobi Model: Define variables
    ProbModel = Model()
    P = ProbModel.addVars(N, lb=0, ub=1, vtype=GRB.CONTINUOUS, name="P")
    S1 = ProbModel.addVars(N, lb=0, vtype=GRB.CONTINUOUS, name="S1")
    S2 = ProbModel.addVars(N, lb=0, vtype=GRB.CONTINUOUS, name="S2")

    M1 = ProbModel.addVars(K, lb=0, vtype=GRB.CONTINUOUS, name="M1")
    M2 = ProbModel.addVars(K, lb=0, vtype=GRB.CONTINUOUS, name="M2")

    #  Objective Function
    Z = quicksum(W[k] * (M1[k] + M2[k])
                 for k in K[1:]) + quicksum(Omega[j] * (S1[j] + S2[j])
                                            for j in T1)
    ProbModel.setObjective(Z, GRB.MINIMIZE)

    # Define Constraints

    ProbModel.addConstr(quicksum(P[j] for j in T1) == 1)
    ProbModel.addConstr(quicksum(D[j] * P[j] for j in T1) == mean)
    ProbModel.addConstrs(
        quicksum((D[j] - mean)**(k + 2) * P[j]
                 for j in T1) + M1[k] - M2[k] == moment[k] for k in K)
    ProbModel.addConstrs(
        stats.norm.cdf((D[j] - mean) / moment[0]) -
        quicksum(P[jp] for jp in T1) == S1[j] - S2[j] for j in T1)
    ProbModel.addConstrs(P[j] >= 0.1 for j in T1)
    # Solve and publish
    ProbModel.Params.OutputFlag = 0
    ProbModel.optimize()

    return ProbModel.x[:N]
Example #24
0
    def Solving_MILP(self, turbines, dist, travelTime, vessel, t, base, farm, \
                     R, routes, Techs, visited):

        for t_1 in range(1, t):
            for b_1 in range(self.num_B):
                if turbines not in visited[vessel][t_1][b_1][farm]:
                    continue
                index = visited[vessel][t_1][b_1][farm].index(turbines)
                if self.time_window[vessel][t][farm] == self.time_window[
                        vessel][t_1][farm]:
                    c_t = R[vessel][t_1][b_1][farm][0][-4, index]
                    c_p = R[vessel][t_1][b_1][farm][0][-3, index]
                    c_lr = sum(max(0, t - self.WF_deadline[farm][j]) \
                               * self.WF_penCost[farm][j] for j in turbines)
                    c_total = c_t + c_p + c_lr
                    path = routes[vessel][t_1][b_1][farm][index]
                    NumTechs = Techs[vessel][t_1][b_1][farm][index]
                    return [[c_t, c_p, c_lr, c_total], path, NumTechs]

        # total num of turbines in the wind farm
        n = len(self.WF_deadline[farm])
        # set of drop off nodes [1,...,n]
        dropoff = list(map(lambda qq: qq + 1, turbines))
        d1 = list(range(n + 1, 2 * n + 1))
        # set of pick up nodes [n+1, n+2,...,2n]
        pickup = [d1[i - 1] for i in dropoff]
        # set of nodes need vessels to be present
        waiting = [i + 1 for i in turbines if self.WF_present[farm][i] == 1]
        nodes = [0] + dropoff + pickup + [2 * n + 1]

        model = Model()
        T = model.addVars(nodes, lb=0.0, vtype=GRB.CONTINUOUS)
        A = [(i, j) for i in nodes for j in nodes if i != j]
        B = [(p, i) for p in self.types for i in nodes]
        y = model.addVars(A, vtype=GRB.BINARY)
        Q = model.addVars(B, lb=0, vtype=GRB.INTEGER)

        model.addConstr(y[2 * n + 1, 0] == 1)
        model.addConstrs(
            quicksum(y[i, j] for j in nodes if i != j) == 1
            for i in nodes)  # 9
        model.addConstr(quicksum(y[0, j] for j in dropoff) == 1)  # 10
        model.addConstr(quicksum(y[j, 2 * n + 1] for j in pickup) == 1)  # 11
        model.addConstrs(quicksum(y[i, j] for j in nodes if i != j) == \
                         quicksum(y[j, i] for j in nodes if i != j) for i in nodes)  # 12
        model.addConstrs(quicksum(y[i, j] for j in nodes if i != j) == \
                         quicksum(y[n + i, j] for j in nodes if n + i != j) for i in dropoff)  # 13
        model.addConstrs(y[i, n + i] == 1 for i in waiting)  # 14
        model.addConstrs(T[n + i] - T[i] >= self.WF_mainTime[farm][i - 1] \
                         + self.V_transTime[vessel] for i in dropoff)  # 15
        model.addConstr(
            T[2 * n + 1] <= self.time_window[vessel][t][farm])  # 16
        model.addConstr(T[0] == 0)  # 17
        model.addConstrs(y[0, j] == 0 for j in pickup)
        model.addConstrs(y[j, 2 * n + 1] == 0 for j in dropoff)
        model.addConstr(
            quicksum(Q[p, 0] for p in self.types) <= self.V_tech[vessel])  # 18
        model.addConstrs(Q[p, 0] <= self.B_tech[base][p][t]
                         for p in self.types)
        model.addConstrs(Q[p, 0] >= Q[p, i] for p in self.types for i in nodes)

        for i in nodes[1:-1]:
            for j in dropoff:
                if i == j:
                    continue
                model.addConstrs((y[i, j] == 1) >> \
                                 (Q[p, i] - Q[p, j] == self.WF_tech[farm][j - 1][p]) for p in self.types)
            for j in pickup:
                if i == j:
                    continue
                model.addConstrs((y[i, j] == 1) >> \
                                 (Q[p, j] - Q[p, i] == self.WF_tech[farm][j - n - 1][p]) for p in self.types)

        model.addConstrs((y[0, j] == 1) >> \
                         (T[0] + travelTime[0, j] <= T[j]) for j in dropoff)
        model.addConstrs((y[j, 2 * n + 1] == 1) >> (T[j] + self.V_transTime[vessel] \
                                                    + travelTime[j - n, 0] <= T[2 * n + 1]) for j in pickup)

        for i in nodes[1:-1]:
            for j in nodes[1:-1]:
                if j == i + n or i == j:
                    continue
                i1 = i if i <= n else i - n
                j1 = j if j <= n else j - n
                model.addConstr((y[i, j] == 1) >> \
                                (T[i] + self.V_transTime[vessel] + travelTime[i1, j1] <= T[j]))  # 19

        # cost for technicians
        c_qr = sum(Q[p, 0] * self.tech_cost[p] for p in self.types)
        # travel cost (fuel cost)
        c_tr = 0
        for i in nodes:
            for j in nodes:
                if i != j:
                    if i == 2 * n + 1:
                        i1 = 0
                    elif i <= n:
                        i1 = i
                    else:
                        i1 = i - n
                        i1 = i if i <= n else i - n
                    if j == 2 * n + 1:
                        j1 = 0
                    elif j <= n:
                        j1 = j
                    else:
                        j1 = j - n
                    c_tr += self.V_cost[vessel] * travelTime[i1, j1] * y[i, j]

        # penalty cost
        c_lr = sum(max(0, t + 1 - self.WF_deadline[farm][j]) \
                   * self.WF_penCost[farm][j] for j in turbines)
        # ojective function
        model.modelSense = GRB.MINIMIZE
        model.setObjective(c_qr + c_tr + c_lr)
        model.setParam('OutputFlag', 0)
        model.optimize()

        if model.status == GRB.OPTIMAL:
            print('optimal')
            c_total = model.objVal
            # cost for technicians
            c_q = sum(Q[p, 0].x * self.tech_cost[p] for p in self.types)
            # travel cost (fuel cost)
            c_t = 0
            for i in nodes:
                for j in nodes:
                    if i != j:
                        if i == 2 * n + 1:
                            i1 = 0
                        elif i <= n:
                            i1 = i
                        else:
                            i1 = i - n
                            i1 = i if i <= n else i - n
                        if j == 2 * n + 1:
                            j1 = 0
                        elif j <= n:
                            j1 = j
                        else:
                            j1 = j - n
                        c_t += self.V_cost[vessel] * travelTime[i1,
                                                                j1] * y[i, j].x

            path = []  # store the optimal route without base
            # path = [0]
            TT = [0]
            rr = 0
            ii = 0
            while rr < len(nodes) - 2:
                for k in nodes:
                    if ii != k and round(y[ii, k].x) == 1:
                        ii = k
                        path.append(k - 1 if k <= n else k - n - 1)
                        TT.append(round(T[k].x, 2))
                        # path.append(k)
                        break
                rr += 1
            TT.append(T[nodes[-1]].x)
            [c_t, c_q, c_lr,
             c_total] = [round(i, 2) for i in [c_t, c_q, c_lr, c_total]]
            num_techs = [Q[p, 0].x for p in self.types]
            # print('nodes: ', nodes)
            # print('path: ', ['vessel[%d]' % vessel] + ['period[%d]' % t] + \
            #      ['wf[%d]' % farm] + ['b[%d]' % base] + path)
            # print ('T: ', TT)
            # print ('###############\n \n')
            return [[c_t, c_q, c_lr, c_total], path, num_techs]
        else:
            print('infeasible')
            return [[None], None, None]
Example #25
0
class Master:
    """ Master Object for initialising, solving, updating, and column creation
     of the tail assignment master problem"""
    def __init__(self, Data):
        """Formulate the master problem.
        INPUTS
            Data    :: object, classes.Data; problem data.
        """
        self.Data = Data
        self.duals = []
        self.master = Model("master LP")  # Init master model
        self.master.Params.OutputFlag = 0  # No output

        self._formulate_master()

    def _formulate_master(self):
        """ Formulate set partitioning model for tail assignment"""
        # Variable dicts #
        a_dict = {(s_label[1], s): s.cost
                  for s_label, s in self.Data.scheds.items()}
        dum_dict = {
            f: 20000 + 20000 * (f.arrival - f.departure)
            for f in self.Data.flights
        }
        # VARIABLES #
        a = self.master.addVars(a_dict.keys(), name="a", vtype="B")
        dummy = self.master.addVars(dum_dict.keys(), name="dummy", vtype="B")
        # OBJECTIVE FUNCTION #
        self.master.setObjective(dummy.prod(dum_dict))
        # FLIGHT CONSTRAINTS #
        self.master.addConstrs((dummy[key] >= 1 for key in dum_dict),
                               name='flight')
        # AIRCRAFT CONSTRAINTS #
        self.master.addConstrs(
            (a.sum(k, '*') <= 1 for k in self.Data.aircraft),
            name='aircraft_schedule')
        self.master.update()
        # write to file
        self.master.write("./output/init.lp")

    def _solve_relax(self):
        """
        Relaxes and solves the master problem.
        INPUTS
            master  :: object, gurobipy.Model; master problem.
        RETURNS
            duals   :: list of tuples, (dual, classes.Flight)
            relax   :: object, gurobipy.Model; relaxed master problem.
        """
        self.relax = self.master.relax()
        self.relax.update()
        self.relax.optimize()
        duals = [(float(c.Pi), [
            f for f in self.Data.flights if f.i_d == self._split(c.ConstrName)
        ][0]) for c in self.relax.getConstrs() if "flight" in c.ConstrName]
        duals = sorted(duals, key=lambda x: x[1].i_d)
        self.duals.append([d[0] for d in duals])
        return self.relax, duals

    def _generate_column(self, k, it, path):
        """
        Adds column using shortest path from extended TSN.

        Parameters
        ----------
        k : str,
            aircraft in subproblem

        it : int,
            iteration number

        path : list,
            edges in shortest path [(edge_dict, edge_weight), ..]

        Returns
        -------
        master : object,
            gurobipy.Model; updated master problem with new column
        """

        col = Column()  # Init Column
        flights = self.Data.flights
        cost_col = 0  # count number of dummy edges for column obj coeff

        for p in path:  # for each flight in the path
            if any(f._full_dict() == p[0] for f in flights):
                flight = [f for f in flights if f._full_dict() == p[0]][0]
                # Get constraints associated with flight
                constrs = [
                    c for c in self.master.getConstrs()
                    if "flight" in c.ConstrName
                    and self._split(c.ConstrName) == flight.i_d
                ]
                # Add terms to column for each constraint
                col.addTerms([1] * len(constrs), constrs)
            else:
                cost_col += p[1]
        # Get constraints associated with aircraft k
        constr = [
            c for c in self.master.getConstrs()
            if "aircraft_schedule" in c.ConstrName and k in c.ConstrName
        ][0]
        col.addTerms(1, constr)
        # Get aircraft dual for cost
        lambda_k = [
            float(c.Pi) for c in self.relax.getConstrs()
            if "aircraft_schedule" in c.ConstrName and k in c.ConstrName
        ][0]
        # cost of path + 2 due to first edge initialisation
        cost = 2 + sum(p[1] for p in path) - lambda_k
        if cost < 0:
            self.master.addVar(obj=cost_col,
                               vtype="B",
                               name="a[%s,s_%s_%s]" % (k, it, k),
                               column=col)
            self.master.update()
        return self, cost

    @staticmethod
    def _split(string):
        """ Split integers in string and return last occurrence"""
        import re
        return list(map(int, re.findall(r'\d+', string)))[-1]
Example #26
0
    for arco in AF:
        rs[arco] = model.addVars(V[arco],
                                 K,
                                 vtype=GRB.CONTINUOUS,
                                 ub=1.0,
                                 lb=0.0,
                                 name='r({},{}){}'.format(arco[0], arco[1], s))
    r[s] = rs

###################
### Constraints ###
###################

## FIRST STAGE CONSTRAINTS ##
#FS1
model.addConstrs((quicksum(y[0][i, j, k] for k in K) <= 1 for i, j in AF),
                 name='(FS1)')
#FS2
model.addConstrs((quicksum(y[0][i, j, k]
                           for i, j in A if i == ii) == nav[ii, k] for k in K
                  for ii in Nf),
                 name='(FS2)')
#FS3
model.addConstrs(
    (quicksum(y[0][i, j, k]
              for i, j in A if j == jj) - quicksum(y[0][i, j, k]
                                                   for i, j in A if i == jj)
     == 0 for k in K for jj in Nint),
    name='(FS3)')
## SECOND STAGE CONSTRAINTS ##
#SS1
model.addConstrs(
def find_ranking(comparisons, equal_width=0.2, max_rank=-1, verbose=False):
    """
    Find the least changes to a set of comparisons so that they are consistent
    (transitive), it returns a topological ranking.

    comparisons     A dictionary with tuple keys in the form of (i, j), values
                    are scalars indicating the probability of i > j. It is
                    assumed that comparisons are symmetric. Use 0 for i < j,
                    0.5 for i == j, and 1 for i > j (and any value in between).
    equal_width     0..0.5-equal_width/2 is considered '<=' and 0.5..0.5+equal_width/2
                    is considered '>='. In between it is considered to be '=='.
    max_rank        Maximal rank, a low value forces the model to choose more
                    equal cases.
    verbose         Whether to print gurobi's progress.

    Returns:
        A tuple of size two:
        0) Ranking derived from topological sort (list of ranks in order of
           nodes);
        1) Sum of absolute changes to the comparisons.
    """
    # remove unnecessary variables
    comparisons = {(i, j) if i < j else (j, i): value if i < j else 1 - value
                   for (i, j), value in comparisons.items()}
    nodes = np.unique([i for ij in comparisons.keys() for i in ij])

    # define variables
    model = Model('comparison')
    model.setParam('OutputFlag', verbose)
    values = np.fromiter(comparisons.values(), dtype=float)
    assert values.max() <= 1 and values.min() >= 0
    # variables to encode the error of comparisons
    E_ij = model.addVars(comparisons.keys(),
                         name='e_ij',
                         vtype=GRB.CONTINUOUS,
                         ub=1.0 - values,
                         lb=-values)
    # variables to encode hard choice of >=, <=, ==
    Ge_ij = model.addVars(comparisons.keys(), name='ge_ij', vtype=GRB.BINARY)
    Le_ij = model.addVars(comparisons.keys(), name='le_ij', vtype=GRB.BINARY)
    Eq_ij = model.addVars(comparisons.keys(), name='eq_ij', vtype=GRB.BINARY)
    # variables to help with transitivity in non-fully connected graphs
    if max_rank < 1:
        max_rank = len(nodes)
    R_i = model.addVars(nodes,
                        name='r_i',
                        vtype=GRB.CONTINUOUS,
                        lb=0,
                        ub=max_rank)
    # variables to emulate abs
    T_ij_pos = {}
    T_ij_neg = {}
    index = (values != 1) & (values != 0)
    T_ij_pos = model.addVars(
        (ij for ij, value in comparisons.items() if value not in [0.0, 1.0]),
        vtype=GRB.CONTINUOUS,
        name='T_ij_pos',
        lb=0,
        ub=1 - values[index])
    T_ij_neg = model.addVars(
        (ij for ij, value in comparisons.items() if value not in [0.0, 1.0]),
        vtype=GRB.CONTINUOUS,
        name='T_ij_neg',
        lb=0,
        ub=values[index])
    model.update()

    # emulate abs for non-binary comparisons: E_ij = T_ij_pos - T_ij_neg
    model.addConstrs((E_ij[ij] == T_ij_pos[ij] - T_ij_neg[ij]
                      for ij in T_ij_pos), 'E_ij = T_ij_pos - T_ij_neg')

    # hard decision of >=, <=, and ==
    lower_bound = 0.5 - equal_width / 2.0
    upper_bound = 0.5 + equal_width / 2.0
    # <=
    model.addConstrs((E_ij[ij] + comparisons[ij] - upper_bound <= ge_ij
                      for ij, ge_ij in Ge_ij.items()), 'ge_ij_lower_bound')
    model.addConstrs((E_ij[ij] + comparisons[ij] - upper_bound >= -1 + ge_ij
                      for ij, ge_ij in Ge_ij.items()), 'ge_ij_upper_bound')
    # >=
    model.addConstrs((E_ij[ij] + comparisons[ij] - lower_bound >= -le_ij
                      for ij, le_ij in Le_ij.items()), 'le_ij_lower_bound')
    model.addConstrs((E_ij[ij] + comparisons[ij] - lower_bound <= 1 - le_ij
                      for ij, le_ij in Le_ij.items()), 'le_ij_upper_bound')
    # ==
    model.addConstrs((
        le + eq + ge == 1
        for le, eq, ge in zip(Le_ij.values(), Eq_ij.values(), Ge_ij.values())),
                     'eq_ij')

    # transitivity
    for (i, j), eq_a in Eq_ij.items():
        le_a = Le_ij[i, j]
        ge_a = Ge_ij[i, j]
        for k in nodes:
            j_, k_ = j, k
            if j > k:
                j_, k_ = k, j
            eq_b = Eq_ij.get((j_, k_), None)
            if eq_b is None:
                continue
            else:
                le_b = Le_ij[j_, k_]
                ge_b = Ge_ij[j_, k_]
            if j_ != j:
                le_b, ge_b = ge_b, le_b

            i_, k_ = i, k
            if i > k:
                i_, k_ = k, i
            eq_c = Eq_ij.get((i_, k_), None)
            if eq_c is None:
                continue
            else:
                le_c = Le_ij[i_, k_]
                ge_c = Ge_ij[i_, k_]
            if i_ != i:
                le_c, ge_c = ge_c, le_c

            # a <= b and b <= c -> a <= c
            model.addLConstr(ge_a + ge_b, GRB.LESS_EQUAL, 1 + ge_c,
                             f'transitivity_ge_{i},{j},{k}')
            # a >= b and b >= c -> a >= c
            model.addLConstr(le_a + le_b, GRB.LESS_EQUAL, 1 + le_c,
                             f'transitivity_le_{i},{j},{k}')
            # a <= b and b == c -> a <= c
            model.addLConstr(le_a + eq_b, GRB.LESS_EQUAL, 1 + le_c,
                             f'transitivity_leeq_{i},{j},{k}')
            # a == b and b <= c -> a <= c
            model.addLConstr(eq_a + le_b, GRB.LESS_EQUAL, 1 + le_c,
                             f'transitivity_eqle_{i},{j},{k}')
            # a >= b and b == c --> a >= c
            model.addLConstr(ge_a + eq_b, GRB.LESS_EQUAL, 1 + ge_c,
                             f'transitivity_geeq_{i},{j},{k}')
            # a == b and b >= c --> a >= c
            model.addLConstr(eq_a + ge_b, GRB.LESS_EQUAL, 1 + ge_c,
                             f'transitivity_eqge_{i},{j},{k}')
            # a == b and b == c --> a == c
            model.addLConstr(eq_a + eq_b, GRB.LESS_EQUAL, 1 + eq_c,
                             f'transitivity_eq_{i},{j},{k}')

    # transitivity helper (for not-fully connected graphs)
    # also provides a latent rank
    big_m = max_rank
    model.addConstrs(((1 - ge_ij) * big_m + R_i[i] >= R_i[j] + 1
                      for (i, j), ge_ij in Ge_ij.items()),
                     'rank_transitivity_larger')
    model.addConstrs(((1 - le_ij) * big_m + R_i[j] >= R_i[i] + 1
                      for (i, j), le_ij in Le_ij.items()),
                     'rank_transitivity_smaller')
    model.addConstrs(((1 - eq_ij) * big_m + R_i[j] >= R_i[i]
                      for (i, j), eq_ij in Eq_ij.items()),
                     'rank_transitivity_equal1')
    model.addConstrs(((1 - eq_ij) * big_m + R_i[i] >= R_i[j]
                      for (i, j), eq_ij in Eq_ij.items()),
                     'rank_transitivity_equal2')

    # objective function
    objective = LinExpr()
    for ij, value in comparisons.items():
        if value == 1.0:
            objective += -E_ij[ij]
        elif value == 0.0:
            objective += E_ij[ij]
        else:
            objective += T_ij_pos[ij] + T_ij_neg[ij]
    model.setObjective(objective, GRB.MINIMIZE)

    # solve
    model.optimize()

    # verify abs emulation: one T_ij has to be 0
    for ij, value in T_ij_pos.items():
        assert value.X == 0 or T_ij_neg[ij] == 0, \
            f'T_{ij} pos {value.X} neg {T_ij_neg[ij]}'

    # find minimal Rs
    model_ = Model('comparison')
    model_.setParam('OutputFlag', verbose)
    R_i = model_.addVars(nodes,
                         name='r_i',
                         vtype=GRB.CONTINUOUS,
                         lb=0,
                         ub=len(nodes))
    for ((i, j), ge_ij), le_ij in zip(Ge_ij.items(), Le_ij.values()):
        if ge_ij.x == 1:
            model_.addConstr(R_i[i] >= R_i[j] + 1)
        elif le_ij.x == 1:
            model_.addConstr(R_i[j] >= R_i[i] + 1)
        else:
            model_.addConstr(R_i[j] == R_i[i])
    model_.setObjective(R_i.sum(), GRB.MINIMIZE)
    model_.optimize()

    return [model_.getVarByName(f'r_i[{i}]').X for i in range(len(nodes))], \
        model.objVal
Example #28
0
def master(params, time_limit=3600, mip_gap=1):
    """Genera el modelo maestro de SSTPA"""

    m = Model("SSTPA Benders Master")
    m.setParam("TimeLimit", time_limit)
    m.setParam("LogToConsole", 1)
    m.setParam("LazyConstraints", 1)
    m.setParam("MIPGap", mip_gap)

    # Parse params dict to values
    N = params['N']
    F = params['F']
    S = params['S']
    I = params['I']
    L = params['L']
    EL = params['EL']
    EV = params['EV']

    #################
    # *  VARIABLES  *#
    #################

    # x_nf: x[partido, fecha]
    # 1 si el partido n se programa finalmente
    # en la fecha f
    # 0 en otro caso.
    x = m.addVars(N, F, vtype=GRB.BINARY, name="x")

    # y_is: y[equipo][patron_localias]
    # 1 si al equipo i se le asigna el patron
    # de localias s
    # 0 en otro caso
    y = {i: m.addVars(S[i], vtype=GRB.BINARY, name="y") for i in I}

    # alfa_jil : alfa[equipo,equipo,fecha]
    # binaria, toma el valor 1 si el equipo j termina con menos puntos
    # que el equipo i en el
    # MEJOR conjunto de
    # resultados futuros para el equipo i considerando que
    # se está en la fecha l
    alfa_m = m.addVars(I, I, F, vtype=GRB.BINARY, name="alfa_m")

    # alfa_jil : alfa[equipo,equipo,fecha]
    # binaria, toma el valor 1 si el equipo j tiene termina
    # con menos puntos que el equipo i, en el PEOR conjunto de
    # resultados futuros para el equipo i considerando que
    # se está en la fecha l
    alfa_p = m.addVars(I, I, F, vtype=GRB.BINARY, name="alfa_p")

    # beta_il: beta[equipo,fecha]
    # discreta, indica la mejor posicion
    # que puede alcanzar el equipo i al final del
    # torneo, mirando desde la fecha l en el MEJOR
    # conjunto de resultados futuros para el equipo i
    beta_m = m.addVars(I, F, vtype=GRB.INTEGER, name="beta_m")

    # beta_il: beta[equipo, fecha]
    # discreta, indica la mejor posicion
    # que puede alcanzar el equipo i al final del
    # torneo, mirando desde la fecha l en el PEOR
    # conjunto de resultados futuros para el equipo i
    beta_p = m.addVars(I, F, vtype=GRB.INTEGER, name="beta_p")

    #####################
    # *  RESTRICCIONES  *#
    #####################

    # R2
    for n in N:
        m.addConstr((quicksum(x[n, f] for f in F) == 1), name=f"R2-{n}")

    # R3
    for i in I:
        for f in F:
            m.addConstr(
                (quicksum(x[n, f]
                          for n in N if EL[i][n] + EV[i][n] == 1) == 1),
                name="R3")

    # R4
    m.addConstrs((quicksum(y[i][s] for s in S[i]) == 1 for i in I), name="R4")

    # R6
    for f in F:
        for i in I:
            _exp1 = LinExpr(quicksum(x[n, f] for n in N if EL[i][n] == 1))
            _exp2 = LinExpr(quicksum(y[i][s] for s in S[i] if L[s][f] == 1))
            m.addConstr(_exp1 == _exp2, name=f"R6-{f}-{i}")

    # R7
    for f in F:
        for i in I:
            _exp1 = LinExpr(quicksum(x[n, f] for n in N if EV[i][n] == 1))
            _exp2 = LinExpr(quicksum(y[i][s] for s in S[i] if L[s][f] == 0))
            m.addConstr(_exp1 == _exp2, name=f"R7-{f}-{i}")

    # R8
    for i in I:
        for l in F:
            _exp = LinExpr(quicksum(alfa_m[j, i, l] for j in I if i != j))
            m.addConstr(beta_m[i, l] == len(I) - _exp, name=f"R8-{i}-{l}")

    # R9
    for i in I:
        for l in F:
            _exp = LinExpr(quicksum(alfa_p[j, i, l] for j in I if i != j))
            m.addConstr(beta_p[i, l] == len(I) - _exp, name=f"R9-{i}-{l}")

    #########################
    # *  FUNCION OBJETIVO  *#
    #########################

    _obj = quicksum(
        quicksum(beta_p[i, l] - beta_m[i, l] for i in I) for l in F)
    m.setObjective(_obj, GRB.MAXIMIZE)

    return m
Example #29
0
    def _create_model(self, job_ids, r_times, p_intervals, m_availabe):
        ## prepare the index for decision variables
        # start time of process
        jobs = tuple(job_ids)
        machines = tuple(range(len(machine_properties)))
        # order of executing jobs: tuple list
        jobPairs = [(i, j) for i in jobs for j in jobs if i < j]
        # assignment of jobs on machines
        job_machinePairs = [(i, k) for i in jobs for k in machines]

        ## parameters model (dictionary)
        # 1. release time
        release_time = dict(zip(jobs, tuple(r_times)))
        # 2. process time
        process_time = dict(zip(jobs, tuple(p_intervals)))
        # 3. machiane available time
        machine_time = dict(zip(machines, tuple(m_availabe)))
        # 4. define BigM
        BigM = np.sum(r_times) + np.sum(p_intervals) + np.sum(m_availabe)

        ## create model
        m = Model('PMSP')
        ## create decision variables
        # 1. assignments of jobs on machines
        z = m.addVars(job_machinePairs, vtype=GRB.BINARY, name='assign')
        # 2. order of executing jobs
        y = m.addVars(jobPairs, vtype=GRB.BINARY, name='order')
        # 3. start time of executing each job
        startTime = m.addVars(jobs, name='startTime')
        ## create objective
        # m.setObjective(quicksum(startTime), GRB.MINIMIZE) # TOTRY

        m._max_complete = m.addVar(1, name='max_complete_time')
        m.setObjective(m._max_complete, GRB.MINIMIZE)  # TOTRY
        m.addConstr((m._max_complete == max_(startTime)), 'minimax')
        ## create constraints
        # 1. job release constraint
        m.addConstrs((startTime[i] >= release_time[i] for i in jobs),
                     'job release constraint')
        # 2. machine available constraint
        m.addConstrs((startTime[i] >= machine_time[k] - BigM * (1 - z[i, k])
                      for (i, k) in job_machinePairs),
                     'machine available constraint')
        # 3. disjunctive constraint
        m.addConstrs((startTime[j] >= startTime[i] + process_time[i] - BigM *
                      ((1 - y[i, j]) + (1 - z[j, k]) + (1 - z[i, k]))
                      for k in machines
                      for (i, j) in jobPairs), 'temporal disjunctive order1')
        m.addConstrs((startTime[i] >= startTime[j] + process_time[j] - BigM *
                      (y[i, j] + (1 - z[j, k]) + (1 - z[i, k]))
                      for k in machines
                      for (i, j) in jobPairs), 'temporal disjunctive order2')
        # 4. one job is assigned to one and only one machine
        m.addConstrs((quicksum([z[i, k] for k in machines]) == 1
                      for i in jobs), 'job non-splitting')

        # set initial solution
        for (i, k) in job_machinePairs:
            if (i, k) in assign_list:
                z[(i, k)].start = 1
            else:
                z[(i, k)].start = 0

        for (i, j) in jobPairs:
            if (i, j) in order_list:
                y[(i, j)].start = 1
            else:
                y[(i, j)].start = 0

        for i in job_ids:
            startTime[i].start = start_times[i]

        return m, z, y, startTime
Example #30
0
vars = m.addVars(dist.keys(), obj=dist, vtype=GRB.BINARY, name='e')
for i, j in vars.keys():
    vars[j, i] = vars[i, j]  # edge in opposite direction

# You could use Python looping constructs and m.addVar() to create
# these decision variables instead.  The following would be equivalent
# to the preceding m.addVars() call...
#
# vars = tupledict()
# for i,j in dist.keys():
#   vars[i,j] = m.addVar(obj=dist[i,j], vtype=GRB.BINARY,
#                        name='e[%d,%d]'%(i,j))

# Add degree-2 constraint

m.addConstrs(vars.sum(i, '*') == 2 for i in range(n))

# Using Python looping constructs, the preceding would be...
#
# for i in range(n):
#   m.addConstr(sum(vars[i,j] for j in range(n)) == 2)

# Optimize model

m._vars = vars
m.Params.lazyConstraints = 1
m.optimize(subtourelim)

vals = m.getAttr('x', vars)
selected = tuplelist((i, j) for i, j in vals.keys() if vals[i, j] > 0.5)