0

I am trying to code the three-index cvrp with CPLEX and python. I have found numerous codes that implement the two-index formulation but have not been able to find the extended version. Following the github code, I am using the generalized miller-tucker-zemlin subtour constraint (see picture 1.37-1.38), but I keep getting unfeasible solutions, regardless of the number of vehicles I choose.

enter image description here

Below is my code:

import numpy as np
import matplotlib.pyplot as plt
from docplex.mp.model import Model

rnd = np.random
rnd.seed(0)

n = 10
Q = 20
N = [i for i in range(1, n+1)]
V = [0] + N
q = {i: rnd.randint(1, 10) for i in N}
K = range(1,4)
loc_x = rnd.rand(len(V))*200
loc_y = rnd.rand(len(V))*100

A = [(i, j, k) for i in V for j in V if i != j for k in K]
Y = [(i, k) for i in V for k in K]
U = [(i, k) for i in N for k in K]
# c = {(i, j): np.hypot(loc_x[i]-loc_x[j], loc_y[i]-loc_y[j]) for i, j, k in A}
c = {(i, j): np.hypot(loc_x[i]-loc_x[j], loc_y[i]-loc_y[j]) for i, j, k in A}

mdl = Model('CVRP')

x = mdl.binary_var_dict(A, name='x')
y = mdl.binary_var_dict(Y, name='y')
u = mdl.continuous_var_dict(U, ub=Q, name='u')

mdl.minimize(mdl.sum(c[i, j]*x[i, j, k] for i, j, k in A))

# constraint 1
#for i in N:
mdl.add_constraints(mdl.sum(y[i, k] for k in K) == 1 for i in N)

# constraint 2
mdl.add_constraint(mdl.sum(y[0, k] for k in K) == len(K))

# constraint 3
mdl.add_constraints(mdl.sum(x[i, j, k] for j in V if i != j) - mdl.sum(x[j, i, k] for j in V if i != j) - y[i, k] == 0 for i in V for k in K)

# constraints 4 and 5 subtour elimination and capacity
mdl.add_indicator_constraints(mdl.indicator_constraint(x[i, j, k], u[i, k]+q[j] == u[j, k]) for i, j, k in A if i != 0 and j != 0)
mdl.add_constraints(u[i, k] >= q[i] for i in N for k in K)

mdl.parameters.timelimit = 30
solution = mdl.solve(log_output=True)

Are there any other ways to code this formulation in CPLEX? I do need the three index formulation to add cost to vehicles.

user6360
  • 21
  • 5

2 Answers2

0

Take a look at Model.binary_var_cube (and other type variations)

Philippe Couronne
  • 826
  • 1
  • 5
  • 6
  • I tried binary_var_cube, but it still returned an infeasible answer. Isn't binary_var_cube the same as binary_var_dict but indexed by [triplets](http://ibmdecisionoptimization.github.io/docplex-doc/mp/docplex.mp.model.html#docplex.mp.model.Model.binary_var_matrix) – user6360 Nov 06 '20 at 22:42
  • Yes, it's basically API sugar around a 3-tuple dict. This means your model formulation is probably incorrect. Take a look at the Relaxer class to search for a relaxed solution. Thus you'll see which constraint is infeasible, and how much slack it needs to become feasible. – Philippe Couronne Nov 12 '20 at 16:30
  • This notebook: https://github.com/IBMDecisionOptimization/docplex-examples/blob/master/examples/mp/jupyter/infeasible.ipynb explains how to deal with infeasible models – Philippe Couronne Nov 12 '20 at 16:32
0

If all vehicles have the same fixed cost, then you can simply add the fixed cost to the variable cost of every arc that departs from the depot, and still be able to use the 2-index formulation.

for i in clients:
    c[0,i] += fixed_cost

If the vehicles have different costs, then you need the 3-index formulation.

Hernan
  • 39
  • 3