next up previous index
Next: External Solver Output and Up: EPLEX: The ECLiPSe/CPLEX Interface Previous: Interface for CLP-Integration   Index

Subsections

Low-Level Solver Interface

For many applications, the facilities presented so far should be appropriate for using Simplex/MIP through ECLiPSe. This section describes lower level operations like how to set up solvers manually and the primitives available to access and modify a solver's state.

Setting up Solvers Manually

This basic interface allows the user to deal with several independent solvers, to set them up, solve and re-solve, extract information about a solver's state and modify various parameters. Each such solver is referred to by a handle representing the solver's state.

lp_setup(+NormConstraints, +Objective, +ListOfOptions, -Handle)

Create a new solver state for the set of constraints NormConstraints (see below for how to obtain a set of normalised constraints). Apart from the explicitly listed constraints, the variable's ranges will be taken into account as the variable bounds for the simplex algorithm. Undeclared variables are implicitly declared as reals/1.

However, when variables have been declared integers (using ::/2 or integers/1), that is not taken into account by the solver by default. This means that the solver will only work on the relaxed problem (ie. ignoring the integrality constraints), unless specified otherwise in the options. Objective is either min(Expr) or max(Expr) where Expr is a linear expression. Options is a list of options (see below). A solver-handle is returned which is used to refer to the solver subsequently.

The solver Options are:

integers(all)
Advises the solver to take all integrality constraints into account, ie. to consider all variables integers that have been declared such. This option will instruct the external solver to use its own MIP solver (ie. branch-and-bound search happens within the external solver) instead of just the Simplex.

integers(+ListOfVars)
Consider the specified variables to be integers (whether or not they have been declared such). This option will instruct the external solver to use its own MIP solver (ie. branch-and-bound search happens within the external solver) instead of just the Simplex.

method(+Method)
Use the specified method (primal, dual, netprimal, netdual, barrier) to solve the problem. The default is primal. See th external solver's manual for a description of these methods.

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. 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. 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.

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

simplify(+YesNo)
Simplify the constraints before sending them to the external solver. The simplification consists of eliminating trivial constraints and turning simple constraints into bound updates. It is solver-dependent whether this step is needed or whether it is covered by the external solvers's preprocessing. YesNo is one of the atoms yes or no, the default is no.

space(+Rows,+Cols,+NonZeros)
This option is needed with solvers that require a-priory memory allocation (currently only XPRESS-MP). The arguments are integers specifying how many extra rows, columns and nonzero coefficients can be added to the solver after it has been set up.

lp_set(+Handle, +What, +Value)

This primitive can be used to change some of the initial options even after setup. Handle refers to an existing solver state, What can be one of the following:
method
Set the method that will be used to solve the problem. Value is one of primal, dual, netprimal, netdual, barrier.

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

reduced_cost
Make the reduced costs available each time the problem has been (re-)solved successfully. Value is one of the atoms yes or no.

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

dual_solution
Make the dual solutions available each time the problem has been (re-)solved successfully. Value is one of the atoms yes or no.

keep_basis
Store the basis each time the problem has been solved successfully, and use this basis as a starting point for re-solving next time. Value is one of the atoms yes or no.

demon_tolerance
Specify how far outside a variable's range an lp-solution can fall before lp_demon_setup/6 re-triggers. Value is a comma-separated pair (RealTol,IntTol) of floating-point values (default (0.00001,0.5)).

simplify
Simplify the constraints before sending them to the external solver. The simplification consists of eliminating trivial constraints and turning simple constraints into bound updates. It is solver-dependent whether this step is needed or whether it is covered by the external solvers's preprocessing. Value is one of the atoms yes or no.

Making solutions available means that they can be retrieved using lp_get/3 or lp_var_get/3 after the solver has been run successfully.

lp_add(+Handle, +NewNormConstraints, +NewIntegers)

Add new constraints (with possibly new variables) to a solver. The new constraints will be taken into account the next time the solver is run. The constraints will be removed on backtracking.

lp_cleanup(+Handle)

Destroy the specified solver, free all memory, etc. Note that ECLiPSewill normally do the cleanup automatically, for instance when execution fails across the solver setup, or when a solver handle gets garbage collected. However, calling lp_cleanup/1 explicitly does not hurt and may cause resources (memory and licence) to be freed earlier.

lp_read(+File, +Format, -Handle)

Read a problem from a file and setup a solver for it. Format is lp or mps. The result is a handle similar to the one obtained by lp_setup/4.

lp_write(+Handle, +Format, +File)

Write the specified solver's problem to a file. Format is lp or mps.

Running a Solver Explicitly

A solver needs to be triggered to actually solve the Linear Programming or Mixed Integer Programming problem that it represents. While solvers created by optimize/2 and lp_demon_setup/6 are triggered automatically, solvers that have been set up manually with lp_solve/2 need to be run explicitly.

lp_solve(+Handle, -Cost)

Apply the external solver's LP or MIP solver to the problem represented by Handle. Precisely which method is used depends on the options given to lp_setup/4. lp_solve/2 fails if there is no solution or succeeds if an optimal solution is found, returning the solution's cost in Cost (unlike with lp_demon_setup/6, Cost gets instantiated to a number). After a success, various solution and status information can be retrieved using lp_get/3,4.

If there was an error condition, or limits were exceeded, lp_solve/2 raises the error 'CPLEX_ABORT'. Even in that case, the external solver return status can be obtained using lp_get(Handle, status, ...).

When a solver is triggered repeatedly, each invocation will automatically take into account the current variable bounds. The set of constraints considered by the solver is the one given when the solver was created plus any new constraints that were added (lp_add/3) in the meantime.

lp_probe(+Handle, +Objective, -Cost)

Similar to lp_solve/2, but optimize for a different objective function rather than the one that was specified during solver setup.

Accessing Solutions and other Solver State

lp_get(+Handle, +What, -Value)

Retrieve information about solver state and results:
vars
Returns a term ''(X1,...,Xn) whose arity is the number of variables involved in the solver's constraint set, and whose arguments are these variables.

ints
Returns a list [Xi1,...,Xik] which is the subset of the problem variables that the solver considers to be integers.

constraints_norm
Returns a list of the problem constraints in normalised form. They may be simplified with respect to the original set that was passed to lp_setup/4.

constraints
Returns a list of the problem constraints in denormalised (readable) form. They may be simplified with respect to the original set that was passed to lp_setup/4.

objective
Returns a term min(E) or max(E), representing objective function and optimisation direction. E is a linear expression.

method
Returns the method (primal, dual, netprimal, netdual, barrier) that is used to solve the problem.

status
Status that was returned by the most recent invocation of the external solver.

cost
Cost of the current solution. Fails if no solution has been computed yet.

typed_solution
Returns a term ''(X1,...,Xn) whose arguments are the properly typed (integer or float) solution values for the corresponding problem variables (vars). The floating point solutions are the same as returned by solution, the integers are obtained by rounding the corresponding floating-point solution to the nearest integer. To instantiate the problem variables to their solutions, unify this term with the corresponding term containing the variables:
    instantiate_solution(Handle) :-
        lp_get(Handle, vars, Vars),
        lp_get(Handle, typed_solution, Values),
        Vars = Values.

slack
Returns a list of floating-point values representing the constraint slacks. The order corresponds to the list order in constraints. Fails if no solution has been computed yet.

dual_solution
Returns a list of floating-point values representing the dual solutions. The order corresponds to the list order in constraints. Fails if no solution has been computed yet.

demon_tolerance
Returns a comma-separated pair (RealTol,IntTol) of floating-point values which specify how far outside a variable's range an lp-solution can fall before lp_demon_setup/6 re-triggers. The tolerances differ for real (default 0.00001) and integer (default 0.5) variables.

simplex_iterations
Returns the external solver's count of simplex iterations.

node_count
Returns the external MIP solver's node count.

statistics
Returns a list of counter values [Successes, Failures, Aborts], indicating how often lp_solve/2 was invoked on the Handle, and how many invocations succeeded, failed and aborted respectively.

Note that reduced_cost, slack, dual_solution can only be retrieved when previously requested in the option list of lp_setup/4 or with lp_set/3.

Accessing Variable-Related Information

Variable-related information can be retrieved individually for every variable without referring to a solver handle:

lp_var_get(+Var, +What, -Value)

Retrieve information about solver state and results related to a particular variable or constraint. Fails if no solution has been computed yet. What can take one of the following values:
solution
Returns the floating-point solution for variable Var.

typed_solution
Returns the properly typed (integer or float) solution for variable Var. For continuous variables, this is the same floating-point value as returned by solution, for integers the value is obtained by rounding the corresponding floating-point solution to the nearest integer.

reduced_cost
Returns the reduced cost for variable Var.

Note that solution or reduced_cost can only be retrieved when previously requested in the option list of lp_setup/4 or with lp_set/3.


Collecting Linear Constraints

There are several ways to obtain a list of normalised constraints as input to lp_setup/4:

collect_lp_constraints_norm(-NormConstraints)

Collect all currently delayed linear constraints of the form X $= Y, X $>= Y or X $=< Y, and return them in normalised form. The corresponding delayed goals are removed (killed), but nonlinear constraints are ignored and remain delayed.

normalise_cstrs(+Constraints, -NormConstraints, -NonlinConstr)

where Constraints is a list of terms of the form X = Y, X >= Y or X =< Y (no dollar-signs!) where X and Y are arithmetic expressions. The linear constraints are returned in normalised form in NormConstraints, the nonlinear ones are returned unchanged in NonlinConstr.

Constraints from other solvers

For example, lib(fdplex) can extract the linear constraints from a set of finite-domain constraints.

Low-Level Interface Examples

Definition of optimize/2

The high-level predicate optimize/2 can be defined as:

optimize(OptExpr, ObjVal) :-
    collect_lp_constraints_norm(NormCstr),
    lp_setup(NormCstr, OptExpr, [integers(all)], Handle),
    lp_solve(Handle, ObjVal),
    lp_get(Handle, vars, VarVector),
    lp_get(Handle, typed_solution, SolutionVector),
    VarVector = SolutionVector,
    lp_cleanup(Handle).
First, all delayed goals of the form X $= Y, X $>= Y or X $=< Y are collected and normalised. Then a solver is set up, taking into account all integrality constraints. This solver is then invoked once, the solution vector obtained, and the variables instantiated to those solutions.

Access to Global Solver Parameters

The external Simplex solver has a number of global (i.e. not specific to a particular problem) parameters that affect the way it works. These can be queried and modified using the following predicates.

lp_get(optimizer, -Value)

Returns the name of the external optimizer, currently 'cplex' or 'xpress'.

lp_get(space, -Value)

This option only applies to solvers that require a-priory memory allocation (currently only XPRESS-MP). The value is a term of the form space(Rows,Cols,NonZeros) whose arguments are integers specifying how many extra rows, columns and nonzero coefficients can be added to a solver after it has been set up. The default is space(0,0,0). It can be changed globally using lp_set/2 or on a per-solver basis using the space-option in lp_setup/4.

lp_get(+ParamName, -Value)

Retrieve the value of a global parameter for the external solver. The Value is either a float or an integer number, depending on the parameter. Refer to the solver documentation for details. The names of the parameters are as follows:

timelimit, time_limit, perturbation_const, lowerobj_limit, upperobj_limit, feasibility_tol, markowitz_tol, optimality_tol, backtrack, treememory, lowercutoff, uppercutoff, absmipgap, mipgap, integrality, objdifference, relobjdifference, crash, dgradient, pricing, iisfind, netfind, perturbation_ind, pgradient, refactor, iteration_limit, singularity_limit, simplex_display, basisinterval, branch, cliques, covers, heuristic, nodeselect, order, sosscan, startalgorithm, subalgorithm, variableselect, solution_limit, node_limit, minsossize, mip_display, mip_interval, advance, aggregator, coeffreduce, dependency, presolve, scale, xxxstart, reducecostfix

lp_set(+ParamName, +Value)

Set a global parameter for the external solver. The parameters are as in lp_get/2.

lp_set(space, +Value)

This setting only applies to solvers that require a-priory memory allocation (currently only XPRESS-MP). The value is a term of the form space(+Rows,+Cols,+NonZeros) whose arguments are integers specifying how many extra rows, columns and nonzero coefficients can be added to a solver after it has been set up. The default is space(0,0,0). The setting can be overwritten using the space-option in lp_setup/4.

int_tolerance(-Value)

The same as lp_get(integrality, Value): The solver's idea of an integer value, i.e. numbers within this tolerance from an integer are considered integers.


next up previous index
Next: External Solver Output and Up: EPLEX: The ECLiPSe/CPLEX Interface Previous: Interface for CLP-Integration   Index

1999-08-06