Callback Setsolution from a MIP solution node
OngoingI am solving a two stage stochastic program (in the extensive or the "deterministic" form) with integer variables in both the stages. I observe that Gurobi's heuristics find good first-stage solutions fast, but the second stage solutions are suboptimal.
But given the first-stage solution, it is easy to solve a second-stage problem. So, I would like to do the following:
Whenever gurobi finds a feasible solution, (GRB.Callback.MIPSOL), I would like to retrieve the first-stage solutions (by using Model.cbGetSolution), and solve the 100 much smaller second-stage MIPs, and feed the solution of the second stage to gurobi (using Model.cbSetSolution and cbUseSolution). I believe this could considerably improve the objective value of the current solution.
My problem is that Model.cbGetSolution is allowed only if where==GRB.Callback.MIPSOL while Model.cbSetSolution is allowed only if where == GRB.Callback.MIPNODE.
Is there a work-around for this problem? I am using the Python API.
-
I am facing the same issue.
Is there any solution for that?
1 -
Hello, I am facing the same question, the only thing I could find cb.GetNodeRel() can be used to retrieve the variables of the relaxation but I am unsure if it actually works for you, would be helpful if someone could share how can this be solved
0 -
In the next major or minor Gurobi release, you will be able to set solutions from the \( \texttt{MIPSOL} \) callback. In the meantime, a workaround is to store the solution, then pass it to Gurobi in the next \( \texttt{MIPNODE} \) callback.
1 -
How can you have two callbacks in one function? to my understanding once you set the first \( \texttt{if} \) block, that's the only one it gets to run:
def mycallback(model, where):
if where == GRB.Callback.MIPSOL:
v = model.cbGetSolution(model._vars)
vs = model._vars
vi = v/(v+3)
elif where == GRB.Callback.MIPNODE:
model.cbLazy(lhs,sense,rhs)
model.cbSetSolution(vs,vi)
model.optimize(mycallback)0 -
Your callback can definitely handle multiple `where` values with if statements.
0 -
You can generate and store the solution when \( \texttt{mycallback} \) is called with \( \texttt{where=MIPSOL} \), then set the solution the next time \( \texttt{mycallback} \) is called with \( \texttt{where=MIPNODE} \). So the solution is generated and set in two different calls to \( \texttt{mycallback} \). E.g.:
def mycallback(model, where):
if where == GRB.Callback.MIPSOL:
vals = model.cbGetSolution(model._vars)
model._vals = [v / (v + 3) for v in vals]
elif where == GRB.Callback.MIPNODE and model._vals is not None:
model.cbSetSolution(model._vars, model._vals)
model._vals = None
model._vars = model.getVars()
model._vals = None
model.optimize(mycallback)1 -
Thanks a lot! I am trying to implement this in the model I am working on, when I tried to use \( \texttt{where=MIPNODE} \) nothing seemed to happen, then I checked for the condition to see if it's being read, if the statement is true then the block inside that \(\texttt{elif}\) will be executed
print(str(where==GRB.Callback.MIPNODE))
However, the result I get back is
False
So,
model.cbSetSolution(vars, solution)
won't get executed, my question is, what could make the \(\texttt{GRB.Callback.MIPNODE}\) false?
0 -
Note that \( \texttt{where} \) is equal to \( \texttt{GRB.Callback.MIPSOL} \) when the solution is set, then \( \texttt{mycallback} \) will be called later (separately) with a \( \texttt{where} \) value of \( \texttt{GRB.Callback.MIPNODE} \). \( \texttt{where==GRB.Callback.MIPNODE} \) is \( \texttt{false} \) whenever \( \texttt{mycallback} \) is called with a non-\( \texttt{MIPNODE} \) value of \( \texttt{where} \) (see the Callback Codes section of the documentation).
Is \( \texttt{mycallback} \) never called with \( \texttt{where==GRB.Callback.MIPNODE} \)? It would be helpful to see the log output from Gurobi and your code for a minimal working callback function.
0 -
Hello,
Thanks, I could see what I was doing wrong. Now my code enters \( \texttt{where=MIPNODE} \) and I can make use of \(\texttt{cb.SetSolution}\). However, I also want to use \(\texttt{Model.UseSolution()}\), and when printing to check what value I am about to pass I get 1e+100. What does this value mean and what kind of heuristic does gurobi implement at this point?
0 -
The return value of Model.cbUseSolution() is \( \texttt{GRB.INFINITY} \) (1e+100) if Gurobi isn't able to compute an improved solution using the variable values specified in Model.cbSetSolution(). Are you sure your solution is feasible and better than the current incumbent objective value?
Gurobi solves an optimization problem to try to "fill in" any missing variable values. The solution you give to Gurobi generally comes from your own heuristic algorithm.
0 -
Hi Everyone,
Gurobi 9.5 was recently released. Included in this release is the ability to set a new solution from the MIP and the MIPSOL callbacks. Therefore, there is no need to store a solution internally and wait for the next MIPNODE callback anymore.
Unfortunately, this new feature is missing in the Gurobi 9.5 documentation. It will be added in the next technical release.
We hope this new feature works well for you. Please let us know if you find any issues using this.
Best regards,
Maliheh
0 -
Dear all,
when useSolution() tries to produce an heuristic solution, does it check if it is feasible also w.r.t branching constraints added during the branch-and-cut algorithm?
I am asking because I am sure to have a feasible solution which improves over the incumbent, which gets surely accepted by useSolution (i.e., that does not return INFINITY) only as long as I am in the root node, while during the branching it may or may not be accepted.
If this is the case, how can I know which are the branching constraints added in the MIPNODE in which I'm feeding the solution? With this information I can modify accordingly my heuristic solution and use it.
Thanks!0 -
Hi,
Same issue here.
To solve a MINLP, I run Gurobi's B&C on a MILP relaxation and, at each MIPSOL, I either cutoff the integer node with a combinatorial cut or provides the actual MINLP solution if exists. With the oldest releases, I used the trick to store the solution and wait for the next MIPNODE event to post it. Now, I updated my code as solutions can now be set at MIPSOL. However, cbSetSolution/cbUseSolution keep rejecting the solutions I provide, and which are feasible (I checked them by cloning the model including all the lazy constraints and fixing the variables).
Systematically, the callback is called twice at these MIPSOL nodes but with a different solution (the fractional part now satisfies the newly added lazy cut, but it is still not feasible for my problem).
I also tried to enforce just partial solutions (only the integer part, or the fractional, or just one variable)... but cbUseSolution keeps returning 1e+101 anyway. I really do not see what I am doing wrong. As a feature request: could it be possible to get more information from cbUseSolution() when it rejects a solution ?
1 -
Hi, here is an update:
I confirm that, in my code, setSolution/useSolution never works at where=MIPSOL (i.e. useSolution returns 1e+101) but it always does (i.e. useSolution returns the actual cost) when I store the solution and set/use it at the next where=MIPNODE.
Now I have another problem in 1 of my test (among a dozen): useSolution "accepts" a solution at where=MIPNODE (i.e. it returns its actual cost) but the incumbent is not updated accordingly. Do you know what could happen and how to know in the callback when a solution is actually "used" ? Another question relative to this one: why MIPSOL_OBJBST returns the value of the current MIP solution and not the value of the incumbent at this point (given that the MIP solution can be cutoff in the callback) ? And could we have access to this (previous) incumbent value at where=MIPSOL ?
Thank you.
2 -
when useSolution() tries to produce an heuristic solution, does it check if it is feasible also w.r.t branching constraints added during the branch-and-cut algorithm?
I am asking because I am sure to have a feasible solution which improves over the incumbent, which gets surely accepted by useSolution (i.e., that does not return INFINITY) only as long as I am in the root node, while during the branching it may or may not be accepted.
If this is the case, how can I know which are the branching constraints added in the MIPNODE in which I'm feeding the solution? With this information I can modify accordingly my heuristic solution and use it.If the solution is feasible to the constraints of the original problem, it should be accepted. Are you using Gurobi 10.0.1? If so, are you able to construct a minimal working example that reproduces this behavior?
I also tried to enforce just partial solutions (only the integer part, or the fractional, or just one variable)... but cbUseSolution keeps returning 1e+101 anyway. I really do not see what I am doing wrong. As a feature request: could it be possible to get more information from cbUseSolution() when it rejects a solution ?
Do you mean that Model.cbUseSolution() always returns a value of 1e+101 when called in the \(\texttt{GRB.Callback.MIP}\) or \(\texttt{GRB.Callback.MIPSOL}\) callbacks? If so, this is expected. From the Model.cbUseSolution() documentation:
Return value:
The objective value for the solution obtained from your solution values. It equals GRB.INFINITY if no improved solution is found or the method has been called from a callback other than GRB.Callback.MIPNODE.
When Model.cbUseSolution() is called from the \(\texttt{GRB.Callback.MIP}\) or \(\texttt{GRB.Callback.MIPSOL}\) callbacks, Gurobi stores the solution until it can be processed. Does the log indicate that the solution is later accepted?
Another question relative to this one: why MIPSOL_OBJBST returns the value of the current MIP solution and not the value of the incumbent at this point (given that the MIP solution can be cutoff in the callback) ?
This is a bug. A fix will be available in Gurobi 10.0.2. Thanks for letting us know!
1 -
If the solution is feasible to the constraints of the original problem, it should be accepted. Are you using Gurobi 10.0.1? If so, are you able to construct a minimal working example that reproduces this behavior?
Sure, in the following you can find the log of my working example. As can be seen, I provide gurobi with an initial solution of value 18084.6. "Staggering vehicle" is the move of my local search, that tries to reduce the total value of the solution by rescheduling the departure time of one vehicle of my fleet at the time. Current total delay is the value of the heuristic solution. As long as I am in the root node the heuristic solutions that I find are accepted (unless gurobi finds a better heuristic solution in a shorter amount of time). The solution that I provide with value 5327.73 is not accepted by useSolution(), and this happens after gurobi started branching. What I do is then calling model.terminate() and restart the search using the solution with value 5327.73 as warm start, which is in this case accepted. Maybe it is worth to mention that I always provide values for integer and fractional variables:
Academic license - for non-commercial use only - expires 2023-11-05
Creating conflict variables
Creating continuous variables
Adding conflict constraints
Writing the continuity constraints
Writing the objective function
saved unaccepted heuristic solution
Set parameter TimeLimit to value 1.7832646110057831e+03
Set parameter MIPGap to value 0
Set parameter NodefileStart to value 0.5
Set parameter MIPFocus to value 2
Set parameter NumericFocus to value 2
Set parameter FeasibilityTol to value 1e-08
Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)
CPU model: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz, instruction set [SSE2|AVX|AVX2|AVX512]
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 82376 rows, 106249 columns and 279747 nonzeros
Model fingerprint: 0x47941e89
Model has 113776 general constraints
Variable types: 24637 continuous, 81612 integer (81612 binary)
Coefficient statistics:
Matrix range [5e-01, 1e+00]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 7e+03]
RHS range [1e+00, 7e+03]
PWLCon x range [1e+00, 7e+00]
PWLCon y range [0e+00, 4e+01]
GenCon rhs range [1e-03, 1e-03]
GenCon coe range [1e+00, 1e+00]
User MIP start produced solution with objective 18084.6 (0.50s)
Loaded user MIP start with objective 18084.6
Presolve removed 181263 rows and 229143 columns (presolve time = 6s) ...
Presolve removed 262189 rows and 263764 columns (presolve time = 34s) ...
Presolve removed 45152 rows and 79076 columns
Presolve time: 33.65s
Presolved: 37224 rows, 27173 columns, 144564 nonzeros
Presolved model has 2319 SOS constraint(s)
Found heuristic solution: objective 13947.533433
Variable types: 12904 continuous, 14269 integer (14268 binary)
Root relaxation presolve removed 207 rows and 238 columns
Root relaxation presolved: 37017 rows, 26935 columns, 144045 nonzeros
Deterministic concurrent LP optimizer: primal and dual simplex
Showing first log only...
Root simplex log...
Iteration Objective Primal Inf. Dual Inf. Time
0 3.1365904e+03 8.387912e+03 4.341447e+09 35s
14061 4.0869493e+03 1.333196e+01 5.275585e+07 35s
16826 1.3307845e+03 0.000000e+00 1.927024e+03 35s
18385 7.5599080e+02 0.000000e+00 0.000000e+00 36s
Concurrent spin time: 1.47s
Solved with primal simplex
18385 7.5599080e+02 0.000000e+00 0.000000e+00 37s
Root relaxation: objective 7.559908e+02, 18385 iterations, 2.75 seconds (0.95 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 755.99080 0 705 13947.5334 755.99080 94.6% - 39s
0 0 755.99080 0 708 13947.5334 755.99080 94.6% - 39s
0 0 755.99080 0 708 13947.5334 755.99080 94.6% - 39s
H 0 0 12827.749905 755.99080 94.1% - 40s
- staggering vehicle 178 by 5.32336 - current total delay: 12800.5 -> OldDelay - NewDelay = 27.259
- staggering vehicle 193 by 26.8083 - current total delay: 12787.7 -> OldDelay - NewDelay = 12.7964
- staggering vehicle 1257 by 9.1239 - current total delay: 12775.9 -> OldDelay - NewDelay = 11.7862
setting heuristic solution in callback
H 0 0 9992.8697310 785.61880 92.1% - 42s
0 0 793.51342 0 1051 9992.86973 793.51342 92.1% - 43s
0 0 793.51342 0 1051 9992.86973 793.51342 92.1% - 43s
- staggering vehicle 38 by 17.3183 - current total delay: 9961 -> OldDelay - NewDelay = 31.8746
- staggering vehicle 211 by 19.374 - current total delay: 9944.04 -> OldDelay - NewDelay = 16.9569
- staggering vehicle 95 by 4.96945 - current total delay: 9931.15 -> OldDelay - NewDelay = 12.8843
- staggering vehicle 46 by 19.1771 - current total delay: 9911.21 -> OldDelay - NewDelay = 19.9416
- staggering vehicle 212 by 38.2075 - current total delay: 9875.98 -> OldDelay - NewDelay = 35.2322
- staggering vehicle 724 by 12.7865 - current total delay: 9857.36 -> OldDelay - NewDelay = 18.6155
setting heuristic solution in callback
0 0 810.03454 0 1028 9992.86973 810.03454 91.9% - 44s
H 0 0 9857.3647500 811.12093 91.8% - 45s
0 0 811.12093 0 1026 9857.36475 811.12093 91.8% - 45s
0 0 854.25190 0 1020 9857.36475 854.25190 91.3% - 45s
0 0 869.63497 0 1133 9857.36475 869.63497 91.2% - 49s
0 0 870.64213 0 1122 9857.36475 870.64213 91.2% - 49s
0 0 870.64213 0 1122 9857.36475 870.64213 91.2% - 49s
H 0 0 8540.3112840 872.89051 89.8% - 50s
0 0 872.89051 0 1144 8540.31128 872.89051 89.8% - 50s
0 0 872.89051 0 1145 8540.31128 872.89051 89.8% - 50s
- staggering vehicle 781 by 68.6936 - destaggering vehicle 722 by 22.3973 - current total delay: 8485.77 -> OldDelay - NewDelay = 54.5431
- staggering vehicle 1235 by 34.4721 - current total delay: 8473.08 -> OldDelay - NewDelay = 12.6875
- staggering vehicle 38 by 17.3183 - current total delay: 8441.21 -> OldDelay - NewDelay = 31.8746
- staggering vehicle 95 by 4.96945 - current total delay: 8428.32 -> OldDelay - NewDelay = 12.8843
- staggering vehicle 1304 by 13.6961 - current total delay: 8418.14 -> OldDelay - NewDelay = 10.1808
- staggering vehicle 1258 by 1.56485 - current total delay: 8415.8 -> OldDelay - NewDelay = 2.33793
- staggering vehicle 931 by 2.68681 - current total delay: 8409.71 -> OldDelay - NewDelay = 6.09559
- staggering vehicle 1069 by 4.76216 - current total delay: 8313.88 -> OldDelay - NewDelay = 95.8227
- staggering vehicle 498 by 14.6169 - current total delay: 8310.3 -> OldDelay - NewDelay = 3.58557
setting heuristic solution in callback
0 0 872.92139 0 1146 8540.31128 872.92139 89.8% - 52s
H 0 0 8310.2992920 872.92139 89.5% - 52s
0 0 872.92139 0 1144 8310.29929 872.92139 89.5% - 52s
0 0 907.59290 0 652 8310.29929 907.59290 89.1% - 60s
H 0 0 6624.8816040 907.59290 86.3% - 60s
H 0 0 6468.2387820 907.59290 86.0% - 61s
H 0 0 5498.4590460 907.59290 83.5% - 68s
- staggering vehicle 904 by 17.6209 - current total delay: 5481.47 -> OldDelay - NewDelay = 16.9901
- staggering vehicle 814 by 29.8285 - current total delay: 5459.35 -> OldDelay - NewDelay = 22.1203
setting heuristic solution in callback
3 4 953.57219 2 120 5498.45905 953.57219 82.7% 14708 75s
H 514 154 5366.8360710 974.57161 81.8% 97.7 80s
- staggering vehicle 904 by 17.6209 - current total delay: 5349.85 -> OldDelay - NewDelay = 16.9901
- staggering vehicle 814 by 29.8285 - current total delay: 5327.73 -> OldDelay - NewDelay = 22.1203
setting heuristic solution in callback
Heuristic solution has not been accepted - terminating MIP model
saved unaccepted heuristic solution
Cutting planes:
Learned: 13
Lift-and-project: 68
Cover: 581
Implied bound: 201
Projected implied bound: 1
Clique: 545
MIR: 286
StrongCG: 8
Flow cover: 1491
Zero half: 13
Network: 1
RLT: 172
Relax-and-lift: 126
Explored 515 nodes (119243 simplex iterations) in 86.43 seconds (42.35 work units)
Thread count was 8 (of 8 available processors)
Solution count 10: 5366.84 5498.46 6468.24 ... 13947.5
Solve interrupted
Best objective 5.366836070999e+03, best bound 1.003840565559e+03, gap 81.2955%
User-callback calls 6672, time in user-callback 8.19 sec
Set parameter TimeLimit to value 1.6964470658302307e+03
Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)
CPU model: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz, instruction set [SSE2|AVX|AVX2|AVX512]
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 82376 rows, 106249 columns and 279747 nonzeros
Model fingerprint: 0xe041006f
Model has 113776 general constraints
Variable types: 24637 continuous, 81612 integer (81612 binary)
Coefficient statistics:
Matrix range [5e-01, 1e+00]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 7e+03]
RHS range [1e+00, 7e+03]
PWLCon x range [1e+00, 7e+00]
PWLCon y range [0e+00, 4e+01]
GenCon rhs range [1e-03, 1e-03]
GenCon coe range [1e+00, 1e+00]
User MIP start produced solution with objective 5327.73 (0.32s)
Loaded user MIP start with objective 5327.73
MIP start from previous solve did not produce a new incumbent solution
[...]Thank you for your help!
1 -
That looks pretty suspicious. I am assuming you are calling Model.cbUseSolution() in the \(\texttt{MIPNODE}\) callback and declaring the heuristic solution to be rejected if Model.cbUseSolution() returns \(\texttt{GRB.INFINITY}\). Are you able to share a minimal working code example?
0 -
I am assuming you are calling Model.cbUseSolution() in the \(\texttt{MIPNODE}\) callback and declaring the heuristic solution to be rejected if Model.cbUseSolution() returns \(\texttt{MIPNODE}\).
This is correct.
Are you able to share a minimal working code example?
This behaviour arises only when the size of the instances I am trying to solve is large, so it is not really possible to provide a minimal working example. I can however share my callback function:
- I retrieve \(\texttt{model._cbReleaseTimes}\) in \(\texttt{MIPSOL}\) using \(\texttt{model.cbGetSolution()}\);
- I use these values to produce the heuristic solution in the subsequent \(\texttt{MIPNODE}\) with \(\texttt{getHeuristicSolution()}\);
- In \(\texttt{setHeuristicSolution()}\), I set the values for my binary and continuous variables using \(\texttt{model.cbSetSolution()}\) (in the following the respective functions). Thereafter, I call \(\texttt{model.cbUseSolution()}\). If the return value of the latter is \(\texttt{1e+100}\), then I save the heuristic solution in an external file, terminate gurobi, and restart the model using the saved solution as warm start.
def callback(instance: Instance, statusQuo: CompleteSolution) -> Callable:
def callLocalSearch(model, where) -> None:
if where == grb.GRB.Callback.MIPSOL:
model._cbReleaseTimes = [model.cbGetSolution(model._departure[vehicle][path[0]])
for vehicle, path in enumerate(instance.arcBasedShortestPaths)]
if where == grb.GRB.Callback.MIPNODE:
heuristicSolution = getHeuristicSolution(model, instance)
setHeuristicSolution(model, heuristicSolution, instance)
return callLocalSearchdef setHeuristicSolution(model: Model, heuristicSolution: HeuristicSolution, instance: Instance) -> None:
print("setting heuristic solution in callback")
setHeuristicBinaryVariables(model, heuristicSolution)
setHeuristicContinuousVariables(model, heuristicSolution)
returnValUseSolution = model.cbUseSolution()
if returnValUseSolution == 1e+100:
print("Heuristic solution has not been accepted - terminating MIP model")
suspendProcedure(heuristicSolution, model, instance)
returndef setHeuristicBinaryVariables(model, heuristicSolution):
for arc in model._gamma:
for firstVehicle, secondVehicle in itertools.combinations(model._gamma[arc], 2):
model.cbSetSolution(model._alpha[arc][firstVehicle][secondVehicle],
heuristicSolution.binaries.alpha[arc][firstVehicle][secondVehicle])
model.cbSetSolution(model._beta[arc][firstVehicle][secondVehicle],
heuristicSolution.binaries.beta[arc][firstVehicle][secondVehicle])
model.cbSetSolution(model._gamma[arc][firstVehicle][secondVehicle],
heuristicSolution.binaries.gamma[arc][firstVehicle][secondVehicle])
model.cbSetSolution(model._alpha[arc][secondVehicle][firstVehicle],
heuristicSolution.binaries.alpha[arc][secondVehicle][firstVehicle])
model.cbSetSolution(model._beta[arc][secondVehicle][firstVehicle],
heuristicSolution.binaries.beta[arc][secondVehicle][firstVehicle])
model.cbSetSolution(model._gamma[arc][secondVehicle][firstVehicle],
heuristicSolution.binaries.gamma[arc][secondVehicle][firstVehicle])def setHeuristicContinuousVariables(model, heuristicSolution):
for vehicle in model._departure:
for position, arc in enumerate(model._departure[vehicle]):
model.cbSetSolution(model._departure[vehicle][arc],
heuristicSolution.congestedSchedule[vehicle][position])
model.cbSetSolution(model._delay[vehicle][arc], heuristicSolution.delaysOnArcs[vehicle][position])Thank you for your help.
0 -
We are very interested in investigating this issue further, though this requires being able to reproduce the issue. I will open a support request for you to discuss how we can replicate the error.
1 -
Is there any update regarding the issue?
I experience the same problem. I find an improved solution in the callback, but Gurobi rejects it. However, if I use the same solution to warm start, the MIP it works fine.
0 -
Our development team is aware of the issue described by Antonio. I unfortunately can't make any guarantees at this time about if/when a fix will become available.
For that particular issue, a workaround is to set the Disconnected parameter to 0. Could you check if setting the Disconnected parameter to 0 resolves the issue? If not, please post the Gurobi log and a minimal version of your callback code.
0 -
I was wondering if this issue has been solved or if there are other problems known to using MIP solutions in callbacks.
I am trying to insert a partial MIP solution in a callback, which works as a starting solution. However, it is not accepted and returns 1e+101 when calling useSolution.
In the following log, The Iteration shows that I am entering the callback, and then if I find my feasible solution, I try to insert it.
Set parameter Username
Academic license - for non-commercial use only - expires 2024-08-01
Warning: parameter changes on this environment will not affect existing models.
Set parameter Threads to value 1
Set parameter Disconnected to value 0
Set parameter MIPGap to value 0.02
Set parameter LazyConstraints to value 1
Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (win64)
CPU model: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz, instruction set [SSE2|AVX|AVX2]
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 1573498 rows, 589114 columns and 3924084 nonzeros
Model fingerprint: 0x8e831791
Variable types: 13024 continuous, 576090 integer (90 binary)
Coefficient statistics:
Matrix range [1e+00, 1e+08]
Objective range [5e-02, 6e+07]
Bounds range [1e+00, 1e+00]
RHS range [9e+01, 1e+02]
Presolve removed 1468318 rows and 486305 columns (presolve time = 5s) ...
Presolve removed 1468318 rows and 486305 columns
Presolve time: 6.39s
Presolved: 105180 rows, 102809 columns, 402180 nonzeros
Variable types: 5610 continuous, 97199 integer (89 binary)
Iteration: 1
Found Insert!
Insert!
Return of useSolution: 1e+101
Insert stop!
Iteration stop: 1
Iteration: 2
Iteration stop: 2
Found heuristic solution: objective 7.336881e+10
Root relaxation presolved: 105000 rows, 102629 columns, 401460 nonzeros
Deterministic concurrent LP optimizer: primal and dual simplex
Showing first log only...
Root simplex log...
Iteration Objective Primal Inf. Dual Inf. Time
0 6.8028811e+10 2.003508e+04 2.188655e+11 12s
Concurrent spin time: 0.00s
Solved with dual simplex
Root simplex log...
Iteration Objective Primal Inf. Dual Inf. Time
29109 1.0025516e+10 0.000000e+00 0.000000e+00 14s
Root relaxation: objective 1.002552e+10, 29109 iterations, 3.08 seconds (1.53 work units)
Iteration: 3
Found Insert!
Insert!
Return of useSolution: 1e+101
Insert stop!
Iteration stop: 3
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 1.0026e+10 0 - 7.3369e+10 1.0026e+10 86.3% - 14s
Iteration: 4
Found Insert!
Insert!
Return of useSolution: 1e+101
Insert stop!
Iteration stop: 4
0 0 1.0041e+10 0 - 7.3369e+10 1.0041e+10 86.3% - 21s
Iteration: 5
Found Insert!
Insert!
Return of useSolution: 1e+101
Insert stop!
Iteration stop: 5
* 0 0 0 1.004100e+10 1.0041e+10 0.00% - 21s
Cutting planes:
Lazy constraints: 1243
Explored 1 nodes (36403 simplex iterations) in 21.63 seconds (13.49 work units)
Thread count was 8 (of 8 available processors)
Solution count 2: 1.0041e+10 7.33688e+10
Optimal solution found (tolerance 2.00e-02)
Best objective 1.004099869152e+10, best bound 1.004099869152e+10, gap 0.0000%
User-callback calls 2760, time in user-callback 2.18 sec
Time measured: 21.891 seconds.0
Please sign in to leave a comment.
Comments
22 comments