Skip to content

Commit

Permalink
🔨 Refactor test to use MTZ TSP
Browse files Browse the repository at this point in the history
- This is a much harder model that is more likely to not be solved within the allowed time
  • Loading branch information
ruaridhw committed Feb 27, 2020
1 parent 211f3e4 commit 8b61118
Showing 1 changed file with 69 additions and 15 deletions.
84 changes: 69 additions & 15 deletions pyomo/solvers/tests/checks/test_CPLEXDirect.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
# This software is distributed under the 3-clause BSD License.
# ___________________________________________________________________________

import sys
from itertools import product
from random import random, seed

import pyutilib.th as unittest
from pyomo.opt import *

from pyomo.environ import *
import sys
from pyomo.opt import *

try:
import cplex
Expand Down Expand Up @@ -116,25 +120,75 @@ def test_infeasible_mip(self):
@unittest.skipIf(not cplexpy_available,
"The 'cplex' python bindings are not available")
def test_no_solution_mip(self):
model = ConcreteModel()
model.S = RangeSet(0, 9)
model.P = list(range(10))
model.X = Var(model.S, within=Binary)
model.C1 = Constraint(expr=summation(model.X) == 1)
model.C2 = Constraint(expr=model.X[0] >= 2)
model.O = Objective(expr=sum_product(model.P, model.X), sense=minimize)
def build_mtz_tsp_model(nodes, links, distances):
# Taken from examples/pyomo/callbacks/tsp.py
model = ConcreteModel()

model.POINTS = Set(initialize=nodes, ordered=True)
model.POINTS_LESS_FIRST = Set(initialize=nodes[1:], ordered=True)
model.LINKS = Set(initialize=links, ordered=True)
model.LINKS_LESS_FIRST = Set(
initialize=[
(i, j) for (i, j) in links if i in nodes[1:] and j in nodes[1:]
],
ordered=True,
)

model.N = len(nodes)
model.d = Param(model.LINKS, initialize=distances)

model.Z = Var(model.LINKS, domain=Binary)
model.FLOW = Var(
model.POINTS_LESS_FIRST,
domain=NonNegativeReals,
bounds=(0, model.N - 1),
)

model.InDegrees = Constraint(
model.POINTS,
rule=lambda m, i: sum(
model.Z[i, j] for (i_, j) in model.LINKS if i == i_
)
== 1,
)
model.OutDegrees = Constraint(
model.POINTS,
rule=lambda m, i: sum(
model.Z[j, i] for (j, i_) in model.LINKS if i == i_
)
== 1,
)

model.FlowCon = Constraint(
model.LINKS_LESS_FIRST,
rule=lambda m, i, j: model.FLOW[i] - model.FLOW[j] + m.N * m.Z[i, j]
<= m.N - 1,
)

model.tour_length = Objective(
expr=sum_product(model.d, model.Z), sense=minimize
)
return model

with SolverFactory("cplex", solver_io="python") as opt:
# Set the `options` such that CPLEX cannot determine the problem as infeasible within the time allowed
opt.options['timelimit'] = 0
opt.options['preprocessing_presolve'] = 0
opt.options['simplex_limits_iterations'] = 1
opt.options['mip_limits_nodes'] = 1
opt.options["timelimit"] = 0.0001
opt.options["preprocessing_presolve"] = 0

nodes = list(range(15))
links = list((i, j) for i, j in product(nodes, nodes) if i != j)

seed(0)
distances = {link: random() for link in links}

model = build_mtz_tsp_model(nodes, links, distances)

results = opt.solve(model)

self.assertEqual(results.solver.termination_condition,
TerminationCondition.noSolution)
self.assertEqual(results.solver.status, SolverStatus.warning)
self.assertEqual(
results.solver.termination_condition, TerminationCondition.noSolution
)

@unittest.skipIf(not cplexpy_available,
"The 'cplex' python bindings are not available")
Expand Down

0 comments on commit 8b61118

Please sign in to comment.