scipopt / soplex

Sequential object-oriented simPlex
Other
59 stars 18 forks source link

Assertion `lp.isScaled()' failed when triying to solve different LP with the same solver instance #17

Open aabbas-brook opened 1 year ago

aabbas-brook commented 1 year ago

Hi ! First of all, thank you for the work you have done here with SoPlex

I am using SoPlex in a project. It worked on thousands problems quiet well, but when I try to solve the system bellow, programm crashes.

Minimize obj: 1.0000000000000000e+00 x5 Subject To C0 : 1.9662500000000001e+01 x0 + 1.8271399999999999e-01 x1 + 2.3599500000000001e-01 x2 = 0.0000000000000000e+00 C1 : 5.0552100000000000e-01 x0 + 4.2908400000000002e-01 x1 - 2.0153399999999999e-01 x2 + 8.0298099999999994e-01 x3 + 5.8319600000000005e-01 x4

Here is the log :

Simplifier removed 0 rows, 2 columns, 2 nonzeros, 0 col bounds, 0 row bounds
Reduced LP has 2 rows 4 columns 7 nonzeros
Equilibrium scaling LP
  L  |    0.0 |       0 |     1 | 0.00e+00 | 2.01e+01 |        1 | -1.00000000e+00
  L  |    0.0 |       1 |     2 | 0.00e+00 | 0.00e+00 |        0 | -1.00000000e+00
 --- unscaling internal solution
 --- unsimplifying solution and basis
 --- unscaling external solution
_tests: /usr/local/include/soplex/spxscaler.hpp:645: void soplex::SPxScaler<R>::unscalePrimal(const soplex::SPxLPBase<R>&, soplex::VectorBase<S>&) const [with R = double]: Assertion `lp.isScaled()' failed.

Am I doing something wrong ?

matbesancon commented 1 year ago

Hi @aabbas-brook, thanks for reporting this issue, we will look into it

aabbas-brook commented 1 year ago

Hi ! I made some tests on my side.

On my program, LP systems are automatically generated in a loop and I use the same solver, that I reset each time, to resolve these LPs systems using:

resetSettings();
clearLPReal();

To check if the problem come from here, I created a test and tried to solve exposed system above, setting manually the parameters. It seems to work. My apologies, problem seems to not come from the solver, but by the way I reset the parameters. I am going to dig this now.

aabbas-brook commented 1 year ago

Hi,

As expected, problem come from the fact of reusing the same solver for solving different problems.

Here is a snippet which illustrates this fact. In the code below:

mysoplex->clearBasis();
mysoplex->clearLPReal();

Is there something that I misunderstood or doing wrong ?

-- code snippet

TEST(testSoplex, reseting)
{

    using namespace soplex;

    //POSITION (1) BEFORE LOOP
    //auto mysoplex = std::make_shared<SoPlex>();
    //mysoplex->setIntParam(SoPlex::OBJSENSE, SoPlex::OBJSENSE_MINIMIZE);
    //mysoplex->setIntParam(SoPlex::VERBOSITY, SoPlex::VERBOSITY_ERROR); 
    //mysoplex->setIntParam(SoPlex::ALGORITHM, SoPlex::ALGORITHM_PRIMAL);

    for (size_t k = 0; k < 200; k++)
    {
        for (size_t i = 0; i < 6; i++)
        {
                auto mysoplex = std::make_shared<SoPlex>();
                mysoplex->setIntParam(SoPlex::OBJSENSE, SoPlex::OBJSENSE_MINIMIZE);
                mysoplex->setIntParam(SoPlex::VERBOSITY, SoPlex::VERBOSITY_ERROR); 
                mysoplex->setIntParam(SoPlex::ALGORITHM, SoPlex::ALGORITHM_PRIMAL);            

            for (size_t j = 0; j < 6; j++)
            {                
                int a = 0;
                if (i == j)
                {
                    a = 1;
                }
                DSVector dummycol(0);
                mysoplex->addColReal(LPCol(a, dummycol, 1, -1));
            }

            /* then constraints one by one */
            DSVector row1(6);
            row1.add(0, 1.96625000e+01);
            row1.add(1, 1.82714000e-01);
            row1.add(2, 2.35995000e-01);
            row1.add(3, 0.0);
            row1.add(4, 0.0);
            row1.add(5, 0.0);

            DSVector row2(6);
            row2.add(0, 5.05521000e-01);
            row2.add(1, 4.29084000e-01);
            row2.add(2, -2.01534000e-01);
            row2.add(3, 8.02981000e-01);
            row2.add(4, 5.83196000e-01);
            row2.add(5, -3.43204000e-01);

            mysoplex->addRowReal(LPRow(0, row1, 0));
            mysoplex->addRowReal(LPRow(2.96227000e-01, row2, 2.96227000e-01));

            SPxSolver::Status stat;
            DVector prim(6);
            stat = mysoplex->optimize();

            /* get solution */
            if (stat == SPxSolver::OPTIMAL)
            {
                mysoplex->getPrimal(prim);
            }
            else
            {
                BOOST_LOG_TRIVIAL(trace) << "Error: SoPlex returned with status " << stat << ".\n";
            }
            //RESET THE SOLVER PARAMETERS
            //mysoplex->clearBasis();
            //mysoplex->clearLPReal();
        }
    }
}