[Scip] Howto setup SCIP to solve LP change Matrix and resolve

Tobias Achterberg achterberg at zib.de
Fri Jul 24 18:13:08 MEST 2009


fergal mohan wrote:
> Thanks Tobias for the helpful insights. Sounds like I need to resolve a few places where I'm using SCIPgetLPI in a manner that is unsupported. I suspect I'll need to check m_islp (SCIPgetNOrigIntVars(scip) + SCIPgetNOrigBinVars(scip) == 0) to prevent inappropriate calling of these routines or find an alternative means to get the information.
> SCIPlpiGetNNonz(p_Lpi, &nonZeros);

This is not so easy. Since SCIP does not know anything about the constraints it cannot
provide the number of non-zeros with a simple API call. What you can do is to either track
the number yourself or you can query the constraint array via SCIPgetNOrigConss() and
SCIPgetOrigConss(), then loop through this array and call for each constraint
SCIPgetNVarsLinear(), assuming that you only add linear constraints to your SCIP model.

Of course, such a loop is a costly operation and you may want to cache the result and
invalidate the cached value if the model is modified.


> SCIPlpiGetSides(p_Lpi, first, last, NULL, valueArray)

This has the same issues as for the number of nonzeros. Again you may need to loop through
all constraints and query SCIPgetRhsLinear() for each of them.


> SCIPlpiGetBounds(p_Lpi, first, last, boundsValueArray, NULL)

You can get the bounds by looping through the variables as returned by SCIPgetNOrigVars()
and SCIPgetOrigVars() and query SCIPvarGetLbOriginal() and SCIPvarGetUbOriginal().


> SCIPlpiGetSol(p_Lpi, NULL, primalColArray, dualRowArray, slacksRowArray, redCostColArray)

As I explained in the previous mail, this should be possible to call after having called
SCIPsolve() on an LP model and obtaining the LPI via SCIPgetLPI().



There is one additional aspect that you may have to consider: You have to note that since
SCIP is meant to be a CIP and MIP solver, it does not support warmstarts as a simplex
solver for LP. So, if you solve a CIP via SCIP (even if it is in fact an LP), then change
a bound of a variable, and solve it again, the simplex solver will start from scratch
instead of using the previous basis.

If this is a critical aspect of your interface, then you probably cannot use SCIP in this
way. In this case, you may have to use an alternate approach:

Build the model inside the LP solver (construct an LPI via SCIPlpiCreate() and populate it
via the LPI methods). Store the integrality information that the user provides in a
private array. Then, if the user calls solve() without having any integer variables, just
use the LPI methods to solve the model and to query the solution, in particular the dual
solution.

But if there are integer variables, copy the whole problem into a SCIP object (create
variables, and create linear constraints, querying your LPI as data storage). Then call
SCIPsolve(). Now, if the user queries the solution, use the SCIP solution query methods.
Whenever the user modifies the model, destroy the SCIP object and modify your LPI object.

Using this approach, you will get the full speed access to LP, but of course every MIP
solve involves the overhead of setting up the SCIP model again. But probably, this is not
as bad as solving a MIP is usually already pretty time consuming.



Tobias



More information about the Scip mailing list