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

Tobias Achterberg achterberg at zib.de
Fri Jul 24 20:47:42 MEST 2009


Hi Fergal,

copying the problem data from the LPI to SCIP is not that hard:

1. Use SCIPlpiGetNCols() to query the number of cols. Then do a loop and call
SCIPcreateVar() and SCIPaddVar() to add a SCIP variable for each column. Store the
VAR-Pointers in a local array indexed from 0 to ncols-1.

2. Use SCIPlpiGetNRows() to query the number of rows. Then call SCIPlpiGetRows() to query
the rows in the LPI and call SCIPcreateConsLinear() and SCIPaddCons() to add the
constraints to SCIP. Store the CONS-Pointers in a local array.

3. When freeing the SCIP object, first call SCIPfreeTransform(), then call
SCIPreleaseCons() for each constraint and SCIPreleaseVar() for each variable.


Tobias


fergal mohan wrote:
> Thanks again Tobias. I think by trying to hide the LP versus MIP details behind a common abstraction layer of the .NET Wrapper it's going to make the code more complicated but from the user's POV it will be more simple. It might make sense for me to CreateLPProb or CreateMIPProb upfront so I can determine if I'll be using the LPi routines and set up storage appropriately (I might even have two separate Solver sub classes). Warm Starts will definitely be used so I'm going to have to do the LPi management. Let me know if there is any code already out there that copies the whole problem into a SCIP object by querying your LPI as data storage. Many thanks again for the "big picture" thinking, cheers,
> Fergal
> 
> --- On Fri, 7/24/09, Tobias Achterberg <achterberg at zib.de> wrote:
> 
>> From: Tobias Achterberg <achterberg at zib.de>
>> Subject: Re: [Scip] Howto setup SCIP to solve LP change Matrix and resolve
>> To: "fergal mohan" <fergal at mohandigital.com>
>> Cc: scip at zib.de
>> Date: Friday, July 24, 2009, 9:13 AM
>> 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
>>
>>
> _______________________________________________
> Scip mailing list
> Scip at zib.de
> http://listserv.zib.de/mailman/listinfo/scip


More information about the Scip mailing list