2017-04-15 6 views
1

pyomo를 사용하여 TSP 문제를 해결하려고합니다. 파이썬과 구로비를 사용하여 성공적으로 구현했지만 구로비 라이센스가 만료되었으므로 이제는 pyomo와 GLPK를 사용하여 TSP 문제를 구현하고 싶습니다. 이것은 내가 지금까지 생각해 낼 수 있었던 것이다. 객관적인 가치가 0으로 작동하지 않습니다. 도와 주실 수 있습니까?여행 판매원 Pyomo를 사용하여

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

다음 답변은 Python 3.5.3 및 Pyomo 5.1.1에서 테스트되었습니다.

  1. 세트들은 model.Mmodel.N가 초기화되지 않았습니다.

    이것은 빈 세트를 선언하는 효과가 있습니다. 따라서 다음을 실행하는 경우 :

    model.con.pprint() 
    

    아무런 제약 조건도 없습니다. 비슷하게, model.obj은 0과 거의 같습니다. model.cmodel.x은 공백 선언입니다.

    당신은 (당신이 1부터 n까지 인덱싱 할 있으리라 믿고있어)와 함께이 문제를 해결할 수 있습니다하십시오 RangeSet를 사용하여 범위가

    model.M = Set(initialize=range(1, n+1)) 
    model.N = Set(initialize=range(1, n+1)) 
    

    model.M 이후 및 model.N는 아마 즉, 적절한 다음 사용하고 대신에, 상기의 :

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

    는 Pyomo RangeSet 상기 세트 {1,2, ..., N}와 동일하다.

    또한 model.Mmodel.N이 동일하므로 세트 중 하나를 선언하는 것으로 충분합니다. 따라서 model.N이라는 선언을 삭제하고 model.N에 대한 참조를 model.M으로 바꾸면 동일한 문제가 발생합니다.

  2. (i, j) 인덱스 당 model.c의 초기화가 수행되어야한다.

    당신은 (lambda 기능을 사용)로이 문제를 해결할 수 있습니다

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

    파이썬 목록 인덱스를 0, model.Mmodel.N 처음부터 1 그러므로 우리가 인덱스 distanceMatrix[i-1][j-1]를 사용에서.

  3. 변수 model.x은 바이너리가 아닙니다.

    TSP에서, model.x이 나타내는 변수는 대개 이진 값입니다. 수행 한 후 문제를 해결하는 1 단계와 2 단계는 model.x 변수 당신은 이진을 model.x의 도메인을 변경할 수 있습니다 등 2.

    로 값을 취할 수 있습니다 :

    model.x = Var(model.N, model.M, within=Binary) 
    
  4. 제약을 model.con 허용하지 않습니다 TSP 투어.

    model.con

    은 동등하다 :

    model_con

    우리가 = 1, model.con는 TSP 솔루션은 두 도시를하게됩니다 N 걸릴 경우가합니다 (model.x 진 것을 가정) 도시 (1)를 시작 방문한 TSP의 정의에 의해 허용되지 않습니다.