 Timestamp:
 Dec 2, 2009 2:25:28 PM (9 years ago)
 Location:
 branches/sandbox/Cbc/src
 Files:

 2 edited
Legend:
 Unmodified
 Added
 Removed

branches/sandbox/Cbc/src/CbcModel.cpp
r1315 r1330 1130 1130 } 1131 1131 1132 1133 1132 void CbcModel::saveModel(OsiSolverInterface * saveSolver, double * checkCutoffForRestart, bool * feasible) 1133 { 1134 if (saveSolver && (specialOptions_&32768) != 0) { 1135 // See if worth trying reduction 1136 *checkCutoffForRestart = getCutoff(); 1137 bool tryNewSearch = solverCharacteristics_>reducedCostsAccurate() && 1138 (*checkCutoffForRestart < 1.0e20); 1139 int numberColumns = getNumCols(); 1140 if (tryNewSearch) { 1141 #ifdef CLP_INVESTIGATE 1142 printf("after %d nodes, cutoff %g  looking\n", 1143 numberNodes_, getCutoff()); 1144 #endif 1145 saveSolver>resolve(); 1146 double direction = saveSolver>getObjSense() ; 1147 double gap = *checkCutoffForRestart  saveSolver>getObjValue() * direction ; 1148 double tolerance; 1149 saveSolver>getDblParam(OsiDualTolerance, tolerance) ; 1150 if (gap <= 0.0) 1151 gap = tolerance; 1152 gap += 100.0 * tolerance; 1153 double integerTolerance = getDblParam(CbcIntegerTolerance) ; 1154 1155 const double *lower = saveSolver>getColLower() ; 1156 const double *upper = saveSolver>getColUpper() ; 1157 const double *solution = saveSolver>getColSolution() ; 1158 const double *reducedCost = saveSolver>getReducedCost() ; 1159 1160 int numberFixed = 0 ; 1161 int numberFixed2 = 0; 1162 for (int i = 0 ; i < numberIntegers_ ; i++) { 1163 int iColumn = integerVariable_[i] ; 1164 double djValue = direction * reducedCost[iColumn] ; 1165 if (upper[iColumn]  lower[iColumn] > integerTolerance) { 1166 if (solution[iColumn] < lower[iColumn] + integerTolerance && djValue > gap) { 1167 saveSolver>setColUpper(iColumn, lower[iColumn]) ; 1168 numberFixed++ ; 1169 } else if (solution[iColumn] > upper[iColumn]  integerTolerance && djValue > gap) { 1170 saveSolver>setColLower(iColumn, upper[iColumn]) ; 1171 numberFixed++ ; 1172 } 1173 } else { 1174 numberFixed2++; 1175 } 1176 } 1177 #ifdef COIN_DEVELOP 1178 if ((specialOptions_&1) != 0) { 1179 const OsiRowCutDebugger *debugger = saveSolver>getRowCutDebugger() ; 1180 if (debugger) { 1181 printf("Contains optimal\n") ; 1182 OsiSolverInterface * temp = saveSolver>clone(); 1183 const double * solution = debugger>optimalSolution(); 1184 const double *lower = temp>getColLower() ; 1185 const double *upper = temp>getColUpper() ; 1186 int n = temp>getNumCols(); 1187 for (int i = 0; i < n; i++) { 1188 if (temp>isInteger(i)) { 1189 double value = floor(solution[i] + 0.5); 1190 assert (value >= lower[i] && value <= upper[i]); 1191 temp>setColLower(i, value); 1192 temp>setColUpper(i, value); 1193 } 1194 } 1195 temp>writeMps("reduced_fix"); 1196 delete temp; 1197 saveSolver>writeMps("reduced"); 1198 } else { 1199 abort(); 1200 } 1201 } 1202 printf("Restart could fix %d integers (%d already fixed)\n", 1203 numberFixed + numberFixed2, numberFixed2); 1204 #endif 1205 numberFixed += numberFixed2; 1206 if (numberFixed*20 < numberColumns) 1207 tryNewSearch = false; 1208 } 1209 if (tryNewSearch) { 1210 // back to solver without cuts? 1211 OsiSolverInterface * solver2 = continuousSolver_>clone(); 1212 const double *lower = saveSolver>getColLower() ; 1213 const double *upper = saveSolver>getColUpper() ; 1214 for (int i = 0 ; i < numberIntegers_ ; i++) { 1215 int iColumn = integerVariable_[i] ; 1216 solver2>setColLower(iColumn, lower[iColumn]); 1217 solver2>setColUpper(iColumn, upper[iColumn]); 1218 } 1219 // swap 1220 delete saveSolver; 1221 saveSolver = solver2; 1222 double * newSolution = new double[numberColumns]; 1223 double objectiveValue = *checkCutoffForRestart; 1224 CbcSerendipity heuristic(*this); 1225 if (bestSolution_) 1226 heuristic.setInputSolution(bestSolution_, bestObjective_); 1227 heuristic.setFractionSmall(0.9); 1228 heuristic.setFeasibilityPumpOptions(1008013); 1229 // Use numberNodes to say how many are original rows 1230 heuristic.setNumberNodes(continuousSolver_>getNumRows()); 1231 #ifdef COIN_DEVELOP 1232 if (continuousSolver_>getNumRows() < 1233 saveSolver>getNumRows()) 1234 printf("%d rows added ZZZZZ\n", 1235 solver_>getNumRows()  continuousSolver_>getNumRows()); 1236 #endif 1237 int returnCode = heuristic.smallBranchAndBound(saveSolver, 1238 1, newSolution, 1239 objectiveValue, 1240 *checkCutoffForRestart, "Reduce"); 1241 if (returnCode < 0) { 1242 #ifdef COIN_DEVELOP 1243 printf("Restart  not small enough to do search after fixing\n"); 1244 #endif 1245 delete [] newSolution; 1246 } else { 1247 if ((returnCode&1) != 0) { 1248 // increment number of solutions so other heuristics can test 1249 numberSolutions_++; 1250 numberHeuristicSolutions_++; 1251 lastHeuristic_ = NULL; 1252 setBestSolution(CBC_ROUNDING, objectiveValue, newSolution) ; 1253 } 1254 delete [] newSolution; 1255 *feasible = false; // stop search 1256 } 1257 } 1258 } 1259 } 1260 /* 1261 Adds integers, called from BranchandBound() 1262 */ 1263 void CbcModel::AddIntegers() 1264 { 1265 int numberColumns = continuousSolver_>getNumCols(); 1266 int numberRows = continuousSolver_>getNumRows(); 1267 int * del = new int [CoinMax(numberColumns, numberRows)]; 1268 int * original = new int [numberColumns]; 1269 char * possibleRow = new char [numberRows]; 1270 { 1271 const CoinPackedMatrix * rowCopy = continuousSolver_>getMatrixByRow(); 1272 const int * column = rowCopy>getIndices(); 1273 const int * rowLength = rowCopy>getVectorLengths(); 1274 const CoinBigIndex * rowStart = rowCopy>getVectorStarts(); 1275 const double * rowLower = continuousSolver_>getRowLower(); 1276 const double * rowUpper = continuousSolver_>getRowUpper(); 1277 const double * element = rowCopy>getElements(); 1278 for (int i = 0; i < numberRows; i++) { 1279 int nLeft = 0; 1280 bool possible = false; 1281 if (rowLower[i] < 1.0e20) { 1282 double value = rowUpper[i]; 1283 if (fabs(value  floor(value + 0.5)) < 1.0e8) 1284 possible = true; 1285 } else if (rowUpper[i] > 1.0e20) { 1286 double value = rowLower[i]; 1287 if (fabs(value  floor(value + 0.5)) < 1.0e8) 1288 possible = true; 1289 } else { 1290 double value = rowUpper[i]; 1291 if (rowLower[i] == rowUpper[i] && 1292 fabs(value  floor(value + 0.5)) < 1.0e8) 1293 possible = true; 1294 } 1295 for (CoinBigIndex j = rowStart[i]; 1296 j < rowStart[i] + rowLength[i]; j++) { 1297 int iColumn = column[j]; 1298 if (continuousSolver_>isInteger(iColumn)) { 1299 if (fabs(element[j]) != 1.0) 1300 possible = false; 1301 } else { 1302 nLeft++; 1303 } 1304 } 1305 if (possible  !nLeft) 1306 possibleRow[i] = 1; 1307 else 1308 possibleRow[i] = 0; 1309 } 1310 } 1311 int nDel = 0; 1312 for (int i = 0; i < numberColumns; i++) { 1313 original[i] = i; 1314 if (continuousSolver_>isInteger(i)) 1315 del[nDel++] = i; 1316 } 1317 int nExtra = 0; 1318 OsiSolverInterface * copy1 = continuousSolver_>clone(); 1319 int nPass = 0; 1320 while (nDel && nPass < 10) { 1321 nPass++; 1322 OsiSolverInterface * copy2 = copy1>clone(); 1323 int nLeft = 0; 1324 for (int i = 0; i < nDel; i++) 1325 original[del[i]] = 1; 1326 for (int i = 0; i < numberColumns; i++) { 1327 int kOrig = original[i]; 1328 if (kOrig >= 0) 1329 original[nLeft++] = kOrig; 1330 } 1331 assert (nLeft == numberColumns  nDel); 1332 copy2>deleteCols(nDel, del); 1333 numberColumns = copy2>getNumCols(); 1334 const CoinPackedMatrix * rowCopy = copy2>getMatrixByRow(); 1335 numberRows = rowCopy>getNumRows(); 1336 const int * column = rowCopy>getIndices(); 1337 const int * rowLength = rowCopy>getVectorLengths(); 1338 const CoinBigIndex * rowStart = rowCopy>getVectorStarts(); 1339 const double * rowLower = copy2>getRowLower(); 1340 const double * rowUpper = copy2>getRowUpper(); 1341 const double * element = rowCopy>getElements(); 1342 const CoinPackedMatrix * columnCopy = copy2>getMatrixByCol(); 1343 const int * columnLength = columnCopy>getVectorLengths(); 1344 nDel = 0; 1345 // Could do gcd stuff on ones with costs 1346 for (int i = 0; i < numberRows; i++) { 1347 if (!rowLength[i]) { 1348 del[nDel++] = i; 1349 possibleRow[i] = 1; 1350 } else if (possibleRow[i]) { 1351 if (rowLength[i] == 1) { 1352 int k = rowStart[i]; 1353 int iColumn = column[k]; 1354 if (!copy2>isInteger(iColumn)) { 1355 double mult = 1.0 / fabs(element[k]); 1356 if (rowLower[i] < 1.0e20) { 1357 double value = rowUpper[i] * mult; 1358 if (fabs(value  floor(value + 0.5)) < 1.0e8) { 1359 del[nDel++] = i; 1360 if (columnLength[iColumn] == 1) { 1361 copy2>setInteger(iColumn); 1362 int kOrig = original[iColumn]; 1363 setOptionalInteger(kOrig); 1364 } 1365 } 1366 } else if (rowUpper[i] > 1.0e20) { 1367 double value = rowLower[i] * mult; 1368 if (fabs(value  floor(value + 0.5)) < 1.0e8) { 1369 del[nDel++] = i; 1370 if (columnLength[iColumn] == 1) { 1371 copy2>setInteger(iColumn); 1372 int kOrig = original[iColumn]; 1373 setOptionalInteger(kOrig); 1374 } 1375 } 1376 } else { 1377 double value = rowUpper[i] * mult; 1378 if (rowLower[i] == rowUpper[i] && 1379 fabs(value  floor(value + 0.5)) < 1.0e8) { 1380 del[nDel++] = i; 1381 copy2>setInteger(iColumn); 1382 int kOrig = original[iColumn]; 1383 setOptionalInteger(kOrig); 1384 } 1385 } 1386 } 1387 } else { 1388 // only if all singletons 1389 bool possible = false; 1390 if (rowLower[i] < 1.0e20) { 1391 double value = rowUpper[i]; 1392 if (fabs(value  floor(value + 0.5)) < 1.0e8) 1393 possible = true; 1394 } else if (rowUpper[i] > 1.0e20) { 1395 double value = rowLower[i]; 1396 if (fabs(value  floor(value + 0.5)) < 1.0e8) 1397 possible = true; 1398 } else { 1399 double value = rowUpper[i]; 1400 if (rowLower[i] == rowUpper[i] && 1401 fabs(value  floor(value + 0.5)) < 1.0e8) 1402 possible = true; 1403 } 1404 if (possible) { 1405 for (CoinBigIndex j = rowStart[i]; 1406 j < rowStart[i] + rowLength[i]; j++) { 1407 int iColumn = column[j]; 1408 if (columnLength[iColumn] != 1  fabs(element[j]) != 1.0) { 1409 possible = false; 1410 break; 1411 } 1412 } 1413 if (possible) { 1414 for (CoinBigIndex j = rowStart[i]; 1415 j < rowStart[i] + rowLength[i]; j++) { 1416 int iColumn = column[j]; 1417 if (!copy2>isInteger(iColumn)) { 1418 copy2>setInteger(iColumn); 1419 int kOrig = original[iColumn]; 1420 setOptionalInteger(kOrig); 1421 } 1422 } 1423 del[nDel++] = i; 1424 } 1425 } 1426 } 1427 } 1428 } 1429 if (nDel) { 1430 copy2>deleteRows(nDel, del); 1431 } 1432 if (nDel != numberRows) { 1433 nDel = 0; 1434 for (int i = 0; i < numberColumns; i++) { 1435 if (copy2>isInteger(i)) { 1436 del[nDel++] = i; 1437 nExtra++; 1438 } 1439 } 1440 } else { 1441 nDel = 0; 1442 } 1443 delete copy1; 1444 copy1 = copy2>clone(); 1445 delete copy2; 1446 } 1447 // See if what's left is a network 1448 bool couldBeNetwork = false; 1449 if (copy1>getNumRows() && copy1>getNumCols()) { 1450 #ifdef COIN_HAS_CLP 1451 OsiClpSolverInterface * clpSolver 1452 = dynamic_cast<OsiClpSolverInterface *> (copy1); 1453 if (false && clpSolver) { 1454 numberRows = clpSolver>getNumRows(); 1455 char * rotate = new char[numberRows]; 1456 int n = clpSolver>getModelPtr()>findNetwork(rotate, 1.0); 1457 delete [] rotate; 1458 #ifdef CLP_INVESTIGATE 1459 printf("INTA network %d rows out of %d\n", n, numberRows); 1460 #endif 1461 if (CoinAbs(n) == numberRows) { 1462 couldBeNetwork = true; 1463 for (int i = 0; i < numberRows; i++) { 1464 if (!possibleRow[i]) { 1465 couldBeNetwork = false; 1466 #ifdef CLP_INVESTIGATE 1467 printf("but row %d is bad\n", i); 1468 #endif 1469 break; 1470 } 1471 } 1472 } 1473 } else 1474 #endif 1475 { 1476 numberColumns = copy1>getNumCols(); 1477 numberRows = copy1>getNumRows(); 1478 const double * rowLower = copy1>getRowLower(); 1479 const double * rowUpper = copy1>getRowUpper(); 1480 couldBeNetwork = true; 1481 for (int i = 0; i < numberRows; i++) { 1482 if (rowLower[i] > 1.0e20 && fabs(rowLower[i]  floor(rowLower[i] + 0.5)) > 1.0e12) { 1483 couldBeNetwork = false; 1484 break; 1485 } 1486 if (rowUpper[i] < 1.0e20 && fabs(rowUpper[i]  floor(rowUpper[i] + 0.5)) > 1.0e12) { 1487 couldBeNetwork = false; 1488 break; 1489 } 1490 } 1491 if (couldBeNetwork) { 1492 const CoinPackedMatrix * matrixByCol = copy1>getMatrixByCol(); 1493 const double * element = matrixByCol>getElements(); 1494 //const int * row = matrixByCol>getIndices(); 1495 const CoinBigIndex * columnStart = matrixByCol>getVectorStarts(); 1496 const int * columnLength = matrixByCol>getVectorLengths(); 1497 for (int iColumn = 0; iColumn < numberColumns; iColumn++) { 1498 CoinBigIndex start = columnStart[iColumn]; 1499 CoinBigIndex end = start + columnLength[iColumn]; 1500 if (end > start + 2) { 1501 couldBeNetwork = false; 1502 break; 1503 } 1504 int type = 0; 1505 for (CoinBigIndex j = start; j < end; j++) { 1506 double value = element[j]; 1507 if (fabs(value) != 1.0) { 1508 couldBeNetwork = false; 1509 break; 1510 } else if (value == 1.0) { 1511 if ((type&1) == 0) 1512 type = 1; 1513 else 1514 type = 7; 1515 } else if (value == 1.0) { 1516 if ((type&2) == 0) 1517 type = 2; 1518 else 1519 type = 7; 1520 } 1521 } 1522 if (type > 3) { 1523 couldBeNetwork = false; 1524 break; 1525 } 1526 } 1527 } 1528 } 1529 } 1530 if (couldBeNetwork) { 1531 for (int i = 0; i < numberColumns; i++) 1532 setOptionalInteger(original[i]); 1533 } 1534 if (nExtra  couldBeNetwork) { 1535 numberColumns = copy1>getNumCols(); 1536 numberRows = copy1>getNumRows(); 1537 if (!numberColumns  !numberRows) { 1538 int numberColumns = solver_>getNumCols(); 1539 for (int i = 0; i < numberColumns; i++) 1540 assert(solver_>isInteger(i)); 1541 } 1542 #ifdef CLP_INVESTIGATE 1543 if (couldBeNetwork  nExtra) 1544 printf("INTA %d extra integers, %d left%s\n", nExtra, 1545 numberColumns, 1546 couldBeNetwork ? ", all network" : ""); 1547 #endif 1548 findIntegers(true, 2); 1549 convertToDynamic(); 1550 } 1551 #ifdef CLP_INVESTIGATE 1552 if (!couldBeNetwork && copy1>getNumCols() && 1553 copy1>getNumRows()) { 1554 printf("INTA %d rows and %d columns remain\n", 1555 copy1>getNumRows(), copy1>getNumCols()); 1556 if (copy1>getNumCols() < 200) { 1557 copy1>writeMps("moreint"); 1558 printf("INTA Written remainder to moreint.mps.gz %d rows %d cols\n", 1559 copy1>getNumRows(), copy1>getNumCols()); 1560 } 1561 } 1562 #endif 1563 delete copy1; 1564 delete [] del; 1565 delete [] original; 1566 delete [] possibleRow; 1567 // double check increment 1568 analyzeObjective(); 1569 } 1134 1570 /** 1135 1571 \todo … … 1217 1653 bool noObjects = (numberObjects_ == 0); 1218 1654 // Set up strategies 1219 if (strategy_) { 1220 // May do preprocessing 1221 originalSolver = solver_; 1222 strategy_>setupOther(*this); 1223 if (strategy_>preProcessState()) { 1224 // preprocessing done 1225 if (strategy_>preProcessState() < 0) { 1226 // infeasible 1227 handler_>message(CBC_INFEAS, messages_) << CoinMessageEol ; 1228 status_ = 0 ; 1229 secondaryStatus_ = 1; 1230 originalContinuousObjective_ = COIN_DBL_MAX; 1231 return ; 1232 } else if (numberObjects_ && object_) { 1233 numberOriginalObjects = numberObjects_; 1234 // redo sequence 1235 numberIntegers_ = 0; 1236 int numberColumns = getNumCols(); 1237 int nOrig = originalSolver>getNumCols(); 1238 CglPreProcess * process = strategy_>process(); 1239 assert (process); 1240 const int * originalColumns = process>originalColumns(); 1241 // allow for cliques etc 1242 nOrig = CoinMax(nOrig, originalColumns[numberColumns1] + 1); 1243 // try and redo debugger 1244 OsiRowCutDebugger * debugger = const_cast<OsiRowCutDebugger *> (solver_>getRowCutDebuggerAlways()); 1245 if (debugger) 1246 debugger>redoSolution(numberColumns, originalColumns); 1247 if (bestSolution_) { 1248 // need to redo  in case no better found in BAB 1249 // just get integer part right 1250 for (int i = 0; i < numberColumns; i++) { 1251 int jColumn = originalColumns[i]; 1252 bestSolution_[i] = bestSolution_[jColumn]; 1253 } 1254 } 1255 originalObject = object_; 1256 // object number or 1 1257 int * temp = new int[nOrig]; 1258 int iColumn; 1259 for (iColumn = 0; iColumn < nOrig; iColumn++) 1260 temp[iColumn] = 1; 1261 int iObject; 1262 int nNonInt = 0; 1263 for (iObject = 0; iObject < numberOriginalObjects; iObject++) { 1264 iColumn = originalObject[iObject]>columnNumber(); 1265 if (iColumn < 0) { 1266 nNonInt++; 1267 } else { 1268 temp[iColumn] = iObject; 1269 } 1270 } 1271 int numberNewIntegers = 0; 1272 int numberOldIntegers = 0; 1273 int numberOldOther = 0; 1274 for (iColumn = 0; iColumn < numberColumns; iColumn++) { 1275 int jColumn = originalColumns[iColumn]; 1276 if (temp[jColumn] >= 0) { 1277 int iObject = temp[jColumn]; 1278 CbcSimpleInteger * obj = 1279 dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ; 1280 if (obj) 1281 numberOldIntegers++; 1282 else 1283 numberOldOther++; 1284 } else if (isInteger(iColumn)) { 1285 numberNewIntegers++; 1286 } 1287 } 1288 /* 1289 Allocate an array to hold the indices of the integer variables. 1290 Make a large enough array for all objects 1291 */ 1292 numberObjects_ = numberNewIntegers + numberOldIntegers + numberOldOther + nNonInt; 1293 object_ = new OsiObject * [numberObjects_]; 1294 delete [] integerVariable_; 1295 integerVariable_ = new int [numberNewIntegers+numberOldIntegers]; 1296 /* 1297 Walk the variables again, filling in the indices and creating objects for 1298 the integer variables. Initially, the objects hold the index and upper & 1299 lower bounds. 1300 */ 1301 numberIntegers_ = 0; 1302 int n = originalColumns[numberColumns1] + 1; 1303 int * backward = new int[n]; 1304 int i; 1305 for ( i = 0; i < n; i++) 1306 backward[i] = 1; 1307 for (i = 0; i < numberColumns; i++) 1308 backward[originalColumns[i]] = i; 1309 for (iColumn = 0; iColumn < numberColumns; iColumn++) { 1310 int jColumn = originalColumns[iColumn]; 1311 if (temp[jColumn] >= 0) { 1312 int iObject = temp[jColumn]; 1313 CbcSimpleInteger * obj = 1314 dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ; 1315 if (obj) { 1316 object_[numberIntegers_] = originalObject[iObject]>clone(); 1317 // redo ids etc 1318 //object_[numberIntegers_]>resetSequenceEtc(numberColumns,originalColumns); 1319 object_[numberIntegers_]>resetSequenceEtc(numberColumns, backward); 1320 integerVariable_[numberIntegers_++] = iColumn; 1321 } 1322 } else if (isInteger(iColumn)) { 1323 object_[numberIntegers_] = 1324 new CbcSimpleInteger(this, iColumn); 1325 integerVariable_[numberIntegers_++] = iColumn; 1326 } 1327 } 1328 delete [] backward; 1329 numberObjects_ = numberIntegers_; 1330 // Now append other column stuff 1331 for (iColumn = 0; iColumn < numberColumns; iColumn++) { 1332 int jColumn = originalColumns[iColumn]; 1333 if (temp[jColumn] >= 0) { 1334 int iObject = temp[jColumn]; 1335 CbcSimpleInteger * obj = 1336 dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ; 1337 if (!obj) { 1338 object_[numberObjects_] = originalObject[iObject]>clone(); 1339 // redo ids etc 1340 CbcObject * obj = 1341 dynamic_cast <CbcObject *>(object_[numberObjects_]) ; 1342 assert (obj); 1343 obj>redoSequenceEtc(this, numberColumns, originalColumns); 1344 numberObjects_++; 1345 } 1346 } 1347 } 1348 // now append non column stuff 1349 for (iObject = 0; iObject < numberOriginalObjects; iObject++) { 1350 iColumn = originalObject[iObject]>columnNumber(); 1351 if (iColumn < 0) { 1352 // already has column numbers changed 1353 object_[numberObjects_] = originalObject[iObject]>clone(); 1354 #if 0 1355 // redo ids etc 1356 CbcObject * obj = 1357 dynamic_cast <CbcObject *>(object_[numberObjects_]) ; 1358 assert (obj); 1359 obj>redoSequenceEtc(this, numberColumns, originalColumns); 1360 #endif 1361 numberObjects_++; 1362 } 1363 } 1364 delete [] temp; 1365 if (!numberObjects_) 1366 handler_>message(CBC_NOINT, messages_) << CoinMessageEol ; 1367 } else { 1368 int numberColumns = getNumCols(); 1369 CglPreProcess * process = strategy_>process(); 1370 assert (process); 1371 const int * originalColumns = process>originalColumns(); 1372 // try and redo debugger 1373 OsiRowCutDebugger * debugger = const_cast<OsiRowCutDebugger *> (solver_>getRowCutDebuggerAlways()); 1374 if (debugger) 1375 debugger>redoSolution(numberColumns, originalColumns); 1376 } 1377 } else { 1378 //no preprocessing 1379 originalSolver = NULL; 1380 } 1381 strategy_>setupCutGenerators(*this); 1382 strategy_>setupHeuristics(*this); 1383 // Set strategy print level to models 1384 strategy_>setupPrinting(*this, handler_>logLevel()); 1385 } 1655 if (strategy_) 1656 { 1657 // May do preprocessing 1658 originalSolver = solver_; 1659 strategy_>setupOther(*this); 1660 if (strategy_>preProcessState()) { 1661 // preprocessing done 1662 if (strategy_>preProcessState() < 0) { 1663 // infeasible 1664 handler_>message(CBC_INFEAS, messages_) << CoinMessageEol ; 1665 status_ = 0 ; 1666 secondaryStatus_ = 1; 1667 originalContinuousObjective_ = COIN_DBL_MAX; 1668 return ; 1669 } else if (numberObjects_ && object_) { 1670 numberOriginalObjects = numberObjects_; 1671 // redo sequence 1672 numberIntegers_ = 0; 1673 int numberColumns = getNumCols(); 1674 int nOrig = originalSolver>getNumCols(); 1675 CglPreProcess * process = strategy_>process(); 1676 assert (process); 1677 const int * originalColumns = process>originalColumns(); 1678 // allow for cliques etc 1679 nOrig = CoinMax(nOrig, originalColumns[numberColumns1] + 1); 1680 // try and redo debugger 1681 OsiRowCutDebugger * debugger = const_cast<OsiRowCutDebugger *> (solver_>getRowCutDebuggerAlways()); 1682 if (debugger) 1683 debugger>redoSolution(numberColumns, originalColumns); 1684 if (bestSolution_) { 1685 // need to redo  in case no better found in BAB 1686 // just get integer part right 1687 for (int i = 0; i < numberColumns; i++) { 1688 int jColumn = originalColumns[i]; 1689 bestSolution_[i] = bestSolution_[jColumn]; 1690 } 1691 } 1692 originalObject = object_; 1693 // object number or 1 1694 int * temp = new int[nOrig]; 1695 int iColumn; 1696 for (iColumn = 0; iColumn < nOrig; iColumn++) 1697 temp[iColumn] = 1; 1698 int iObject; 1699 int nNonInt = 0; 1700 for (iObject = 0; iObject < numberOriginalObjects; iObject++) { 1701 iColumn = originalObject[iObject]>columnNumber(); 1702 if (iColumn < 0) { 1703 nNonInt++; 1704 } else { 1705 temp[iColumn] = iObject; 1706 } 1707 } 1708 int numberNewIntegers = 0; 1709 int numberOldIntegers = 0; 1710 int numberOldOther = 0; 1711 for (iColumn = 0; iColumn < numberColumns; iColumn++) { 1712 int jColumn = originalColumns[iColumn]; 1713 if (temp[jColumn] >= 0) { 1714 int iObject = temp[jColumn]; 1715 CbcSimpleInteger * obj = 1716 dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ; 1717 if (obj) 1718 numberOldIntegers++; 1719 else 1720 numberOldOther++; 1721 } else if (isInteger(iColumn)) { 1722 numberNewIntegers++; 1723 } 1724 } 1725 /* 1726 Allocate an array to hold the indices of the integer variables. 1727 Make a large enough array for all objects 1728 */ 1729 numberObjects_ = numberNewIntegers + numberOldIntegers + numberOldOther + nNonInt; 1730 object_ = new OsiObject * [numberObjects_]; 1731 delete [] integerVariable_; 1732 integerVariable_ = new int [numberNewIntegers+numberOldIntegers]; 1733 /* 1734 Walk the variables again, filling in the indices and creating objects for 1735 the integer variables. Initially, the objects hold the index and upper & 1736 lower bounds. 1737 */ 1738 numberIntegers_ = 0; 1739 int n = originalColumns[numberColumns1] + 1; 1740 int * backward = new int[n]; 1741 int i; 1742 for ( i = 0; i < n; i++) 1743 backward[i] = 1; 1744 for (i = 0; i < numberColumns; i++) 1745 backward[originalColumns[i]] = i; 1746 for (iColumn = 0; iColumn < numberColumns; iColumn++) { 1747 int jColumn = originalColumns[iColumn]; 1748 if (temp[jColumn] >= 0) { 1749 int iObject = temp[jColumn]; 1750 CbcSimpleInteger * obj = 1751 dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ; 1752 if (obj) { 1753 object_[numberIntegers_] = originalObject[iObject]>clone(); 1754 // redo ids etc 1755 //object_[numberIntegers_]>resetSequenceEtc(numberColumns,originalColumns); 1756 object_[numberIntegers_]>resetSequenceEtc(numberColumns, backward); 1757 integerVariable_[numberIntegers_++] = iColumn; 1758 } 1759 } else if (isInteger(iColumn)) { 1760 object_[numberIntegers_] = 1761 new CbcSimpleInteger(this, iColumn); 1762 integerVariable_[numberIntegers_++] = iColumn; 1763 } 1764 } 1765 delete [] backward; 1766 numberObjects_ = numberIntegers_; 1767 // Now append other column stuff 1768 for (iColumn = 0; iColumn < numberColumns; iColumn++) { 1769 int jColumn = originalColumns[iColumn]; 1770 if (temp[jColumn] >= 0) { 1771 int iObject = temp[jColumn]; 1772 CbcSimpleInteger * obj = 1773 dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ; 1774 if (!obj) { 1775 object_[numberObjects_] = originalObject[iObject]>clone(); 1776 // redo ids etc 1777 CbcObject * obj = 1778 dynamic_cast <CbcObject *>(object_[numberObjects_]) ; 1779 assert (obj); 1780 obj>redoSequenceEtc(this, numberColumns, originalColumns); 1781 numberObjects_++; 1782 } 1783 } 1784 } 1785 // now append non column stuff 1786 for (iObject = 0; iObject < numberOriginalObjects; iObject++) { 1787 iColumn = originalObject[iObject]>columnNumber(); 1788 if (iColumn < 0) { 1789 // already has column numbers changed 1790 object_[numberObjects_] = originalObject[iObject]>clone(); 1791 #if 0 1792 // redo ids etc 1793 CbcObject * obj = 1794 dynamic_cast <CbcObject *>(object_[numberObjects_]) ; 1795 assert (obj); 1796 obj>redoSequenceEtc(this, numberColumns, originalColumns); 1797 #endif 1798 numberObjects_++; 1799 } 1800 } 1801 delete [] temp; 1802 if (!numberObjects_) 1803 handler_>message(CBC_NOINT, messages_) << CoinMessageEol ; 1804 } else { 1805 int numberColumns = getNumCols(); 1806 CglPreProcess * process = strategy_>process(); 1807 assert (process); 1808 const int * originalColumns = process>originalColumns(); 1809 // try and redo debugger 1810 OsiRowCutDebugger * debugger = const_cast<OsiRowCutDebugger *> (solver_>getRowCutDebuggerAlways()); 1811 if (debugger) 1812 debugger>redoSolution(numberColumns, originalColumns); 1813 } 1814 } else { 1815 //no preprocessing 1816 originalSolver = NULL; 1817 } 1818 strategy_>setupCutGenerators(*this); 1819 strategy_>setupHeuristics(*this); 1820 // Set strategy print level to models 1821 strategy_>setupPrinting(*this, handler_>logLevel()); 1822 } 1386 1823 eventHappened_ = false; 1387 1824 CbcEventHandler *eventHandler = getEventHandler() ; … … 1932 2369 } 1933 2370 // See if we can add integers 1934 if (noObjects && numberIntegers_ < solver_>getNumCols() && (specialOptions_&65536) != 0 && !parentModel_) { 1935 int numberColumns = continuousSolver_>getNumCols(); 1936 int numberRows = continuousSolver_>getNumRows(); 1937 int * del = new int [CoinMax(numberColumns, numberRows)]; 1938 int * original = new int [numberColumns]; 1939 char * possibleRow = new char [numberRows]; 1940 { 1941 const CoinPackedMatrix * rowCopy = continuousSolver_>getMatrixByRow(); 1942 const int * column = rowCopy>getIndices(); 1943 const int * rowLength = rowCopy>getVectorLengths(); 1944 const CoinBigIndex * rowStart = rowCopy>getVectorStarts(); 1945 const double * rowLower = continuousSolver_>getRowLower(); 1946 const double * rowUpper = continuousSolver_>getRowUpper(); 1947 const double * element = rowCopy>getElements(); 1948 for (int i = 0; i < numberRows; i++) { 1949 int nLeft = 0; 1950 bool possible = false; 1951 if (rowLower[i] < 1.0e20) { 1952 double value = rowUpper[i]; 1953 if (fabs(value  floor(value + 0.5)) < 1.0e8) 1954 possible = true; 1955 } else if (rowUpper[i] > 1.0e20) { 1956 double value = rowLower[i]; 1957 if (fabs(value  floor(value + 0.5)) < 1.0e8) 1958 possible = true; 1959 } else { 1960 double value = rowUpper[i]; 1961 if (rowLower[i] == rowUpper[i] && 1962 fabs(value  floor(value + 0.5)) < 1.0e8) 1963 possible = true; 1964 } 1965 for (CoinBigIndex j = rowStart[i]; 1966 j < rowStart[i] + rowLength[i]; j++) { 1967 int iColumn = column[j]; 1968 if (continuousSolver_>isInteger(iColumn)) { 1969 if (fabs(element[j]) != 1.0) 1970 possible = false; 1971 } else { 1972 nLeft++; 1973 } 1974 } 1975 if (possible  !nLeft) 1976 possibleRow[i] = 1; 1977 else 1978 possibleRow[i] = 0; 1979 } 1980 } 1981 int nDel = 0; 1982 for (int i = 0; i < numberColumns; i++) { 1983 original[i] = i; 1984 if (continuousSolver_>isInteger(i)) 1985 del[nDel++] = i; 1986 } 1987 int nExtra = 0; 1988 OsiSolverInterface * copy1 = continuousSolver_>clone(); 1989 int nPass = 0; 1990 while (nDel && nPass < 10) { 1991 nPass++; 1992 OsiSolverInterface * copy2 = copy1>clone(); 1993 int nLeft = 0; 1994 for (int i = 0; i < nDel; i++) 1995 original[del[i]] = 1; 1996 for (int i = 0; i < numberColumns; i++) { 1997 int kOrig = original[i]; 1998 if (kOrig >= 0) 1999 original[nLeft++] = kOrig; 2000 } 2001 assert (nLeft == numberColumns  nDel); 2002 copy2>deleteCols(nDel, del); 2003 numberColumns = copy2>getNumCols(); 2004 const CoinPackedMatrix * rowCopy = copy2>getMatrixByRow(); 2005 numberRows = rowCopy>getNumRows(); 2006 const int * column = rowCopy>getIndices(); 2007 const int * rowLength = rowCopy>getVectorLengths(); 2008 const CoinBigIndex * rowStart = rowCopy>getVectorStarts(); 2009 const double * rowLower = copy2>getRowLower(); 2010 const double * rowUpper = copy2>getRowUpper(); 2011 const double * element = rowCopy>getElements(); 2012 const CoinPackedMatrix * columnCopy = copy2>getMatrixByCol(); 2013 const int * columnLength = columnCopy>getVectorLengths(); 2014 nDel = 0; 2015 // Could do gcd stuff on ones with costs 2016 for (int i = 0; i < numberRows; i++) { 2017 if (!rowLength[i]) { 2018 del[nDel++] = i; 2019 possibleRow[i] = 1; 2020 } else if (possibleRow[i]) { 2021 if (rowLength[i] == 1) { 2022 int k = rowStart[i]; 2023 int iColumn = column[k]; 2024 if (!copy2>isInteger(iColumn)) { 2025 double mult = 1.0 / fabs(element[k]); 2026 if (rowLower[i] < 1.0e20) { 2027 double value = rowUpper[i] * mult; 2028 if (fabs(value  floor(value + 0.5)) < 1.0e8) { 2029 del[nDel++] = i; 2030 if (columnLength[iColumn] == 1) { 2031 copy2>setInteger(iColumn); 2032 int kOrig = original[iColumn]; 2033 setOptionalInteger(kOrig); 2034 } 2035 } 2036 } else if (rowUpper[i] > 1.0e20) { 2037 double value = rowLower[i] * mult; 2038 if (fabs(value  floor(value + 0.5)) < 1.0e8) { 2039 del[nDel++] = i; 2040 if (columnLength[iColumn] == 1) { 2041 copy2>setInteger(iColumn); 2042 int kOrig = original[iColumn]; 2043 setOptionalInteger(kOrig); 2044 } 2045 } 2046 } else { 2047 double value = rowUpper[i] * mult; 2048 if (rowLower[i] == rowUpper[i] && 2049 fabs(value  floor(value + 0.5)) < 1.0e8) { 2050 del[nDel++] = i; 2051 copy2>setInteger(iColumn); 2052 int kOrig = original[iColumn]; 2053 setOptionalInteger(kOrig); 2371 if (noObjects && numberIntegers_ < solver_>getNumCols() && (specialOptions_&65536) != 0 && !parentModel_) 2372 AddIntegers(); 2373 2374 int iObject ; 2375 int preferredWay ; 2376 int numberUnsatisfied = 0 ; 2377 delete [] currentSolution_; 2378 currentSolution_ = new double [numberColumns]; 2379 testSolution_ = currentSolution_; 2380 memcpy(currentSolution_, solver_>getColSolution(), 2381 numberColumns*sizeof(double)) ; 2382 // point to useful information 2383 OsiBranchingInformation usefulInfo = usefulInformation(); 2384 2385 for (iObject = 0 ; iObject < numberObjects_ ; iObject++) { 2386 double infeasibility = 2387 object_[iObject]>infeasibility(&usefulInfo, preferredWay) ; 2388 if (infeasibility ) numberUnsatisfied++ ; 2389 } 2390 // replace solverType 2391 if (solverCharacteristics_>tryCuts()) { 2392 2393 if (numberUnsatisfied) { 2394 // User event 2395 if (!eventHappened_ && feasible) { 2396 feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_, 2397 NULL); 2398 if ((specialOptions_&524288) != 0 && !parentModel_ 2399 && storedRowCuts_) { 2400 if (feasible) { 2401 /* pick up stuff and try again 2402 add cuts, maybe keep around 2403 do best solution and if so new heuristics 2404 obviously tighten bounds 2405 */ 2406 // A and B probably done on entry 2407 // A) tight bounds on integer variables 2408 const double * lower = solver_>getColLower(); 2409 const double * upper = solver_>getColUpper(); 2410 const double * tightLower = storedRowCuts_>tightLower(); 2411 const double * tightUpper = storedRowCuts_>tightUpper(); 2412 int nTightened = 0; 2413 for (int i = 0; i < numberIntegers_; i++) { 2414 int iColumn = integerVariable_[i]; 2415 if (tightLower[iColumn] > lower[iColumn]) { 2416 nTightened++; 2417 solver_>setColLower(iColumn, tightLower[iColumn]); 2418 } 2419 if (tightUpper[iColumn] < upper[iColumn]) { 2420 nTightened++; 2421 solver_>setColUpper(iColumn, tightUpper[iColumn]); 2422 } 2423 } 2424 if (nTightened) 2425 printf("%d tightened by alternate cuts\n", nTightened); 2426 if (storedRowCuts_>bestObjective() < bestObjective_) { 2427 // B) best solution 2428 double objValue = storedRowCuts_>bestObjective(); 2429 setBestSolution(CBC_SOLUTION, objValue, 2430 storedRowCuts_>bestSolution()) ; 2431 // Do heuristics 2432 // Allow RINS 2433 for (int i = 0; i < numberHeuristics_; i++) { 2434 CbcHeuristicRINS * rins 2435 = dynamic_cast<CbcHeuristicRINS *> (heuristic_[i]); 2436 if (rins) { 2437 rins>setLastNode(100); 2054 2438 } 2055 2439 } 2440 doHeuristicsAtRoot(); 2056 2441 } 2057 } else { 2058 // only if all singletons 2059 bool possible = false; 2060 if (rowLower[i] < 1.0e20) { 2061 double value = rowUpper[i]; 2062 if (fabs(value  floor(value + 0.5)) < 1.0e8) 2063 possible = true; 2064 } else if (rowUpper[i] > 1.0e20) { 2065 double value = rowLower[i]; 2066 if (fabs(value  floor(value + 0.5)) < 1.0e8) 2067 possible = true; 2442 #if 0 2443 int nCuts = storedRowCuts_>sizeRowCuts(); 2444 // add to global list 2445 for (int i = 0; i < nCuts; i++) { 2446 OsiRowCut newCut(*storedRowCuts_>rowCutPointer(i)); 2447 newCut.setGloballyValidAsInteger(2); 2448 newCut.mutableRow().setTestForDuplicateIndex(false); 2449 globalCuts_.insert(newCut) ; 2450 } 2451 #else 2452 addCutGenerator(storedRowCuts_, 99, "Stored from previous run", 2453 true, false, false, 200); 2454 #endif 2455 // Set cuts as active 2456 delete [] addedCuts_ ; 2457 maximumNumberCuts_ = cuts.sizeRowCuts(); 2458 if (maximumNumberCuts_) { 2459 addedCuts_ = new CbcCountRowCut * [maximumNumberCuts_]; 2068 2460 } else { 2069 double value = rowUpper[i]; 2070 if (rowLower[i] == rowUpper[i] && 2071 fabs(value  floor(value + 0.5)) < 1.0e8) 2072 possible = true; 2461 addedCuts_ = NULL; 2073 2462 } 2074 if (possible) { 2075 for (CoinBigIndex j = rowStart[i]; 2076 j < rowStart[i] + rowLength[i]; j++) { 2077 int iColumn = column[j]; 2078 if (columnLength[iColumn] != 1  fabs(element[j]) != 1.0) { 2079 possible = false; 2080 break; 2081 } 2082 } 2083 if (possible) { 2084 for (CoinBigIndex j = rowStart[i]; 2085 j < rowStart[i] + rowLength[i]; j++) { 2086 int iColumn = column[j]; 2087 if (!copy2>isInteger(iColumn)) { 2088 copy2>setInteger(iColumn); 2089 int kOrig = original[iColumn]; 2090 setOptionalInteger(kOrig); 2091 } 2092 } 2093 del[nDel++] = i; 2094 } 2095 } 2096 } 2097 } 2098 } 2099 if (nDel) { 2100 copy2>deleteRows(nDel, del); 2101 } 2102 if (nDel != numberRows) { 2103 nDel = 0; 2104 for (int i = 0; i < numberColumns; i++) { 2105 if (copy2>isInteger(i)) { 2106 del[nDel++] = i; 2107 nExtra++; 2108 } 2463 for (int i = 0; i < maximumNumberCuts_; i++) 2464 addedCuts_[i] = new CbcCountRowCut(*cuts.rowCutPtr(i), 2465 NULL, 1, 1, 2); 2466 printf("size %d\n", cuts.sizeRowCuts()); 2467 cuts = OsiCuts(); 2468 currentNumberCuts_ = maximumNumberCuts_; 2469 feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_, 2470 NULL); 2471 for (int i = 0; i < maximumNumberCuts_; i++) 2472 delete addedCuts_[i]; 2473 } 2474 delete storedRowCuts_; 2475 storedRowCuts_ = NULL; 2109 2476 } 2110 2477 } else { 2111 nDel = 0; 2112 } 2113 delete copy1; 2114 copy1 = copy2>clone(); 2115 delete copy2; 2116 } 2117 // See if what's left is a network 2118 bool couldBeNetwork = false; 2119 if (copy1>getNumRows() && copy1>getNumCols()) { 2120 #ifdef COIN_HAS_CLP 2121 OsiClpSolverInterface * clpSolver 2122 = dynamic_cast<OsiClpSolverInterface *> (copy1); 2123 if (false && clpSolver) { 2124 numberRows = clpSolver>getNumRows(); 2125 char * rotate = new char[numberRows]; 2126 int n = clpSolver>getModelPtr()>findNetwork(rotate, 1.0); 2127 delete [] rotate; 2128 #ifdef CLP_INVESTIGATE 2129 printf("INTA network %d rows out of %d\n", n, numberRows); 2130 #endif 2131 if (CoinAbs(n) == numberRows) { 2132 couldBeNetwork = true; 2133 for (int i = 0; i < numberRows; i++) { 2134 if (!possibleRow[i]) { 2135 couldBeNetwork = false; 2136 #ifdef CLP_INVESTIGATE 2137 printf("but row %d is bad\n", i); 2138 #endif 2139 break; 2140 } 2141 } 2142 } 2143 } else 2144 #endif 2145 { 2146 numberColumns = copy1>getNumCols(); 2147 numberRows = copy1>getNumRows(); 2148 const double * rowLower = copy1>getRowLower(); 2149 const double * rowUpper = copy1>getRowUpper(); 2150 couldBeNetwork = true; 2151 for (int i = 0; i < numberRows; i++) { 2152 if (rowLower[i] > 1.0e20 && fabs(rowLower[i]  floor(rowLower[i] + 0.5)) > 1.0e12) { 2153 couldBeNetwork = false; 2154 break; 2155 } 2156 if (rowUpper[i] < 1.0e20 && fabs(rowUpper[i]  floor(rowUpper[i] + 0.5)) > 1.0e12) { 2157 couldBeNetwork = false; 2158 break; 2159 } 2160 } 2161 if (couldBeNetwork) { 2162 const CoinPackedMatrix * matrixByCol = copy1>getMatrixByCol(); 2163 const double * element = matrixByCol>getElements(); 2164 //const int * row = matrixByCol>getIndices(); 2165 const CoinBigIndex * columnStart = matrixByCol>getVectorStarts(); 2166 const int * columnLength = matrixByCol>getVectorLengths(); 2167 for (int iColumn = 0; iColumn < numberColumns; iColumn++) { 2168 CoinBigIndex start = columnStart[iColumn]; 2169 CoinBigIndex end = start + columnLength[iColumn]; 2170 if (end > start + 2) { 2171 couldBeNetwork = false; 2172 break; 2173 } 2174 int type = 0; 2175 for (CoinBigIndex j = start; j < end; j++) { 2176 double value = element[j]; 2177 if (fabs(value) != 1.0) { 2178 couldBeNetwork = false; 2179 break; 2180 } else if (value == 1.0) { 2181 if ((type&1) == 0) 2182 type = 1; 2183 else 2184 type = 7; 2185 } else if (value == 1.0) { 2186 if ((type&2) == 0) 2187 type = 2; 2188 else 2189 type = 7; 2190 } 2191 } 2192 if (type > 3) { 2193 couldBeNetwork = false; 2194 break; 2195 } 2196 } 2197 } 2198 } 2199 } 2200 if (couldBeNetwork) { 2201 for (int i = 0; i < numberColumns; i++) 2202 setOptionalInteger(original[i]); 2203 } 2204 if (nExtra  couldBeNetwork) { 2205 numberColumns = copy1>getNumCols(); 2206 numberRows = copy1>getNumRows(); 2207 if (!numberColumns  !numberRows) { 2208 int numberColumns = solver_>getNumCols(); 2209 for (int i = 0; i < numberColumns; i++) 2210 assert(solver_>isInteger(i)); 2211 } 2212 #ifdef CLP_INVESTIGATE 2213 if (couldBeNetwork  nExtra) 2214 printf("INTA %d extra integers, %d left%s\n", nExtra, 2215 numberColumns, 2216 couldBeNetwork ? ", all network" : ""); 2217 #endif 2218 findIntegers(true, 2); 2219 convertToDynamic(); 2220 } 2221 #ifdef CLP_INVESTIGATE 2222 if (!couldBeNetwork && copy1>getNumCols() && 2223 copy1>getNumRows()) { 2224 printf("INTA %d rows and %d columns remain\n", 2225 copy1>getNumRows(), copy1>getNumCols()); 2226 if (copy1>getNumCols() < 200) { 2227 copy1>writeMps("moreint"); 2228 printf("INTA Written remainder to moreint.mps.gz %d rows %d cols\n", 2229 copy1>getNumRows(), copy1>getNumCols()); 2230 } 2231 } 2232 #endif 2233 delete copy1; 2234 delete [] del; 2235 delete [] original; 2236 delete [] possibleRow; 2237 // double check increment 2238 analyzeObjective(); 2239 } 2240 { 2241 int iObject ; 2242 int preferredWay ; 2243 int numberUnsatisfied = 0 ; 2244 delete [] currentSolution_; 2245 currentSolution_ = new double [numberColumns]; 2246 testSolution_ = currentSolution_; 2247 memcpy(currentSolution_, solver_>getColSolution(), 2248 numberColumns*sizeof(double)) ; 2249 // point to useful information 2250 OsiBranchingInformation usefulInfo = usefulInformation(); 2251 2252 for (iObject = 0 ; iObject < numberObjects_ ; iObject++) { 2253 double infeasibility = 2254 object_[iObject]>infeasibility(&usefulInfo, preferredWay) ; 2255 if (infeasibility ) numberUnsatisfied++ ; 2256 } 2257 // replace solverType 2258 if (solverCharacteristics_>tryCuts()) { 2259 2260 if (numberUnsatisfied) { 2261 // User event 2262 if (!eventHappened_ && feasible) { 2263 feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_, 2264 NULL); 2265 if ((specialOptions_&524288) != 0 && !parentModel_ 2266 && storedRowCuts_) { 2267 if (feasible) { 2268 /* pick up stuff and try again 2269 add cuts, maybe keep around 2270 do best solution and if so new heuristics 2271 obviously tighten bounds 2272 */ 2273 // A and B probably done on entry 2274 // A) tight bounds on integer variables 2275 const double * lower = solver_>getColLower(); 2276 const double * upper = solver_>getColUpper(); 2277 const double * tightLower = storedRowCuts_>tightLower(); 2278 const double * tightUpper = storedRowCuts_>tightUpper(); 2279 int nTightened = 0; 2280 for (int i = 0; i < numberIntegers_; i++) { 2281 int iColumn = integerVariable_[i]; 2282 if (tightLower[iColumn] > lower[iColumn]) { 2283 nTightened++; 2284 solver_>setColLower(iColumn, tightLower[iColumn]); 2285 } 2286 if (tightUpper[iColumn] < upper[iColumn]) { 2287 nTightened++; 2288 solver_>setColUpper(iColumn, tightUpper[iColumn]); 2289 } 2290 } 2291 if (nTightened) 2292 printf("%d tightened by alternate cuts\n", nTightened); 2293 if (storedRowCuts_>bestObjective() < bestObjective_) { 2294 // B) best solution 2295 double objValue = storedRowCuts_>bestObjective(); 2296 setBestSolution(CBC_SOLUTION, objValue, 2297 storedRowCuts_>bestSolution()) ; 2298 // Do heuristics 2299 // Allow RINS 2300 for (int i = 0; i < numberHeuristics_; i++) { 2301 CbcHeuristicRINS * rins 2302 = dynamic_cast<CbcHeuristicRINS *> (heuristic_[i]); 2303 if (rins) { 2304 rins>setLastNode(100); 2305 } 2306 } 2307 doHeuristicsAtRoot(); 2308 } 2309 #if 0 2310 int nCuts = storedRowCuts_>sizeRowCuts(); 2311 // add to global list 2312 for (int i = 0; i < nCuts; i++) { 2313 OsiRowCut newCut(*storedRowCuts_>rowCutPointer(i)); 2314 newCut.setGloballyValidAsInteger(2); 2315 newCut.mutableRow().setTestForDuplicateIndex(false); 2316 globalCuts_.insert(newCut) ; 2317 } 2318 #else 2319 addCutGenerator(storedRowCuts_, 99, "Stored from previous run", 2320 true, false, false, 200); 2321 #endif 2322 // Set cuts as active 2323 delete [] addedCuts_ ; 2324 maximumNumberCuts_ = cuts.sizeRowCuts(); 2325 if (maximumNumberCuts_) { 2326 addedCuts_ = new CbcCountRowCut * [maximumNumberCuts_]; 2327 } else { 2328 addedCuts_ = NULL; 2329 } 2330 for (int i = 0; i < maximumNumberCuts_; i++) 2331 addedCuts_[i] = new CbcCountRowCut(*cuts.rowCutPtr(i), 2332 NULL, 1, 1, 2); 2333 printf("size %d\n", cuts.sizeRowCuts()); 2334 cuts = OsiCuts(); 2335 currentNumberCuts_ = maximumNumberCuts_; 2336 feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_, 2337 NULL); 2338 for (int i = 0; i < maximumNumberCuts_; i++) 2339 delete addedCuts_[i]; 2340 } 2341 delete storedRowCuts_; 2342 storedRowCuts_ = NULL; 2343 } 2344 } else { 2345 feasible = false; 2346 } 2347 } else if (solverCharacteristics_>solutionAddsCuts()  2348 solverCharacteristics_>alwaysTryCutsAtRootNode()) { 2349 // may generate cuts and turn the solution 2350 //to an infeasible one 2351 feasible = solveWithCuts(cuts, 1, 2352 NULL); 2353 } 2354 } 2355 // check extra info on feasibility 2356 if (!solverCharacteristics_>mipFeasible()) 2357 feasible = false; 2358 } 2478 feasible = false; 2479 } 2480 } else if (solverCharacteristics_>solutionAddsCuts()  2481 solverCharacteristics_>alwaysTryCutsAtRootNode()) { 2482 // may generate cuts and turn the solution 2483 //to an infeasible one 2484 feasible = solveWithCuts(cuts, 1, 2485 NULL); 2486 } 2487 } 2488 // check extra info on feasibility 2489 if (!solverCharacteristics_>mipFeasible()) 2490 feasible = false; 2491 2359 2492 // make cut generators less aggressive 2360 2493 for (iCutGenerator = 0; iCutGenerator < numberCutGenerators_; iCutGenerator++) { … … 2537 2670 saveSolver = solver_>clone(); 2538 2671 double checkCutoffForRestart = 1.0e100; 2539 if (saveSolver && (specialOptions_&32768) != 0) { 2540 // See if worth trying reduction 2541 checkCutoffForRestart = getCutoff(); 2542 bool tryNewSearch = solverCharacteristics_>reducedCostsAccurate() && 2543 (checkCutoffForRestart < 1.0e20); 2544 int numberColumns = getNumCols(); 2545 if (tryNewSearch) { 2546 #ifdef CLP_INVESTIGATE 2547 printf("after %d nodes, cutoff %g  looking\n", 2548 numberNodes_, getCutoff()); 2549 #endif 2550 saveSolver>resolve(); 2551 double direction = saveSolver>getObjSense() ; 2552 double gap = checkCutoffForRestart  saveSolver>getObjValue() * direction ; 2553 double tolerance; 2554 saveSolver>getDblParam(OsiDualTolerance, tolerance) ; 2555 if (gap <= 0.0) 2556 gap = tolerance; 2557 gap += 100.0 * tolerance; 2558 double integerTolerance = getDblParam(CbcIntegerTolerance) ; 2559 2560 const double *lower = saveSolver>getColLower() ; 2561 const double *upper = saveSolver>getColUpper() ; 2562 const double *solution = saveSolver>getColSolution() ; 2563 const double *reducedCost = saveSolver>getReducedCost() ; 2564 2565 int numberFixed = 0 ; 2566 int numberFixed2 = 0; 2567 for (int i = 0 ; i < numberIntegers_ ; i++) { 2568 int iColumn = integerVariable_[i] ; 2569 double djValue = direction * reducedCost[iColumn] ; 2570 if (upper[iColumn]  lower[iColumn] > integerTolerance) { 2571 if (solution[iColumn] < lower[iColumn] + integerTolerance && djValue > gap) { 2572 saveSolver>setColUpper(iColumn, lower[iColumn]) ; 2573 numberFixed++ ; 2574 } else if (solution[iColumn] > upper[iColumn]  integerTolerance && djValue > gap) { 2575 saveSolver>setColLower(iColumn, upper[iColumn]) ; 2576 numberFixed++ ; 2577 } 2578 } else { 2579 numberFixed2++; 2580 } 2581 } 2582 #ifdef COIN_DEVELOP 2583 if ((specialOptions_&1) != 0) { 2584 const OsiRowCutDebugger *debugger = saveSolver>getRowCutDebugger() ; 2585 if (debugger) { 2586 printf("Contains optimal\n") ; 2587 OsiSolverInterface * temp = saveSolver>clone(); 2588 const double * solution = debugger>optimalSolution(); 2589 const double *lower = temp>getColLower() ; 2590 const double *upper = temp>getColUpper() ; 2591 int n = temp>getNumCols(); 2592 for (int i = 0; i < n; i++) { 2593 if (temp>isInteger(i)) { 2594 double value = floor(solution[i] + 0.5); 2595 assert (value >= lower[i] && value <= upper[i]); 2596 temp>setColLower(i, value); 2597 temp>setColUpper(i, value); 2598 } 2599 } 2600 temp>writeMps("reduced_fix"); 2601 delete temp; 2602 saveSolver>writeMps("reduced"); 2603 } else { 2604 abort(); 2605 } 2606 } 2607 printf("Restart could fix %d integers (%d already fixed)\n", 2608 numberFixed + numberFixed2, numberFixed2); 2609 #endif 2610 numberFixed += numberFixed2; 2611 if (numberFixed*20 < numberColumns) 2612 tryNewSearch = false; 2613 } 2614 if (tryNewSearch) { 2615 // back to solver without cuts? 2616 OsiSolverInterface * solver2 = continuousSolver_>clone(); 2617 const double *lower = saveSolver>getColLower() ; 2618 const double *upper = saveSolver>getColUpper() ; 2619 for (int i = 0 ; i < numberIntegers_ ; i++) { 2620 int iColumn = integerVariable_[i] ; 2621 solver2>setColLower(iColumn, lower[iColumn]); 2622 solver2>setColUpper(iColumn, upper[iColumn]); 2623 } 2624 // swap 2625 delete saveSolver; 2626 saveSolver = solver2; 2627 double * newSolution = new double[numberColumns]; 2628 double objectiveValue = checkCutoffForRestart; 2629 CbcSerendipity heuristic(*this); 2630 if (bestSolution_) 2631 heuristic.setInputSolution(bestSolution_, bestObjective_); 2632 heuristic.setFractionSmall(0.9); 2633 heuristic.setFeasibilityPumpOptions(1008013); 2634 // Use numberNodes to say how many are original rows 2635 heuristic.setNumberNodes(continuousSolver_>getNumRows()); 2636 #ifdef COIN_DEVELOP 2637 if (continuousSolver_>getNumRows() < 2638 saveSolver>getNumRows()) 2639 printf("%d rows added ZZZZZ\n", 2640 solver_>getNumRows()  continuousSolver_>getNumRows()); 2641 #endif 2642 int returnCode = heuristic.smallBranchAndBound(saveSolver, 2643 1, newSolution, 2644 objectiveValue, 2645 checkCutoffForRestart, "Reduce"); 2646 if (returnCode < 0) { 2647 #ifdef COIN_DEVELOP 2648 printf("Restart  not small enough to do search after fixing\n"); 2649 #endif 2650 delete [] newSolution; 2651 } else { 2652 if ((returnCode&1) != 0) { 2653 // increment number of solutions so other heuristics can test 2654 numberSolutions_++; 2655 numberHeuristicSolutions_++; 2656 lastHeuristic_ = NULL; 2657 setBestSolution(CBC_ROUNDING, objectiveValue, newSolution) ; 2658 } 2659 delete [] newSolution; 2660 feasible = false; // stop search 2661 } 2662 } 2663 } 2672 saveModel(saveSolver, &checkCutoffForRestart, &feasible); 2664 2673 if ((specialOptions_&262144) != 0 && !parentModel_) { 2665 2674 // Save stuff and return! 
branches/sandbox/Cbc/src/CbcModel.hpp
r1315 r1330 434 434 void analyzeObjective(); 435 435 436 436 /** 437 Add additional integers. 438 */ 439 void AddIntegers(); 440 441 /** 442 Save copy of the model. 443 */ 444 445 void saveModel(OsiSolverInterface * saveSolver, double * checkCutoffForRestart, bool * feasible); 437 446 //@} 438 447
Note: See TracChangeset
for help on using the changeset viewer.