Traveling Salesman using Pyomo

送分小仙女□ 提交于 2019-12-21 06:17:56

问题


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.

  1. The sets model.M and model.N have 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.obj is trivially equal to 0 and model.c and model.x are 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.M and model.N are ranges using a RangeSet is probably more suitable, i.e. using the following instead of the above:

    model.M = RangeSet(n)
    model.N = RangeSet(n)
    

    The above Pyomo RangeSet is equal to the set {1, 2, ..., n}.

    Furthermore, since model.M and model.N are the same, declaring one of the sets is sufficient. So if we remove the declaration of model.N and replace any reference to model.N with model.M, we get the same behaviour.

  2. The initialisation of model.c has to be carried out per (i, j) index.

    You can fix this with (using lambda function):

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

    Python lists index from 0, model.M and model.N start from 1 therefore we use the index distanceMatrix[i-1][j-1].

  3. The variables model.x are not binary.

    In a TSP, the variables that model.x represent are usually binary. Solving the problem after carrying out steps 1 and 2 allows the model.x variables to take values such as 2.

    You can change the domain of model.x to binary with:

    model.x = Var(model.N, model.M, within=Binary)
    
  4. The constraint model.con does not allow a TSP tour.

    model.con is equivalent to:

    If we take n = 1, model.con will cause the TSP solution to have two cities visited from starting city 1 (assuming that the model.x are binary), which is not allowed by the definition of TSP.



来源:https://stackoverflow.com/questions/43422144/traveling-salesman-using-pyomo

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!