Skip to content

_performOptIRStable assertion fail on unbound instance #51

Description

@TendTo

While using soplex as an exact LP solver, I encountered an issue trying to solve a problem like the one shown below.
Based on my superficial analysis, it seems it has something to do with the routine _transformUnbounded, and in general the unboundness check, not playing along with _performOptIRStable's check.
Below I have provided an instance that on my machine exhibits the problematic behavior.
I tested it with

SoPlex version 9.0.0 [mode: debug] [precision: 8 byte] [rational: GMP 6.2.1] [PaPILO n/a] [GitHash: 37f6c488-dirty]

The interesting part is that, feeding back to soplex the output of soplex.writeFileRational and then using the file as an input with

soplex file.mps --loadset=settings/exact.set

produces the correct output, provided the solver is in mode: optimized. So I wonder whether the assertion is wrong and the underlying logic is sound.

// Example
#include <iostream>

#include "soplex.h"

using namespace soplex;

void test_rational() {
  SoPlex mysoplex;

  /* set parameters for exact solving */
  mysoplex.setIntParam(SoPlex::OBJSENSE, SoPlex::OBJSENSE_MINIMIZE);
  // Same result with both SIMPLIFIER_OFF and SIMPLIFIER_AUTO
  mysoplex.setIntParam(SoPlex::SIMPLIFIER, SoPlex::SIMPLIFIER_AUTO);
  // Same result with both ALGORITHM_PRIMAL and ALGORITHM_DUAL
  mysoplex.setIntParam(SoPlex::ALGORITHM, SoPlex::ALGORITHM_PRIMAL);
  mysoplex.setIntParam(SoPlex::READMODE, SoPlex::READMODE_RATIONAL);
  mysoplex.setIntParam(SoPlex::SYNCMODE, SoPlex::SYNCMODE_AUTO);
  // Using SOLVEMODE_REAL and CHECKMODE_REAL,
  // along with a non-zero FEASTOL and OPTTOL, does not manifest the issue
  mysoplex.setIntParam(SoPlex::SOLVEMODE, SoPlex::SOLVEMODE_RATIONAL);
  mysoplex.setIntParam(SoPlex::CHECKMODE, SoPlex::CHECKMODE_RATIONAL);
  mysoplex.setRealParam(SoPlex::FEASTOL, 0.0);
  mysoplex.setRealParam(SoPlex::OPTTOL, 0.0);

  /*
   * We first build the problem using sets of rows and cols
   * The goal is to define the problem.
   *
   * Minimize
   *   obj: -1 x0
   * Subject To
   *  C0 : 1 x1 - 1 x2 >= -1
   *  C1 : -1 x0 + 1 x1 - 1 x2 <= 1
   *  C2_1 : 1 x3 - 1 x4 >= -1
   *  C2_2 : 1 x3 - 1 x4 <= 1
   *  C3 : 1 x0 + 1 x5 >= 1
   * Bounds
   *   0 <= x0
   *   x1 = 1
   *   x2 = 1
   *   x3 = 1
   *   x4 = 1
   *   1 <= x5 <= 121
   * End
   *
   * When run externally, via
   *
   * soplex problem.lp --loadset=settings/exact.set
   *
   * SoPlex seems to produce the correct output, i.e., UNBOUNDED.
   */
  LPColSetRational cols(6);
  LPRowSetRational rows(4);

  cols.add({-1.0, DSVectorRational(), infinity, 0});
  cols.add({0.0, DSVectorRational(), 1, 1});
  cols.add({0.0, DSVectorRational(), 1, 1});
  cols.add({0.0, DSVectorRational(), 1, 1});
  cols.add({0.0, DSVectorRational(), 1, 1});
  cols.add({0.0, DSVectorRational(), 121, 1});

  {
    DSVectorRational vec(2);
    vec.add(1, 1);
    vec.add(2, -1);
    rows.add(-1, vec, infinity);
  }
  {
    DSVectorRational vec(3);
    vec.add(0, -1);
    vec.add(1, 1);
    vec.add(2, -1);
    rows.add(-infinity, vec, 1);
  }
  {
    DSVectorRational vec(2);
    vec.add(3, 1);
    vec.add(4, -1);
    rows.add(-1, vec, 1);
  }
  {
    DSVectorRational vec(2);
    vec.add(0, 1);
    vec.add(5, 1);
    rows.add(1, vec, infinity);
  }

  mysoplex.addColsRational(cols);
  mysoplex.addRowsRational(rows);

  // The optimiation fais on the assertion
  //
  // assert((lhsRational(r) == rhsRational(r)) == (_rowTypes[r] == RANGETYPE_FIXED));
  //
  // in src/soplex/solverational.hpp:2351
  auto res = mysoplex.optimize();
  std::cout << "Optimization result: " << res << std::endl;
}

int main() {
  test_rational();
  return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions