问题
I am trying to use pyomo to solve TSP problem. I have successfully implemented using python and Gurobi but my Gurobi license expired so I want to now use pyomo and GLPK to implement the TSP problem. This is what I could come up with so far. It is not working the objective value is 0. Can you please help.
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')
回答1:
The following answer has been tested for Python 3.5.3 and Pyomo 5.1.1.
The sets
model.Mandmodel.Nhave not been initialised.This has the effect of declaring empty sets. So if you run:
model.con.pprint()you will find that no constraints have been declared. Similarly,
model.objis trivially equal to 0 andmodel.candmodel.xare empty declarations.You can fix this with (I'm assuming that you want to index from 1 to n):
model.M = Set(initialize=range(1, n+1)) model.N = Set(initialize=range(1, n+1))Since
model.Mandmodel.Nare ranges using aRangeSetis probably more suitable, i.e. using the following instead of the above:model.M = RangeSet(n) model.N = RangeSet(n)The above Pyomo
RangeSetis equal to the set {1, 2, ..., n}.Furthermore, since
model.Mandmodel.Nare the same, declaring one of the sets is sufficient. So if we remove the declaration ofmodel.Nand replace any reference tomodel.Nwithmodel.M, we get the same behaviour.The initialisation of
model.chas to be carried out per(i, j)index.You can fix this with (using
lambdafunction):model.c = Param(model.N, model.M, initialize=lambda model, i, j: distanceMatrix[i-1][j-1])Python lists index from 0,
model.Mandmodel.Nstart from 1 therefore we use the indexdistanceMatrix[i-1][j-1].The variables
model.xare not binary.In a TSP, the variables that
model.xrepresent are usually binary. Solving the problem after carrying out steps 1 and 2 allows themodel.xvariables to take values such as 2.You can change the domain of
model.xto binary with:model.x = Var(model.N, model.M, within=Binary)The constraint
model.condoes not allow a TSP tour.model.conis equivalent to:
If we take n = 1,
model.conwill cause the TSP solution to have two cities visited from starting city 1 (assuming that themodel.xare binary), which is not allowed by the definition of TSP.
来源:https://stackoverflow.com/questions/43422144/traveling-salesman-using-pyomo