Python 使用Pyomo的旅行推销员

Python 使用Pyomo的旅行推销员,python,pyomo,Python,Pyomo,我正在尝试使用pyomo来解决TSP问题。我已经成功地使用python和Grubi实现了,但是我的Grubi许可证过期了,所以我现在想使用pyomo和GLPK来实现TSP问题。这就是我目前能想到的。目标值为0时,它不起作用。你能帮忙吗 from pyomo.environ import * from pyomo.opt import SolverFactory import pyomo.environ n=13 distanceMatrix=[[0,8,4,10,12,9,15,8,11,5

我正在尝试使用pyomo来解决TSP问题。我已经成功地使用python和Grubi实现了,但是我的Grubi许可证过期了,所以我现在想使用pyomo和GLPK来实现TSP问题。这就是我目前能想到的。目标值为0时,它不起作用。你能帮忙吗

from pyomo.environ import * 
from pyomo.opt import SolverFactory
import pyomo.environ

n=13
distanceMatrix=[[0,8,4,10,12,9,15,8,11,5,9,4,10],
    [8,0,7,6,8,6,7,10,12,9,8,7,5],
    [4,7,0,7,9,5,8,5,4,8,6  ,10,8],
    [10,6   ,7,0,6,11,5 ,9,8,12,11,6,9],
    [12,8   ,9,6,   0,7,9,6,9,8,4,11,10],
    [9,6,5,11,7,0,10,4,3,10,6,5,7],
    [15,7   ,8,5,9,10,0,10,9,8,5,9,10],
    [8,10   ,5,9,6,4,10,0,11,5,9,6,7],
    [11,12,4,8, 9,3,9,11,0, 9,11,11,6],
    [5,9,8,12,8,10,8,5,9,0,6,7,5],
       [9,8,6,11,4,6,5,9,11,6,0,10,7],
       [4,7,10,6,11,5,9,6,11,7,10,0,9],
       [10,5,8,9,10,7,10,7,6,5,7,9,0]] 
startCity = 0

model = ConcreteModel()
model.N=Set()
model.M=Set()
model.c=Param(model.N,model.M, initialize=distanceMatrix)
model.x=Var(model.N,model.M, within=NonNegativeReals)
def obj_rule(model):            
    return sum(model.c[n,j]*model.x[n,j] for n in model.N for j in    model.M)
model.obj = Objective(rule=obj_rule,sense=minimize)
def con_rule(model, n):
    return sum(model.x[j,n] for j in model.M if j < n) + sum(model.x[n,j] for j in Model.M if j > i) == 2

model.con = Constraint(model.N, rule=con_rule,doc='constraint1')
opt = SolverFactory("glpk")
results = opt.solve(model)
results.write()
print('Printing Values')
从pyomo.environ导入*
从pyomo.opt导入SolverFactory
导入pyomo.environ
n=13
距离矩阵=[[0,8,4,10,12,9,15,8,11,5,9,4,10],
[8,0,7,6,8,6,7,10,12,9,8,7,5],
[4,7,0,7,9,5,8,5,4,8,6  ,10,8],
[10,6   ,7,0,6,11,5 ,9,8,12,11,6,9],
[12,8   ,9,6,   0,7,9,6,9,8,4,11,10],
[9,6,5,11,7,0,10,4,3,10,6,5,7],
[15,7   ,8,5,9,10,0,10,9,8,5,9,10],
[8,10   ,5,9,6,4,10,0,11,5,9,6,7],
[11,12,4,8, 9,3,9,11,0, 9,11,11,6],
[5,9,8,12,8,10,8,5,9,0,6,7,5],
[9,8,6,11,4,6,5,9,11,6,0,10,7],
[4,7,10,6,11,5,9,6,11,7,10,0,9],
[10,5,8,9,10,7,10,7,6,5,7,9,0]] 
startCity=0
模型=混凝土模型()
model.N=Set()
model.M=Set()
model.c=Param(model.N,model.M,initialize=distance矩阵)
model.x=Var(model.N,model.M,in=nonnegativereleases)
def obj_规则(型号):
返回和(model.c[n,j]*model.x[n,j]表示模型中的n,n表示模型中的j)
model.obj=目标(规则=obj_规则,意义=最小化)
def con_规则(型号n):
返回和(如果ji,模型M中j的模型x[n,j])==2
model.con=Constraint(model.N,rule=con_rule,doc='constraint1')
opt=SolverFactory(“glpk”)
结果=最优解算(模型)
结果:write()
打印('打印值')

以下答案已经针对Python 3.5.3和Pyomo 5.1.1进行了测试

  • 尚未初始化集合
    model.M
    model.N

    这具有声明空集的效果。因此,如果你跑步:

    model.con.pprint()
    
    您将发现没有声明任何约束。类似地,
    model.obj
    非常小地等于0,
    model.c
    model.x
    是空声明

    您可以通过以下方法解决此问题(我假设您希望从1到n进行索引):

    由于
    model.M
    model.N
    是范围,因此使用
    范围集可能更合适,即使用以下内容代替上述内容:

    model.M = RangeSet(n)
    model.N = RangeSet(n)
    
    上面的Pyomo
    RangeSet
    等于集合{1,2,…,n}

    此外,由于
    model.M
    model.N
    是相同的,因此声明其中一个集合就足够了。因此,如果我们删除
    model.N
    的声明,并将对
    model.N
    的任何引用替换为
    model.M
    ,我们将得到相同的行为

  • 必须按照
    (i,j)
    索引对
    模型.c
    进行初始化

    您可以使用(使用
    lambda
    函数)修复此问题:

    Python从0开始列出索引,
    model.M
    model.N
    从1开始,因此我们使用索引
    距离矩阵[i-1][j-1]

  • 变量
    model.x
    不是二进制的

    在TSP中,
    model.x
    表示的变量通常是二进制的。在执行步骤1和步骤2后解决问题,允许
    model.x
    变量采用2等值

    您可以使用以下命令将
    model.x
    的域更改为二进制:

    model.x = Var(model.N, model.M, within=Binary)
    
  • 约束
    model.con
    不允许TSP巡更

    model.con
    相当于:

    如果我们取n=1,
    model.con
    将导致TSP解决方案从城市1开始访问两个城市(假设
    model.x
    是二进制的),这是TSP定义不允许的

  • model.c = Param(model.N, model.M, initialize=lambda model, i, j: distanceMatrix[i-1][j-1])
    
    model.x = Var(model.N, model.M, within=Binary)