Changeset 1330


Ignore:
Timestamp:
Dec 2, 2009 2:25:28 PM (9 years ago)
Author:
EdwinStraver
Message:

Broke a few routines out of branchAndBound routine.

Location:
branches/sandbox/Cbc/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/sandbox/Cbc/src/CbcModel.cpp

    r1315 r1330  
    11301130}
    11311131
    1132 
    1133 
     1132void 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/*
     1261Adds integers, called from BranchandBound()
     1262*/
     1263void 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.0e-8)
     1284                    possible = true;
     1285            } else if (rowUpper[i] > 1.0e20) {
     1286                double value = rowLower[i];
     1287                if (fabs(value - floor(value + 0.5)) < 1.0e-8)
     1288                    possible = true;
     1289            } else {
     1290                double value = rowUpper[i];
     1291                if (rowLower[i] == rowUpper[i] &&
     1292                        fabs(value - floor(value + 0.5)) < 1.0e-8)
     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.0e-8) {
     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.0e-8) {
     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.0e-8) {
     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.0e-8)
     1393                            possible = true;
     1394                    } else if (rowUpper[i] > 1.0e20) {
     1395                        double value = rowLower[i];
     1396                        if (fabs(value - floor(value + 0.5)) < 1.0e-8)
     1397                            possible = true;
     1398                    } else {
     1399                        double value = rowUpper[i];
     1400                        if (rowLower[i] == rowUpper[i] &&
     1401                                fabs(value - floor(value + 0.5)) < 1.0e-8)
     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.0e-12) {
     1483                    couldBeNetwork = false;
     1484                    break;
     1485                }
     1486                if (rowUpper[i] < 1.0e20 && fabs(rowUpper[i] - floor(rowUpper[i] + 0.5)) > 1.0e-12) {
     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}
    11341570/**
    11351571  \todo
     
    12171653    bool noObjects = (numberObjects_ == 0);
    12181654    // Set up strategies
    1219     if (strategy_) {
    1220         // May do preprocessing
    1221         originalSolver = solver_;
    1222         strategy_->setupOther(*this);
    1223         if (strategy_->preProcessState()) {
    1224             // pre-processing 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[numberColumns-1] + 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[numberColumns-1] + 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                        // pre-processing 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[numberColumns-1] + 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[numberColumns-1] + 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        }
    13861823    eventHappened_ = false;
    13871824    CbcEventHandler *eventHandler = getEventHandler() ;
     
    19322369    }
    19332370    // 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.0e-8)
    1954                         possible = true;
    1955                 } else if (rowUpper[i] > 1.0e20) {
    1956                     double value = rowLower[i];
    1957                     if (fabs(value - floor(value + 0.5)) < 1.0e-8)
    1958                         possible = true;
    1959                 } else {
    1960                     double value = rowUpper[i];
    1961                     if (rowLower[i] == rowUpper[i] &&
    1962                             fabs(value - floor(value + 0.5)) < 1.0e-8)
    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.0e-8) {
    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.0e-8) {
    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.0e-8) {
    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);
    20542438                                }
    20552439                            }
     2440                            doHeuristicsAtRoot();
    20562441                        }
    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.0e-8)
    2063                                 possible = true;
    2064                         } else if (rowUpper[i] > 1.0e20) {
    2065                             double value = rowLower[i];
    2066                             if (fabs(value - floor(value + 0.5)) < 1.0e-8)
    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_];
    20682460                        } else {
    2069                             double value = rowUpper[i];
    2070                             if (rowLower[i] == rowUpper[i] &&
    2071                                     fabs(value - floor(value + 0.5)) < 1.0e-8)
    2072                                 possible = true;
     2461                            addedCuts_ = NULL;
    20732462                        }
    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;
    21092476                }
    21102477            } 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.0e-12) {
    2153                         couldBeNetwork = false;
    2154                         break;
    2155                     }
    2156                     if (rowUpper[i] < 1.0e20 && fabs(rowUpper[i] - floor(rowUpper[i] + 0.5)) > 1.0e-12) {
    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
    23592492    // make cut generators less aggressive
    23602493    for (iCutGenerator = 0; iCutGenerator < numberCutGenerators_; iCutGenerator++) {
     
    25372670        saveSolver = solver_->clone();
    25382671    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);
    26642673    if ((specialOptions_&262144) != 0 && !parentModel_) {
    26652674        // Save stuff and return!
  • branches/sandbox/Cbc/src/CbcModel.hpp

    r1315 r1330  
    434434    void analyzeObjective();
    435435
    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);
    437446    //@}
    438447
Note: See TracChangeset for help on using the changeset viewer.