I'm solving the traveling salesman problem using PuLP optimizer on python. The code takes the time matrix as an ndarray and uses it to calculate the optimal route. My first version is running perfectly but i am facing some issue when i add a variable which calculates the time at which the vehicle reaches each point.
Version 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()}")
In version 2 I add another variable decisionVariableT which stores the value of time at which the truck reaches each node. But adding this constraint makes the problem infeasible. Can someone help me in identifying whats wrong with the code?
TIA
Version 2 addition
# 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]
The result of Version 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
The result of Version 2:
status: -1, Infeasible
objective: 0.0