void LinearCutsGenerator::generateCuts(const OsiSolverInterface &solver, OsiCuts &cs, const CglTreeInfo info) const { //const OsiTMINLPInterface * tmp = dynamic_cast<const OsiTMINLPInterface *>(&solver); OsiTMINLPInterface * nlp = dynamic_cast<OsiTMINLPInterface *>(solver.clone());//const_cast<OsiTMINLPInterface *>(tmp); assert(nlp); OuterApprox oa; //si.writeMps("toto"); int numberRows = nlp->getNumRows(); for(int i = 0 ; i < 5 ; i++){ nlp->resolve(); OsiClpSolverInterface si; oa(*nlp, &si, solver.getColSolution(), true); si.resolve(); OsiCuts cuts; for(std::list<Coin::SmartPtr<CuttingMethod> >::const_iterator i = methods_.begin() ; i != methods_.end() ; i++){ (*i)->cgl->generateCuts(si, cuts, info); } std::vector<OsiRowCut *> mycuts(cuts.sizeRowCuts()); for(int i = 0 ; i < cuts.sizeRowCuts() ; i++){ mycuts[i] = cuts.rowCutPtr(i); cs.insert(*mycuts[i]); } nlp->applyRowCuts(mycuts.size(), const_cast<const OsiRowCut **> (&mycuts[0])); } // Take off slack cuts std::vector<int> kept; int numberRowsNow = nlp->getNumRows(); int * del = new int [numberRowsNow-numberRows]; nlp->resolve(); const double * activity = nlp->getRowActivity(); const double * lb = nlp->getRowLower(); const double * ub = nlp->getRowUpper(); CoinRelFltEq eq(1e-06); //int nDelete=0; for (int i=numberRowsNow -1;i>=numberRows;i--) { if ( !(eq(activity[i], lb[i]) || eq(activity[i], ub[i])) ) cs.eraseRowCut(i - numberRows); } delete [] del; delete nlp; }
// inner part of dive int CbcHeuristicDive::solution(double & solutionValue, int & numberNodes, int & numberCuts, OsiRowCut ** cuts, CbcSubProblem ** & nodes, double * newSolution) { #ifdef DIVE_DEBUG int nRoundInfeasible = 0; int nRoundFeasible = 0; #endif int reasonToStop = 0; double time1 = CoinCpuTime(); int numberSimplexIterations = 0; int maxSimplexIterations = (model_->getNodeCount()) ? maxSimplexIterations_ : maxSimplexIterationsAtRoot_; // but can't be exactly coin_int_max maxSimplexIterations = CoinMin(maxSimplexIterations,COIN_INT_MAX>>3); OsiSolverInterface * solver = cloneBut(6); // was model_->solver()->clone(); # ifdef COIN_HAS_CLP OsiClpSolverInterface * clpSolver = dynamic_cast<OsiClpSolverInterface *> (solver); if (clpSolver) { ClpSimplex * clpSimplex = clpSolver->getModelPtr(); int oneSolveIts = clpSimplex->maximumIterations(); oneSolveIts = CoinMin(1000+2*(clpSimplex->numberRows()+clpSimplex->numberColumns()),oneSolveIts); clpSimplex->setMaximumIterations(oneSolveIts); if (!nodes) { // say give up easily clpSimplex->setMoreSpecialOptions(clpSimplex->moreSpecialOptions() | 64); } else { // get ray int specialOptions = clpSimplex->specialOptions(); specialOptions &= ~0x3100000; specialOptions |= 32; clpSimplex->setSpecialOptions(specialOptions); clpSolver->setSpecialOptions(clpSolver->specialOptions() | 1048576); if ((model_->moreSpecialOptions()&16777216)!=0) { // cutoff is constraint clpSolver->setDblParam(OsiDualObjectiveLimit, COIN_DBL_MAX); } } } # endif const double * lower = solver->getColLower(); const double * upper = solver->getColUpper(); const double * rowLower = solver->getRowLower(); const double * rowUpper = solver->getRowUpper(); const double * solution = solver->getColSolution(); const double * objective = solver->getObjCoefficients(); double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance); double primalTolerance; solver->getDblParam(OsiPrimalTolerance, primalTolerance); int numberRows = matrix_.getNumRows(); assert (numberRows <= solver->getNumRows()); int numberIntegers = model_->numberIntegers(); const int * integerVariable = model_->integerVariable(); double direction = solver->getObjSense(); // 1 for min, -1 for max double newSolutionValue = direction * solver->getObjValue(); int returnCode = 0; // Column copy const double * element = matrix_.getElements(); const int * row = matrix_.getIndices(); const CoinBigIndex * columnStart = matrix_.getVectorStarts(); const int * columnLength = matrix_.getVectorLengths(); #ifdef DIVE_FIX_BINARY_VARIABLES // Row copy const double * elementByRow = matrixByRow_.getElements(); const int * column = matrixByRow_.getIndices(); const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts(); const int * rowLength = matrixByRow_.getVectorLengths(); #endif // Get solution array for heuristic solution int numberColumns = solver->getNumCols(); memcpy(newSolution, solution, numberColumns*sizeof(double)); // vectors to store the latest variables fixed at their bounds int* columnFixed = new int [numberIntegers]; double* originalBound = new double [numberIntegers+2*numberColumns]; double * lowerBefore = originalBound+numberIntegers; double * upperBefore = lowerBefore+numberColumns; memcpy(lowerBefore,lower,numberColumns*sizeof(double)); memcpy(upperBefore,upper,numberColumns*sizeof(double)); double * lastDjs=newSolution+numberColumns; bool * fixedAtLowerBound = new bool [numberIntegers]; PseudoReducedCost * candidate = new PseudoReducedCost [numberIntegers]; double * random = new double [numberIntegers]; int maxNumberAtBoundToFix = static_cast<int> (floor(percentageToFix_ * numberIntegers)); assert (!maxNumberAtBoundToFix||!nodes); // count how many fractional variables int numberFractionalVariables = 0; for (int i = 0; i < numberIntegers; i++) { random[i] = randomNumberGenerator_.randomDouble() + 0.3; int iColumn = integerVariable[i]; double value = newSolution[iColumn]; if (fabs(floor(value + 0.5) - value) > integerTolerance) { numberFractionalVariables++; } } const double* reducedCost = NULL; // See if not NLP if (model_->solverCharacteristics()->reducedCostsAccurate()) reducedCost = solver->getReducedCost(); int iteration = 0; while (numberFractionalVariables) { iteration++; // initialize any data initializeData(); // select a fractional variable to bound int bestColumn = -1; int bestRound; // -1 rounds down, +1 rounds up bool canRound = selectVariableToBranch(solver, newSolution, bestColumn, bestRound); // if the solution is not trivially roundable, we don't try to round; // if the solution is trivially roundable, we try to round. However, // if the rounded solution is worse than the current incumbent, // then we don't round and proceed normally. In this case, the // bestColumn will be a trivially roundable variable if (canRound) { // check if by rounding all fractional variables // we get a solution with an objective value // better than the current best integer solution double delta = 0.0; for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = newSolution[iColumn]; if (fabs(floor(value + 0.5) - value) > integerTolerance) { assert(downLocks_[i] == 0 || upLocks_[i] == 0); double obj = objective[iColumn]; if (downLocks_[i] == 0 && upLocks_[i] == 0) { if (direction * obj >= 0.0) delta += (floor(value) - value) * obj; else delta += (ceil(value) - value) * obj; } else if (downLocks_[i] == 0) delta += (floor(value) - value) * obj; else delta += (ceil(value) - value) * obj; } } if (direction*(solver->getObjValue() + delta) < solutionValue) { #ifdef DIVE_DEBUG nRoundFeasible++; #endif if (!nodes||bestColumn<0) { // Round all the fractional variables for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = newSolution[iColumn]; if (fabs(floor(value + 0.5) - value) > integerTolerance) { assert(downLocks_[i] == 0 || upLocks_[i] == 0); if (downLocks_[i] == 0 && upLocks_[i] == 0) { if (direction * objective[iColumn] >= 0.0) newSolution[iColumn] = floor(value); else newSolution[iColumn] = ceil(value); } else if (downLocks_[i] == 0) newSolution[iColumn] = floor(value); else newSolution[iColumn] = ceil(value); } } break; } else { // can't round if going to use in branching int i; for (i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = newSolution[bestColumn]; if (fabs(floor(value + 0.5) - value) > integerTolerance) { if (iColumn==bestColumn) { assert(downLocks_[i] == 0 || upLocks_[i] == 0); double obj = objective[bestColumn]; if (downLocks_[i] == 0 && upLocks_[i] == 0) { if (direction * obj >= 0.0) bestRound=-1; else bestRound=1; } else if (downLocks_[i] == 0) bestRound=-1; else bestRound=1; break; } } } } } #ifdef DIVE_DEBUG else nRoundInfeasible++; #endif } // do reduced cost fixing #ifdef DIVE_DEBUG int numberFixed = reducedCostFix(solver); std::cout << "numberReducedCostFixed = " << numberFixed << std::endl; #else reducedCostFix(solver); #endif int numberAtBoundFixed = 0; #ifdef DIVE_FIX_BINARY_VARIABLES // fix binary variables based on pseudo reduced cost if (binVarIndex_.size()) { int cnt = 0; int n = static_cast<int>(binVarIndex_.size()); for (int j = 0; j < n; j++) { int iColumn1 = binVarIndex_[j]; double value = newSolution[iColumn1]; if (fabs(value) <= integerTolerance && lower[iColumn1] != upper[iColumn1]) { double maxPseudoReducedCost = 0.0; #ifdef DIVE_DEBUG std::cout << "iColumn1 = " << iColumn1 << ", value = " << value << std::endl; #endif int iRow = vbRowIndex_[j]; double chosenValue = 0.0; for (int k = rowStart[iRow]; k < rowStart[iRow] + rowLength[iRow]; k++) { int iColumn2 = column[k]; #ifdef DIVE_DEBUG std::cout << "iColumn2 = " << iColumn2 << std::endl; #endif if (iColumn1 != iColumn2) { double pseudoReducedCost = fabs(reducedCost[iColumn2] * elementByRow[k]); #ifdef DIVE_DEBUG int k2; for (k2 = rowStart[iRow]; k2 < rowStart[iRow] + rowLength[iRow]; k2++) { if (column[k2] == iColumn1) break; } std::cout << "reducedCost[" << iColumn2 << "] = " << reducedCost[iColumn2] << ", elementByRow[" << iColumn2 << "] = " << elementByRow[k] << ", elementByRow[" << iColumn1 << "] = " << elementByRow[k2] << ", pseudoRedCost = " << pseudoReducedCost << std::endl; #endif if (pseudoReducedCost > maxPseudoReducedCost) maxPseudoReducedCost = pseudoReducedCost; } else { // save value chosenValue = fabs(elementByRow[k]); } } assert (chosenValue); maxPseudoReducedCost /= chosenValue; #ifdef DIVE_DEBUG std::cout << ", maxPseudoRedCost = " << maxPseudoReducedCost << std::endl; #endif candidate[cnt].var = iColumn1; candidate[cnt++].pseudoRedCost = maxPseudoReducedCost; } } #ifdef DIVE_DEBUG std::cout << "candidates for rounding = " << cnt << std::endl; #endif std::sort(candidate, candidate + cnt, compareBinaryVars); for (int i = 0; i < cnt; i++) { int iColumn = candidate[i].var; if (numberAtBoundFixed < maxNumberAtBoundToFix) { columnFixed[numberAtBoundFixed] = iColumn; originalBound[numberAtBoundFixed] = upper[iColumn]; fixedAtLowerBound[numberAtBoundFixed] = true; solver->setColUpper(iColumn, lower[iColumn]); numberAtBoundFixed++; if (numberAtBoundFixed == maxNumberAtBoundToFix) break; } } } #endif // fix other integer variables that are at their bounds int cnt = 0; #ifdef GAP double gap = 1.0e30; #endif if (reducedCost && true) { #ifndef JJF_ONE cnt = fixOtherVariables(solver, solution, candidate, random); #else #ifdef GAP double cutoff = model_->getCutoff() ; if (cutoff < 1.0e20 && false) { double direction = solver->getObjSense() ; gap = cutoff - solver->getObjValue() * direction ; gap *= 0.1; // Fix more if plausible double tolerance; solver->getDblParam(OsiDualTolerance, tolerance) ; if (gap <= 0.0) gap = tolerance; gap += 100.0 * tolerance; } int nOverGap = 0; #endif int numberFree = 0; int numberFixed = 0; for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; if (upper[iColumn] > lower[iColumn]) { numberFree++; double value = newSolution[iColumn]; if (fabs(floor(value + 0.5) - value) <= integerTolerance) { candidate[cnt].var = iColumn; candidate[cnt++].pseudoRedCost = fabs(reducedCost[iColumn] * random[i]); #ifdef GAP if (fabs(reducedCost[iColumn]) > gap) nOverGap++; #endif } } else { numberFixed++; } } #ifdef GAP int nLeft = maxNumberAtBoundToFix - numberAtBoundFixed; #ifdef CLP_INVESTIGATE4 printf("cutoff %g obj %g nover %d - %d free, %d fixed\n", cutoff, solver->getObjValue(), nOverGap, numberFree, numberFixed); #endif if (nOverGap > nLeft && true) { nOverGap = CoinMin(nOverGap, nLeft + maxNumberAtBoundToFix / 2); maxNumberAtBoundToFix += nOverGap - nLeft; } #else #ifdef CLP_INVESTIGATE4 printf("cutoff %g obj %g - %d free, %d fixed\n", model_->getCutoff(), solver->getObjValue(), numberFree, numberFixed); #endif #endif #endif } else { for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; if (upper[iColumn] > lower[iColumn]) { double value = newSolution[iColumn]; if (fabs(floor(value + 0.5) - value) <= integerTolerance) { candidate[cnt].var = iColumn; candidate[cnt++].pseudoRedCost = numberIntegers - i; } } } } std::sort(candidate, candidate + cnt, compareBinaryVars); for (int i = 0; i < cnt; i++) { int iColumn = candidate[i].var; if (upper[iColumn] > lower[iColumn]) { double value = newSolution[iColumn]; if (fabs(floor(value + 0.5) - value) <= integerTolerance && numberAtBoundFixed < maxNumberAtBoundToFix) { // fix the variable at one of its bounds if (fabs(lower[iColumn] - value) <= integerTolerance) { columnFixed[numberAtBoundFixed] = iColumn; originalBound[numberAtBoundFixed] = upper[iColumn]; fixedAtLowerBound[numberAtBoundFixed] = true; solver->setColUpper(iColumn, lower[iColumn]); numberAtBoundFixed++; } else if (fabs(upper[iColumn] - value) <= integerTolerance) { columnFixed[numberAtBoundFixed] = iColumn; originalBound[numberAtBoundFixed] = lower[iColumn]; fixedAtLowerBound[numberAtBoundFixed] = false; solver->setColLower(iColumn, upper[iColumn]); numberAtBoundFixed++; } if (numberAtBoundFixed == maxNumberAtBoundToFix) break; } } } #ifdef DIVE_DEBUG std::cout << "numberAtBoundFixed = " << numberAtBoundFixed << std::endl; #endif double originalBoundBestColumn; double bestColumnValue; int whichWay; if (bestColumn >= 0) { bestColumnValue = newSolution[bestColumn]; if (bestRound < 0) { originalBoundBestColumn = upper[bestColumn]; solver->setColUpper(bestColumn, floor(bestColumnValue)); whichWay=0; } else { originalBoundBestColumn = lower[bestColumn]; solver->setColLower(bestColumn, ceil(bestColumnValue)); whichWay=1; } } else { break; } int originalBestRound = bestRound; int saveModelOptions = model_->specialOptions(); while (1) { model_->setSpecialOptions(saveModelOptions | 2048); solver->resolve(); model_->setSpecialOptions(saveModelOptions); if (!solver->isAbandoned()&&!solver->isIterationLimitReached()) { numberSimplexIterations += solver->getIterationCount(); } else { numberSimplexIterations = maxSimplexIterations + 1; reasonToStop += 100; break; } if (!solver->isProvenOptimal()) { if (nodes) { if (solver->isProvenPrimalInfeasible()) { if (maxSimplexIterationsAtRoot_!=COIN_INT_MAX) { // stop now printf("stopping on first infeasibility\n"); break; } else if (cuts) { // can do conflict cut printf("could do intermediate conflict cut\n"); bool localCut; OsiRowCut * cut = model_->conflictCut(solver,localCut); if (cut) { if (!localCut) { model_->makePartialCut(cut,solver); cuts[numberCuts++]=cut; } else { delete cut; } } } } else { reasonToStop += 10; break; } } if (numberAtBoundFixed > 0) { // Remove the bound fix for variables that were at bounds for (int i = 0; i < numberAtBoundFixed; i++) { int iColFixed = columnFixed[i]; if (fixedAtLowerBound[i]) solver->setColUpper(iColFixed, originalBound[i]); else solver->setColLower(iColFixed, originalBound[i]); } numberAtBoundFixed = 0; } else if (bestRound == originalBestRound) { bestRound *= (-1); whichWay |=2; if (bestRound < 0) { solver->setColLower(bestColumn, originalBoundBestColumn); solver->setColUpper(bestColumn, floor(bestColumnValue)); } else { solver->setColLower(bestColumn, ceil(bestColumnValue)); solver->setColUpper(bestColumn, originalBoundBestColumn); } } else break; } else break; } if (!solver->isProvenOptimal() || direction*solver->getObjValue() >= solutionValue) { reasonToStop += 1; } else if (iteration > maxIterations_) { reasonToStop += 2; } else if (CoinCpuTime() - time1 > maxTime_) { reasonToStop += 3; } else if (numberSimplexIterations > maxSimplexIterations) { reasonToStop += 4; // also switch off #ifdef CLP_INVESTIGATE printf("switching off diving as too many iterations %d, %d allowed\n", numberSimplexIterations, maxSimplexIterations); #endif when_ = 0; } else if (solver->getIterationCount() > 1000 && iteration > 3 && !nodes) { reasonToStop += 5; // also switch off #ifdef CLP_INVESTIGATE printf("switching off diving one iteration took %d iterations (total %d)\n", solver->getIterationCount(), numberSimplexIterations); #endif when_ = 0; } memcpy(newSolution, solution, numberColumns*sizeof(double)); numberFractionalVariables = 0; double sumFractionalVariables=0.0; for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = newSolution[iColumn]; double away = fabs(floor(value + 0.5) - value); if (away > integerTolerance) { numberFractionalVariables++; sumFractionalVariables += away; } } if (nodes) { // save information //branchValues[numberNodes]=bestColumnValue; //statuses[numberNodes]=whichWay+(bestColumn<<2); //bases[numberNodes]=solver->getWarmStart(); ClpSimplex * simplex = clpSolver->getModelPtr(); CbcSubProblem * sub = new CbcSubProblem(clpSolver,lowerBefore,upperBefore, simplex->statusArray(),numberNodes); nodes[numberNodes]=sub; // other stuff sub->branchValue_=bestColumnValue; sub->problemStatus_=whichWay; sub->branchVariable_=bestColumn; sub->objectiveValue_ = simplex->objectiveValue(); sub->sumInfeasibilities_ = sumFractionalVariables; sub->numberInfeasibilities_ = numberFractionalVariables; printf("DiveNode %d column %d way %d bvalue %g obj %g\n", numberNodes,sub->branchVariable_,sub->problemStatus_, sub->branchValue_,sub->objectiveValue_); numberNodes++; if (solver->isProvenOptimal()) { memcpy(lastDjs,solver->getReducedCost(),numberColumns*sizeof(double)); memcpy(lowerBefore,lower,numberColumns*sizeof(double)); memcpy(upperBefore,upper,numberColumns*sizeof(double)); } } if (!numberFractionalVariables||reasonToStop) break; } if (nodes) { printf("Exiting dive for reason %d\n",reasonToStop); if (reasonToStop>1) { printf("problems in diving\n"); int whichWay=nodes[numberNodes-1]->problemStatus_; CbcSubProblem * sub; if ((whichWay&2)==0) { // leave both ways sub = new CbcSubProblem(*nodes[numberNodes-1]); nodes[numberNodes++]=sub; } else { sub = nodes[numberNodes-1]; } if ((whichWay&1)==0) sub->problemStatus_=whichWay|1; else sub->problemStatus_=whichWay&~1; } if (!numberNodes) { // was good at start! - create fake clpSolver->resolve(); ClpSimplex * simplex = clpSolver->getModelPtr(); CbcSubProblem * sub = new CbcSubProblem(clpSolver,lowerBefore,upperBefore, simplex->statusArray(),numberNodes); nodes[numberNodes]=sub; // other stuff sub->branchValue_=0.0; sub->problemStatus_=0; sub->branchVariable_=-1; sub->objectiveValue_ = simplex->objectiveValue(); sub->sumInfeasibilities_ = 0.0; sub->numberInfeasibilities_ = 0; printf("DiveNode %d column %d way %d bvalue %g obj %g\n", numberNodes,sub->branchVariable_,sub->problemStatus_, sub->branchValue_,sub->objectiveValue_); numberNodes++; assert (solver->isProvenOptimal()); } nodes[numberNodes-1]->problemStatus_ |= 256*reasonToStop; // use djs as well if (solver->isProvenPrimalInfeasible()&&cuts) { // can do conflict cut and re-order printf("could do final conflict cut\n"); bool localCut; OsiRowCut * cut = model_->conflictCut(solver,localCut); if (cut) { printf("cut - need to use conflict and previous djs\n"); if (!localCut) { model_->makePartialCut(cut,solver); cuts[numberCuts++]=cut; } else { delete cut; } } else { printf("bad conflict - just use previous djs\n"); } } } // re-compute new solution value double objOffset = 0.0; solver->getDblParam(OsiObjOffset, objOffset); newSolutionValue = -objOffset; for (int i = 0 ; i < numberColumns ; i++ ) newSolutionValue += objective[i] * newSolution[i]; newSolutionValue *= direction; //printf("new solution value %g %g\n",newSolutionValue,solutionValue); if (newSolutionValue < solutionValue && !reasonToStop) { double * rowActivity = new double[numberRows]; memset(rowActivity, 0, numberRows*sizeof(double)); // paranoid check memset(rowActivity, 0, numberRows*sizeof(double)); for (int i = 0; i < numberColumns; i++) { int j; double value = newSolution[i]; if (value) { for (j = columnStart[i]; j < columnStart[i] + columnLength[i]; j++) { int iRow = row[j]; rowActivity[iRow] += value * element[j]; } } } // check was approximately feasible bool feasible = true; for (int i = 0; i < numberRows; i++) { if (rowActivity[i] < rowLower[i]) { if (rowActivity[i] < rowLower[i] - 1000.0*primalTolerance) feasible = false; } else if (rowActivity[i] > rowUpper[i]) { if (rowActivity[i] > rowUpper[i] + 1000.0*primalTolerance) feasible = false; } } for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = newSolution[iColumn]; if (fabs(floor(value + 0.5) - value) > integerTolerance) { feasible = false; break; } } if (feasible) { // new solution solutionValue = newSolutionValue; //printf("** Solution of %g found by CbcHeuristicDive\n",newSolutionValue); //if (cuts) //clpSolver->getModelPtr()->writeMps("good8.mps", 2); returnCode = 1; } else { // Can easily happen //printf("Debug CbcHeuristicDive giving bad solution\n"); } delete [] rowActivity; } #ifdef DIVE_DEBUG std::cout << "nRoundInfeasible = " << nRoundInfeasible << ", nRoundFeasible = " << nRoundFeasible << ", returnCode = " << returnCode << ", reasonToStop = " << reasonToStop << ", simplexIts = " << numberSimplexIterations << ", iterations = " << iteration << std::endl; #endif delete [] columnFixed; delete [] originalBound; delete [] fixedAtLowerBound; delete [] candidate; delete [] random; delete [] downArray_; downArray_ = NULL; delete [] upArray_; upArray_ = NULL; delete solver; return returnCode; }
int main(int argc, char **argv) { char *f_name_lp, *last_dot_pos, f_name[256], *f_name_pos; int i, ncol; if((argc < 2) || (argc > 2)) { printf("### ERROR: main(): Usage: One of the following\ncgl_data_test input_file_name.mps\ncgl_data_test input_file_name.lp\n"); exit(1); } f_name_lp = strdup(argv[1]); f_name_pos = strrchr(f_name_lp, '/'); if(f_name_pos != NULL) { strcpy(f_name, &(f_name_pos[1])); } else { strcpy(f_name, f_name_lp); } last_dot_pos = strrchr(f_name, '.'); if(last_dot_pos != NULL) { last_dot_pos = '\0'; } OsiClpSolverInterface *clp = new OsiClpSolverInterface; clp->messageHandler()->setLogLevel(0); if(strcmp(&(f_name_lp[strlen(f_name_lp)-3]), ".lp") == 0) { clp->readLp(f_name_lp); } else { if(strcmp(&(f_name_lp[strlen(f_name_lp)-4]), ".mps") == 0) { clp->readMps(f_name_lp); } else { printf("### ERROR: unrecognized file type\n"); exit(1); } } ncol = clp->getNumCols(); clp->initialSolve(); printf("LP value: %12.2f\n", clp->getObjValue()); OsiCuts cuts; // Define parameters for CglRedSplit generator CglParam cpar; cpar.setMAX_SUPPORT(ncol+1); CglRedSplitParam rspar(cpar); // Create a cut generator with the given parameters CglRedSplit cutGen(rspar); char *colType = new char[ncol]; for(i=0; i<ncol; i++) { if(clp->isContinuous(i)) { colType[i] = 'C'; } else { colType[i] = 'I'; } } int round, max_rounds = 10; for(round=0; round<max_rounds; round++) { cutGen.generateCuts(*clp, cuts); int ncuts = cuts.sizeRowCuts(); const OsiRowCut **newRowCuts = new const OsiRowCut * [ncuts]; for(i=0; i<ncuts; i++) { newRowCuts[i] = &cuts.rowCut(i); } clp->applyRowCuts(ncuts, newRowCuts); delete[] newRowCuts; printf("round %4d: %4d generated cuts new objective value: %12.2f\n", round, ncuts, clp->getObjValue()); clp->resolve(); if(clp->isAbandoned()) { printf("###ERROR: Numerical difficulties in Solver\n"); exit(1); } if(clp->isProvenPrimalInfeasible()) { printf("### WARNING: Problem is infeasible\n"); exit(1); } } delete clp; free(f_name_lp); delete[] colType; return(0); }