变量
约束
代码
用gurobi跑一跑,把xmk和ymk作为已知量。
import sys
from gurobipy import *
from decimal import Decimal
from math import *
import os
import random
import pandas as pd
from numpy import *
num_leg = 7
num_yard = 6
demand = 1
set_k = num_leg + num_yard #相当于r
x = [[1,0,0,1,0,1,0]] # xmk
y = [[0,0,0,0,1,0]] #ymk
cost = [60,50,40,35,55,45,75,80,80,80,80,80,80] # c代表cost,cl和ck都在一个c里,只不过前面对应的是leg,后面对应的是yard
# Create a new model
hazmat = Model('hazmat')
# **********************
# ** Create variables **
# **********************
# zmk 表示m路线中经过的(i,j)和yard的集合
z = [0] * demand
for m in range(demand):
z[m]=[0] * set_k
for k in range(set_k):
z[m][k] = hazmat.addVar(0.0, 1.0, 0.0, GRB.BINARY, 'z[%d][%d]' % (m,k))
# πmkr
π = [0] * demand
for m in range(demand):
π[m] = [0] * set_k
for k in range(set_k):
π[m][k] = [0] * set_k
for r in range(set_k):
π[m][k][r] = hazmat.addVar(0.0, 1.0, 0.0, GRB.BINARY, 'π[%d][%d][%d]' % (m,k,r))
# cmr
c = [0] * demand
for m in range(demand):
c[m] = [0] * set_k
for r in range(set_k):
c[m][r] = hazmat.addVar(0.0, 100, 1.0, GRB.CONTINUOUS, 'c[%d][%d]' % (m,r))
hazmat.update()
#************************************************************
# ** Add constraints **
#************************************************************
# LinExpr.addTerms(coeffs, vars) 要一个系数乘上一个变量
# 对应约束(1), 对于leg:zmk=xmk
for m in range(demand):
for k in range(num_leg):
lhs = LinExpr()
lhs.addTerms(1.0, z[m][k])
hazmat.addConstr(lhs, GRB.EQUAL, x[m][k], 'c1(%d,%d)' %(m,k))
# 对应约束(2), 对于yard:zmk=xmk
for m in range(demand):
for k in range(num_leg,num_leg+num_yard):
lhs = LinExpr()
lhs.addTerms(1.0, z[m][k])
hazmat.addConstr(lhs, GRB.EQUAL, y[m][k-num_leg], 'c2(%d,%d)' %(m,k))
# 对应约束(3), πmkr<=zmk
for m in range(demand):
for k in range(set_k):
for r in range(set_k):
lhs = LinExpr()
lhs.addTerms(1.0, π[m][k][r])
lhs.addTerms(-1.0, z[m][k])
hazmat.addConstr(lhs, GRB.LESS_EQUAL, 0.0, 'c3(%d,%d,%d)' %(m,k,r))
# 对应约束(4), 累加r的πmkr<=1
for m in range(demand):
for k in range(set_k):
lhs = LinExpr()
lhs.addTerms(-1.0, z[m][k])
for r in range(set_k):
lhs.addTerms(1.0, π[m][k][r])
hazmat.addConstr(lhs, GRB.EQUAL, 0.0, 'c4(%d,%d)' %(m,k))
# 对应约束(5), 累加m和k的πmkr<=1
for m in range(demand):
for r in range(set_k):
lhs = LinExpr()
for k in range(set_k):
lhs.addTerms(1.0, π[m][k][r])
hazmat.addConstr(lhs, GRB.LESS_EQUAL, 1.0, 'c5(%d,%d)' %(m,r))
# 对应约束(6), 累加m和k的πmkr<=1
for m in range(demand):
lhs = LinExpr()
for k in range(set_k):
lhs.addTerms(-1.0, z[m][k])
for r in range(set_k):
lhs.addTerms(1.0, π[m][k][r])
hazmat.addConstr(lhs, GRB.EQUAL, 0.0, 'c6(%d)' %(m))
# 对应约束(7), 累加r的πmkr=ymk
for m in range(demand):
for r in range(set_k-1):
lhs = LinExpr()
for k in range(num_leg+num_yard):
lhs.addTerms(1.0, π[m][k][r+1])
lhs.addTerms(-1.0, π[m][k][r])
hazmat.addConstr(lhs, GRB.LESS_EQUAL, 0.0, 'c7(%d,%d)' %(m,r))
# 对应约束(8), ck*πmkr>=cl*πmlr
for m in range(demand):
for r in range(set_k-1):
lhs = LinExpr()
for k in range(num_leg+num_yard):
lhs.addTerms(-cost[k], π[m][k][r])
for l in range(num_leg+num_yard):
lhs.addTerms(cost[l], π[m][l][r+1])
hazmat.addConstr(lhs, GRB.LESS_EQUAL, 0.0, 'c8(%d,%d)' %(m,r))
# 对应约束(9), cmr=cl*πmlr
for m in range(demand):
for r in range(set_k):
lhs = LinExpr()
lhs.addTerms(1.0, c[m][r])
for k in range(num_leg+num_yard):
lhs.addTerms(-cost[k], π[m][k][r])
hazmat.addConstr(lhs, GRB.EQUAL, 0.0, 'c10(%d,%d)' %(m,r))
此代码对应着下图的路线,其中令x和y的值都是已知的,但在实际运行中,x和y是决策变量。
然后得到结果如下:
<gurobi.Var c[0][0] (value 80.0)>
<gurobi.Var c[0][1] (value 60.0)>
<gurobi.Var c[0][2] (value 45.0)>
<gurobi.Var c[0][3] (value 35.0)>
<gurobi.Var c[0][4] (value 0.0)>
<gurobi.Var c[0][5] (value 0.0)>
<gurobi.Var c[0][6] (value 0.0)>
<gurobi.Var c[0][7] (value 0.0)>
即完成了对路线中的c从大到小进行排序。