簡體   English   中英

紙漿優化旅行商問題 - 計算每個節點的到達時間

[英]PuLP Optimization Traveling Salesman Problem - Calculating arrival time for each node

我正在使用python 上的 PuLP優化器解決旅行商問題 該代碼將時間矩陣作為 ndarray 並使用它來計算最佳路線。 我的第一個版本運行完美,但是當我添加一個變量來計算車輛到達每個點的時間時,我遇到了一些問題。

版本 1

import numpy as np 
from pulp import *

time_matrix = np.array([[0,5,4,6,7,10], 
                      [5,0,3,2,6,15], 
                      [4,3,0,4,5,6],
                      [6,2,4,0,7,8],
                      [7,6,5,7,0,11],
                      [10,15,6,8,11,0]])

row,col = time_matrix.shape

problem = LpProblem('TravellingSalesmanProblem', LpMinimize)

# Decision variable X for truck route
decisionVariableX = LpVariable.dicts('decisionVariable_X', ((i, j) for i in range(row) for j in range(row)), lowBound=0, upBound=1, cat='Integer')

# subtours elimination
decisionVariableU = LpVariable.dicts('decisionVariable_U', (i for i in range(row)), lowBound=1, cat='Integer')

# Objective Function
problem += lpSum(time_matrix[i][j] * decisionVariableX[i, j] for i in range(row) for j in range(row))

# Constraint
for i in range(row):
  problem += (decisionVariableX[i,i] == 0) # elimination of (1 to 1) route
  problem += lpSum(decisionVariableX[i,j] for j in range(row))==1 # truck reaches all points once
  problem += lpSum(decisionVariableX[j,i] for j in range(row)) ==1 #truck dispatches from all points once
  for j in range(row):
    if i != j and (i != 0 and j != 0):
        problem += decisionVariableU[i]  <=  decisionVariableU[j] + row * (1 - decisionVariableX[i, j])-1 # sub-tour elimination for truck

status = problem.solve() 
print(f"status: {problem.status}, {LpStatus[problem.status]}")
print(f"objective: {problem.objective.value()}")
for var in problem.variables():
    if (problem.status == 1):
        if (var.value() !=0):
            print(f"{var.name}: {var.value()}")

在版本 2 中,我添加了另一個變量decisionVariableT ,它存儲卡車到達每個節點的時間值。 但是添加這個約束會使問題變得不可行。 有人可以幫我確定代碼有什么問題嗎?

TIA

版本 2 添加

# Decision variable T for truck arrival time
decisionVariableT = LpVariable.dicts('decisionVariable_T', (i for i in range(row)), lowBound=0, cat='Integer')

M=1000

# Calculating truck arrival time at each node
for i in range(row):
    for j in range(row):
        if (decisionVariableX[i,j]==1):
            problem += decisionVariableT[j] == decisionVariableT[i] + time_matrix[i][j]

版本 1的結果:

status: 1, Optimal
objective: 33.0
decisionVariable_U_1: 5.0
decisionVariable_U_2: 2.0
decisionVariable_U_3: 4.0
decisionVariable_U_4: 1.0
decisionVariable_U_5: 3.0
decisionVariable_X_(0,_4): 1.0
decisionVariable_X_(1,_0): 1.0
decisionVariable_X_(2,_5): 1.0
decisionVariable_X_(3,_1): 1.0
decisionVariable_X_(4,_2): 1.0
decisionVariable_X_(5,_3): 1.0

版本 2的結果:

status: -1, Infeasible
objective: 0.0

考慮您的時序矩陣是否具有以下值:

t[2,3] = 2
t[3,2] = 4

因為您正在枚舉矩陣中的所有組合,所以您正在做出(不可行的)聲明

t[2] >= t[3] + 4 + C
t[3] >= t[2] + 2 + C

其中C是一個常量,並且是您的 big-M 約束的結果,如果兩者都不使用(或兩者)。

重新排列為:

t[2] >= t[3] + 4
t[2] <= t[3] - 2

編輯...關於修復的想法

至於修復......你可以......

創建一個變量並在行上保持運行總和,不是在列上。 在偽代碼中:

problem += cumulative_time[0] >= sum(x[0,c] * t[0,c] for c in cols)
for r in rows[1:]:
    prob += cumulative_time[r] >= cumulative_time[r-1] + <above, with 'r' instead of '0'>

或者

意識到沒有必要將累積時間視為變量,因為您可以從解決方案中推斷出它,並且在循環打印結果值時對結果值執行相同的構造......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM