Skip to content

Commit

Permalink
Trac #20406: get_solver should allow passing a function (a solver fac…
Browse files Browse the repository at this point in the history
…tory) as the solver argument

For example, to use GLPK's exact simplex algorithm:

{{{
from sage.numerical.backends.generic_backend import get_solver
def glpk_exact_solver():
    b = get_solver(solver="GLPK")
    b.solver_parameter("simplex_or_intopt", "exact_simplex_only")
    return b

delsarte_bound_additive_hamming_space(19,15,7,solver=glpk_exact_solver)
}}}

URL: http://trac.sagemath.org/20406
Reported by: mkoeppe
Ticket author(s): Matthias Koeppe
Reviewer(s): Dima Pasechnik
  • Loading branch information
Release Manager authored and vbraun committed Apr 15, 2016
2 parents b36941a + 37e87a5 commit b2ebc97
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
31 changes: 30 additions & 1 deletion src/sage/numerical/backends/generic_backend.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,9 @@ cpdef GenericBackend get_solver(constraint_generation = False, solver = None, ba
or ``None``. If ``solver=None`` (default),
the default solver is used (see ``default_mip_solver`` method).
``solver`` can also be a callable, in which case it is called,
and its result is returned.
- ``base_ring`` -- If not ``None``, request a solver that works over this
(ordered) field. If ``base_ring`` is not a field, its fraction field
is used.
Expand Down Expand Up @@ -1432,6 +1435,26 @@ cpdef GenericBackend get_solver(constraint_generation = False, solver = None, ba
<...sage.numerical.backends.interactivelp_backend.InteractiveLPBackend...>
sage: p.base_ring()
Rational Field
Passing a callable as the 'solver'::
sage: from sage.numerical.backends.glpk_backend import GLPKBackend
sage: p = get_solver(GLPKBackend); p
<...sage.numerical.backends.glpk_backend.GLPKBackend...>
Passing a callable that customizes a backend::
sage: def glpk_exact_solver():
....: from sage.numerical.backends.generic_backend import get_solver
....: b = get_solver(solver="GLPK")
....: b.solver_parameter("simplex_or_intopt", "exact_simplex_only")
....: return b
sage: delsarte_bound_additive_hamming_space(11,3,4,solver=glpk_exact_solver) # long time
glp_exact...
...
OPTIMAL SOLUTION FOUND
8
"""
if solver is None:

Expand All @@ -1452,6 +1475,12 @@ cpdef GenericBackend get_solver(constraint_generation = False, solver = None, ba
if solver == "Coin" and constraint_generation:
solver = "Glpk"

elif callable(solver):
kwds = {}
if base_ring is not None:
kwds['base_ring']=base_ring
return solver(**kwds)

else:
solver = solver.capitalize()

Expand Down Expand Up @@ -1484,4 +1513,4 @@ cpdef GenericBackend get_solver(constraint_generation = False, solver = None, ba
return InteractiveLPBackend(base_ring=base_ring)

else:
raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'CVXOPT', 'Gurobi', 'PPL', 'InteractiveLP', or None (in which case the default one is used).")
raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'CVXOPT', 'Gurobi', 'PPL', 'InteractiveLP', None (in which case the default one is used), or a callable.")
18 changes: 14 additions & 4 deletions src/sage/numerical/mip.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ cdef class MixedIntegerLinearProgram(SageObject):
- If ``solver=None`` (default), the default solver is used (see
:func:`default_mip_solver`)
- ``solver`` can also be a callable,
see :func:`sage.numerical.backends.generic_backend.get_solver` for
examples.
- ``maximization``
- When set to ``True`` (default), the ``MixedIntegerLinearProgram``
Expand Down Expand Up @@ -358,8 +362,12 @@ cdef class MixedIntegerLinearProgram(SageObject):
- PPL (``solver="PPL"``). See the `PPL
<http://bugseng.com/products/ppl>`_ web site.
-If ``solver=None`` (default), the default solver is used (see
``default_mip_solver`` method.
- If ``solver=None`` (default), the default solver is used, see
:func:`default_mip_solver`.
- ``solver`` can also be a callable,
see :func:`sage.numerical.backends.generic_backend.get_solver` for
examples.
- ``maximization``
Expand Down Expand Up @@ -536,8 +544,11 @@ cdef class MixedIntegerLinearProgram(SageObject):
sage: q.number_of_constraints()
1
"""
def copying_solver(**kwdargs):
return (<GenericBackend> self._backend).copy()

cdef MixedIntegerLinearProgram p = \
MixedIntegerLinearProgram(solver="GLPK")
MixedIntegerLinearProgram(solver=copying_solver)
try:
p._variables = copy(self._variables)
except AttributeError:
Expand All @@ -554,7 +565,6 @@ cdef class MixedIntegerLinearProgram(SageObject):
except AttributeError:
pass

p._backend = (<GenericBackend> self._backend).copy()
return p

def __getitem__(self, v):
Expand Down

0 comments on commit b2ebc97

Please sign in to comment.