93be33a6c2 Add complete predicate REVERT: 4f10c82056 Merge branch 'MiniZinc:master' into feature/on_restart REVERT: 0848ce7ec7 Add changelog for 2.5.5 REVERT: 44e2f770d5 Add test for insertion of ArrayLits into CSE REVERT: 8a68d3dea8 Don't insert par expressions into CSE map unless they're an ArrayLit REVERT: 6bf6f1180f Increase version number of development build REVERT: dcaac92a74 Make min/max on array of opt vars return non-optional var. This is consistent with other functions on optional arrays like sum, product, exists, forall. REVERT: 32aa288884 Update changelog REVERT: a4edf0669f Fix flattening of all-par set literals REVERT: 8c1c9605f6 Fix chain compressor, needs to ignore par constants REVERT: 0cad1c6306 Use file_path on include paths to ensure separator consistency REVERT: 05ad7d1931 Update changelog REVERT: 22f5e2557b Define HAVE_CONFIG_H only for UNIX REVERT: 81c7778d55 Define HAVE_CONFIG_H for CBC REVERT: 1f56608e10 mzn-test: don't check symmetry breaking constraints REVERT: 1a9767457e mzn-test: fix parsing %%%mzn-stat: ... output REVERT: a41533fd54 MIP: report CPU time in %%%mzn-stat: solveTime= REVERT: 9d490acd52 Updated docs on OR-Tools v8 installation REVERT: c513f6599f Add changelog for 2.5.4 REVERT: b2eef2772b Follow ids to declarations when flattening par arrays. Fixes #448. REVERT: c5c846d426 Check if result of flattening rhs of a vardecl is par. REVERT: c496052767 Escape strings when pretty printing include items REVERT: 9e379c995e Canonicalise file names before adding include items into "already seen" list REVERT: d5d5d0d88c Use generic flattening inside generators. Fixes #451. REVERT: dc8630a6e9 Small fix to multi-pass library change: use original include path if it is absolute REVERT: 79c6092bd8 Strip library paths from includes in multi-pass compilation. Fixes #455. REVERT: 897875d6d7 Compile infinite domains with holes into constraints. Fixes #457. REVERT: b4e700dc67 Don't create copies of global declarations when creating par versions of functions REVERT: 0e8cc42bb1 Fix typechecker to coerce bool to int in the objective. REVERT: e05523b344 Add test for dzn output of arrays REVERT: 1e0269000e Don't evaluate output_only arrays when generating dzn output. REVERT: 57018c31d6 Fix matrix transposition in lex2 globals REVERT: 2617c0c829 Fix output variables in lex_chain tests REVERT: ef1a250c98 another efort to fix tests REVERT: c00e199dfd Fix test globals_lex_chain.mzn REVERT: b5c997d045 Fix code analysis REVERT: 3352cf0bd5 SCIP constraint handler for lex_chain_..._orbitope REVERT: 4e71a2cc97 Globals lex_chain_..., including lex_chain_..._orbitope REVERT: d807428baf Move test specifcation into the correct folder REVERT: 5be74bc74d MIP decompositions for lex_less_(bool, int, float) REVERT: 36a554ba40 Don't modify infinte domain of optional variables. Fixes #456. REVERT: f9e5306d75 Run clang-format REVERT: 4b57667608 Fix comment reference to relevant test case REVERT: 648f2ab36d Fix equality of indirection annotations REVERT: ef7be5fd78 MIP decompositions for lex_lesseq_(bool=int, float) REVERT: 6511b14e73 Propagate cv flag correctly. REVERT: 6f27ecf1c0 Never insert par expressions into the CSE map. REVERT: 7414f3ca0f Fix cplex id in example configuration REVERT: 7ad7cec506 Update strictly_decreasing with documentation and opt version REVERT: 8029f6e957 Support undefined enums in type checker. REVERT: 79e0f0f546 Revert using mzn_in_symmetry_breaking_constraint() for SCIP's orbisack REVERT: e88efda76c Fix format REVERT: 4802031dc1 Added test mzn_in_symmetry_breaking_constraint() REVERT: e21cc2515a More format fixes 02 ... REVERT: 5bbd67c130 More format fixes... REVERT: d5f9b777ea Format fixes REVERT: 43757a09a0 Remove MIP-specific fzn_less(eq)_bool(_reif).mzn REVERT: c93b5736a3 SCIP: orbisack constraint handler 'fzn_lex_lesseq__orbisack' REVERT: 4516bb4e2c mzn-test.py: add OR-Tools as checker REVERT: e2176f017d Add fix and test for crash with empty enum. REVERT: ac7db35951 Fix documentation bugs. REVERT: 47ba245832 Fix the incorrect renaming of key in model output interface REVERT: 925796ed20 Fail on empty var domains in agenda REVERT: 1ec19d7025 Fix error messages in CMake FindGurobi, FindCPlex REVERT: 6d169475c1 mzn-test.py: Use -i for intermediate solutions REVERT: df2f3e423a Allow coercion of JSON lists to enum definitions REVERT: 2b0b8165e5 Fix clang-tidy errors REVERT: 6597bc1920 Change the CI build image location REVERT: 360c988452 Remove illegal duplicate keys in .gitlab-ci.yml REVERT: 6a5d69c64b Add missing par opt versions of coercion functions REVERT: 63014e3d8f Don't propagate annotations into annotation calls. Avoids infinite recursion. REVERT: 54b19428ab Don't use GRB_INT_PAR_NONCONVEX if it's undefined REVERT: a5bb56c47d Added piecewise_linear for non-continuous intervals git-subtree-dir: software/minizinc git-subtree-split: 93be33a6c254e54be7cd38abb7ebd6a6022f0c46
286 lines
15 KiB
ReStructuredText
286 lines
15 KiB
ReStructuredText
.. _ch-solvers:
|
|
|
|
Solving Technologies and Solver Backends
|
|
========================================
|
|
|
|
The ``minizinc`` tool can use various solver backends for a given model.
|
|
Some solvers are separate executables that are called by ``minizinc``;
|
|
other solvers are part of the ``minizinc`` binary (either hard-coded or loaded as a dynamic library or "plugin").
|
|
In the former case, a temporary FlatZinc file is created and passed to the solver binary;
|
|
in the latter one, the flattened model is passed to the backend directly in memory.
|
|
Some solvers are part of the binary MiniZinc distribution, others have to be installed separately.
|
|
You can find instructions for installing these solvers from source code and integrating into the ``minizinc`` tool
|
|
in :ref:`ch-installation_detailed`.
|
|
This chapter summarises usage options available for various target solvers.
|
|
|
|
The help text of ``minizinc`` shows a list of configured solver backends and their tags. You can see solver-specific command-line options by running
|
|
|
|
.. code-block:: bash
|
|
|
|
$ minizinc --help <solver-id or tag>
|
|
|
|
Constraint Programming Solvers
|
|
------------------------------
|
|
|
|
Constraint Programming is the 'native' paradigm of MiniZinc. Below we discuss most common CP solvers.
|
|
For their performance, consult MiniZinc Challenges (https://www.minizinc.org/challenge.html).
|
|
|
|
Gecode
|
|
~~~~~~
|
|
|
|
Gecode is an open-source constraint programming system (see https://www.gecode.org).
|
|
It supports many of MiniZinc's global constraints natively, and has support for integer, set and float variables.
|
|
|
|
Gecode supports a number of constraints and search annotations that are not part of the MiniZinc standard library.
|
|
You can get access to these by adding :mzn:`include "gecode.mzn";` to your model. The additional declarations are documented in :numref:`ch-lib-gecode`.
|
|
|
|
|
|
Chuffed
|
|
~~~~~~~
|
|
|
|
Chuffed is a constraint solver based on *lazy clause generation* (see https://github.com/chuffed/chuffed).
|
|
This type of solver adapts techniques from SAT solving, such as conflict clause learning,
|
|
watched literal propagation and activity-based search heuristics, and can often be much faster than traditional CP solvers.
|
|
|
|
In order to take full advantage of Chuffed's performance,
|
|
it is often useful to add a search annotation to the model (see :ref:`sec-search`),
|
|
but allow Chuffed to switch between this defined search and its activity-based search.
|
|
In order to enable this behaviour, use the ``-f`` (free search) command line option or
|
|
select *Free search* in the solver configuration pane of the MiniZinc IDE.
|
|
|
|
Chuffed supports a number of additional search annotations that are not part of the MiniZinc standard library.
|
|
The additional declarations are documented in :numref:`ch-lib-chuffed`.
|
|
|
|
OR-Tools
|
|
~~~~~~~~
|
|
|
|
OR-Tools is a powerful open-source CP/SAT/LP solver (see https://developers.google.com/optimization/).
|
|
It supports many of MiniZinc's global constraints natively. It often performs better multi-threaded (option ``-p``)
|
|
so it can employ various solving technologies. A search annotation (see :ref:`sec-search`) can be useful,
|
|
however allowing OR-Tools to mix the prescribed strategy with its own (option ``-f``) usually is best,
|
|
analogously to Chuffed.
|
|
|
|
|
|
Mixed-Integer Programming Solvers
|
|
---------------------------------
|
|
|
|
MiniZinc has built-in support for Mixed Integer Programing solvers.
|
|
If you have any MIP solver installed (and MiniZinc was compiled with its support),
|
|
you can run a model using MIP like this on the command line:
|
|
|
|
.. code-block:: bash
|
|
|
|
minizinc --solver mip -v -s -a model.mzn data.dzn
|
|
|
|
Of course, you can also select a particular solver, e.g. Gurobi (in case it is available):
|
|
|
|
.. code-block:: bash
|
|
|
|
minizinc --solver gurobi -v -s -a model.mzn data.dzn
|
|
|
|
MIP-Aware Modeling (But Mostly Useful for All Backends)
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Avoid mixing positive and negative coefficients in the objective. Use 'complementing' variables to revert sense.
|
|
|
|
Avoid nested expressions which are hard to linearize (decompose for MIP). For example, instead of
|
|
|
|
.. code-block:: minizinc
|
|
|
|
constraint forall(s in TASKS)(exists([whentask[s]=0] ++
|
|
[whentask[s]>= start[s]+(t*numslots) /\ whentask[s]<=stop[s]+(t*numslots) | t in 0..nummachines-1]));
|
|
|
|
prefer the tight domain constraint
|
|
|
|
.. code-block:: minizinc
|
|
|
|
constraint forall(s in TASKS)(whentask[s] in
|
|
{0} union array_union([ start[s]+(t*numslots) .. stop[s]+(t*numslots) | t in 0..nummachines-1]));
|
|
|
|
To avoid **numerical issues**, make variable domains as tight as possible (compiler can deduce bounds in certain cases but explicit bounding can be stronger).
|
|
Try to keep magnitude difference in each constraint below 1e4.
|
|
Especially for variables involved in logical constraints, if you cannot reduce the domains to be in +/-1e4,
|
|
consider indicator constraints (available for some solvers, see below), or use the following trick:
|
|
instead of saying :mzn:`b=1 -> x<=0` where x can become very big, use e.g. :mzn:`b=1 -> 0.001*x<=0.0`.
|
|
Especially for integer variables, the domain size of 1e4 should be an upper bound if possible -- what is the value of integrality otherwise?
|
|
Avoid large coefficients too, as well as large values in the objective function.
|
|
See more on tolerances in the Solver Options section.
|
|
|
|
Example 1: *basic big-M constraint vs implication*. Instead of :mzn:`<expr> <= 1000000*y` given :mzn:`var 0..1: y`
|
|
and where you use the 'big-M' value of 1000000 because you don't know a good upper bound on :mzn:`<expr>`, prefer :mzn:`y=0 -> <expr> <= 0`
|
|
so that MiniZinc computes a possibly tighter bound, and consider the above trick: :mzn:`y=0 -> 0.0001*<expr> <= 0.0` to reduce magnitudes.
|
|
|
|
Example 2: *cost-based choice*. Assume you want the model to make a certain decision, e.g., constructing a road, but then its cost should be minimal among some others, otherwise not considered. This can be modeled as follows:
|
|
|
|
.. code-block:: minizinc
|
|
|
|
var 0..1: c; %% Whether we construct the road
|
|
var int: cost_road = 286*c + 1000000*(1-c);
|
|
var int: cost_final = min( [ cost_road, cost1, cost2 ] );
|
|
|
|
Note the big coefficient in the definition of :mzn:`cost_road`. It can lead to numerical issues and a wrong answer: when the solver's integrality tolerance is 1e-6, it can assume :mzn:`c=0.999999` as equivalent to :mzn:`c=1` leading to :mzn:`cost_road=287` after rounding.
|
|
|
|
A better solution, given reasonable bounds on :mzn:`cost1` and :mzn:`cost2`, is to replace the definition as follows:
|
|
|
|
.. code-block:: minizinc
|
|
|
|
int: cost_others_ub = 1+2*ub_array( [cost1, cost2] ); %% Multiply by 2 for a stronger LP relaxation
|
|
var int: cost_road = 286*c + cost_others_ub*(1-c);
|
|
|
|
|
|
Useful Flattening Parameters
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The following parameters can be given on the command line or modified in ``share/minizinc/linear/options.mzn``:
|
|
|
|
::
|
|
|
|
-D nSECcuts=0/1/2 %% Subtour Elimination Constraints, see below
|
|
-D fMIPdomains=true/false %% The unified domains feature, see below
|
|
-D float_EPS=1e-6 %% Epsilon for floats' strict comparison,
|
|
%% used e.g. for the following cases:
|
|
%% x!=y, x<y, b -> x<y, b <-> x<=y
|
|
-DfIndConstr=true -DfMIPdomains=false %% Use solver's indicator constraints, see below
|
|
-DMinMaxGeneral=true %% Send min/max constraints to the solver (Gurobi only)
|
|
-DQuadrFloat=false -DQuadrInt=false %% Not forward float/integer multiplications for MIQCP backends, see below
|
|
-DCumulative=false %% Not forward cumulative with fixed durations/resources (SCIP only)
|
|
--no-half-reifications %% Turn off halfreification (full reification was until v2.2.3)
|
|
|
|
Some Solver Options and Changed Default Values
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The following command-line options affect the backend or invoke extra functionality. Note that some of them have default values which may be different from the backend's ones.
|
|
For example, tolerances have been tightened to enable more precise solving with integer variables and objective. This slightly deteriorates performance on average, so when your model has moderate constant and bound magnitudes, you may want to pass negative values to use solver's defaults.
|
|
|
|
::
|
|
|
|
-h <solver-tag> full description of the backend options
|
|
--relGap <n> relative gap |primal-dual|/<solver-dep> to stop. Default 1e-8, set <0 to use backend's default
|
|
--feasTol <n> primal feasibility tolerance (Gurobi). Default 1e-8
|
|
--intTol <n> integrality tolerance for a variable. Default 1e-8
|
|
--solver-time-limit-feas <n>, --solver-tlf <n>
|
|
stop after <n> milliseconds after the first feasible solution (some backends)
|
|
--writeModel <file>
|
|
write model to <file> (.lp, .mps, .sav, ...). All solvers support the MPS format
|
|
which is industry standard. Most support the LP format. Some solvers have own formats,
|
|
for example, the CIP format of SCIP ("constraint integer programming").
|
|
--readParam <file>
|
|
read backend-specific parameters from file (some backends)
|
|
--writeParam <file>
|
|
write backend-specific parameters to file (some backends)
|
|
--readConcurrentParam <file>
|
|
each of these commands specifies a parameter file of one concurrent solve (Gurobi only)
|
|
--keep-paths this standard flattening option annotates every item in FlatZinc by its "flattening history".
|
|
For MIP solvers, it additionally assigns each constraint's name as the first 255 symbols of that.
|
|
--cbcArgs '-guess -cuts off -preprocess off -passc 1'
|
|
parameters for the COIN-OR CBC backend
|
|
|
|
All MIP solvers directly support multi-threading (option ``-p``). For COIN-BC to use it, it needs to be
|
|
configured with ``--enable-cbc-parallel``.
|
|
|
|
Subtour Elimination Constraints
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Optionally use the SEC cuts for the circuit global constraint.
|
|
Currently only Gurobi, IBM ILOG CPLEX, and COIN-OR CBC (trunk as of Nov 2019).
|
|
If compiling from source, this needs boost and cmake flag ``-DCOMPILE_BOOST_MINCUT=ON``
|
|
(or ``#define`` it in ``lib/algorithms/min_cut.cpp``).
|
|
Compile your model with the flag ``-DnSECcuts=<n>`` with the following possible ``<n>``:
|
|
0,1: use MTZ formulation; 1,2: pass on circuit constraints
|
|
to the SEC cut generator, so 1 would use both.
|
|
|
|
Unified Domains (MIPdomains)
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The 'MIPdomains' feature of the Flattener aims at reducing the number of binary flags
|
|
encoding linearized domain constraints, see the paper
|
|
*Belov, Stuckey, Tack, Wallace. Improved Linearization of Constraint Programming Models. CP 2016.*
|
|
|
|
By default it is on.
|
|
To turn it off which might be good for some models, add option ``-D fMIPdomains=false`` during flattening.
|
|
Some parameters of the unification are available, run with ``--help``.
|
|
|
|
Indicator Constraints
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Some solvers (IBM ILOG CPLEX, Gurobi, SCIP) have indicator constrains with greater numerical stability than big-M decomposition.
|
|
Moreover, they can be applied to decompose logical constraints on *unbounded variables*. However, for reified comparisons with
|
|
reasonable big-M bounds they perform worse because solvers don't include them in the LP relaxation.
|
|
Add command-line parameters ``-D fIndConstr=true -D fMIPdomains=false`` when flattening
|
|
to use them.
|
|
|
|
Quadratic Constraints and Objectives (MIQCP)
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Gurobi 9.0 and SCIP support MIQCP (invoking non-convex global optimizer because MiniZinc translates multiplication to
|
|
equality with an intermediate variable: whenever the model uses an expression x*y it is converted to z with z==x*y which is non-convex).
|
|
While this is mostly advantageous for integer multiplication (which is linearly decomposed for other solvers), for float variables
|
|
this is the only way to go. To switch off forwarding float/integer multiplications to the backend, run compiler with either or both of
|
|
``-DQuadrFloat=false -DQuadrInt=false``.
|
|
|
|
Pools of User Cuts and Lazy Constraints
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
Some constraints in the model can be declared as user and/or lazy cuts and they will be added to the corresponding pools
|
|
for the solvers supporting them. For that, apply annotations :mzn:`::MIP_cut` and/or :mzn:`::MIP_lazy` after a constraint.
|
|
For Gurobi and IBM ILOG CPLEX, see ``share/minizinc/linear/options.mzn`` for their exact meaning.
|
|
|
|
Warm Starts
|
|
~~~~~~~~~~~
|
|
|
|
For general information of warm start annotations, see :ref:`sec_warm_starts`.
|
|
Warm starts are currently implemented for Gurobi, IBM ILOG CPLEX, XPRESS, and COIN-OR CBC.
|
|
|
|
.. _ch-solvers-nonlinear:
|
|
|
|
Non-Linear Solvers via NL File Format
|
|
-------------------------------------
|
|
|
|
MiniZinc has experimental support for non-linear solvers that conform to the AMPL NL standard. There are a number of open-source solvers, such as Ipopt, Bonmin and Couenne, that can be interfaced to MiniZinc in this way.
|
|
|
|
You can download binaries of these solvers from AMPL (https://ampl.com/products/solvers/open-source/). In order to use them with MiniZinc, you need to create a solver configuration file. Future version of MiniZinc will make this easier, but for now you can follow these steps:
|
|
|
|
1. Download the solver binary. For this example, we assume you chose the Couenne solver, which supports non-linear, non-convex, mixed discrete and continuous problems.
|
|
2. Create a solver configuration file called ``couenne.msc`` in the ``share/minizinc/solvers`` directory of your MiniZinc installation, with the following contents:
|
|
|
|
.. code-block:: json
|
|
|
|
{
|
|
"id" : "org.coin-or.couenne",
|
|
"name" : "Couenne",
|
|
"executable" : "/Users/tack/Downloads/couenne-osx/couenne",
|
|
"version": "0.5.6",
|
|
"supportsFzn":false,
|
|
"supportsNL":true
|
|
}
|
|
|
|
You can adapt the ``version`` field if you downloaded a different version (it's only used for displaying).
|
|
|
|
3. Run ``minizinc --solvers``. The Couenne solver should appear in the list of solvers now.
|
|
4. Run ``minizinc --solver couenne model.mzn`` on some MiniZinc model, or use Couenne from the MiniZinc IDE.
|
|
|
|
The AMPL NL support is currently experimental, and your MiniZinc model is translated to NL without regard
|
|
for the capabilities of the target solver. For example, Ipopt only supports continuous variables, so translating
|
|
a model with integer variables will result in a solver-level error message. There is currently no support for
|
|
translating Boolean variables and constraints into 0/1 integer variables (as required by e.g. Couenne).
|
|
You can experiment with the standard linearisation library, using the ``-Glinear [-DQuadrFloat=true -DQuadrInt=true]``
|
|
flag. However, this will either
|
|
linearise all integer constraints, even the ones that solvers like Couenne may support natively, or use non-convex
|
|
representation. We will ship dedicated solver libraries for some NL solvers with future versions of MiniZinc.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|