Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • pmag/topupopt
1 result
Show changes
......@@ -321,12 +321,12 @@ class TestGisCalculate:
true_length_3_points = true_length_2_points_a + true_length_2_points_b
# make sure the function fails with a single point (sanity check)
error_triggered = False
error_raised = False
try:
line = LineString(list_1_points)
except Exception:
error_triggered = True
assert error_triggered
error_raised = True
assert error_raised
# make sure it works with 2 points
......
......@@ -4215,7 +4215,7 @@ class TestGisIdentify:
# not allowed
error_triggered = False
error_raised = False
try:
# inconsistent edge key format
gis_iden.is_edge_path(
......@@ -4224,8 +4224,8 @@ class TestGisIdentify:
allow_multiple_formats=False,
)
except ValueError:
error_triggered = True
assert error_triggered
error_raised = True
assert error_raised
# *********************************************************************
# *********************************************************************
......@@ -4294,15 +4294,15 @@ class TestGisIdentify:
# not allowed
error_triggered = False
error_raised = False
try:
# inconsistent edge key format
gis_iden.is_edge_path(
network, path=[(10, 8, 0), (8, 9)], allow_multiple_formats=False
)
except ValueError:
error_triggered = True
assert error_triggered
error_raised = True
assert error_raised
# inconsistent edge key format
......@@ -4314,15 +4314,15 @@ class TestGisIdentify:
# not allowed
error_triggered = False
error_raised = False
try:
# inconsistent edge key format
gis_iden.is_edge_path(
network, path=[(6, 5), (5, 4, 0), (4, 3)], allow_multiple_formats=False
)
except ValueError:
error_triggered = True
assert error_triggered
error_raised = True
assert error_raised
# *********************************************************************
# *********************************************************************
......
# imports
# standard
import sys
from ast import literal_eval
import random
......@@ -1121,7 +1121,7 @@ class TestGisUtils:
# trigger the error
error_triggered = False
error_raised = False
try:
(
node_keys,
......@@ -1129,8 +1129,8 @@ class TestGisUtils:
_,
) = gis_utils.prepare_node_data_from_geodataframe(gdf=gdf)
except ValueError:
error_triggered = True
assert error_triggered
error_raised = True
assert error_raised
# *****************************************************************************
# *****************************************************************************
......@@ -1322,18 +1322,18 @@ class TestGisUtils:
# mismatched longitudes and latitudes
error_triggered = False
error_raised = False
try:
_ = gis_utils.create_node_geodataframe(
longitudes=(_longitude, 528), latitudes=(_latitude,)
)
except ValueError:
error_triggered = True
assert error_triggered
error_raised = True
assert error_raised
# mismatched longitudes/latitudes and osmids
error_triggered = False
error_raised = False
try:
_ = gis_utils.create_node_geodataframe(
longitudes=(_longitude, 528),
......@@ -1341,8 +1341,8 @@ class TestGisUtils:
osmids=(59, 482, 135),
)
except ValueError:
error_triggered = True
assert error_triggered
error_raised = True
assert error_raised
# *************************************************************************
# *************************************************************************
......@@ -1881,12 +1881,12 @@ class TestGisUtils:
gdf.to_file(filename_gpkg)
else: # incompatible: errors are expected
error_triggered = False
error_raised = False
try:
gdf.to_file(filename_gpkg)
except Exception:
error_triggered = True
assert error_triggered
error_raised = True
assert error_raised
# *********************************************************************
# *********************************************************************
......@@ -2603,6 +2603,21 @@ class TestGisUtils:
# *************************************************************************
def test_simplify_network_osmnx(self):
# BUG: there is a bug here, therefore we are printing the seed number
# it seems to occur if all the nodes around 1106295281 are simplified
# seed: 5785034948163332129
# for edge_key in network.edges(keys=True):
# > assert len(tuple(gis_iden.get_edges_between_two_nodes(network, *edge_key[0:2]))) == 1
# E assert 2 == 1
# E + where 2 = len(((1106295281, 1106295315, 0), (1106295315, 1106295281, 0)))
# E + where ((1106295281, 1106295315, 0), (1106295315, 1106295281, 0)) = tuple([(1106295281, 1106295315, 0), (1106295315, 1106295281, 0)])
# E + where [(1106295281, 1106295315, 0), (1106295315, 1106295281, 0)] = <function get_edges_between_two_nodes at 0x7f8d07bc9ee0>(<networkx.classes.multidigraph.MultiDiGraph object at 0x7f8d00d17410>, *(1106295281, 1106295315))
# E + where <function get_edges_between_two_nodes at 0x7f8d07bc9ee0> = gis_iden.get_edges_between_two_nodes
seed = random.randrange(sys.maxsize)
random.seed(seed)
print("Seed was:", seed)
# get a network
network = ox.graph_from_point(
(55.71654, 9.11728),
......@@ -2618,6 +2633,11 @@ class TestGisUtils:
node_keys[random.randint(0, len(node_keys) - 1)]
for i in range(number_nodes_protected)
]
# protected_nodes.append(1106295281)
# assert 1 == 0
# E + where 1 = len([[317212013, 1106295281, 1106295315]])
# E + where [[317212013, 1106295281, 1106295315]] = <function find_simplifiable_paths at 0x7f9ac0cf22a0>(<networkx.classes.multidigraph.MultiDiGraph object at 0x7f9ab2c7b350>, [115838, 317195115, 5031764839, 317811652, 5076232388, 615539272, ...])
# E + where <function find_simplifiable_paths at 0x7f9ac0cf22a0> = gis_iden.find_simplifiable_paths
# try simplifying it
gis_utils.simplify_network(network, protected_nodes=protected_nodes)
# protected nodes must still exist
......
......@@ -5,29 +5,99 @@ from src.topupopt.solvers.interface import SolverInterface
from pyomo.opt.results.solver import TerminationCondition
import pyomo.environ as pyo
from pyomo.common.errors import ApplicationError
from pyomo.opt import check_available_solvers
import random
import pytest
# *****************************************************************************
# *****************************************************************************
@pytest.mark.parametrize(
"solver",
['glpk',
'cbc',
'scip',
'fakesolver']
)
class TestSolvers:
# *************************************************************************
# *************************************************************************
def test_solver_factory_arguments(self):
# test a collection of problems using different solvers
def test_inexistent_solver(self, solver):
# try using a fake solver and a problem incompatible with another solver
# list of problems: one compatible, one incompatible
list_problems = [
problem_milp_feasible(20, seed_number=50),
problem_lp_optimal(),
problem_qp_optimal(),
problem_qp_optimal(),
]
problem = self.problem_milp_feasible()
# problem types
list_problem_types = [
SolverInterface.PROBLEM_LP,
SolverInterface.PROBLEM_LP,
SolverInterface.PROBLEM_QP,
"fake_problem_type",
]
# solver settings
solver_timelimit = 30
solver_abs_mip_gap = 0
solver_rel_mip_gap = 0.01
solver_options = {
"time_limit": solver_timelimit,
"relative_mip_gap": solver_rel_mip_gap,
"absolute_mip_gap": solver_abs_mip_gap,
}
solver_timelimit = 10
# *********************************************************************
# *********************************************************************
solver_abs_mip_gap = 0.001
for index, problem in enumerate(list_problems):
# optimise
try:
# test problem-solver compatibility
problem_type = list_problem_types[index]
if not SolverInterface.problem_and_solver_are_compatible(
solver, problem_type):
continue
except SolverInterface.UnknownSolverError:
assert True
except SolverInterface.UnknownProblemTypeError:
assert True
# test the solver interface
try:
# configure common solver interface
_ = SolverInterface(solver_name=solver, **solver_options)
except SolverInterface.UnknownSolverError:
assert True
# *************************************************************************
# *************************************************************************
# @pytest.mark.skipif(True, reason="requires python3.10 or higher")
def test_solver_factory_arguments(self, solver):
# skip test if the solver is not available
if not bool(check_available_solvers(solver)):
return
# test a feasible problem
problem = problem_milp_feasible()
# solver settings
solver_timelimit = 10
solver_abs_mip_gap = 0.001
solver_rel_mip_gap = 0.01
solver_options = {
......@@ -35,61 +105,30 @@ class TestSolvers:
"relative_mip_gap": solver_rel_mip_gap,
"absolute_mip_gap": solver_abs_mip_gap,
# special option
"tee": True,
"tee": False,
}
solver_name = "scip"
results, solver_interface = self.optimise(solver_name, solver_options, problem)
results, solver_interface = optimise(solver, solver_options, problem)
# *************************************************************************
# *************************************************************************
def test_problems(self):
def test_problems(self, solver):
# test a collection of problems using different solvers
# solver = "scip"
# # scip_exec_path = '/usr/bin/scip'
# # solver_options = {'executable': scip_exec_path}
# solver_options = {}
# solver = 'cplex'
# # cplex_exec_path = '/home/pmlpm/Software/CPLEX/cplex/bin/x86-64_linux/cplex'
# cplex_exec_path = '/home/pmlpm/CPLEX/cplex/bin/x86-64_linux/cplex'
# #solver_options = {}
# solver_options = {'executable':cplex_exec_path}
list_solvers = [
"fake_solver",
"cbc",
"glpk",
"scip",
'cplex'
]
list_solver_options = [
None, # fake
None, # cbc
{"tee": False}, # glpk
None, # scip {'executable': scip_exec_path},
None, # cplex
# {'executable': cplex_exec_path},
]
# list of problems
list_concrete_models = [
self.problem_qp_optimal(),
self.problem_qp_infeasible(),
self.problem_lp_unbounded(),
self.problem_lp_infeasible(),
self.problem_lp_optimal(),
self.problem_milp_unbounded(),
self.problem_milp_infeasible(),
self.problem_milp_optimal(),
self.problem_milp_feasible(),
self.problem_milp_feasible(15, 64),
self.problem_milp_feasible(10, 46),
problem_qp_optimal(),
problem_qp_infeasible(),
problem_lp_unbounded(),
problem_lp_infeasible(),
problem_lp_optimal(),
problem_milp_unbounded(),
problem_milp_infeasible(),
problem_milp_optimal(),
problem_milp_feasible(),
problem_milp_feasible(15, 64),
problem_milp_feasible(10, 46),
]
# list of problem types
......@@ -138,577 +177,475 @@ class TestSolvers:
True,
]
# list of solvers
list_solvers = ["fake_solver", "cbc", "glpk", "scip", "cplex"]
# solver settings
solver_timelimit = 10
solver_abs_mip_gap = 0.001
solver_rel_mip_gap = 0.01
solver_options = {
"time_limit": solver_timelimit,
"relative_mip_gap": solver_rel_mip_gap,
"absolute_mip_gap": solver_abs_mip_gap,
}
for solver_name, solver_options in zip(list_solvers, list_solver_options):
if type(solver_options) == dict:
solver_options.update(
{
"time_limit": solver_timelimit,
"relative_mip_gap": solver_rel_mip_gap,
"absolute_mip_gap": solver_abs_mip_gap,
}
)
else:
solver_options = {
"time_limit": solver_timelimit,
"relative_mip_gap": solver_rel_mip_gap,
"absolute_mip_gap": solver_abs_mip_gap,
}
for problem_index, problem in enumerate(list_concrete_models):
try:
# check problem and solver compatibility
problem_type = list_problem_types[problem_index]
if (
SolverInterface.problem_and_solver_are_compatible(
solver_name, problem_type
)
== False
):
continue
# optimise
results, solver_interface = self.optimise(
solver_name, solver_options, problem, print_solver_output=False
)
except SolverInterface.UnknownSolverError:
continue
except SolverInterface.UnknownProblemTypeError:
continue
# *************************************************************
# *************************************************************
# termination condition
exp_term_cond = list_problem_termination_conditions[problem_index]
term_cond = results.solver.termination_condition
if (
exp_term_cond == None
or (
solver_name == "glpk"
and exp_term_cond == TerminationCondition.unbounded
)
or (
solver_name == "cplex"
and exp_term_cond == TerminationCondition.unbounded
)
or (
solver_name == "cplex"
and exp_term_cond == TerminationCondition.optimal
)
or (
solver_name == "cplex"
and exp_term_cond == TerminationCondition.infeasible
)
):
# exceptions in need of correction
pass
else:
# print(solver_name)
# print(results)
assert exp_term_cond == term_cond
# *************************************************************
# *************************************************************
# solver status
if (
(
solver_name == "glpk"
and term_cond == TerminationCondition.infeasible
)
or (
solver_name == "cplex"
and term_cond == TerminationCondition.unknown
)
or (
solver_name == "cplex"
and exp_term_cond == TerminationCondition.unbounded
)
or (
solver_name == "cplex"
and exp_term_cond == TerminationCondition.infeasible
)
):
pass
else:
# check if the solver status matches the one one would expect
# if the termination condition was correct
assert (
TerminationCondition.to_solver_status(term_cond)
== results.solver.status
)
# if valid, it means the results object is coherent
for problem_index, problem in enumerate(list_concrete_models):
try:
# check problem and solver compatibility
# *************************************************************
# *************************************************************
problem_type = list_problem_types[problem_index]
if (
exp_term_cond == None
or (
solver_name == "glpk"
and exp_term_cond == TerminationCondition.unbounded
)
or (
solver_name == "glpk"
and exp_term_cond == TerminationCondition.infeasible
)
or (
solver_name == "cplex"
and exp_term_cond == TerminationCondition.unknown
)
or (
solver_name == "cplex"
and exp_term_cond == TerminationCondition.unbounded
)
or (
solver_name == "cplex"
and exp_term_cond == TerminationCondition.infeasible
SolverInterface.problem_and_solver_are_compatible(
solver, problem_type
)
== False
):
pass
continue
else:
# check if the solver status matches the one one would expect
# if the termination condition predicted was obtained
# optimise
assert (
TerminationCondition.to_solver_status(exp_term_cond)
== results.solver.status
)
results, solver_interface = optimise(
solver, solver_options, problem, print_solver_output=False
)
# if valid, the solver status is correct despite other issues
except SolverInterface.UnknownSolverError:
continue
# *************************************************************
# *************************************************************
except SolverInterface.UnknownProblemTypeError:
continue
# make sure the optimisation went as expected
# *************************************************************
# *************************************************************
exp_optim_result = list_problem_optimisation_sucess[problem_index]
# termination condition
if (
TerminationCondition.to_solver_status(
results.solver.termination_condition
)
!= results.solver.status
):
# this can be removed once the aforementioned issues have
# been fixed (e.g. for the cplex and glpk solvers)
exp_term_cond = list_problem_termination_conditions[problem_index]
pass
term_cond = results.solver.termination_condition
else:
optim_result = solver_interface.was_optimisation_sucessful(
results, problem_type
)
# *************************************************************
# *************************************************************
if (
exp_term_cond == None
or (
solver == "glpk"
and exp_term_cond == TerminationCondition.unbounded
)
or (
solver == "cplex"
and exp_term_cond == TerminationCondition.unbounded
)
or (
solver == "cplex"
and exp_term_cond == TerminationCondition.optimal
)
or (
solver == "cplex"
and exp_term_cond == TerminationCondition.infeasible
)
):
# exceptions in need of correction
if (
TerminationCondition.to_solver_status(
results.solver.termination_condition
)
!= results.solver.status
or exp_term_cond == TerminationCondition.unbounded
):
# this can be removed once the aforementioned issues have
# been fixed (e.g. for the cplex and glpk solvers)
pass
pass
else:
# print(solver)
# print(results)
assert exp_term_cond == term_cond
else:
assert optim_result == exp_optim_result
# *************************************************************
# *************************************************************
# *************************************************************
# *************************************************************
# solver status
# test additional scenarios
if (
(
solver == "glpk"
and term_cond == TerminationCondition.infeasible
)
or (
solver == "cplex"
and term_cond == TerminationCondition.unknown
)
or (
solver == "cplex"
and exp_term_cond == TerminationCondition.unbounded
)
or (
solver == "cplex"
and exp_term_cond == TerminationCondition.infeasible
)
):
pass
if optim_result == False:
continue
else:
# check if the solver status matches the one one would expect
# if the termination condition was correct
# force unknown solver status error
assert (
TerminationCondition.to_solver_status(term_cond)
== results.solver.status
)
results.solver.status = "false_solver_status"
# if valid, it means the results object is coherent
try:
_ = solver_interface.was_optimisation_sucessful(
results, problem_type
)
# *************************************************************
# *************************************************************
except solver_interface.UnknownSolverStatusError:
assert True
if (
exp_term_cond == None
or (
solver == "glpk"
and exp_term_cond == TerminationCondition.unbounded
)
or (
solver == "glpk"
and exp_term_cond == TerminationCondition.infeasible
)
or (
solver == "cplex"
and exp_term_cond == TerminationCondition.unknown
)
or (
solver == "cplex"
and exp_term_cond == TerminationCondition.unbounded
)
or (
solver == "cplex"
and exp_term_cond == TerminationCondition.infeasible
)
):
pass
# force unknown termination condition error
else:
# check if the solver status matches the one one would expect
# if the termination condition predicted was obtained
results.solver.termination_condition = "false_termin_condition"
assert (
TerminationCondition.to_solver_status(exp_term_cond)
== results.solver.status
)
try:
_ = solver_interface.was_optimisation_sucessful(
results, problem_type
)
# if valid, the solver status is correct despite other issues
except solver_interface.UnknownTerminationConditionError:
assert True
# *************************************************************
# *************************************************************
# force an InconsistentSolverStatusError
# make sure the optimisation went as expected
results.solver.termination_condition = TerminationCondition.optimal
exp_optim_result = list_problem_optimisation_sucess[problem_index]
results.solver.status = TerminationCondition.to_solver_status(
if (
TerminationCondition.to_solver_status(
results.solver.termination_condition
)
!= results.solver.status
):
# this can be removed once the aforementioned issues have
# been fixed (e.g. for the cplex and glpk solvers)
results.solver.termination_condition = TerminationCondition.unknown
pass
try:
_ = solver_interface.was_optimisation_sucessful(
results, problem_type
)
else:
optim_result = solver_interface.was_optimisation_sucessful(
results, problem_type
)
except solver_interface.InconsistentSolverStatusError:
assert True
# *************************************************************
# *************************************************************
# force an InconsistentProblemTypeAndSolverError
if (
TerminationCondition.to_solver_status(
results.solver.termination_condition
)
!= results.solver.status
or exp_term_cond == TerminationCondition.unbounded
):
# this can be removed once the aforementioned issues have
# been fixed (e.g. for the cplex and glpk solvers)
if problem_type == SolverInterface.PROBLEM_LP and solver_name == "glpk":
problem_type = SolverInterface.PROBLEM_QP
pass
try:
_ = solver_interface.was_optimisation_sucessful(
results, problem_type
)
else:
assert optim_result == exp_optim_result
except solver_interface.InconsistentProblemTypeAndSolverError:
assert True
# *************************************************************
# *************************************************************
# *********************************************************************
# *********************************************************************
# test additional scenarios
# *************************************************************************
# *************************************************************************
if optim_result == False:
continue
# carry out optimisations
# force unknown solver status error
def optimise(
self,
solver_name: str,
solver_options: dict,
# solver_interface: SolverInterface,
problem: pyo.ConcreteModel,
print_solver_output: bool = True,
):
# configure common solver interface
solver_interface = SolverInterface(solver_name=solver_name, **solver_options)
results.solver.status = "false_solver_status"
# get the solver handler
solver_handler = solver_interface.get_solver_handler(**solver_options)
try:
_ = solver_interface.was_optimisation_sucessful(
results, problem_type
)
# solve
if "tee" not in solver_options:
results = solver_handler.solve(problem, tee=print_solver_output)
else:
results = solver_handler.solve(problem)
except solver_interface.UnknownSolverStatusError:
assert True
# return
return results, solver_interface
# force unknown termination condition error
# *************************************************************************
# *************************************************************************
results.solver.termination_condition = "false_termin_condition"
def problem_qp_optimal(self):
model = pyo.ConcreteModel("qp_optimal")
try:
_ = solver_interface.was_optimisation_sucessful(
results, problem_type
)
model.x = pyo.Var(within=pyo.NonNegativeReals)
model.y = pyo.Var(within=pyo.NonNegativeReals)
except solver_interface.UnknownTerminationConditionError:
assert True
def constraint_rule(model):
return model.x + model.y >= 10
# force an InconsistentSolverStatusError
model.constraint = pyo.Constraint(rule=constraint_rule)
results.solver.termination_condition = TerminationCondition.optimal
def objective_rule(model):
return (
model.x
+ model.y
+ 0.5
* (model.x * model.x + 4 * model.x * model.y + 7 * model.y * model.y)
results.solver.status = TerminationCondition.to_solver_status(
results.solver.termination_condition
)
model.objective = pyo.Objective(rule=objective_rule, sense=pyo.minimize)
return model
# *************************************************************************
# *************************************************************************
def problem_qp_infeasible(self):
model = pyo.ConcreteModel("qp_infeasible")
results.solver.termination_condition = TerminationCondition.unknown
# model.x = pyo.Var(within=pyo.NonNegativeReals, bounds=(0,5))
# model.y = pyo.Var(within=pyo.NonNegativeReals, bounds=(0,4))
try:
_ = solver_interface.was_optimisation_sucessful(
results, problem_type
)
model.x = pyo.Var(bounds=(0, 5))
model.y = pyo.Var(bounds=(0, 4))
except solver_interface.InconsistentSolverStatusError:
assert True
def constraint_rule(model):
return model.x + model.y >= 10
# force an InconsistentProblemTypeAndSolverError
model.constraint = pyo.Constraint(rule=constraint_rule)
if problem_type == SolverInterface.PROBLEM_LP and solver == "glpk":
problem_type = SolverInterface.PROBLEM_QP
def objective_rule(model):
return (
model.x
+ model.y
+ 0.5
* (model.x * model.x + 4 * model.x * model.y + 7 * model.y * model.y)
)
try:
_ = solver_interface.was_optimisation_sucessful(
results, problem_type
)
model.objective = pyo.Objective(rule=objective_rule, sense=pyo.minimize)
except solver_interface.InconsistentProblemTypeAndSolverError:
assert True
return model
# *********************************************************************
# *********************************************************************
# *************************************************************************
# *************************************************************************
def problem_lp_optimal(self):
model = pyo.ConcreteModel("lp_optimal")
model.x = pyo.Var([1, 2], domain=pyo.NonNegativeReals)
# *****************************************************************************
# *****************************************************************************
model.OBJ = pyo.Objective(expr=2 * model.x[1] + 3 * model.x[2])
# carry out optimisations
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] >= 1)
def optimise(
solver_name: str,
solver_options: dict,
# solver_interface: SolverInterface,
problem: pyo.ConcreteModel,
print_solver_output: bool = True,
):
# configure common solver interface
solver_interface = SolverInterface(solver_name=solver_name, **solver_options)
return model
# get the solver handler
solver_handler = solver_interface.get_solver_handler(**solver_options)
# *************************************************************************
# *************************************************************************
# solve
if "tee" not in solver_options:
results = solver_handler.solve(problem, tee=print_solver_output)
else:
results = solver_handler.solve(problem)
def problem_lp_infeasible(self):
model = pyo.ConcreteModel("lp_infeasible")
# return
return results, solver_interface
model.x = pyo.Var([1, 2], domain=pyo.NonNegativeReals)
model.OBJ = pyo.Objective(expr=2 * model.x[1] + 3 * model.x[2])
# *****************************************************************************
# *****************************************************************************
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] <= -1)
def problem_qp_optimal():
model = pyo.ConcreteModel("qp_optimal")
return model
model.x = pyo.Var(within=pyo.NonNegativeReals)
model.y = pyo.Var(within=pyo.NonNegativeReals)
# *************************************************************************
# *************************************************************************
def constraint_rule(model):
return model.x + model.y >= 10
def problem_lp_unbounded(self):
model = pyo.ConcreteModel("lp_unbounded")
model.constraint = pyo.Constraint(rule=constraint_rule)
model.x = pyo.Var([1, 2], domain=pyo.NonNegativeReals)
model.OBJ = pyo.Objective(
expr=2 * model.x[1] + 3 * model.x[2], sense=pyo.maximize
def objective_rule(model):
return (
model.x
+ model.y
+ 0.5
* (model.x * model.x + 4 * model.x * model.y + 7 * model.y * model.y)
)
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] >= 1)
model.objective = pyo.Objective(rule=objective_rule, sense=pyo.minimize)
return model
return model
# *************************************************************************
# *************************************************************************
# *****************************************************************************
# *****************************************************************************
def problem_milp_optimal(self):
model = pyo.ConcreteModel("milp_optimal")
def problem_qp_infeasible():
model = pyo.ConcreteModel("qp_infeasible")
model.x = pyo.Var([1, 2], domain=pyo.Binary)
# model.x = pyo.Var(within=pyo.NonNegativeReals, bounds=(0,5))
# model.y = pyo.Var(within=pyo.NonNegativeReals, bounds=(0,4))
model.OBJ = pyo.Objective(expr=2.15 * model.x[1] + 3.8 * model.x[2])
model.x = pyo.Var(bounds=(0, 5))
model.y = pyo.Var(bounds=(0, 4))
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] >= 1)
def constraint_rule(model):
return model.x + model.y >= 10
return model
model.constraint = pyo.Constraint(rule=constraint_rule)
# *************************************************************************
# *************************************************************************
def objective_rule(model):
return (
model.x
+ model.y
+ 0.5
* (model.x * model.x + 4 * model.x * model.y + 7 * model.y * model.y)
)
def problem_milp_infeasible(self):
model = pyo.ConcreteModel("milp_infeasible")
model.objective = pyo.Objective(rule=objective_rule, sense=pyo.minimize)
model.x = pyo.Var([1, 2], domain=pyo.Binary)
return model
model.OBJ = pyo.Objective(expr=2 * model.x[1] + 3 * model.x[2])
# *****************************************************************************
# *****************************************************************************
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] <= -1)
def problem_lp_optimal():
model = pyo.ConcreteModel("lp_optimal")
return model
model.x = pyo.Var([1, 2], domain=pyo.NonNegativeReals)
# *************************************************************************
# *************************************************************************
model.OBJ = pyo.Objective(expr=2 * model.x[1] + 3 * model.x[2])
def problem_milp_unbounded(self):
model = pyo.ConcreteModel("milp_unbounded")
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] >= 1)
model.x = pyo.Var([1, 2], domain=pyo.NonNegativeReals)
return model
model.y = pyo.Var(domain=pyo.Binary)
# *****************************************************************************
# *****************************************************************************
model.OBJ = pyo.Objective(
expr=2 * model.x[1] + 3 * model.x[2] + model.y, sense=pyo.maximize
)
def problem_lp_infeasible():
model = pyo.ConcreteModel("lp_infeasible")
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] >= 1)
model.x = pyo.Var([1, 2], domain=pyo.NonNegativeReals)
return model
model.OBJ = pyo.Objective(expr=2 * model.x[1] + 3 * model.x[2])
# *************************************************************************
# *************************************************************************
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] <= -1)
def problem_milp_feasible(self, number_binary_variables=25, seed_number=None):
if seed_number != None:
random.seed(seed_number)
return model
model = pyo.ConcreteModel("milp_feasible")
# *****************************************************************************
# *****************************************************************************
# a knapsack-type problem
def problem_lp_unbounded():
model = pyo.ConcreteModel("lp_unbounded")
model.Y = pyo.RangeSet(number_binary_variables)
model.x = pyo.Var([1, 2], domain=pyo.NonNegativeReals)
model.y = pyo.Var(model.Y, domain=pyo.Binary)
model.OBJ = pyo.Objective(
expr=2 * model.x[1] + 3 * model.x[2], sense=pyo.maximize
)
model.OBJ = pyo.Objective(
expr=sum(model.y[j] * random.random() for j in model.Y), sense=pyo.maximize
)
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] >= 1)
model.Constraint1 = pyo.Constraint(
expr=sum(model.y[j] * random.random() for j in model.Y)
<= round(number_binary_variables / 5)
)
return model
def rule_c1(m, i):
return (
sum(
model.y[j] * (random.random() - 0.5)
for j in model.Y
if j != i
if random.randint(0, 1)
)
<= round(number_binary_variables / 5) * model.y[i]
)
# *****************************************************************************
# *****************************************************************************
model.constr_c1 = pyo.Constraint(model.Y, rule=rule_c1)
def problem_milp_optimal():
model = pyo.ConcreteModel("milp_optimal")
return model
model.x = pyo.Var([1, 2], domain=pyo.Binary)
# *************************************************************************
# *************************************************************************
model.OBJ = pyo.Objective(expr=2.15 * model.x[1] + 3.8 * model.x[2])
def test_inexistent_solver(self):
fake_solver = "fake_solver"
good_solver = "glpk"
# solver_options: dict = None
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] >= 1)
# try using a fake solver and a problem incompatible with another solver
return model
# list of problems: one compatible, one incompatible
# *****************************************************************************
# *****************************************************************************
list_problems = [
self.problem_milp_feasible(20, seed_number=50),
self.problem_lp_optimal(),
self.problem_qp_optimal(),
self.problem_qp_optimal(),
]
def problem_milp_infeasible():
model = pyo.ConcreteModel("milp_infeasible")
# problem types
model.x = pyo.Var([1, 2], domain=pyo.Binary)
list_problem_types = [
SolverInterface.PROBLEM_LP,
SolverInterface.PROBLEM_LP,
SolverInterface.PROBLEM_QP,
"fake_problem_type",
]
model.OBJ = pyo.Objective(expr=2 * model.x[1] + 3 * model.x[2])
# list of solvers: one fake, one real
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] <= -1)
list_solvers = [fake_solver, good_solver]
return model
# solver settings
# *****************************************************************************
# *****************************************************************************
solver_timelimit = 30
def problem_milp_unbounded():
model = pyo.ConcreteModel("milp_unbounded")
solver_abs_mip_gap = 0
model.x = pyo.Var([1, 2], domain=pyo.NonNegativeReals)
solver_rel_mip_gap = 0.01
model.y = pyo.Var(domain=pyo.Binary)
solver_options = {
"time_limit": solver_timelimit,
"relative_mip_gap": solver_rel_mip_gap,
"absolute_mip_gap": solver_abs_mip_gap,
}
model.OBJ = pyo.Objective(
expr=2 * model.x[1] + 3 * model.x[2] + model.y, sense=pyo.maximize
)
# *********************************************************************
# *********************************************************************
model.Constraint1 = pyo.Constraint(expr=3 * model.x[1] + 4 * model.x[2] >= 1)
for solver_name in list_solvers:
for index, problem in enumerate(list_problems):
# optimise
return model
try:
# test problem-solver compatibility
# *****************************************************************************
# *****************************************************************************
problem_type = list_problem_types[index]
def problem_milp_feasible(number_binary_variables=25, seed_number=None):
if seed_number != None:
random.seed(seed_number)
if (
SolverInterface.problem_and_solver_are_compatible(
solver_name, problem_type
)
== False
):
continue
model = pyo.ConcreteModel("milp_feasible")
except SolverInterface.UnknownSolverError:
assert True
# a knapsack-type problem
except SolverInterface.UnknownProblemTypeError:
assert True
model.Y = pyo.RangeSet(number_binary_variables)
# test the solver interface
model.y = pyo.Var(model.Y, domain=pyo.Binary)
try:
# configure common solver interface
model.OBJ = pyo.Objective(
expr=sum(model.y[j] * random.random() for j in model.Y), sense=pyo.maximize
)
_ = SolverInterface(solver_name=solver_name, **solver_options)
model.Constraint1 = pyo.Constraint(
expr=sum(model.y[j] * random.random() for j in model.Y)
<= round(number_binary_variables / 5)
)
except SolverInterface.UnknownSolverError:
assert True
def rule_c1(m, i):
return (
sum(
model.y[j] * (random.random() - 0.5)
for j in model.Y
if j != i
if random.randint(0, 1)
)
<= round(number_binary_variables / 5) * model.y[i]
)
# **************************************************************************
# **************************************************************************
model.constr_c1 = pyo.Constraint(model.Y, rule=rule_c1)
return model
# ******************************************************************************
# ******************************************************************************
# *****************************************************************************
# *****************************************************************************