[ library(eplex) | Reference Manual | Alphabetic Index ]

eplex_solver_setup(+Objective, ?Cost, ++ListOfOptions, +TriggerModes)

EplexInstance:eplex_solver_setup(+Objective, ?Cost, ++ListOfOptions, +TriggerModes)

Setup an external solver state for eplex instance EplexInstance
Objective
Objective function: min(CostExpr) or max(CostExpr)
Cost
Variable bounded by the optimal solution
ListOfOptions
List of solver options
TriggerModes
List of conditions for re-triggering solver

Description

Setup a new external solver state for the eplex instance EplexInstance. The solver state will be associated with EplexInstance; EplexInstance must not already have a solver state associated with it. This predicate allow various options to be specified when setting up the solver state. ListOfOptions allows a list of solver options to be specified, and TriggerModes allows the solver state to be set up as a demon so that the external solver is automatically invoked when the conditions for re-triggering specified in TriggerModes are met. The external solver can also be invoked explicitly via eplex_solve/1.

Declaratively, this can be seen as a compound constraint representing all the individual linear constraints that have been set so far and are going to be set up later for EplexInstance. Operationally, when the external solver is invoked, the delayed constraints posted to EplexInstance are collected and taken into account.

CostExpr is a linear cost expression (or quadratic, if supported by the external solver).

The external solver's best objective bound will be exported as a bound for Cost: For a minimisation problem, each solution's best bound becomes a lower bound, for maximisation an upper bound on Cost. This technique allows for repeated re-solving with reduced bounds or added constraints. Note that Cost is not automatically made a problem variable (it can be a problem variable if there are constraints that involve it), and thus may not have bounds associated with in. In order for the bounds information not to be lost, some bounds should be given to Cost (e.g. making it a problem variable (but this might introduce unnecessary self-waking on bounds change), or via another solver with bounds (e.g. ic)).

ListOfOptions is the same as in the low-level primitive lp_demon_setup/5, except that EplexInstance is implicitly associated with the new external solver state, so the collect_from option of lp_demon_setup/5 is not allowed (it is set to collect_from(pool(EplexInstance)) by the predicate). See below for more details.

TriggerModes specifies under which conditions the external solver will be re-triggered. If no condition is specified, then the solver must be explicitly triggered, usually via eplex_solve/1. The conditions are the same as in the low-level primitive lp_demon_setup/5 called by this predicate. See below (after ListOfOptions descriptions) for more details.

Note: Some external solvers need to write temporary files when they are solving a problem. These are written to the temporary directory specified in ECLiPSe's tmp_dir setting (get_flag/2, set_flag/2).

ListOfOptions are (unless explicitly specified otherwise, each option should occur no more than once):

initial_solve(+YesNo)
Specifies if an initial solve (call to the external solver) should be performed immediately after problem setup. YesNo is one of the atoms yes or no, the default is yes if any trigger condition is specified in TriggerModes, no if no trigger condition is specified.

method(+Method)
Use the specified method (default, auto, primal, dual, net, barrier, sifting, concurrent, concurrent_det) (representing Primal Simplex, Dual Simplex, Network Simplex, Barrier, Sifting etc) to solve the problem. For MIP problems, this specifies the start algorithm (the one that is used to solve the initial relaxation). See the external solver's manual for a description of these methods.

For some of the methods, an additional `auxiliary' method may be specified in brackets. These are:

net(Simplex):
specifies the Simplex method (primal or dual) to follow the network optimisation. For LP problems only.

barrier(Crossover):
specifies how the crossover to a basic solution from the barrier solution is performed. Crossover can be primal, dual, or none. none means no crossover is performed.

sifting(SubMethod):
specifies the method for solving the sifting subproblem. SubMethod can be primal, dual, net, barrier.

For all the auxiliary methods, default can also be specified. This is equivalent to not specifying an auxiliary method at all.

Note that not every method is available on every external solver. The default method would use the solver's default method, or any selections done via solver-specific optimizer_param(_) settings.

node_method(+Method)
For MIP problems only. Use the specified method (default, primal, dual, net, barrier, sifting) to solve the subproblem at each node of the MIP search-tree, except the root node, which is specified by method option above. See method option for more description of the methods. Note that there are less choices in the specifications of the auxiliary methods that in the method option, due to limitations in the solvers. If a specified auxiliary method cannot be used, `default' will be used instead.

solution(+YesNo)
Make the solutions available each time the problem has been (re-)solved successfully. YesNo is one of the atoms yes or no, the default is yes.

dual_solution(+YesNo)
Make the dual solutions available each time the problem has been (re-)solved successfully. If the problem is a MIP, then depending on the external solver, this is either unavailable or are the values for the optimal LP node. YesNo is one of the atoms yes or no, the default is no.

slack(+YesNo)
Make the constraint slacks available each time the problem has been (re-)solved successfully. YesNo is one of the atoms yes or no, the default is no.

reduced_cost(+YesNo)
Make the reduced costs available each time the problem has been (re-)solved successfully. If the problem is a MIP, then depending on the external solver, this is either unavailable or are the values for the optimal LP node. YesNo is one of the atoms yes or no, the default is no.

keep_basis(+YesNo)
Store the basis each time the problem has been solved successfully, and use this basis as a starting point for re-solving next time. This option only affects performance. YesNo is one of the atoms yes or no, the default is no.

mipstart(+Option)
Use the previous solution values as a warm-start heuristics for the MIP search. This only has an effect for certain solvers (e.g. Gurobi), if there are integrality constraints, and if there is a previous solution available. Possible values are none (no mipstart values, the default), all (use previous solution for all variables), or integers (use previous solution for all variables that are now constrained to be integral).

cache_iis(YesNo)
Specify if an IIS should be computed immediately for an infeasible problem (if supported by the external solver), and store it so that it can bee retrieved by eplex_get_iis/4 or lp_get_iis/5 (called from within a user-defined infeasible handler). This will be done before the problem can be modified and make the computing of the IIS impossible. The IIS will only be available before the problem is solved again, and also before the infeasible solve is backtracked. This option has no effect if the external solver does not support the computation of an IIS. Note that if this option is set, eplex will always ask for an IIS to computed for an infeasible problem, even if it is immediately backtracked by the infeasible handler failing, and that the option is only needed if the problem instance in the external solver is modified before eplex_get_iis/4 or lp_get_iis/5 is called. YesNo is one of the atoms yes or no, the default is no.

demon_tolerance(RealTol, IntTol)
Specify how far outside a variable's range an lp-solution can fall before lp_demon_setup/5 re-triggers. RealTol and IntTol are floats and default to 0.00001 and 0.5 respectively.

sos1(VarList) - deprecated, use sos1/1 constraint
VarList is a list of variables which the solver should treat as variables of a type 1 special ordered set (SOS), i.e. at most one of the variables in the set can be non-zero. This can occur multiple times, for different sets of variables.

sos2(VarList) - deprecated, use sos2/1 constraint
VarList is a list of variables which the solver should treat as variables of a type 2 special ordered set (SOS), i.e. at most two of the variables in the set can be non-zero. This can occur multiple times, for different sets of variables.

presolve(+YesNo)
Specify if the external solver should perform presolve for this problem. With presolving, the external solver will transform the problem before solving it. This can lead to significantly faster times to find solutions. However, as the problem has been transformed, some external solvers have restriction on accessing or changing the problem state. In addition, if the solver is repeatedly called because the problem is frequently modified, then presolve may not be an advantage. YesNo is one of the atoms yes or no, the default is determined by the global setting of presolve, which can be changed via lp_set/2. The initial default is yes. Note that the presolve setting cannot be changed for a problem once it is set. If the external solver supports per-problem optimizer_params, their global defaults will be used for presolve(yes).

timeout(+TimeOut)
Set the external solver to time-out after TimeOut seconds. TimeOut is a positive number. The solver will abort (in either the abort or suboptimal state, depending on if a suboptimal solution was found) if the optimal solution was not found within the time limit. This should be used instead of setting the solver-specific parameter for time-out directly. In cases where the solver expects an integer for the time-out interval, the time given is rounded up to the next integer value. The timeout is set by setting the external solver's timeout settings, and the exact behaviour may be solver dependent.

suboptimal_handler(+Goal)
Specifies a user defined goal Goal to handle the case when the external solver returned a suboptimal solution (because the problem was aborted). Goal would be run in place of raising the default eplex_suboptimal event.

unbounded_handler(+Goal)
Specifies a user defined goal Goal to handle the case when the problem is unbounded. Goal would be run in place of raising the default eplex_unbounded event.

infeasible_handler(+Goal)
Specifies a user defined goal Goal to handle the case when the external solver found that the problem is infeasible. Goal would be run in place of raising the default eplex_infeasible event. Note that the default and logically correct behaviour is to fail, this handler is provided to allow the user to analyse the cause of the infeasibility. It is recommended that the handler should also fail after performing the analysis.

unknown_handler(+Goal)
Specifies a user defined goal Goal to handle the case when the external solver was not able to determine if the problem is unbounded or infeasible. Goal would be run in place of raising the default eplex_unknown event.

abort_handler(+Goal)
Specifies a user defined goal Goal to handle the case when the external solver aborted without finding any solution. Goal would be run in place of raising the default eplex_abort event.

use_var_names(+YesNo)
Specify if variable names (set using set_var_name/2 of the var_name library) should be passed to the external solver. If a particular variable does not have a name when it is first passed to the external solver, a default name determined by the solver would be used. Note that for XPRESS-MP, there is a limit on the length of the name, which can be changed between 8 and 64 in steps of 8 with the parameter mpsnamelength (XPRS_MPSNAMELENGTH). Variable names longer than this limit are truncated to the limit. YesNo is one of the atoms yes or no, the default is no.

priority(+Prio)
Prio is the scheduling priority with which the solver gets woken up. This priority determines whether the solver is run before or after other constraints. By default, if no priority is specified, the default priority (0, mapped to 5 unless changed) is used. Normally, the default priority should be sufficient and this option is not needed, unless there is a specific need to have the external solver invoked with higher or lower priority than some other constraints.

mip_use_copy(+YesNo)
Some external solvers do not allow a MIP problem to be modified once the MIP search has been started. Eplex works around this problem by making a copy of the problem and solving that, so that the original problem can still be modified. This can be turned off to avoid the overhead of making this copy, in which case the MIP problem cannot be modified. This option is used only when solving a MIP problem, and the external solver does not allow a MIP problem to be modified; otherwise it is ignored. YesNo is one of the atoms yes or no, the default is yes so that the problem can be modified.

write_before_solve(+Format,+File)
This option is most useful for debugging purposes. If given, Eplex will ask the external solver to dump the problem each time the problem is solved. This allows the problem in an eplex_probe/2 or lp_probe/3 to be dumped. As in lp_write/3, Format is the format of the dumped file and File is its name. Note that the problem is dumped each time the external solver is invoked if the problem has cutpool constraints, where there may be multiple invocations of the solver per solver call. The default without this option is that the problem would not be dumped.

post_equality_when_unified(+YesNo)
This option determines if an equality constraint between two variables will be posted to the solver when these variables are unified. Setting YesNo to no means that the constraint will not be posted. Note that this can lead to the solver's problem becoming inconsistent with ECLiPSe's. YesNo is one of the atoms yes or no, the default is yes.

sync_bounds(+YesNo)
This option determines if the bounds of the problems variables are synchronised with other solvers (i.e. the generic bounds are obtained with get_var_bounds/3 and then passed to the external solver) before the external solver is invoked. This was always done for previous non-standalone version of eplex. For standalone eplex, as the bounds are communicated directly to the external solver, the synchronisation of variable bounds is not needed unless the user is using eplex co-operatively with other solvers (e.g. ic). Even in such cases, it may be more efficient to communicate these bounds changes by explicitly programming it, especially if the problem has many variables and bounds changes happen only to a few of the variables. Setting YesNo to yes should increase compatibility with previous code (but note that previous eplex obtained the bounds from a specific bounds keeper like ic rather than the generic bounds). YesNo is one of the atoms yes or no, the default is no.

TriggerModes can be a list of the following specifiers:

inst
re-trigger if a problem variable gets instantiated.
ModuleName:Index
re-trigger when the suspension list given by ModuleName:Index is woken for any of the problem variables. The format for ModuleName:Index is the same as for specifying the suspension list in suspend/3,4.
deviating_inst
re-trigger if a problem variable gets instantiated to a value that differs from its lp-solution more than a tolerance.
bounds
re-trigger each time a variable bound for the solver instance changes.
deviating_bounds
re-trigger each time a variable's solver instance bound changes such that its lp-solution gets excluded more than a tolerance.
new_constraint
re-trigger each time a new (arithmetic or integral) constraint is added to the solver instance. Note that adding integral constraint on new problem variables, or adding bounds constraint, or adding constraints to the cutpool will *not* re-trigger.
trigger(Atom)
re-trigger each time the symbolic trigger Atom is pulled by invoking schedule_suspensions/1
pre(Goal)
an additional condition to be used together with other triggers. When the demon is triggered, it first executes PreGoal. Only if that succeeds, does the appropriate external solver get invoked. This provides a way of reducing the number of (possibly expensive) solver invocations when given preconditions are not met.
post(Goal)
this is not a trigger condition, but specifies a goal to be executed after solver success, but before the Cost variable gets constrained. It is intended as a hook for exporting solution information, e.g. copying solutions from the solver state into variable attributes (eg. tentative value), or computing weights for labelling heuristics from the solver state.
suspension(Susp)
this is not a trigger condition, but instead is used to access the demon used to trigger the solver. Susp is instantiated to the suspension that triggers the solver: by waking Susp, the solver is triggered. Susp is a demon in that it stays around after being woken. Accessing Susp allows the user to specify arbitrary conditions for triggering the solver.
The tolerances mentioned can be specified in lp_setup/4 or lp_set/3 as demon_tolerance.

If several trigger conditions are specified, then any of them will trigger the solver.

When a solver demon runs frequently on relatively small problems, it can be important for efficiency to switch off the presolve option to reduce overheads.

See Also

$= / 2, $=< / 2, $>= / 2, $:: / 2, integers / 1, reals / 1, eplex_solver_setup / 1, eplex_probe / 2, eplex_solve / 1, eplex_get / 2, eplex_var_get / 3, eplex_get_iis / 4, lp_demon_setup / 5, lp_setup / 4, optimize / 2, optimize / 3