Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

failing assert at MIPSolverCbc.cpp:1464 #72

Closed
svigerske opened this issue May 5, 2020 · 9 comments · Fixed by #78
Closed

failing assert at MIPSolverCbc.cpp:1464 #72

svigerske opened this issue May 5, 2020 · 9 comments · Fixed by #78
Assignees

Comments

@svigerske
Copy link
Member

svigerske commented May 5, 2020

When I run GAMS test library model miqcp01 with SHOT compiled without -DNDEBUG and use Cbc as MIP solver, this assert fails:

        osiInterface->setColBounds(varIndex, lowerBound, upperBound);
        assert(osiInterface->getColLower()[varIndex] == lowerBound);

gdb doesn't want to tell me osiInterface->getColLower()[varIndex] , but lowerBound is -1e50.

I usually don't build solver source without -DNDEBUG, so I don't really need a fix, but is that something to worry about or easy to fix? (or first question: can you reproduce?)

@andreaslundell
Copy link
Member

No, my version of SHOT with Cbc seems to solve this problem fine... Can you see the value of varIndex?

@svigerske
Copy link
Member Author

varIndex is 1.

osiInterface->getColLower()[varIndex] is -1.79769e+308, so that seems to be some mismatch about what is -infinity.

@andreaslundell
Copy link
Member

#76 should fix this as well I assume. Can you verify @svigerske?

@svigerske
Copy link
Member Author

No, I still get that one.

@andreaslundell
Copy link
Member

Hmm... Cannot still reproduce this, but the asserts are there for a reason, because I noticed there was some issues with Cbc not saving the variable limits.

Can you try to set Model.Variables.Continuous.MaximumUpperBound=1e+10 and Model.Variables.Continuous.MinimumLowerBound=-1e+10 and see if that helps. I believe the "infinity" value in Cbc is 1e+50, which is set here, but perhaps that has changed.

@svigerske
Copy link
Member Author

Yes, that makes the assert go away.
So that means that if SHOT sets the lower bound to -1e10, then Cbc accepts and keeps it, probably assuming that this really means -1e10 and is not just some proxy for -infinity.
But if one passes on -1e50, then Cbc turns this into a -1e308 (actually COIN_DBL_MAX = (std::numeric_limits< double >::max)()).

This is where Clp changes everything below -1e27 to -COIN_DBL_MAX:

https://github.com/coin-or/Clp/blob/134c3360ce71a54ed8ce9fdc68d3393f0897e383/Clp/src/ClpModel.cpp#L592-L604

There is this line in MIPSolverCbc.cpp, which may then use a wrong constant:

double MIPSolverCbc::getUnboundedVariableBoundValue() { return 1e50; }

If I change this to 1e27, things also work. I guess that's the same reason why setting the parameter to 1e10 worked - it's still a finite bound for Cbc. But I suspect that this means that when there is an unbounded variable in SHOT, then it will have a very large finite bound for the MIP solver?

@andreaslundell
Copy link
Member

Yes, the same is true for Gurobi and Cplex as well afaik: infinity is 1e+20. So perhaps I will change this into

double MIPSolverCbc::getUnboundedVariableBoundValue() { return 1e27; }

(or should it rather be 1e26 since there is strict inequality in the Clp code?).

@svigerske
Copy link
Member Author

1e26 or 1e27 doesn't really matter. For both values, the solver will assume that the variable has a finite bound. If you want Cbc to handle the variable as unbounded, then you need to set it to something above 1e27.

Setting it to COIN_DBL_MAX would help to avoid the assert for unbounded variables, but Cbc will then set any (finite) bound above 1e27 to COIN_DBL_MAX.

Setting it to nextafter(1e27, DBL_MAX) could make sense. But one would still need to adapt the assert to allow that if a Cbc bound is set to nextafter(1e27, DBL_MAX), then it will internally be changed to COIN_DBL_MAX.

@andreaslundell
Copy link
Member

When I'm thinking about it everything except the assert works well now. I am afraid that if I change the logic behind this things might break down (for example, with regards to the infeasibility repair, unbounded MIP iterations, etc.). I think I will disable the assert for now, close this issue and create a new issue to look into changing the Cbc max variable bound to 1e27.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants