Obtain best feasible solution with SCIP - scip

I am using SCIP (SoPlex) to solve a MIP (mixed integer program) provided by a .mps file. I use SCIP via command line as follows:
SCIP> read file.mps
original problem has 1049 variables (471 bin, 0 int, 0 impl, 578 cont) and 638 constraints
SCIP> optimize # so i am using default settings
... some solving information ...
SCIP Status : problem is solved [optimal solution found]
Solving Time (sec) : 0.46
Solving Nodes : 1
Primal Bound : -6.58117502066443e+05 (2 solutions)
Dual Bound : -6.58117502066443e+05
Gap : 0.00 %
[linear] c_2_141>: x_2_73_141[C] - 1000000000 y_2_141[B] <= 0;
violation: right hand side is violated by 236.775818639799
best solution is not feasible in original problem
I do not want to have an infeasible solution – a want the best feasible. For your information: I used CPLEX with the same file and it confirmed that there is an optimal feasible solution with slightly worse obj value (like 0.05 % worse).
I already tried to put emphasis on feasibility with SCIP> set emphasis feasibility but that did not help me – see for yourself:
SCIP Status : problem is solved [optimal solution found]
Solving Time (sec) : 0.42
Solving Nodes : 3 (total of 5 nodes in 3 runs)
Primal Bound : -6.58117502066443e+05 (4 solutions)
Dual Bound : -6.58117502066443e+05
Gap : 0.00 %
[linear] c_2_141>: x_2_73_141[C] - 1000000000 y_2_141[B] <= 0;
violation: right hand side is violated by 236.775818639799
best solution is not feasible in original problem
Kind regards.
EDIT:
In response to the answer of user mattmilten, I have to share that using set numerics feastol 1e-9 alone did not bring a feasible solution, but using a lower tolerance like 1e-10 in combination with set emphasis feasibility, SCIP is able to provide a good feasible solution that is just 0.005 % worse than CPLEX’.
Thanks for your help mattmilten!

You could try to tighten the tolerances, especially the feasibility tolerance:
set numerics feastol 1e-9
The violated constraint contains a very large coefficient. This is likely the cause for this high absolute error. In CPLEX you should also try
display solution quality
to check whether the solution found by CPLEX is also violating the bounds.

Related

Model is infeasible in Gurobi although it has a feasible solution

I am attempting to solve a non-convex quadratic optimization problem using Gurobi, but I have encountered an issue. Specifically, I have a specific objective function; however, I am only interested in finding a feasible solution. To do this, I tried two ways:
1- set my specific objective function as the model objective and set the parameter "SolutionLimit" to 1. This works fine, and Gurobi gives me a feasible solution.
2- give Gurobi no objective function (or set the objective to some arbitrary number like 0). In this case, Gurobi returns no feasible solution. The log it prints says:
Optimal solution found (tolerance 1.00e-04)
Warning: max constraint violation (1.5757e+01) exceeds tolerance
(model may be infeasible or unbounded - try turning presolve off)
Best objective -0.000000000000e+00, best bound -0.000000000000e+00, gap 0.0000%
I checked the solution it returned, and it is infeasible. I want the second method to work too. I have attempted to modify the solver parameters (such as "m.ModelSense = GRB.MAXIMIZE," "m.params.MIPFocus = 3," "m.params.NoRelHeurTime = 200," "m.params.DualReductions = 0," "m.params.Presolve = 2," and "m.params.Crossover = 0") in an effort to resolve this issue but have been unsuccessful. Are there any other parameters that I can adjust in order to successfully solve this problem?
This model has numerical issues; to understand more, please see Guidelines for Numerical Issues in the Gurobi Reference Manual.

Cannot understand the reason of the problem being infeasible

I have a simple linear programming problem written in OSiL format, which is carved out from a complicated non-linear problem that reported as infeasible by SCIP. This simple problem is the minimal lines to reproduce this infeasible problem, however it confuses me. Below is the content of the OSiL:
<instanceData>
<variables numberOfVariables="1">
<var name="F"/>
</variables>
<objectives numberOfObjectives="1">
<obj maxOrMin="min" numberOfObjCoef="1" >
<coef idx="0">1</coef>
</obj>
</objectives>
<constraints numberOfConstraints="1">
<con lb="10"/>
</constraints>
</instanceData>
Isn't the OSiL saying:
Minimize: F
Subject to: F >= 0
? Why should this problem be infeasible? Looks to me, the <con lb="10"/> is useless because no one is referencing it. But in fact this constraint does influence the original problem in a way that I failed to notice, because the problem can be solved if the lower bound is changed to 0 or smaller, or change it to upper bound.
Can someone explain this to me? I'm a newbie in numerical optimization and the OSiL format, so thanks in advance for your time.
There is no F in your constraint, you only added the variable to the objective.
The constraint that is formulated there is 10 <= 0, which is infeasible.
If you look at the problem in SCIP, this may become more apparent:
original problem has 1 variables (0 bin, 0 int, 0 impl, 1 cont) and 1 constraints
SCIP> disp prob
STATISTICS
Problem name : a.osil
Variables : 1 (0 binary, 0 integer, 0 implicit integer, 1 continuous)
Constraints : 0 initial, 1 maximal
OBJECTIVE
Sense : minimize
VARIABLES
[continuous] <F>: obj=1, original bounds=[0,+inf]
CONSTRAINTS
[linear] <cons0>: 0 >= 10;
END

Interpretation of GAP in CPLEX

This is a part of the engine-log output that I get from a small-scale mixed integer linear optimization problem that I solved in CPLEX 12.7.0
Nodes Cuts/
Node Left Objective IInf Best Integer Best Bound ItCnt Gap
0 0 280.0338 78 280.0338 72
0 0 428.8558 28 Cuts: 89 137
0 0 429.5221 34 Cuts: 2 142
0 0 429.7745 34 MIRcuts: 2 143
* 0+ 0 460.9166 429.7745 6.76%
0 2 429.7745 34 460.9166 429.8666 143 6.74%
Elapsed time = 0.49 sec. (31.07 ticks, tree = 0.01 MB, solutions = 1)
* 35 8 integral 0 438.1448 435.6381 211 0.57%
Cover cuts applied: 17
Implied bound cuts applied: 10
Flow cuts applied: 11
Mixed integer rounding cuts applied: 9
Gomory fractional cuts applied: 24
Root node processing (before b&c):
Real time = 0.45 sec. (31.09 ticks)
Sequential b&c:
Real time = 0.08 sec. (20.80 ticks)
------------
Total (root+branch&cut) = 0.53 sec. (51.89 ticks)
What I understand from this, is that the best integer solution (for the objective function) found has the value of 438.1448, whereas the relaxed solution (non integer values) has the value of 435.6381 as best bound solution.
( 438.1448 / 435.6381 ) - 1 = 0.57% GAP
Does this mean that the solution still has that small gap, however it is proven to be the optimal solution? I had the (maybe wrong) idea that optimality is proven by a 0% gap.
I'm not sure how to interpret it correctly. Thanks for your help in advance.
Your understanding of the best bound isn't 100% correct. You can think of the best bound as the best objective value an integer solution could potentially have, based on information the solver has discovered so far. In your case there might actually be a better solution than the one you found, but if there is, it won't have an objective value better than 435.6381.
A more technical definition of the best bound is the best relaxed-but-region-constrained solution for any region that has not yet been eliminated from the search space. Solvers like CPLEX search for an optimal solution by splitting the search space into sub-regions and then ruling out sub-regions that can't possibly contain the optimal integer-feasible solution. These sub-regions get split into sub-sub-regions, and so on. Within each region, the original problem is modified to force variables to fall within the region. The relaxed solution to this modified problem is the best bound for the region. The best of these region-specific best bounds is the best bound for the problem as a whole.
The best bound changes as regions are ruled out. If the best bound does not equal the best solution, then by definition, there is still at least one region other than the region holding the current incumbent that could potentially hold a better solution. Exploring one of these regions might uncover an even better solution than your current incumbent, or it might lead to the region being ruled out. You don't know which until the region is explored. Only when the best solution equals the best bound do you know for sure that there isn't a better solution hiding in a remaining region.
Yes you are right. The optimality is proven if the upper bound and the lower bound evaluate the same value, i.e. CPLEX could prove an optimality gap of 0%.
Since CPLEX stops with a solution that has a gap of 0.57%, I would assume that you configured an MIP-gap <1%. If you are interested in a solution with proven optimal, you should change the MIPGap parameter to zero. See also here.

Why could a SCIPcopy model be infeasible a when original model is feasible?

I'm new to SCIP, so I'm not sure if this is a bug or if I'm just doing something wrong.
I have a MIP instance that solves perfectly using SCIP, however when I try to solve a copy of the model SCIP says that it is infeasible. It seems to be more noticeable when presolve is turned off.
I'm using windows with the pre-built SCIP v3.2.0. The model only has binary and integer variables.
The following code outlines my attempt:
SCIP* _scip, subscip;
SCIPcreate(&_scip);
SCIPincludeDefaultPlugins(_scip);
SCIPcreateProbBasic(_scip, "interval_solver")); // create an empty problem
SCIPsetPresolving(_scip, SCIP_PARAMSETTING_OFF, true); //disable presolving
// build model (snipped)
SCIPsolve(_scip); // succeeds and gives feasible solution
SCIP_Bool valid = FALSE;
SCIPcreate(&subscip);
SCIPcopy(_scip, subscip, NULL, NULL, "1", TRUE, FALSE, TRUE, &valid);
SCIPsolve(subscip); // infeasible
Something that might be related (and seems weird to me) is that after solving the original problem (and getting a feasible solution), checking the solution reports an infeasible result. i.e.
SCIP_SOL* sol = SCIPgetBestSol(_scip);
SCIPcheckSol(_scip, sol, TRUE, TRUE, TRUE, TRUE, &valid);
gives:
solution value 1 violates bounds of <t_x71_(6,1275,6805)_(9,1275,6805)>[-0,0] by 1
Any ideas why this could be happening? Thanks!
Propagation in SCIP may take into account the best solution known so far and do reductions which are only valid for the problem of finding a solution better than this.
For example, if you have a minimization problem with n variables x_1,...,x_n with objective coefficients c_1,...,c_n >= 0 and already found a solution with x_1 = 1, x_2 = ... = x_n = 0, then propagation will globally fix x_1 to 0, because the objective of any solution with x_1 = 1 will be at least as large as the objective of the solution you already found.
This means that the solutions found so far may not be feasible anymore for the remaining problem (which looks for a strictly better solution).
In order to check the solution, you should check it in the original problem space, which you can do with SCIPcheckSolOrig().
Disabling presolving an propagation might help, but does not guarantee that the global presolved problem is not changed. Presolving in the LP solver should not be the problem, but might have changed the reported optimal LP solution (if there are multiple optima) and therefore caused a change in the solving process. This might have avoided your issue in this case, but probably by pure luck and the issue may still appear again on other instances. Moreover, the more features you disable, the more this will have a negative impact on your performance.
However, there is an easy solution to your problem: You can copy the original unchanged problem by using SCIPcopyOrig().
Some of the variable bounds were still being presolved. To fix the issue I needed to add:
SCIPsetBoolParam(_scip, "lp/presolving", FALSE);
This fixed most things, but the following also helped fix some 'check solution' issues:
SCIPsetIntParam(_scip, "propagating/maxrounds", 0);
SCIPsetIntParam(_scip, "propagating/maxroundsroot", 0);

SCIP unmodified LP-bound

I am using SCIP 3.0.2 with cplex 12.6 as LP-solver. My model requires Column generation. I already implemented it in CPLEX but since CPLEX can only do CG in the root node I am using SCIP to do Branch-and-Price.
In CPLEX it turned out to be beneficial to turn off heursitics, cuts and preprocessing/probing. I set the following in SCIP:
SCIP_CALL( SCIPsetBoolParam(scip, "lp/presolving", FALSE) );
SCIPsetSeparating(scip, SCIP_PARAMSETTING_OFF, true); //disable cuts
SCIPsetHeuristics(scip, SCIP_PARAMSETTING_OFF, true); //disable heuristics
SCIPsetPresolving(scip, SCIP_PARAMSETTING_OFF, true); //disable presolving
My parameter-file looks as follows:
display/primalbound/active = 1
presolving/maxrounds = 0
separating/maxrounds = 0
separating/maxroundsroot = 0
separating/maxcuts = 0
separating/maxcutsroot = 0
lp/initalgorithm = d
lp/resolvealgorithm = d
lp/fastmip = 1
lp/threads = 1
limits/time = 7200
limits/memory = 2900
limits/absgap = 0
#display/verblevel = 5
#display/freq = 10
To check that the models are the same I solved the CPLEX model in SCIP (without CG) and I obtained the same LP-bound as for the model generated with SCIP but different from the LP-bound when solving with CPLEX.
It seems that SCIP is still using some 'magic' I have not deactivated yet. So my question is what do I have to deactivate to obtain an LP-bound relying just on my model.
I already took a look at the statistics out-put and there are indeed some things that might help to solve the problem:
Constraints #EnfoLP lists 1 for integral (seems strange since cuts are disabled?)
The transformed problem seems to be ok. The statistics-output prints:
Presolved Problem :
Problem name : t_ARLP
Variables : 969 (806 binary, 0 integer, 0 implicit integer, 163 continuous)
Constraints : 9311 initial, 9311 maximal
and before the iterations start I get the following:
LP Solver : row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect
transformed problem has 897 variables (806 bin, 0 int, 0 impl, 91 cont) and 9311 constraints
9311 constraints of type < linear >
presolving:
presolving (0 rounds):
0 deleted vars, 0 deleted constraints, 0 added constraints, 0 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients
0 implications, 0 cliques
presolved problem has 897 variables (806 bin, 0 int, 0 impl, 91 cont) and 9311 constraints
9311 constraints of type < linear >
Presolving Time: 0.00
I added 72 columns: 91 original +72 added = 163 total. This seems to be ok.
I added the suggested parameters. It seems that domain propagation has not been in use before but there has been strong branching. Unfortunately nothing changed with the parameters.
In addition to adding the parameters I also tried to use SCIP 3.0.1 instead. This improved my bound from 670.194 to 699.203 but this is still quite different from the cplex bound with 754.348. I know that the solvers differ by a lot of numerical parameters but I guess the difference is too large to be caused by these parameters?
There are two further things that might affect the LP bound at the root node: domain propagation and strong branching.
Domain propagation is a sort of node preprocessing and tries to reduce variable domains based on the current local domains and constraints. Strong branching precomputes the LP bounds of potential child nodes to select a good variable to branch on. If one of the child nodes is detected to be infeasible, its domain is reduced.
You can disable domain propagation by setting
propagating/maxrounds = 0
propagating/maxroundsroot = 0
Strong branching can be disabled by setting a high priority to a branching rule which does not apply strong branching. For example, set
branching/pscost/priority = 100000000
in order to enable pure pseudo cost branching.
In general, you should check the statistics for non-zero values in the DomReds columns.
You can just write the internal problem to a file and then compare it to the original:
SCIP> write transproblem
You should also read SCIP's statistics thoroughly to find out what kind of 'magic' SCIP performed:
SCIP> display statistics
I almost forgot about the thread and then stumbled upon it again and thought it might be good to add the answer after finding it myself:
Within the cut callback (unfortunately I did not mention that I used one) I used the method:
SCIPisCutEfficacious
which discarded some of the cuts that are relevant to obtain a true LP bound. Not calling this method slows down the solution process but at least it preserves the result.