Example #1
0
def create_master_FSC_sb_ContFlow(days,
                                  S,
                                  airports,
                                  Nint,
                                  Nf,
                                  Nl,
                                  N,
                                  AF,
                                  AG,
                                  A,
                                  K,
                                  nav,
                                  n,
                                  av,
                                  air_cap,
                                  air_vol,
                                  Cargo,
                                  OD,
                                  size,
                                  vol,
                                  ex,
                                  mand,
                                  cv,
                                  cf,
                                  ch,
                                  inc,
                                  lc,
                                  sc,
                                  delta,
                                  V,
                                  gap,
                                  tv,
                                  model_name,
                                  instance,
                                  L,
                                  L_method,
                                  master_time,
                                  volperkg_sb,
                                  incperkg_sb,
                                  lazy=True):

    ####################
    ### Master Model ###
    ####################

    model = Model(model_name)
    log_name = "log {}.log".format(model.ModelName)
    model.setParam("LogFile", log_name)

    #To add feasible solutions after solving integer Q(y)
    model._sol_to_add = []  # list y0
    model._theta_to_add = 0  # float theta
    model._current_incumbent = 0  # float -FSC + Q_int

    #track the cuts actually aded (not all the computed are added)
    model._Q_cblazy_added = 0
    model._Q_relaxed_cblazy_added = 0
    model._QTbound_cblazy_added = 0

    #################
    ### Variables ###
    #################

    y = {}  #{s: y[i, j, k]}
    # first stage
    y0 = model.addVars(A, K, vtype=GRB.INTEGER, name=('y0'))
    y[0] = y0
    theta = model.addVar(vtype=GRB.CONTINUOUS,
                         ub=GRB.INFINITY,
                         lb=-GRB.INFINITY,
                         name='theta')
    # bound theta with a real second stage, min{vol, cv} and max{inc, density}, but selecting one scenario for size
    y_bound = model.addVars(A, K, vtype=GRB.INTEGER, name=('y_bound'))
    f_bound = model.addVars(A, Cargo, vtype=GRB.CONTINUOUS, name='f_bound')
    zplus_bound = model.addVars(A, K, vtype=GRB.INTEGER, name='zplus_bound')
    zminus_bound = model.addVars(A, K, vtype=GRB.INTEGER, name='zminus_bound')
    sel_size = model.addVars(Cargo, vtype=GRB.CONTINUOUS, name='sel_size')
    #retiming
    r_bound = {}
    for arco in AF:
        r_bound[arco] = model.addVars(V[arco],
                                      K,
                                      vtype=GRB.CONTINUOUS,
                                      ub=1.0,
                                      lb=0.0,
                                      name='r({},{})_bound'.format(
                                          arco[0], arco[1]))
    #select only one scenario to bound
    gamma = model.addVars(S, vtype=GRB.INTEGER, name='gamma')

    ###################
    ### 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)')
    #Upper bound for theta
    model.addConstr((theta <= L), name="theta<=L")
    ## BOUND BY SELECTING AND SOLVING ONE SCENARIO ##
    #B1
    model.addConstrs(
        (quicksum(y_bound[i, j, k] for k in K) <= 1 for i, j in AF),
        name='(B1)')
    #B2
    model.addConstrs(
        (y_bound[i, j, k]
         == y[0][i, j, k] + zplus_bound[i, j, k] - zminus_bound[i, j, k]
         for k in K for i, j in A),
        name="(B2)")
    #B3
    model.addConstrs((quicksum(y_bound[i, j, k]
                               for i, j in A if i == ii) == nav[ii, k]
                      for k in K for ii in Nf),
                     name='(B3)')
    #B4
    model.addConstrs((quicksum(y_bound[i, j, k] for i, j in A if j == jj) -
                      quicksum(y_bound[i, j, k] for i, j in A if i == jj) == 0
                      for k in K for jj in Nint),
                     name='(B4)')
    #B5
    for jj in N:
        for item in Cargo:
            od = OD[item]
            if mand[0][item]:
                if od[1] == jj:
                    #B5.1
                    model.addConstr(
                        (quicksum(f_bound[i, j, item]
                                  for i, j in A if j == jj) -
                         quicksum(f_bound[i, j, item]
                                  for i, j in A if i == jj) == sel_size[item]),
                        name='(B5.1)')
                elif od[0] == jj:
                    #B5.2
                    model.addConstr(
                        (quicksum(f_bound[i, j, item]
                                  for i, j in A if j == jj) -
                         quicksum(f_bound[i, j, item] for i, j in A if i == jj)
                         == -sel_size[item]),
                        name='(B5.2)')
                else:
                    #B5.3
                    model.addConstr((quicksum(f_bound[i, j, item]
                                              for i, j in A if j == jj) -
                                     quicksum(f_bound[i, j, item]
                                              for i, j in A if i == jj) == 0),
                                    name='(B5.3)')
            else:
                if od[1] == jj:
                    #B5.1
                    model.addConstr(
                        (quicksum(f_bound[i, j, item]
                                  for i, j in A if j == jj) -
                         quicksum(f_bound[i, j, item]
                                  for i, j in A if i == jj) <= sel_size[item]),
                        name='(B5.1)')
                elif od[0] == jj:
                    #B5.2
                    model.addConstr(
                        (quicksum(f_bound[i, j, item]
                                  for i, j in A if j == jj) -
                         quicksum(f_bound[i, j, item] for i, j in A if i == jj)
                         >= -sel_size[item]),
                        name='(B5.2)')
                else:
                    #B5.3
                    model.addConstr((quicksum(f_bound[i, j, item]
                                              for i, j in A if j == jj) -
                                     quicksum(f_bound[i, j, item]
                                              for i, j in A if i == jj) == 0),
                                    name='(B5.3)')
    #B6
    model.addConstrs(
        (quicksum(f_bound[i, j, item]
                  for item in Cargo) <= quicksum(air_cap[k] * y_bound[i, j, k]
                                                 for k in K) for i, j in AF),
        name="(B6)")
    #B7
    model.addConstrs(
        (quicksum(f_bound[i, j, item] * volperkg_sb[item]
                  for item in Cargo) <= quicksum(air_vol[k] * y_bound[i, j, k]
                                                 for k in K) for i, j in AF),
        name="(B7)")
    #B8
    model.addConstrs(
        (f_bound[i, j, item] <= quicksum(air_cap[k] * y_bound[i, j, k]
                                         for k in K) for item in Cargo
         for i, j in AF),
        name="(B8)")
    #B9
    model.addConstrs((sel_size[item] == quicksum(size[s][item] * gamma[s]
                                                 for s in S)
                      for item in Cargo),
                     name="(B9)")
    #B12
    model.addConstrs(
        (zminus_bound[i, j, k] <= y[0][i, j, k] for k in K for i, j in AF),
        name="(B12)")
    #B13
    model.addConstrs(
        (y[0][i, j, k] + zplus_bound[i, j, k] <= 1 for k in K for i, j in AF),
        name="(B13)")
    #B19 z+_bin_flight
    model.addConstrs((zplus_bound[i, j, k] <= 1 for k in K for i, j in AF),
                     name="(z+_bin_flight)")
    #B21 z-_bin_flight
    model.addConstrs((zminus_bound[i, j, k] <= 1 for k in K for i, j in AF),
                     name="(z-_bin_flight)")
    # Retiming
    #RT1
    model.addConstrs(
        (y[0][i, j, k] + zminus_bound[i, j, k] + zplus_bound[i2, j2, k] <=
         2 + r_bound[i, j][i2, j2, k] for k in K for i, j in AF
         for i2, j2 in V[i, j]),
        name="(RT1)")
    #RT2
    model.addConstrs((quicksum(r_bound[i, j][i2, j2, k]
                               for i2, j2 in V[i, j]) <= y[0][i, j, k]
                      for k in K for i, j in AF),
                     name="(RT2)")
    #RT3
    model.addConstrs((quicksum(r_bound[i, j][i2, j2, k]
                               for i2, j2 in V[i, j]) <= zminus_bound[i, j, k]
                      for k in K for i, j in AF),
                     name="(RT3)")
    #RT4
    model.addConstrs((quicksum(r_bound[i, j][i2, j2, k]
                               for i, j in V[i2, j2]) <= zplus_bound[i2, j2, k]
                      for k in K for i2, j2 in AF),
                     name="(RT4)")
    # Definition of the second stage value
    SSP_bound = (quicksum(
        incperkg_sb[item] * quicksum(f_bound[i, j, item]
                                     for i, j in A if j == OD[item][1])
        for item in Cargo) -
                 quicksum(cf[arco, k] * y_bound[arco[0], arco[1], k]
                          for arco in AF for k in K) - quicksum(
                              min(cv[(arco, k)]
                                  for k in K) * f_bound[arco[0], arco[1], item]
                              for item in Cargo for arco in AF) -
                 quicksum(ch[arco] * f_bound[arco[0], arco[1], item]
                          for item in Cargo for arco in AG))
    TRC_bound = quicksum(
        min(sc[s][(arco, k)] for s in S) * zplus_bound[arco[0], arco[1], k]
        for k in K for arco in AF)

    RC_bound = quicksum(
        tv * gap[arco, arco2] *
        r_bound[arco[0], arco[1]][arco2[0], arco2[1], k] -
        min(sc[s][(arco, k)]
            for s in S) * r_bound[arco[0], arco[1]][arco2[0], arco2[1], k]
        for k in K for arco in AF for arco2 in V[arco])
    #BQ
    Q_bound = SSP_bound - TRC_bound - RC_bound
    #Upper bound for theta with average scenario
    model.addConstr((theta <= Q_bound), name="theta<=Q_bound")
    #B10 Only one gamma
    model.addConstr((quicksum(gamma[s] for s in S) == 1), name="(One_gamma)")

    ##########################
    ### Objective Function ###
    ##########################

    # Definition of the first stage costs
    FSC = quicksum(lc[(arco, k)] * y[0][arco[0], arco[1], k] for arco in AF
                   for k in K)

    obj = -FSC + theta
    model.setObjective(obj, GRB.MAXIMIZE)
    model.Params.Threads = 1
    if lazy:
        model.Params.lazyConstraints = 1
    if master_gap != None:
        model.setParam('MIPGap', master_gap)
    if master_time != None:
        model.setParam('TimeLimit', master_time)
    if MIPFocus != None:
        model.setParam('MIPFocus', MIPFocus)
    if NodefileStart != None:
        model.setParam('NodefileStart', NodefileStart)
    model.update()

    return model, log_name, y, y0, theta, FSC
Example #2
0
def create_master_FSC(days,
                      S,
                      airports,
                      Nint,
                      Nf,
                      Nl,
                      N,
                      AF,
                      AG,
                      A,
                      K,
                      nav,
                      n,
                      av,
                      lc,
                      model_name,
                      instance,
                      L,
                      L_method,
                      master_time,
                      lazy=True):

    ####################
    ### Master Model ###
    ####################

    model = Model(model_name)
    log_name = "log {}.log".format(model.ModelName)
    model.setParam("LogFile", log_name)

    #To add feasible solutions after solving integer Q(y)
    model._sol_to_add = []  # list y0
    model._theta_to_add = 0  # float theta
    model._current_incumbent = 0  # float -FSC + Q_int

    #track the cuts actually aded (not all the computed are added)
    model._Q_cblazy_added = 0
    model._Q_relaxed_cblazy_added = 0

    #################
    ### Variables ###
    #################

    y = {}  #{s: y[i, j, k]}
    # first stage
    y0 = model.addVars(A, K, vtype=GRB.INTEGER, name=('y0'))
    y[0] = y0
    theta = model.addVar(vtype=GRB.CONTINUOUS,
                         ub=GRB.INFINITY,
                         lb=-GRB.INFINITY,
                         name='theta')

    ###################
    ### 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)')
    #Upper bound for theta
    model.addConstr((theta <= L), name="theta<=L")

    ##########################
    ### Objective Function ###
    ##########################

    # Definition of the first stage costs
    FSC = quicksum(lc[(arco, k)] * y[0][arco[0], arco[1], k] for arco in AF
                   for k in K)

    obj = -FSC + theta
    model.setObjective(obj, GRB.MAXIMIZE)
    model.Params.Threads = 1
    if lazy:
        model.Params.lazyConstraints = 1
    if master_gap != None:
        model.setParam('MIPGap', master_gap)
    if master_time != None:
        model.setParam('TimeLimit', master_time)
    if MIPFocus != None:
        model.setParam('MIPFocus', MIPFocus)
    if NodefileStart != None:
        model.setParam('NodefileStart', NodefileStart)
    model.update()

    return model, log_name, y, y0, theta, FSC