1 /* $Id$ */
2 // Copyright (C) 2007, International Business Machines
3 // Corporation and others. All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5
6 /*! \file CbcSolverHeuristics.cpp
7 \brief Second level routines for the cbc stand-alone solver.
8 */
9
10 #include "CbcConfig.h"
11 #include "CoinPragma.hpp"
12
13 #include "CoinTime.hpp"
14
15 #include "OsiClpSolverInterface.hpp"
16
17 #include "ClpPresolve.hpp"
18
19 #include "CbcOrClpParam.hpp"
20
21 #include "CbcModel.hpp"
22
23 #include "CbcHeuristicLocal.hpp"
24 #include "CbcHeuristicPivotAndFix.hpp"
25 //#include "CbcHeuristicPivotAndComplement.hpp"
26 #include "CbcHeuristicRandRound.hpp"
27 #include "CbcHeuristicGreedy.hpp"
28 #include "CbcHeuristicFPump.hpp"
29 #include "CbcHeuristicRINS.hpp"
30 #include "CbcHeuristicDW.hpp"
31 #include "CbcHeuristicVND.hpp"
32
33 #include "CbcHeuristicDiveCoefficient.hpp"
34 #include "CbcHeuristicDiveFractional.hpp"
35 #include "CbcHeuristicDiveGuided.hpp"
36 #include "CbcHeuristicDiveVectorLength.hpp"
37 #include "CbcHeuristicDivePseudoCost.hpp"
38 #include "CbcHeuristicDiveLineSearch.hpp"
39
40 #include "CbcStrategy.hpp"
41 #include "OsiAuxInfo.hpp"
42
43 #include "ClpSimplexOther.hpp"
44
45 // Crunch down model
crunchIt(ClpSimplex * model)46 void crunchIt(ClpSimplex *model)
47 {
48 #ifdef JJF_ZERO
49 model->dual();
50 #else
51 int numberColumns = model->numberColumns();
52 int numberRows = model->numberRows();
53 // Use dual region
54 double *rhs = model->dualRowSolution();
55 int *whichRow = new int[3 * numberRows];
56 int *whichColumn = new int[2 * numberColumns];
57 int nBound;
58 ClpSimplex *small = static_cast< ClpSimplexOther * >(model)->crunch(rhs, whichRow, whichColumn,
59 nBound, false, false);
60 if (small) {
61 small->dual();
62 if (small->problemStatus() == 0) {
63 model->setProblemStatus(0);
64 static_cast< ClpSimplexOther * >(model)->afterCrunch(*small, whichRow, whichColumn, nBound);
65 } else if (small->problemStatus() != 3) {
66 model->setProblemStatus(1);
67 } else {
68 if (small->problemStatus() == 3) {
69 // may be problems
70 small->computeObjectiveValue();
71 model->setObjectiveValue(small->objectiveValue());
72 model->setProblemStatus(3);
73 } else {
74 model->setProblemStatus(3);
75 }
76 }
77 delete small;
78 } else {
79 model->setProblemStatus(1);
80 }
81 delete[] whichRow;
82 delete[] whichColumn;
83 #endif
84 }
85 /*
86 On input
87 doAction - 0 just fix in original and return NULL
88 1 return fixed non-presolved solver
89 2 as one but use presolve Inside this
90 3 use presolve and fix ones with large cost
91 ? do heuristics and set best solution
92 ? do BAB and just set best solution
93 10+ then use lastSolution and relax a few
94 -2 cleanup afterwards if using 2
95 On output - number fixed
96 */
97 OsiClpSolverInterface *
fixVubs(CbcModel & model,int skipZero2,int & doAction,CoinMessageHandler *,const double * lastSolution,double dextra[6],int extra[5])98 fixVubs(CbcModel &model, int skipZero2,
99 int &doAction,
100 CoinMessageHandler * /*generalMessageHandler*/,
101 const double *lastSolution, double dextra[6],
102 int extra[5])
103 {
104 if (doAction == 11 && !lastSolution)
105 lastSolution = model.bestSolution();
106 assert(((doAction >= 0 && doAction <= 3) && !lastSolution) || (doAction == 11 && lastSolution));
107 double fractionIntFixed = dextra[3];
108 double fractionFixed = dextra[4];
109 double fixAbove = dextra[2];
110 double fixAboveValue = (dextra[5] > 0.0) ? dextra[5] : 1.0;
111 #ifdef COIN_DETAIL
112 double time1 = CoinCpuTime();
113 #endif
114 int leaveIntFree = extra[1];
115 OsiSolverInterface *originalSolver = model.solver();
116 OsiClpSolverInterface *originalClpSolver = dynamic_cast< OsiClpSolverInterface * >(originalSolver);
117 ClpSimplex *originalLpSolver = originalClpSolver->getModelPtr();
118 int *originalColumns = NULL;
119 OsiClpSolverInterface *clpSolver;
120 ClpSimplex *lpSolver;
121 ClpPresolve pinfo;
122 assert(originalSolver->getObjSense() > 0);
123 if (doAction == 2 || doAction == 3) {
124 double *saveLB = NULL;
125 double *saveUB = NULL;
126 int numberColumns = originalLpSolver->numberColumns();
127 if (fixAbove > 0.0) {
128 #ifdef COIN_DETAIL
129 double time1 = CoinCpuTime();
130 #endif
131 originalClpSolver->initialSolve();
132 COIN_DETAIL_PRINT(printf("first solve took %g seconds\n", CoinCpuTime() - time1));
133 double *columnLower = originalLpSolver->columnLower();
134 double *columnUpper = originalLpSolver->columnUpper();
135 const double *solution = originalLpSolver->primalColumnSolution();
136 saveLB = CoinCopyOfArray(columnLower, numberColumns);
137 saveUB = CoinCopyOfArray(columnUpper, numberColumns);
138 const double *objective = originalLpSolver->getObjCoefficients();
139 int iColumn;
140 int nFix = 0;
141 int nArt = 0;
142 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
143 if (objective[iColumn] > fixAbove) {
144 if (solution[iColumn] < columnLower[iColumn] + 1.0e-8) {
145 columnUpper[iColumn] = columnLower[iColumn];
146 nFix++;
147 } else {
148 nArt++;
149 }
150 } else if (objective[iColumn] < -fixAbove) {
151 if (solution[iColumn] > columnUpper[iColumn] - 1.0e-8) {
152 columnLower[iColumn] = columnUpper[iColumn];
153 nFix++;
154 } else {
155 nArt++;
156 }
157 }
158 }
159 COIN_DETAIL_PRINT(printf("%d artificials fixed, %d left as in solution\n", nFix, nArt));
160 lpSolver = pinfo.presolvedModel(*originalLpSolver, 1.0e-8, true, 10);
161 if (!lpSolver || doAction == 2) {
162 // take off fixing in original
163 memcpy(columnLower, saveLB, numberColumns * sizeof(double));
164 memcpy(columnUpper, saveUB, numberColumns * sizeof(double));
165 }
166 delete[] saveLB;
167 delete[] saveUB;
168 if (!lpSolver) {
169 // try again
170 pinfo.destroyPresolve();
171 lpSolver = pinfo.presolvedModel(*originalLpSolver, 1.0e-8, true, 10);
172 assert(lpSolver);
173 }
174 } else {
175 lpSolver = pinfo.presolvedModel(*originalLpSolver, 1.0e-8, true, 10);
176 assert(lpSolver);
177 }
178 clpSolver = new OsiClpSolverInterface(lpSolver, true);
179 assert(lpSolver == clpSolver->getModelPtr());
180 numberColumns = lpSolver->numberColumns();
181 originalColumns = CoinCopyOfArray(pinfo.originalColumns(), numberColumns);
182 doAction = 1;
183 } else {
184 OsiSolverInterface *solver = originalSolver->clone();
185 clpSolver = dynamic_cast< OsiClpSolverInterface * >(solver);
186 lpSolver = clpSolver->getModelPtr();
187 }
188 // Tighten bounds
189 lpSolver->tightenPrimalBounds(0.0, 11, true);
190 int numberColumns = clpSolver->getNumCols();
191 double *saveColumnLower = CoinCopyOfArray(lpSolver->columnLower(), numberColumns);
192 double *saveColumnUpper = CoinCopyOfArray(lpSolver->columnUpper(), numberColumns);
193 //char generalPrint[200];
194 const double *objective = lpSolver->getObjCoefficients();
195 double *columnLower = lpSolver->columnLower();
196 double *columnUpper = lpSolver->columnUpper();
197 int numberRows = clpSolver->getNumRows();
198 int iRow, iColumn;
199
200 // Row copy
201 CoinPackedMatrix matrixByRow(*clpSolver->getMatrixByRow());
202 const double *elementByRow = matrixByRow.getElements();
203 const int *column = matrixByRow.getIndices();
204 const CoinBigIndex *rowStart = matrixByRow.getVectorStarts();
205 const int *rowLength = matrixByRow.getVectorLengths();
206
207 // Column copy
208 CoinPackedMatrix matrixByCol(*clpSolver->getMatrixByCol());
209 //const double * element = matrixByCol.getElements();
210 const int *row = matrixByCol.getIndices();
211 const CoinBigIndex *columnStart = matrixByCol.getVectorStarts();
212 const int *columnLength = matrixByCol.getVectorLengths();
213
214 const double *rowLower = clpSolver->getRowLower();
215 const double *rowUpper = clpSolver->getRowUpper();
216
217 // Get maximum size of VUB tree
218 // otherColumn is one fixed to 0 if this one zero
219 CoinBigIndex nEl = matrixByCol.getNumElements();
220 CoinBigIndex *fixColumn = new CoinBigIndex[numberColumns + 1];
221 int *otherColumn = new int[nEl];
222 int *fix = new int[numberColumns];
223 char *mark = new char[numberColumns];
224 memset(mark, 0, numberColumns);
225 int numberInteger = 0;
226 int numberOther = 0;
227 fixColumn[0] = 0;
228 double large = lpSolver->largeValue(); // treat bounds > this as infinite
229 #ifndef NDEBUG
230 double large2 = 1.0e10 * large;
231 #endif
232 double tolerance = lpSolver->primalTolerance();
233 int *check = new int[numberRows];
234 for (iRow = 0; iRow < numberRows; iRow++) {
235 check[iRow] = -2; // don't check
236 if (rowLower[iRow] < -1.0e6 && rowUpper[iRow] > 1.0e6)
237 continue; // unlikely
238 // possible row
239 int numberPositive = 0;
240 int iPositive = -1;
241 int numberNegative = 0;
242 int iNegative = -1;
243 CoinBigIndex rStart = rowStart[iRow];
244 CoinBigIndex rEnd = rowStart[iRow] + rowLength[iRow];
245 CoinBigIndex j;
246 int kColumn;
247 for (j = rStart; j < rEnd; ++j) {
248 double value = elementByRow[j];
249 kColumn = column[j];
250 if (columnUpper[kColumn] > columnLower[kColumn]) {
251 if (value > 0.0) {
252 numberPositive++;
253 iPositive = kColumn;
254 } else {
255 numberNegative++;
256 iNegative = kColumn;
257 }
258 }
259 }
260 if (numberPositive == 1 && numberNegative == 1)
261 check[iRow] = -1; // try both
262 if (numberPositive == 1 && rowLower[iRow] > -1.0e20)
263 check[iRow] = iPositive;
264 else if (numberNegative == 1 && rowUpper[iRow] < 1.0e20)
265 check[iRow] = iNegative;
266 }
267 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
268 fix[iColumn] = -1;
269 if (columnUpper[iColumn] > columnLower[iColumn] + 1.0e-8) {
270 if (clpSolver->isInteger(iColumn))
271 numberInteger++;
272 if (columnLower[iColumn] == 0.0) {
273 bool infeasible = false;
274 fix[iColumn] = 0;
275 // fake upper bound
276 double saveUpper = columnUpper[iColumn];
277 columnUpper[iColumn] = 0.0;
278 for (CoinBigIndex i = columnStart[iColumn];
279 i < columnStart[iColumn] + columnLength[iColumn]; i++) {
280 iRow = row[i];
281 if (check[iRow] != -1 && check[iRow] != iColumn)
282 continue; // unlikely
283 // possible row
284 int infiniteUpper = 0;
285 int infiniteLower = 0;
286 double maximumUp = 0.0;
287 double maximumDown = 0.0;
288 double newBound;
289 CoinBigIndex rStart = rowStart[iRow];
290 CoinBigIndex rEnd = rowStart[iRow] + rowLength[iRow];
291 CoinBigIndex j;
292 int kColumn;
293 // Compute possible lower and upper ranges
294 for (j = rStart; j < rEnd; ++j) {
295 double value = elementByRow[j];
296 kColumn = column[j];
297 if (value > 0.0) {
298 if (columnUpper[kColumn] >= large) {
299 ++infiniteUpper;
300 } else {
301 maximumUp += columnUpper[kColumn] * value;
302 }
303 if (columnLower[kColumn] <= -large) {
304 ++infiniteLower;
305 } else {
306 maximumDown += columnLower[kColumn] * value;
307 }
308 } else if (value < 0.0) {
309 if (columnUpper[kColumn] >= large) {
310 ++infiniteLower;
311 } else {
312 maximumDown += columnUpper[kColumn] * value;
313 }
314 if (columnLower[kColumn] <= -large) {
315 ++infiniteUpper;
316 } else {
317 maximumUp += columnLower[kColumn] * value;
318 }
319 }
320 }
321 // Build in a margin of error
322 maximumUp += 1.0e-8 * fabs(maximumUp);
323 maximumDown -= 1.0e-8 * fabs(maximumDown);
324 double maxUp = maximumUp + infiniteUpper * 1.0e31;
325 double maxDown = maximumDown - infiniteLower * 1.0e31;
326 if (maxUp <= rowUpper[iRow] + tolerance && maxDown >= rowLower[iRow] - tolerance) {
327 //printf("Redundant row in vubs %d\n",iRow);
328 } else {
329 if (maxUp < rowLower[iRow] - 100.0 * tolerance || maxDown > rowUpper[iRow] + 100.0 * tolerance) {
330 infeasible = true;
331 break;
332 }
333 double lower = rowLower[iRow];
334 double upper = rowUpper[iRow];
335 for (j = rStart; j < rEnd; ++j) {
336 double value = elementByRow[j];
337 kColumn = column[j];
338 double nowLower = columnLower[kColumn];
339 double nowUpper = columnUpper[kColumn];
340 if (value > 0.0) {
341 // positive value
342 if (lower > -large) {
343 if (!infiniteUpper) {
344 assert(nowUpper < large2);
345 newBound = nowUpper + (lower - maximumUp) / value;
346 // relax if original was large
347 if (fabs(maximumUp) > 1.0e8)
348 newBound -= 1.0e-12 * fabs(maximumUp);
349 } else if (infiniteUpper == 1 && nowUpper > large) {
350 newBound = (lower - maximumUp) / value;
351 // relax if original was large
352 if (fabs(maximumUp) > 1.0e8)
353 newBound -= 1.0e-12 * fabs(maximumUp);
354 } else {
355 newBound = -COIN_DBL_MAX;
356 }
357 if (newBound > nowLower + 1.0e-12 && newBound > -large) {
358 // Tighten the lower bound
359 // check infeasible (relaxed)
360 if (nowUpper < newBound) {
361 if (nowUpper - newBound < -100.0 * tolerance) {
362 infeasible = true;
363 break;
364 }
365 }
366 }
367 }
368 if (upper < large) {
369 if (!infiniteLower) {
370 assert(nowLower > -large2);
371 newBound = nowLower + (upper - maximumDown) / value;
372 // relax if original was large
373 if (fabs(maximumDown) > 1.0e8)
374 newBound += 1.0e-12 * fabs(maximumDown);
375 } else if (infiniteLower == 1 && nowLower < -large) {
376 newBound = (upper - maximumDown) / value;
377 // relax if original was large
378 if (fabs(maximumDown) > 1.0e8)
379 newBound += 1.0e-12 * fabs(maximumDown);
380 } else {
381 newBound = COIN_DBL_MAX;
382 }
383 if (newBound < nowUpper - 1.0e-12 && newBound < large) {
384 // Tighten the upper bound
385 // check infeasible (relaxed)
386 if (nowLower > newBound) {
387 if (newBound - nowLower < -100.0 * tolerance) {
388 infeasible = true;
389 break;
390 } else {
391 newBound = nowLower;
392 }
393 }
394 if (!newBound || (clpSolver->isInteger(kColumn) && newBound < 0.999)) {
395 // fix to zero
396 if (!mark[kColumn]) {
397 otherColumn[numberOther++] = kColumn;
398 mark[kColumn] = 1;
399 if (check[iRow] == -1)
400 check[iRow] = iColumn;
401 else
402 assert(check[iRow] == iColumn);
403 }
404 }
405 }
406 }
407 } else {
408 // negative value
409 if (lower > -large) {
410 if (!infiniteUpper) {
411 assert(nowLower < large2);
412 newBound = nowLower + (lower - maximumUp) / value;
413 // relax if original was large
414 if (fabs(maximumUp) > 1.0e8)
415 newBound += 1.0e-12 * fabs(maximumUp);
416 } else if (infiniteUpper == 1 && nowLower < -large) {
417 newBound = (lower - maximumUp) / value;
418 // relax if original was large
419 if (fabs(maximumUp) > 1.0e8)
420 newBound += 1.0e-12 * fabs(maximumUp);
421 } else {
422 newBound = COIN_DBL_MAX;
423 }
424 if (newBound < nowUpper - 1.0e-12 && newBound < large) {
425 // Tighten the upper bound
426 // check infeasible (relaxed)
427 if (nowLower > newBound) {
428 if (newBound - nowLower < -100.0 * tolerance) {
429 infeasible = true;
430 break;
431 } else {
432 newBound = nowLower;
433 }
434 }
435 if (!newBound || (clpSolver->isInteger(kColumn) && newBound < 0.999)) {
436 // fix to zero
437 if (!mark[kColumn]) {
438 otherColumn[numberOther++] = kColumn;
439 mark[kColumn] = 1;
440 if (check[iRow] == -1)
441 check[iRow] = iColumn;
442 else
443 assert(check[iRow] == iColumn);
444 }
445 }
446 }
447 }
448 if (upper < large) {
449 if (!infiniteLower) {
450 assert(nowUpper < large2);
451 newBound = nowUpper + (upper - maximumDown) / value;
452 // relax if original was large
453 if (fabs(maximumDown) > 1.0e8)
454 newBound -= 1.0e-12 * fabs(maximumDown);
455 } else if (infiniteLower == 1 && nowUpper > large) {
456 newBound = (upper - maximumDown) / value;
457 // relax if original was large
458 if (fabs(maximumDown) > 1.0e8)
459 newBound -= 1.0e-12 * fabs(maximumDown);
460 } else {
461 newBound = -COIN_DBL_MAX;
462 }
463 if (newBound > nowLower + 1.0e-12 && newBound > -large) {
464 // Tighten the lower bound
465 // check infeasible (relaxed)
466 if (nowUpper < newBound) {
467 if (nowUpper - newBound < -100.0 * tolerance) {
468 infeasible = true;
469 break;
470 }
471 }
472 }
473 }
474 }
475 }
476 }
477 }
478 for (CoinBigIndex i = fixColumn[iColumn]; i < numberOther; i++)
479 mark[otherColumn[i]] = 0;
480 // reset bound unless infeasible
481 if (!infeasible || !clpSolver->isInteger(iColumn))
482 columnUpper[iColumn] = saveUpper;
483 else if (clpSolver->isInteger(iColumn))
484 columnLower[iColumn] = 1.0;
485 }
486 }
487 fixColumn[iColumn + 1] = numberOther;
488 }
489 delete[] check;
490 delete[] mark;
491 // Now do reverse way
492 int *counts = new int[numberColumns];
493 CoinZeroN(counts, numberColumns);
494 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
495 for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++)
496 counts[otherColumn[i]]++;
497 }
498 numberOther = 0;
499 CoinBigIndex *fixColumn2 = new CoinBigIndex[numberColumns + 1];
500 int *otherColumn2 = new int[fixColumn[numberColumns]];
501 fixColumn2[0] = 0;
502 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
503 numberOther += counts[iColumn];
504 counts[iColumn] = 0;
505 fixColumn2[iColumn + 1] = numberOther;
506 }
507 // Create other way
508 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
509 for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
510 int jColumn = otherColumn[i];
511 CoinBigIndex put = fixColumn2[jColumn] + counts[jColumn];
512 counts[jColumn]++;
513 otherColumn2[put] = iColumn;
514 }
515 }
516 // get top layer i.e. those which are not fixed by any other
517 int kLayer = 0;
518 while (true) {
519 int numberLayered = 0;
520 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
521 if (fix[iColumn] == kLayer) {
522 for (CoinBigIndex i = fixColumn2[iColumn]; i < fixColumn2[iColumn + 1]; i++) {
523 int jColumn = otherColumn2[i];
524 if (fix[jColumn] == kLayer) {
525 fix[iColumn] = kLayer + 100;
526 }
527 }
528 }
529 if (fix[iColumn] == kLayer) {
530 numberLayered++;
531 }
532 }
533 if (numberLayered) {
534 kLayer += 100;
535 } else {
536 break;
537 }
538 }
539 for (int iPass = 0; iPass < 2; iPass++) {
540 for (int jLayer = 0; jLayer < kLayer; jLayer++) {
541 int check[] = { -1, 0, 1, 2, 3, 4, 5, 10, 50, 100, 500, 1000, 5000, 10000, COIN_INT_MAX };
542 int nCheck = static_cast< int >(sizeof(check) / sizeof(int));
543 int countsI[20];
544 int countsC[20];
545 assert(nCheck <= 20);
546 memset(countsI, 0, nCheck * sizeof(int));
547 memset(countsC, 0, nCheck * sizeof(int));
548 check[nCheck - 1] = numberColumns;
549 int numberLayered = 0;
550 int numberInteger = 0;
551 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
552 if (fix[iColumn] == jLayer) {
553 numberLayered++;
554 int nFix = static_cast< int >(fixColumn[iColumn + 1] - fixColumn[iColumn]);
555 if (iPass) {
556 // just integers
557 nFix = 0;
558 for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
559 int jColumn = otherColumn[i];
560 if (clpSolver->isInteger(jColumn))
561 nFix++;
562 }
563 }
564 int iFix;
565 for (iFix = 0; iFix < nCheck; iFix++) {
566 if (nFix <= check[iFix])
567 break;
568 }
569 assert(iFix < nCheck);
570 if (clpSolver->isInteger(iColumn)) {
571 numberInteger++;
572 countsI[iFix]++;
573 } else {
574 countsC[iFix]++;
575 }
576 }
577 }
578 #ifdef COIN_DETAIL
579 if (numberLayered) {
580 printf("%d (%d integer) at priority %d\n", numberLayered, numberInteger, 1 + (jLayer / 100));
581 char buffer[50];
582 for (int i = 1; i < nCheck; i++) {
583 if (countsI[i] || countsC[i]) {
584 if (i == 1)
585 sprintf(buffer, " == zero ");
586 else if (i < nCheck - 1)
587 sprintf(buffer, "> %6d and <= %6d ", check[i - 1], check[i]);
588 else
589 sprintf(buffer, "> %6d ", check[i - 1]);
590 printf("%s %8d integers and %8d continuous\n", buffer, countsI[i], countsC[i]);
591 }
592 }
593 }
594 #endif
595 }
596 }
597 delete[] counts;
598 // Now do fixing
599 {
600 // switch off presolve and up weight
601 ClpSolve solveOptions;
602 //solveOptions.setPresolveType(ClpSolve::presolveOff,0);
603 solveOptions.setSolveType(ClpSolve::usePrimalorSprint);
604 //solveOptions.setSpecialOption(1,3,30); // sprint
605 int numberColumns = lpSolver->numberColumns();
606 int iColumn;
607 bool allSlack = true;
608 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
609 if (lpSolver->getColumnStatus(iColumn) == ClpSimplex::basic) {
610 allSlack = false;
611 break;
612 }
613 }
614 if (allSlack)
615 solveOptions.setSpecialOption(1, 2, 50); // idiot
616 lpSolver->setInfeasibilityCost(1.0e11);
617 lpSolver->defaultFactorizationFrequency();
618 if (doAction != 11)
619 lpSolver->initialSolve(solveOptions);
620 double *columnLower = lpSolver->columnLower();
621 double *columnUpper = lpSolver->columnUpper();
622 double *fullSolution = lpSolver->primalColumnSolution();
623 const double *dj = lpSolver->dualColumnSolution();
624 int iPass = 0;
625 #define MAXPROB 2
626 ClpSimplex models[MAXPROB];
627 int kPass = -1;
628 int kLayer = 0;
629 int skipZero = 0;
630 if (skipZero2 == -1)
631 skipZero2 = 40; //-1;
632 /* 0 fixed to 0 by choice
633 1 lb of 1 by choice
634 2 fixed to 0 by another
635 3 as 2 but this go
636 -1 free
637 */
638 char *state = new char[numberColumns];
639 for (iColumn = 0; iColumn < numberColumns; iColumn++)
640 state[iColumn] = -1;
641 while (true) {
642 double largest = -0.1;
643 double smallest = 1.1;
644 int iLargest = -1;
645 int iSmallest = -1;
646 int atZero = 0;
647 int atOne = 0;
648 int toZero = 0;
649 int toOne = 0;
650 int numberFree = 0;
651 int numberGreater = 0;
652 columnLower = lpSolver->columnLower();
653 columnUpper = lpSolver->columnUpper();
654 fullSolution = lpSolver->primalColumnSolution();
655 if (doAction == 11) {
656 {
657 double *columnLower = lpSolver->columnLower();
658 double *columnUpper = lpSolver->columnUpper();
659 // lpSolver->dual();
660 memcpy(columnLower, saveColumnLower, numberColumns * sizeof(double));
661 memcpy(columnUpper, saveColumnUpper, numberColumns * sizeof(double));
662 // lpSolver->dual();
663 int iColumn;
664 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
665 if (columnUpper[iColumn] > columnLower[iColumn] + 1.0e-8) {
666 if (clpSolver->isInteger(iColumn)) {
667 double value = lastSolution[iColumn];
668 int iValue = static_cast< int >(value + 0.5);
669 assert(fabs(value - static_cast< double >(iValue)) < 1.0e-3);
670 assert(iValue >= columnLower[iColumn] && iValue <= columnUpper[iColumn]);
671 columnLower[iColumn] = iValue;
672 columnUpper[iColumn] = iValue;
673 }
674 }
675 }
676 lpSolver->initialSolve(solveOptions);
677 memcpy(columnLower, saveColumnLower, numberColumns * sizeof(double));
678 memcpy(columnUpper, saveColumnUpper, numberColumns * sizeof(double));
679 }
680 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
681 if (columnUpper[iColumn] > columnLower[iColumn] + 1.0e-8) {
682 if (clpSolver->isInteger(iColumn)) {
683 double value = lastSolution[iColumn];
684 int iValue = static_cast< int >(value + 0.5);
685 assert(fabs(value - static_cast< double >(iValue)) < 1.0e-3);
686 assert(iValue >= columnLower[iColumn] && iValue <= columnUpper[iColumn]);
687 if (!fix[iColumn]) {
688 if (iValue == 0) {
689 state[iColumn] = 0;
690 assert(!columnLower[iColumn]);
691 columnUpper[iColumn] = 0.0;
692 } else if (iValue == 1) {
693 state[iColumn] = 1;
694 columnLower[iColumn] = 1.0;
695 } else {
696 // leave fixed
697 columnLower[iColumn] = iValue;
698 columnUpper[iColumn] = iValue;
699 }
700 } else if (iValue == 0) {
701 state[iColumn] = 10;
702 columnUpper[iColumn] = 0.0;
703 } else {
704 // leave fixed
705 columnLower[iColumn] = iValue;
706 columnUpper[iColumn] = iValue;
707 }
708 }
709 }
710 }
711 int jLayer = 0;
712 int nFixed = -1;
713 int nTotalFixed = 0;
714 while (nFixed) {
715 nFixed = 0;
716 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
717 if (columnUpper[iColumn] == 0.0 && fix[iColumn] == jLayer) {
718 for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
719 int jColumn = otherColumn[i];
720 if (columnUpper[jColumn]) {
721 bool canFix = true;
722 for (CoinBigIndex k = fixColumn2[jColumn]; k < fixColumn2[jColumn + 1]; k++) {
723 int kColumn = otherColumn2[k];
724 if (state[kColumn] == 1) {
725 canFix = false;
726 break;
727 }
728 }
729 if (canFix) {
730 columnUpper[jColumn] = 0.0;
731 nFixed++;
732 }
733 }
734 }
735 }
736 }
737 nTotalFixed += nFixed;
738 jLayer += 100;
739 }
740 COIN_DETAIL_PRINT(printf("This fixes %d variables in lower priorities\n", nTotalFixed));
741 break;
742 }
743 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
744 if (!clpSolver->isInteger(iColumn) || fix[iColumn] > kLayer)
745 continue;
746 // skip if fixes nothing
747 if (fixColumn[iColumn + 1] - fixColumn[iColumn] <= skipZero2)
748 continue;
749 double value = fullSolution[iColumn];
750 if (value > 1.00001) {
751 numberGreater++;
752 continue;
753 }
754 double lower = columnLower[iColumn];
755 double upper = columnUpper[iColumn];
756 if (lower == upper) {
757 if (lower)
758 atOne++;
759 else
760 atZero++;
761 continue;
762 }
763 if (value < 1.0e-7) {
764 toZero++;
765 columnUpper[iColumn] = 0.0;
766 state[iColumn] = 10;
767 continue;
768 }
769 if (value > 1.0 - 1.0e-7) {
770 toOne++;
771 columnLower[iColumn] = 1.0;
772 state[iColumn] = 1;
773 continue;
774 }
775 numberFree++;
776 // skip if fixes nothing
777 if (fixColumn[iColumn + 1] - fixColumn[iColumn] <= skipZero)
778 continue;
779 if (value < smallest) {
780 smallest = value;
781 iSmallest = iColumn;
782 }
783 if (value > largest) {
784 largest = value;
785 iLargest = iColumn;
786 }
787 }
788 if (toZero || toOne)
789 COIN_DETAIL_PRINT(printf("%d at 0 fixed and %d at one fixed\n", toZero, toOne));
790 COIN_DETAIL_PRINT(printf("%d variables free, %d fixed to 0, %d to 1 - smallest %g, largest %g\n",
791 numberFree, atZero, atOne, smallest, largest));
792 if (numberGreater && !iPass)
793 COIN_DETAIL_PRINT(printf("%d variables have value > 1.0\n", numberGreater));
794 //skipZero2=0; // leave 0 fixing
795 int jLayer = 0;
796 int nFixed = -1;
797 int nTotalFixed = 0;
798 while (nFixed) {
799 nFixed = 0;
800 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
801 if (columnUpper[iColumn] == 0.0 && fix[iColumn] == jLayer) {
802 for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
803 int jColumn = otherColumn[i];
804 if (columnUpper[jColumn]) {
805 bool canFix = true;
806 for (CoinBigIndex k = fixColumn2[jColumn]; k < fixColumn2[jColumn + 1]; k++) {
807 int kColumn = otherColumn2[k];
808 if (state[kColumn] == 1) {
809 canFix = false;
810 break;
811 }
812 }
813 if (canFix) {
814 columnUpper[jColumn] = 0.0;
815 nFixed++;
816 }
817 }
818 }
819 }
820 }
821 nTotalFixed += nFixed;
822 jLayer += 100;
823 }
824 COIN_DETAIL_PRINT(printf("This fixes %d variables in lower priorities\n", nTotalFixed));
825 if (iLargest < 0 || numberFree <= leaveIntFree)
826 break;
827 double movement;
828 int way;
829 if (smallest <= 1.0 - largest && smallest < 0.2 && largest < fixAboveValue) {
830 columnUpper[iSmallest] = 0.0;
831 state[iSmallest] = 0;
832 movement = smallest;
833 way = -1;
834 } else {
835 columnLower[iLargest] = 1.0;
836 state[iLargest] = 1;
837 movement = 1.0 - largest;
838 way = 1;
839 }
840 double saveObj = lpSolver->objectiveValue();
841 iPass++;
842 kPass = iPass % MAXPROB;
843 models[kPass] = *lpSolver;
844 if (way == -1) {
845 // fix others
846 for (CoinBigIndex i = fixColumn[iSmallest]; i < fixColumn[iSmallest + 1]; i++) {
847 int jColumn = otherColumn[i];
848 if (state[jColumn] == -1) {
849 columnUpper[jColumn] = 0.0;
850 state[jColumn] = 3;
851 }
852 }
853 }
854 double maxCostUp = COIN_DBL_MAX;
855 objective = lpSolver->getObjCoefficients();
856 if (way == -1)
857 maxCostUp = (1.0 - movement) * objective[iSmallest];
858 lpSolver->setDualObjectiveLimit(saveObj + maxCostUp);
859 crunchIt(lpSolver);
860 double moveObj = lpSolver->objectiveValue() - saveObj;
861 COIN_DETAIL_PRINT(printf("movement %s was %g costing %g\n",
862 (way == -1) ? "down" : "up", movement, moveObj));
863 if (way == -1 && (moveObj >= maxCostUp || lpSolver->status())) {
864 // go up
865 columnLower = models[kPass].columnLower();
866 columnUpper = models[kPass].columnUpper();
867 columnLower[iSmallest] = 1.0;
868 columnUpper[iSmallest] = saveColumnUpper[iSmallest];
869 *lpSolver = models[kPass];
870 columnLower = lpSolver->columnLower();
871 columnUpper = lpSolver->columnUpper();
872 fullSolution = lpSolver->primalColumnSolution();
873 dj = lpSolver->dualColumnSolution();
874 columnLower[iSmallest] = 1.0;
875 columnUpper[iSmallest] = saveColumnUpper[iSmallest];
876 state[iSmallest] = 1;
877 // unfix others
878 for (CoinBigIndex i = fixColumn[iSmallest]; i < fixColumn[iSmallest + 1]; i++) {
879 int jColumn = otherColumn[i];
880 if (state[jColumn] == 3) {
881 columnUpper[jColumn] = saveColumnUpper[jColumn];
882 state[jColumn] = -1;
883 }
884 }
885 crunchIt(lpSolver);
886 }
887 models[kPass] = *lpSolver;
888 }
889 lpSolver->dual();
890 COIN_DETAIL_PRINT(printf("Fixing took %g seconds\n", CoinCpuTime() - time1));
891 columnLower = lpSolver->columnLower();
892 columnUpper = lpSolver->columnUpper();
893 fullSolution = lpSolver->primalColumnSolution();
894 dj = lpSolver->dualColumnSolution();
895 int *sort = new int[numberColumns];
896 double *dsort = new double[numberColumns];
897 int chunk = 20;
898 int iRelax = 0;
899 //double fractionFixed=6.0/8.0;
900 // relax while lots fixed
901 while (true) {
902 if (skipZero2 > 10 && doAction < 10)
903 break;
904 iRelax++;
905 int n = 0;
906 double sum0 = 0.0;
907 double sum00 = 0.0;
908 double sum1 = 0.0;
909 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
910 if (!clpSolver->isInteger(iColumn) || fix[iColumn] > kLayer)
911 continue;
912 // skip if fixes nothing
913 if (fixColumn[iColumn + 1] - fixColumn[iColumn] == 0 && doAction < 10)
914 continue;
915 double djValue = dj[iColumn];
916 if (state[iColumn] == 1) {
917 assert(columnLower[iColumn]);
918 assert(fullSolution[iColumn] > 0.1);
919 if (djValue > 0.0) {
920 //printf("YY dj of %d at %g is %g\n",iColumn,value,djValue);
921 sum1 += djValue;
922 sort[n] = iColumn;
923 dsort[n++] = -djValue;
924 } else {
925 //printf("dj of %d at %g is %g\n",iColumn,value,djValue);
926 }
927 } else if (state[iColumn] == 0 || state[iColumn] == 10) {
928 assert(fullSolution[iColumn] < 0.1);
929 assert(!columnUpper[iColumn]);
930 double otherValue = 0.0;
931 int nn = 0;
932 for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
933 int jColumn = otherColumn[i];
934 if (columnUpper[jColumn] == 0.0) {
935 if (dj[jColumn] < -1.0e-5) {
936 nn++;
937 otherValue += dj[jColumn]; // really need to look at rest
938 }
939 }
940 }
941 if (djValue < -1.0e-2 || otherValue < -1.0e-2) {
942 //printf("XX dj of %d at %g is %g - %d out of %d contribute %g\n",iColumn,value,djValue,
943 // nn,fixColumn[iColumn+1]-fixColumn[iColumn],otherValue);
944 if (djValue < 1.0e-8) {
945 sum0 -= djValue;
946 sum00 -= otherValue;
947 sort[n] = iColumn;
948 if (djValue < -1.0e-2)
949 dsort[n++] = djValue + otherValue;
950 else
951 dsort[n++] = djValue + 0.001 * otherValue;
952 }
953 } else {
954 //printf("dj of %d at %g is %g - no contribution from %d\n",iColumn,value,djValue,
955 // fixColumn[iColumn+1]-fixColumn[iColumn]);
956 }
957 }
958 }
959 CoinSort_2(dsort, dsort + n, sort);
960 double *originalColumnLower = saveColumnLower;
961 double *originalColumnUpper = saveColumnUpper;
962 double *lo = CoinCopyOfArray(columnLower, numberColumns);
963 double *up = CoinCopyOfArray(columnUpper, numberColumns);
964 for (int k = 0; k < CoinMin(chunk, n); k++) {
965 iColumn = sort[k];
966 state[iColumn] = -2;
967 }
968 memcpy(columnLower, originalColumnLower, numberColumns * sizeof(double));
969 memcpy(columnUpper, originalColumnUpper, numberColumns * sizeof(double));
970 int nFixed = 0;
971 int nFixed0 = 0;
972 int nFixed1 = 0;
973 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
974 if (state[iColumn] == 0 || state[iColumn] == 10) {
975 columnUpper[iColumn] = 0.0;
976 assert(lo[iColumn] == 0.0);
977 nFixed++;
978 nFixed0++;
979 for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
980 int jColumn = otherColumn[i];
981 if (columnUpper[jColumn]) {
982 bool canFix = true;
983 for (CoinBigIndex k = fixColumn2[jColumn]; k < fixColumn2[jColumn + 1]; k++) {
984 int kColumn = otherColumn2[k];
985 if (state[kColumn] == 1 || state[kColumn] == -2) {
986 canFix = false;
987 break;
988 }
989 }
990 if (canFix) {
991 columnUpper[jColumn] = 0.0;
992 assert(lo[jColumn] == 0.0);
993 nFixed++;
994 }
995 }
996 }
997 } else if (state[iColumn] == 1) {
998 columnLower[iColumn] = 1.0;
999 nFixed1++;
1000 }
1001 }
1002 COIN_DETAIL_PRINT(printf("%d fixed %d orig 0 %d 1\n", nFixed, nFixed0, nFixed1));
1003 int jLayer = 0;
1004 nFixed = -1;
1005 int nTotalFixed = 0;
1006 while (nFixed) {
1007 nFixed = 0;
1008 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1009 if (columnUpper[iColumn] == 0.0 && fix[iColumn] == jLayer) {
1010 for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
1011 int jColumn = otherColumn[i];
1012 if (columnUpper[jColumn]) {
1013 bool canFix = true;
1014 for (CoinBigIndex k = fixColumn2[jColumn]; k < fixColumn2[jColumn + 1]; k++) {
1015 int kColumn = otherColumn2[k];
1016 if (state[kColumn] == 1 || state[kColumn] == -2) {
1017 canFix = false;
1018 break;
1019 }
1020 }
1021 if (canFix) {
1022 columnUpper[jColumn] = 0.0;
1023 assert(lo[jColumn] == 0.0);
1024 nFixed++;
1025 }
1026 }
1027 }
1028 }
1029 }
1030 nTotalFixed += nFixed;
1031 jLayer += 100;
1032 }
1033 nFixed = 0;
1034 int nFixedI = 0;
1035 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1036 if (columnLower[iColumn] == columnUpper[iColumn]) {
1037 if (clpSolver->isInteger(iColumn))
1038 nFixedI++;
1039 nFixed++;
1040 }
1041 }
1042 COIN_DETAIL_PRINT(printf("This fixes %d variables in lower priorities - total %d (%d integer) - all target %d, int target %d\n",
1043 nTotalFixed, nFixed, nFixedI, static_cast< int >(fractionFixed * numberColumns), static_cast< int >(fractionIntFixed * numberInteger)));
1044 int nBad = 0;
1045 int nRelax = 0;
1046 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1047 if (lo[iColumn] < columnLower[iColumn] || up[iColumn] > columnUpper[iColumn]) {
1048 COIN_DETAIL_PRINT(printf("bad %d old %g %g, new %g %g\n", iColumn, lo[iColumn], up[iColumn],
1049 columnLower[iColumn], columnUpper[iColumn]));
1050 nBad++;
1051 }
1052 if (lo[iColumn] > columnLower[iColumn] || up[iColumn] < columnUpper[iColumn]) {
1053 nRelax++;
1054 }
1055 }
1056 COIN_DETAIL_PRINT(printf("%d relaxed\n", nRelax));
1057 if (iRelax > 20 && nRelax == chunk)
1058 nRelax = 0;
1059 if (iRelax > 50)
1060 nRelax = 0;
1061 assert(!nBad);
1062 delete[] lo;
1063 delete[] up;
1064 lpSolver->primal(1);
1065 if (nFixed < fractionFixed * numberColumns || nFixedI < fractionIntFixed * numberInteger || !nRelax)
1066 break;
1067 }
1068 delete[] state;
1069 delete[] sort;
1070 delete[] dsort;
1071 }
1072 delete[] fix;
1073 delete[] fixColumn;
1074 delete[] otherColumn;
1075 delete[] otherColumn2;
1076 delete[] fixColumn2;
1077 // See if was presolved
1078 if (originalColumns) {
1079 columnLower = lpSolver->columnLower();
1080 columnUpper = lpSolver->columnUpper();
1081 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1082 saveColumnLower[iColumn] = columnLower[iColumn];
1083 saveColumnUpper[iColumn] = columnUpper[iColumn];
1084 }
1085 pinfo.postsolve(true);
1086 columnLower = originalLpSolver->columnLower();
1087 columnUpper = originalLpSolver->columnUpper();
1088 double *newColumnLower = lpSolver->columnLower();
1089 double *newColumnUpper = lpSolver->columnUpper();
1090 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1091 int jColumn = originalColumns[iColumn];
1092 columnLower[jColumn] = CoinMax(columnLower[jColumn], newColumnLower[iColumn]);
1093 columnUpper[jColumn] = CoinMin(columnUpper[jColumn], newColumnUpper[iColumn]);
1094 }
1095 numberColumns = originalLpSolver->numberColumns();
1096 delete[] originalColumns;
1097 }
1098 delete[] saveColumnLower;
1099 delete[] saveColumnUpper;
1100 if (!originalColumns) {
1101 // Basis
1102 memcpy(originalLpSolver->statusArray(), lpSolver->statusArray(), numberRows + numberColumns);
1103 memcpy(originalLpSolver->primalColumnSolution(), lpSolver->primalColumnSolution(), numberColumns * sizeof(double));
1104 memcpy(originalLpSolver->primalRowSolution(), lpSolver->primalRowSolution(), numberRows * sizeof(double));
1105 // Fix in solver
1106 columnLower = lpSolver->columnLower();
1107 columnUpper = lpSolver->columnUpper();
1108 }
1109 double *originalColumnLower = originalLpSolver->columnLower();
1110 double *originalColumnUpper = originalLpSolver->columnUpper();
1111 // number fixed
1112 doAction = 0;
1113 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1114 originalColumnLower[iColumn] = columnLower[iColumn];
1115 originalColumnUpper[iColumn] = columnUpper[iColumn];
1116 if (columnLower[iColumn] == columnUpper[iColumn])
1117 doAction++;
1118 }
1119 COIN_DETAIL_PRINT(printf("%d fixed by vub preprocessing\n", doAction));
1120 if (originalColumns) {
1121 originalLpSolver->initialSolve();
1122 }
1123 delete clpSolver;
1124 return NULL;
1125 }
1126
doHeuristics(CbcModel * model,int type,std::vector<CbcOrClpParam> parameters_,int noPrinting_,int initialPumpTune)1127 int doHeuristics(CbcModel *model, int type, std::vector< CbcOrClpParam > parameters_,
1128 int noPrinting_, int initialPumpTune)
1129 {
1130 #ifdef JJF_ZERO //NEW_STYLE_SOLVER==0
1131 CbcOrClpParam *parameters_ = parameters;
1132 int numberParameters_ = numberParameters;
1133 bool noPrinting_ = noPrinting_;
1134 #endif
1135 char generalPrint[10000];
1136 CoinMessages generalMessages = model->messages();
1137 CoinMessageHandler *generalMessageHandler = model->messageHandler();
1138 //generalMessageHandler->setPrefix(false);
1139 bool anyToDo = false;
1140 int logLevel = parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, parameters_)].intValue();
1141 int useFpump = parameters_[whichParam(CBC_PARAM_STR_FPUMP, parameters_)].currentOptionAsInteger();
1142 int useRounding = parameters_[whichParam(CBC_PARAM_STR_ROUNDING, parameters_)].currentOptionAsInteger();
1143 int useGreedy = parameters_[whichParam(CBC_PARAM_STR_GREEDY, parameters_)].currentOptionAsInteger();
1144 int useCombine = parameters_[whichParam(CBC_PARAM_STR_COMBINE, parameters_)].currentOptionAsInteger();
1145 int useProximity = parameters_[whichParam(CBC_PARAM_STR_PROXIMITY, parameters_)].currentOptionAsInteger();
1146 int useCrossover = parameters_[whichParam(CBC_PARAM_STR_CROSSOVER2, parameters_)].currentOptionAsInteger();
1147 //int usePivotC = parameters_[whichParam(CBC_PARAM_STR_PIVOTANDCOMPLEMENT, parameters_)].currentOptionAsInteger();
1148 int usePivotF = parameters_[whichParam(CBC_PARAM_STR_PIVOTANDFIX, parameters_)].currentOptionAsInteger();
1149 int useRand = parameters_[whichParam(CBC_PARAM_STR_RANDROUND, parameters_)].currentOptionAsInteger();
1150 int useRINS = parameters_[whichParam(CBC_PARAM_STR_RINS, parameters_)].currentOptionAsInteger();
1151 int useRENS = parameters_[whichParam(CBC_PARAM_STR_RENS, parameters_)].currentOptionAsInteger();
1152 int useVND = parameters_[whichParam(CBC_PARAM_STR_VND, parameters_)].currentOptionAsInteger();
1153 int useDINS = parameters_[whichParam(CBC_PARAM_STR_DINS, parameters_)].currentOptionAsInteger();
1154 int useDIVING2 = parameters_[whichParam(CBC_PARAM_STR_DIVINGS, parameters_)].currentOptionAsInteger();
1155 int useNaive = parameters_[whichParam(CBC_PARAM_STR_NAIVE, parameters_)].currentOptionAsInteger();
1156 int useDW = parameters_[whichParam(CBC_PARAM_STR_DW, parameters_)].currentOptionAsInteger();
1157 int kType = (type < 10) ? type : 1;
1158 assert(kType == 1 || kType == 2);
1159 // FPump done first as it only works if no solution
1160 if (useFpump >= kType && useFpump <= kType + 1) {
1161 anyToDo = true;
1162 CbcHeuristicFPump heuristic4(*model);
1163 double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_SMALLBAB, parameters_)].doubleValue();
1164 heuristic4.setFractionSmall(dextra3);
1165 double dextra1 = parameters_[whichParam(CBC_PARAM_DBL_ARTIFICIALCOST, parameters_)].doubleValue();
1166 if (dextra1)
1167 heuristic4.setArtificialCost(dextra1);
1168 heuristic4.setMaximumPasses(parameters_[whichParam(CBC_PARAM_INT_FPUMPITS, parameters_)].intValue());
1169 if (parameters_[whichParam(CBC_PARAM_INT_FPUMPITS, parameters_)].intValue() == 21)
1170 heuristic4.setIterationRatio(1.0);
1171 int pumpTune = parameters_[whichParam(CBC_PARAM_INT_FPUMPTUNE, parameters_)].intValue();
1172 int pumpTune2 = parameters_[whichParam(CBC_PARAM_INT_FPUMPTUNE2, parameters_)].intValue();
1173 if (pumpTune > 0) {
1174 bool printStuff = (pumpTune != initialPumpTune || logLevel > 1 || pumpTune2 > 0)
1175 && !noPrinting_;
1176 if (printStuff) {
1177 generalMessageHandler->message(CBC_GENERAL, generalMessages)
1178 << "Options for feasibility pump - "
1179 << CoinMessageEol;
1180 }
1181 /*
1182 >=10000000 for using obj
1183 >=1000000 use as accumulate switch
1184 >=1000 use index+1 as number of large loops
1185 >=100 use dextra1 as cutoff
1186 %100 == 10,20 etc for experimentation
1187 1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds
1188 4 and static continuous, 5 as 3 but no internal integers
1189 6 as 3 but all slack basis!
1190 */
1191 double value = model->solver()->getObjSense() * model->solver()->getObjValue();
1192 int w = pumpTune / 10;
1193 int i = w % 10;
1194 w /= 10;
1195 int c = w % 10;
1196 w /= 10;
1197 int r = w;
1198 int accumulate = r / 1000;
1199 r -= 1000 * accumulate;
1200 if (accumulate >= 100) {
1201 int which = accumulate / 100;
1202 accumulate -= 100 * which;
1203 which--;
1204 // weights and factors
1205 double weight[] = { 0.01, 0.01, 0.1, 0.1, 0.5, 0.5, 1.0, 1.0, 5.0, 5.0 };
1206 double factor[] = { 0.1, 0.5, 0.1, 0.5, 0.1, 0.5, 0.1, 0.5, 0.1, 0.5 };
1207 heuristic4.setInitialWeight(weight[which]);
1208 heuristic4.setWeightFactor(factor[which]);
1209 if (printStuff) {
1210 sprintf(generalPrint, "Initial weight for objective %g, decay factor %g",
1211 weight[which], factor[which]);
1212 generalMessageHandler->message(CBC_GENERAL, generalMessages)
1213 << generalPrint
1214 << CoinMessageEol;
1215 }
1216 }
1217 // fake cutoff
1218 if (c) {
1219 double cutoff;
1220 model->solver()->getDblParam(OsiDualObjectiveLimit, cutoff);
1221 cutoff = CoinMin(cutoff, value + 0.05 * fabs(value) * c);
1222 double fakeCutoff = parameters_[whichParam(CBC_PARAM_DBL_FAKECUTOFF, parameters_)].doubleValue();
1223 if (fakeCutoff)
1224 cutoff = fakeCutoff;
1225 heuristic4.setFakeCutoff(cutoff);
1226 if (printStuff) {
1227 sprintf(generalPrint, "Fake cutoff of %g", cutoff);
1228 generalMessageHandler->message(CBC_GENERAL, generalMessages)
1229 << generalPrint
1230 << CoinMessageEol;
1231 }
1232 }
1233 int offRandomEtc = 0;
1234 if (pumpTune2) {
1235 if ((pumpTune2 / 1000) != 0) {
1236 offRandomEtc = 1000000 * (pumpTune2 / 1000);
1237 if (printStuff) {
1238 generalMessageHandler->message(CBC_GENERAL, generalMessages)
1239 << "Feasibility pump may run twice"
1240 << CoinMessageEol;
1241 }
1242 pumpTune2 = pumpTune2 % 1000;
1243 }
1244 if ((pumpTune2 / 100) != 0) {
1245 offRandomEtc += 100 * (pumpTune2 / 100);
1246 if (printStuff) {
1247 generalMessageHandler->message(CBC_GENERAL, generalMessages)
1248 << "Not using randomized objective"
1249 << CoinMessageEol;
1250 }
1251 }
1252 int maxAllowed = pumpTune2 % 100;
1253 if (maxAllowed) {
1254 offRandomEtc += 1000 * maxAllowed;
1255 if (printStuff) {
1256 sprintf(generalPrint, "Fixing if same for %d passes",
1257 maxAllowed);
1258 generalMessageHandler->message(CBC_GENERAL, generalMessages)
1259 << generalPrint
1260 << CoinMessageEol;
1261 }
1262 }
1263 }
1264 if (accumulate) {
1265 heuristic4.setAccumulate(accumulate);
1266 if (printStuff) {
1267 if (accumulate) {
1268 sprintf(generalPrint, "Accumulate of %d", accumulate);
1269 generalMessageHandler->message(CBC_GENERAL, generalMessages)
1270 << generalPrint
1271 << CoinMessageEol;
1272 }
1273 }
1274 }
1275 if (r) {
1276 // also set increment
1277 //double increment = (0.01*i+0.005)*(fabs(value)+1.0e-12);
1278 double increment = 0.0;
1279 double fakeIncrement = parameters_[whichParam(CBC_PARAM_DBL_FAKEINCREMENT, parameters_)].doubleValue();
1280 if (fakeIncrement)
1281 increment = fakeIncrement;
1282 if (increment >= 0.0)
1283 heuristic4.setAbsoluteIncrement(increment);
1284 else
1285 heuristic4.setRelativeIncrement(-increment);
1286 heuristic4.setMaximumRetries(r + 1);
1287 if (printStuff) {
1288 if (increment) {
1289 if (increment > 0.0)
1290 sprintf(generalPrint, "Absolute increment of %g", increment);
1291 else
1292 sprintf(generalPrint, "Relative increment of %g", -increment);
1293 generalMessageHandler->message(CBC_GENERAL, generalMessages)
1294 << generalPrint
1295 << CoinMessageEol;
1296 }
1297 sprintf(generalPrint, "%d retries", r + 1);
1298 generalMessageHandler->message(CBC_GENERAL, generalMessages)
1299 << generalPrint
1300 << CoinMessageEol;
1301 }
1302 }
1303 if (i + offRandomEtc) {
1304 heuristic4.setFeasibilityPumpOptions(i * 10 + offRandomEtc);
1305 if (printStuff) {
1306 sprintf(generalPrint, "Feasibility pump options of %d",
1307 i * 10 + offRandomEtc);
1308 generalMessageHandler->message(CBC_GENERAL, generalMessages)
1309 << generalPrint
1310 << CoinMessageEol;
1311 }
1312 }
1313 pumpTune = pumpTune % 100;
1314 if (pumpTune == 6)
1315 pumpTune = 13;
1316 heuristic4.setWhen((pumpTune % 10) + 10);
1317 if (printStuff) {
1318 sprintf(generalPrint, "Tuning (fixing) %d", pumpTune % 10);
1319 generalMessageHandler->message(CBC_GENERAL, generalMessages)
1320 << generalPrint
1321 << CoinMessageEol;
1322 }
1323 }
1324 heuristic4.setHeuristicName("feasibility pump");
1325 //#define ROLF
1326 #ifdef ROLF
1327 CbcHeuristicFPump pump(*model);
1328 pump.setMaximumTime(60);
1329 pump.setMaximumPasses(100);
1330 pump.setMaximumRetries(1);
1331 pump.setFixOnReducedCosts(0);
1332 pump.setHeuristicName("Feasibility pump");
1333 pump.setFractionSmall(1.0);
1334 pump.setWhen(13);
1335 model->addHeuristic(&pump);
1336 #else
1337 model->addHeuristic(&heuristic4);
1338 #endif
1339 }
1340 if (useRounding >= type && useRounding >= kType && useRounding <= kType + 1) {
1341 CbcRounding heuristic1(*model);
1342 heuristic1.setHeuristicName("rounding");
1343 model->addHeuristic(&heuristic1);
1344 anyToDo = true;
1345 }
1346 if (useGreedy >= type && useGreedy >= kType && useGreedy <= kType + 1) {
1347 CbcHeuristicGreedyCover heuristic3(*model);
1348 heuristic3.setHeuristicName("greedy cover");
1349 CbcHeuristicGreedyEquality heuristic3a(*model);
1350 heuristic3a.setHeuristicName("greedy equality");
1351 model->addHeuristic(&heuristic3);
1352 model->addHeuristic(&heuristic3a);
1353 anyToDo = true;
1354 }
1355 if ((useRENS == 7 && kType == 1) || (useRENS == 8 && kType == 2)) {
1356 useRENS = 1 + 2 * (useRENS - 7);
1357 CbcHeuristicRENS heuristic6a(*model);
1358 heuristic6a.setHeuristicName("RENSdj");
1359 heuristic6a.setFractionSmall(0.6 /*3.4*/);
1360 heuristic6a.setFeasibilityPumpOptions(3);
1361 heuristic6a.setNumberNodes(10);
1362 heuristic6a.setWhereFrom(4 * 256 + 4 * 1);
1363 heuristic6a.setWhen(2);
1364 heuristic6a.setRensType(1 + 16);
1365 model->addHeuristic(&heuristic6a);
1366 heuristic6a.setHeuristicName("RENSub");
1367 heuristic6a.setFractionSmall(0.4);
1368 heuristic6a.setFeasibilityPumpOptions(1008003);
1369 heuristic6a.setNumberNodes(50);
1370 heuristic6a.setWhereFrom(4 * 256 + 4 * 1);
1371 heuristic6a.setWhen(2);
1372 heuristic6a.setRensType(2 + 16);
1373 model->addHeuristic(&heuristic6a);
1374 }
1375 if ((useRENS >= kType && useRENS <= kType + 1) || useRENS > 2) {
1376 CbcHeuristicRENS heuristic6(*model);
1377 heuristic6.setHeuristicName("RENS");
1378 heuristic6.setFractionSmall(0.4);
1379 heuristic6.setFeasibilityPumpOptions(1008003);
1380 int nodes[] = { -2, 50, 50, 50, 200, 1000, 10000, -1, -1, 200 };
1381 heuristic6.setNumberNodes(nodes[useRENS]);
1382 heuristic6.setRensType(useRENS != 9 ? 0 : 32);
1383 model->addHeuristic(&heuristic6);
1384 anyToDo = true;
1385 }
1386 if (useVND >= kType && useVND <= kType + 1) {
1387 CbcHeuristicVND heuristic6b(*model);
1388 heuristic6b.setHeuristicName("VND");
1389 heuristic6b.setFractionSmall(0.4);
1390 heuristic6b.setFeasibilityPumpOptions(1008003);
1391 int nodes[] = { -2, 50, 50, 50, 200, 1000, 10000 };
1392 heuristic6b.setNumberNodes(nodes[useVND]);
1393 model->addHeuristic(&heuristic6b);
1394 anyToDo = true;
1395 }
1396 if (useNaive >= kType && useNaive <= kType + 1) {
1397 CbcHeuristicNaive heuristic5b(*model);
1398 heuristic5b.setHeuristicName("Naive");
1399 heuristic5b.setFractionSmall(0.4);
1400 heuristic5b.setNumberNodes(50);
1401 model->addHeuristic(&heuristic5b);
1402 anyToDo = true;
1403 }
1404 int useDIVING = 0;
1405 {
1406 int useD;
1407 useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGV, parameters_)].currentOptionAsInteger();
1408 useDIVING |= 1 * ((useD >= kType) ? 1 : 0);
1409 useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGG, parameters_)].currentOptionAsInteger();
1410 useDIVING |= 2 * ((useD >= kType) ? 1 : 0);
1411 useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGF, parameters_)].currentOptionAsInteger();
1412 useDIVING |= 4 * ((useD >= kType) ? 1 : 0);
1413 useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGC, parameters_)].currentOptionAsInteger();
1414 useDIVING |= 8 * ((useD >= kType) ? 1 : 0);
1415 useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGL, parameters_)].currentOptionAsInteger();
1416 useDIVING |= 16 * ((useD >= kType) ? 1 : 0);
1417 useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGP, parameters_)].currentOptionAsInteger();
1418 useDIVING |= 32 * ((useD >= kType) ? 1 : 0);
1419 }
1420 if (useDIVING2 >= kType && useDIVING2 <= kType + 1) {
1421 int diveOptions = parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, parameters_)].intValue();
1422 if (diveOptions < 0 || diveOptions > 10)
1423 diveOptions = 2;
1424 CbcHeuristicJustOne heuristicJustOne(*model);
1425 heuristicJustOne.setHeuristicName("DiveAny");
1426 heuristicJustOne.setWhen(diveOptions);
1427 // add in others
1428 CbcHeuristicDiveCoefficient heuristicDC(*model);
1429 heuristicDC.setHeuristicName("DiveCoefficient");
1430 heuristicJustOne.addHeuristic(&heuristicDC, 1.0);
1431 CbcHeuristicDiveFractional heuristicDF(*model);
1432 heuristicDF.setHeuristicName("DiveFractional");
1433 heuristicJustOne.addHeuristic(&heuristicDF, 1.0);
1434 CbcHeuristicDiveGuided heuristicDG(*model);
1435 heuristicDG.setHeuristicName("DiveGuided");
1436 heuristicJustOne.addHeuristic(&heuristicDG, 1.0);
1437 CbcHeuristicDiveLineSearch heuristicDL(*model);
1438 heuristicDL.setHeuristicName("DiveLineSearch");
1439 heuristicJustOne.addHeuristic(&heuristicDL, 1.0);
1440 CbcHeuristicDivePseudoCost heuristicDP(*model);
1441 heuristicDP.setHeuristicName("DivePseudoCost");
1442 heuristicJustOne.addHeuristic(&heuristicDP, 1.0);
1443 CbcHeuristicDiveVectorLength heuristicDV(*model);
1444 heuristicDV.setHeuristicName("DiveVectorLength");
1445 heuristicJustOne.addHeuristic(&heuristicDV, 1.0);
1446 // Now normalize probabilities
1447 heuristicJustOne.normalizeProbabilities();
1448 model->addHeuristic(&heuristicJustOne);
1449 }
1450
1451 if (useDIVING > 0) {
1452 int majorIterations = parameters_[whichParam(CBC_PARAM_INT_DIVEOPTSOLVES, parameters_)].intValue();
1453 int diveOptions2 = parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, parameters_)].intValue();
1454 int diveOptions;
1455 if (diveOptions2 > 99) {
1456 // switch on various active set stuff
1457 diveOptions = diveOptions2 % 100;
1458 diveOptions2 /= 100;
1459 } else {
1460 diveOptions = diveOptions2;
1461 diveOptions2 = 0;
1462 }
1463 if (diveOptions < 0 || diveOptions > 29)
1464 diveOptions = 2;
1465 int diveOptionsNotC = diveOptions;
1466 if (diveOptions > 10) {
1467 if (diveOptions > 20) {
1468 diveOptions -= 20;
1469 diveOptionsNotC -= 20;
1470 } else {
1471 diveOptions -= 10;
1472 diveOptionsNotC = 4;
1473 }
1474 useDIVING = 63;
1475 }
1476 if ((useDIVING & 1) != 0) {
1477 CbcHeuristicDiveVectorLength heuristicDV(*model);
1478 heuristicDV.setHeuristicName("DiveVectorLength");
1479 heuristicDV.setWhen(diveOptionsNotC);
1480 heuristicDV.setMaxIterations(majorIterations);
1481 if (diveOptions2) {
1482 heuristicDV.setPercentageToFix(0.0);
1483 heuristicDV.setMaxSimplexIterations(COIN_INT_MAX);
1484 heuristicDV.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1485 }
1486 model->addHeuristic(&heuristicDV);
1487 }
1488 if ((useDIVING & 2) != 0) {
1489 CbcHeuristicDiveGuided heuristicDG(*model);
1490 heuristicDG.setHeuristicName("DiveGuided");
1491 heuristicDG.setWhen(diveOptionsNotC);
1492 heuristicDG.setMaxIterations(majorIterations);
1493 if (diveOptions2) {
1494 heuristicDG.setPercentageToFix(0.0);
1495 heuristicDG.setMaxSimplexIterations(COIN_INT_MAX);
1496 heuristicDG.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1497 }
1498 model->addHeuristic(&heuristicDG);
1499 }
1500 if ((useDIVING & 4) != 0) {
1501 CbcHeuristicDiveFractional heuristicDF(*model);
1502 heuristicDF.setHeuristicName("DiveFractional");
1503 heuristicDF.setWhen(diveOptionsNotC);
1504 heuristicDF.setMaxIterations(majorIterations);
1505 if (diveOptions2) {
1506 heuristicDF.setPercentageToFix(0.0);
1507 heuristicDF.setMaxSimplexIterations(COIN_INT_MAX);
1508 heuristicDF.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1509 }
1510 model->addHeuristic(&heuristicDF);
1511 }
1512 if ((useDIVING & 8) != 0) {
1513 CbcHeuristicDiveCoefficient heuristicDC(*model);
1514 heuristicDC.setHeuristicName("DiveCoefficient");
1515 heuristicDC.setWhen(diveOptions);
1516 heuristicDC.setMaxIterations(majorIterations);
1517 if (diveOptions2) {
1518 heuristicDC.setPercentageToFix(0.0);
1519 heuristicDC.setMaxSimplexIterations(COIN_INT_MAX);
1520 heuristicDC.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1521 }
1522 model->addHeuristic(&heuristicDC);
1523 }
1524 if ((useDIVING & 16) != 0) {
1525 CbcHeuristicDiveLineSearch heuristicDL(*model);
1526 heuristicDL.setHeuristicName("DiveLineSearch");
1527 heuristicDL.setWhen(diveOptionsNotC);
1528 heuristicDL.setMaxIterations(majorIterations);
1529 if (diveOptions2) {
1530 heuristicDL.setPercentageToFix(0.0);
1531 heuristicDL.setMaxSimplexIterations(COIN_INT_MAX);
1532 heuristicDL.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1533 }
1534 model->addHeuristic(&heuristicDL);
1535 }
1536 if ((useDIVING & 32) != 0) {
1537 CbcHeuristicDivePseudoCost heuristicDP(*model);
1538 heuristicDP.setHeuristicName("DivePseudoCost");
1539 heuristicDP.setWhen(diveOptionsNotC /*+ diveOptions2*/);
1540 heuristicDP.setMaxIterations(majorIterations);
1541 if (diveOptions2) {
1542 heuristicDP.setPercentageToFix(0.0);
1543 heuristicDP.setMaxSimplexIterations(COIN_INT_MAX);
1544 heuristicDP.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1545 }
1546 model->addHeuristic(&heuristicDP);
1547 }
1548 anyToDo = true;
1549 }
1550 #ifdef JJF_ZERO
1551 if (usePivotC >= type && usePivotC <= kType + 1) {
1552 CbcHeuristicPivotAndComplement heuristic(*model);
1553 heuristic.setHeuristicName("pivot and complement");
1554 heuristic.setFractionSmall(10.0); // normally 0.5
1555 model->addHeuristic(&heuristic);
1556 anyToDo = true;
1557 }
1558 #endif
1559 if (usePivotF >= type && usePivotF <= kType + 1) {
1560 CbcHeuristicPivotAndFix heuristic(*model);
1561 heuristic.setHeuristicName("pivot and fix");
1562 heuristic.setFractionSmall(10.0); // normally 0.5
1563 model->addHeuristic(&heuristic);
1564 anyToDo = true;
1565 }
1566 if (useRand >= type && useRand <= kType + 1) {
1567 CbcHeuristicRandRound heuristic(*model);
1568 heuristic.setHeuristicName("randomized rounding");
1569 heuristic.setFractionSmall(10.0); // normally 0.5
1570 model->addHeuristic(&heuristic);
1571 anyToDo = true;
1572 }
1573 if (useDINS >= kType && useDINS <= kType + 1) {
1574 CbcHeuristicDINS heuristic5a(*model);
1575 heuristic5a.setHeuristicName("DINS");
1576 heuristic5a.setFractionSmall(0.6);
1577 if (useDINS < 4)
1578 heuristic5a.setDecayFactor(5.0);
1579 else
1580 heuristic5a.setDecayFactor(1.5);
1581 heuristic5a.setNumberNodes(1000);
1582 model->addHeuristic(&heuristic5a);
1583 anyToDo = true;
1584 }
1585 if (useRINS >= kType && useRINS <= kType + 1) {
1586 CbcHeuristicRINS heuristic5(*model);
1587 heuristic5.setHeuristicName("RINS");
1588 if (useRINS < 4) {
1589 heuristic5.setFractionSmall(0.5);
1590 heuristic5.setDecayFactor(5.0);
1591 } else {
1592 heuristic5.setFractionSmall(0.6);
1593 heuristic5.setDecayFactor(1.5);
1594 }
1595 model->addHeuristic(&heuristic5);
1596 anyToDo = true;
1597 }
1598 if (useDW >= kType && useDW <= kType + 1) {
1599 CbcHeuristicDW heuristic13(*model);
1600 heuristic13.setHeuristicName("Dantzig-Wolfe");
1601 heuristic13.setNumberPasses(100);
1602 heuristic13.setNumberBadPasses(10);
1603 int numberIntegers = 0;
1604 const OsiSolverInterface *solver = model->solver();
1605 int numberColumns = solver->getNumCols();
1606 for (int i = 0; i < numberColumns; i++) {
1607 if (solver->isInteger(i))
1608 numberIntegers++;
1609 }
1610 heuristic13.setNumberNeeded(CoinMin(200, numberIntegers / 10));
1611 model->addHeuristic(&heuristic13);
1612 anyToDo = true;
1613 }
1614 if (useCombine >= kType && (useCombine - 1) % 3 <= kType) {
1615 CbcHeuristicLocal heuristic2(*model);
1616 heuristic2.setHeuristicName("combine solutions");
1617 heuristic2.setFractionSmall(0.5);
1618 int searchType = 1;
1619 if (useCombine > 3)
1620 searchType += 10; // experiment
1621 heuristic2.setSearchType(searchType);
1622 model->addHeuristic(&heuristic2);
1623 anyToDo = true;
1624 }
1625 if ((useProximity >= kType && useProximity <= kType + 1) || (kType == 1 && useProximity > 3)) {
1626 CbcHeuristicProximity heuristic2a(*model);
1627 heuristic2a.setHeuristicName("Proximity Search");
1628 heuristic2a.setFractionSmall(9999999.0);
1629 heuristic2a.setNumberNodes(30);
1630 heuristic2a.setFeasibilityPumpOptions(-2);
1631 if (useProximity >= 4) {
1632 const int nodes[] = { 10, 100, 300 };
1633 heuristic2a.setNumberNodes(nodes[useProximity - 4]);
1634 // more print out and stronger feasibility pump
1635 if (useProximity == 6)
1636 heuristic2a.setFeasibilityPumpOptions(-3);
1637 } else {
1638 int proximityNumber;
1639 parameters_[whichParam(CBC_PARAM_STR_PROXIMITY, parameters_)].currentOptionAsInteger(proximityNumber);
1640 if (proximityNumber > 0) {
1641 heuristic2a.setNumberNodes(proximityNumber);
1642 // more print out and stronger feasibility pump
1643 if (proximityNumber >= 300)
1644 heuristic2a.setFeasibilityPumpOptions(-3);
1645 }
1646 }
1647 model->addHeuristic(&heuristic2a);
1648 anyToDo = true;
1649 }
1650 if (useCrossover >= kType && useCrossover <= kType + 1) {
1651 CbcHeuristicCrossover heuristic2a(*model);
1652 heuristic2a.setHeuristicName("crossover");
1653 heuristic2a.setFractionSmall(0.3);
1654 // just fix at lower
1655 heuristic2a.setWhen(11);
1656 model->addHeuristic(&heuristic2a);
1657 model->setMaximumSavedSolutions(5);
1658 anyToDo = true;
1659 }
1660 int heurSwitches = parameters_[whichParam(CBC_PARAM_INT_HOPTIONS, parameters_)].intValue() % 100;
1661 if (heurSwitches) {
1662 for (int iHeur = 0; iHeur < model->numberHeuristics(); iHeur++) {
1663 CbcHeuristic *heuristic = model->heuristic(iHeur);
1664 heuristic->setSwitches(heurSwitches);
1665 }
1666 }
1667 if (type == 2 && anyToDo) {
1668 // Do heuristics
1669 #ifndef JJF_ONE
1670 // clean copy
1671 CbcModel model2(*model);
1672 // But get rid of heuristics in model
1673 model->doHeuristicsAtRoot(2);
1674 if (logLevel <= 1)
1675 model2.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
1676 OsiBabSolver defaultC;
1677 //solver_->setAuxiliaryInfo(&defaultC);
1678 model2.passInSolverCharacteristics(&defaultC);
1679 // Save bounds
1680 int numberColumns = model2.solver()->getNumCols();
1681 model2.createContinuousSolver();
1682 bool cleanModel = !model2.numberIntegers() && !model2.numberObjects();
1683 model2.findIntegers(false);
1684 int heurOptions = (parameters_[whichParam(CBC_PARAM_INT_HOPTIONS, parameters_)].intValue() / 100) % 100;
1685 if (heurOptions == 0 || heurOptions == 2) {
1686 model2.doHeuristicsAtRoot(1);
1687 } else if (heurOptions == 1 || heurOptions == 3) {
1688 model2.setMaximumNodes(-1);
1689 CbcStrategyDefault strategy(0, 5, 5);
1690 strategy.setupPreProcessing(1, 0);
1691 model2.setStrategy(strategy);
1692 model2.branchAndBound();
1693 }
1694 if (cleanModel)
1695 model2.zapIntegerInformation(false);
1696 if (model2.bestSolution()) {
1697 double value = model2.getMinimizationObjValue();
1698 model->setCutoff(value);
1699 model->setBestSolution(model2.bestSolution(), numberColumns, value);
1700 model->setSolutionCount(1);
1701 model->setNumberHeuristicSolutions(1);
1702 }
1703 #else
1704 if (logLevel <= 1)
1705 model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
1706 OsiBabSolver defaultC;
1707 //solver_->setAuxiliaryInfo(&defaultC);
1708 model->passInSolverCharacteristics(&defaultC);
1709 // Save bounds
1710 int numberColumns = model->solver()->getNumCols();
1711 model->createContinuousSolver();
1712 bool cleanModel = !model->numberIntegers() && !model->numberObjects();
1713 model->findIntegers(false);
1714 model->doHeuristicsAtRoot(1);
1715 if (cleanModel)
1716 model->zapIntegerInformation(false);
1717 #endif
1718 return 0;
1719 } else {
1720 return 0;
1721 }
1722 }
1723
1724 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
1725 */
1726