Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit 7b7aa5e

Browse files
author
Matthias Koeppe
committed
to_linear_program: Select solver according to base_ring, which can be overriden by keyword argument
1 parent 4b42d4a commit 7b7aa5e

File tree

1 file changed

+55
-15
lines changed
  • src/sage/geometry/polyhedron

1 file changed

+55
-15
lines changed

src/sage/geometry/polyhedron/base.py

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,20 +1032,25 @@ def n_lines(self):
10321032
"""
10331033
return len(self.lines())
10341034

1035-
def to_linear_program(self, solver=None, return_variable=False):
1035+
def to_linear_program(self, solver=None, return_variable=False, base_ring=None):
10361036
r"""
1037-
Return the polyhedron as a :class:`MixedIntegerLinearProgram`.
1037+
Return a linear optimization problem over the polyhedron in the form of
1038+
a :class:`MixedIntegerLinearProgram`.
10381039
10391040
INPUT:
10401041
1041-
- ``solver`` -- select a solver (data structure). See the documentation
1042+
- ``solver`` -- select a solver (MIP backend). See the documentation
10421043
of for :class:`MixedIntegerLinearProgram`. Set to ``None`` by default.
10431044
10441045
- ``return_variable`` -- (default: ``False``) If ``True``, return a tuple
10451046
``(p, x)``, where ``p`` is the :class:`MixedIntegerLinearProgram` object
10461047
and ``x`` is the vector-valued MIP variable in this problem, indexed
10471048
from 0. If ``False``, only return ``p``.
10481049
1050+
- ``base_ring`` -- select a field over which the linear program should be
1051+
set up. Use ``RDF`` to request a fast inexact (floating point) solver
1052+
even if ``self`` is exact.
1053+
10491054
Note that the :class:`MixedIntegerLinearProgram` object will have the
10501055
null function as an objective to be maximized.
10511056
@@ -1055,17 +1060,56 @@ def to_linear_program(self, solver=None, return_variable=False):
10551060
polyhedron associated with a :class:`MixedIntegerLinearProgram`
10561061
object.
10571062
1058-
EXAMPLE::
1063+
EXAMPLES:
1064+
1065+
Exact rational linear program::
10591066
10601067
sage: p = polytopes.cube()
10611068
sage: p.to_linear_program()
10621069
Mixed Integer Program ( maximization, 3 variables, 6 constraints )
10631070
sage: lp, x = p.to_linear_program(return_variable=True)
10641071
sage: lp.set_objective(2*x[0] + 1*x[1] + 39*x[2])
10651072
sage: lp.solve()
1066-
42.0
1073+
42
10671074
sage: lp.get_values(x[0], x[1], x[2])
1068-
[1.0, 1.0, 1.0]
1075+
[1, 1, 1]
1076+
1077+
Floating-point linear program::
1078+
1079+
sage: lp, x = p.to_linear_program(return_variable=True, base_ring=RDF)
1080+
sage: lp.set_objective(2*x[0] + 1*x[1] + 39*x[2])
1081+
sage: lp.solve()
1082+
42.0
1083+
1084+
Irrational algebraic linear program over an embedded number field::
1085+
1086+
sage: p=polytopes.icosahedron()
1087+
sage: lp, x = p.to_linear_program(return_variable=True)
1088+
sage: lp.set_objective(x[0] + x[1] + x[2])
1089+
sage: lp.solve()
1090+
1/4*sqrt5 + 3/4
1091+
1092+
Same example with floating point::
1093+
1094+
sage: lp, x = p.to_linear_program(return_variable=True, base_ring=RDF)
1095+
sage: lp.set_objective(x[0] + x[1] + x[2])
1096+
sage: lp.solve() # tol 1e-5
1097+
1.3090169943749475
1098+
1099+
Same example with a specific floating point solver::
1100+
1101+
sage: lp, x = p.to_linear_program(return_variable=True, solver='GLPK')
1102+
sage: lp.set_objective(x[0] + x[1] + x[2])
1103+
sage: lp.solve() # tol 1e-8
1104+
1.3090169943749475
1105+
1106+
Irrational algebraic linear program over `AA`::
1107+
1108+
sage: p=polytopes.icosahedron(base_ring=AA)
1109+
sage: lp, x = p.to_linear_program(return_variable=True)
1110+
sage: lp.set_objective(x[0] + x[1] + x[2])
1111+
sage: lp.solve()
1112+
1.309016994374948?
10691113
10701114
TESTS::
10711115
@@ -1077,17 +1121,13 @@ def to_linear_program(self, solver=None, return_variable=False):
10771121
sage: p.to_linear_program(solver='PPL')
10781122
Traceback (most recent call last):
10791123
...
1080-
NotImplementedError: Cannot use PPL on exact irrational data.
1124+
TypeError: The PPL backend only supports rational data.
10811125
"""
1082-
from sage.rings.rational_field import QQ
1083-
R = self.base_ring()
1084-
if (solver is not None and
1085-
solver.lower() == 'ppl' and
1086-
R.is_exact() and (not R == QQ)):
1087-
raise NotImplementedError('Cannot use PPL on exact irrational data.')
1088-
1126+
if base_ring is None:
1127+
base_ring = self.base_ring()
1128+
base_ring = base_ring.fraction_field()
10891129
from sage.numerical.mip import MixedIntegerLinearProgram
1090-
p = MixedIntegerLinearProgram(solver=solver)
1130+
p = MixedIntegerLinearProgram(solver=solver, base_ring=base_ring)
10911131
x = p.new_variable(real=True, nonnegative=False)
10921132

10931133
for ineqn in self.inequalities_list():

0 commit comments

Comments
 (0)