// 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; }
/* After a CbcModel::resolve this can return a status -1 no effect 0 treat as optimal 1 as 0 but do not do any more resolves (i.e. no more cuts) 2 treat as infeasible */ int CbcNlpStrategy::status(CbcModel * model, CbcNodeInfo * parent,int whereFrom) { OsiSolverInterface * solver = model->solver();//get solver int feasible = 1; bool solved = true; int returnStatus = -1; BonCbcPartialNodeInfo * bmNodeInfo = dynamic_cast<BonCbcPartialNodeInfo *>(parent); if (!bmNodeInfo) return -1; int seqOfInfeasiblesSize = bmNodeInfo->getSequenceOfInfeasiblesSize(); int seqOfUnsolvedSize = bmNodeInfo->getSequenceOfUnsolvedSize(); if (solver->isAbandoned()) { solved = false; seqOfUnsolvedSize++; ; } else if (solver->isProvenPrimalInfeasible()) { feasible = 0; seqOfInfeasiblesSize++; } if ((seqOfUnsolvedSize==0) || (maxFailure_ == 0) && (maxInfeasible_== 0) || (seqOfInfeasiblesSize==0)) if (feasible && seqOfInfeasiblesSize > 1) { (*model->messageHandler())<<"Feasible node while father was infeasible." <<CoinMessageEol; } if (solved && seqOfUnsolvedSize > 1) { (*model->messageHandler())<<"Solved node while father was unsolved." <<CoinMessageEol; } if (seqOfInfeasiblesSize < maxInfeasible_ && solved && !feasible) { (*model->messageHandler())<<"Branching on infeasible node, sequence of infeasibles size " <<seqOfInfeasiblesSize<<CoinMessageEol; // Have to make sure that we will branch OsiTMINLPInterface * ipopt = dynamic_cast<OsiTMINLPInterface *>(solver); ipopt->forceBranchable(); //change objective value returnStatus = 0; } if (!solved && parent != NULL && seqOfUnsolvedSize <= maxFailure_) { (*model->messageHandler())<<"Branching on unsolved node, sequence of unsolved size "<<seqOfUnsolvedSize<<CoinMessageEol; // Have to make sure that we will branch OsiTMINLPInterface * osiMinlp = dynamic_cast<OsiTMINLPInterface *>(solver); osiMinlp->forceBranchable(); // feasible=1; returnStatus = 0; } if (solver->isAbandoned() && parent != NULL && seqOfUnsolvedSize > maxFailure_) { hasFailed_ = true; OsiTMINLPInterface * osiMinlp = dynamic_cast<OsiTMINLPInterface *>(solver); if (pretendFailIsInfeasible_) { //force infeasible osiMinlp->forceInfeasible(); returnStatus = 2; } else { std::string probName; osiMinlp->getStrParam(OsiProbName,probName); throw osiMinlp->newUnsolvedError(0, osiMinlp->problem(), probName); } } return returnStatus; }
int main( int argc, char **argv ) { if ( argc < 2 ) { printf("Invalid number of parameters!\n"); exit( EXIT_FAILURE ); } char problemName[ 256 ]; getFileName( problemName, argv[1] ); clock_t start = clock(); OsiClpSolverInterface *realSolver = new OsiClpSolverInterface(); realSolver->getModelPtr()->setPerturbation(50); /* makes CLP faster for hard instances */ OsiSolverInterface *solver = (OsiSolverInterface*) realSolver; parseParameters( argc, argv ); readLP( solver, argv[1] ); FILE *log = NULL; if(!output.empty()) { log = fopen(output.c_str(), "a"); if(!log) { printf("Could not open the file!\n"); exit(EXIT_FAILURE); } } const int numCols = solver->getNumCols(), numRows = solver->getNumRows(); int pass = 0, newCuts = 0, totalCuts = 0; double pTime, opt, cgTime; CGraph *cgraph = NULL; if(sepMethod == Npsep) cgraph = build_cgraph_osi( solver ); if(!optFile.empty()) { getOptimals(); if(optimals.find(problemName) == optimals.end()) { fprintf(stderr, "ERROR: optimal value not found!\n"); exit(EXIT_FAILURE); } opt = optimals[problemName]; } solver->initialSolve(); if (!solver->isProvenOptimal()) { if (solver->isAbandoned()) { fprintf( stderr, "LP solver abandoned due to numerical dificulties.\n" ); exit( EXIT_FAILURE ); } if (solver->isProvenPrimalInfeasible()) { fprintf( stderr, "LP solver says PRIMAL INFEASIBLE.\n" ); exit( EXIT_FAILURE ); } if (solver->isProvenDualInfeasible()) { fprintf( stderr, "LP solver says DUAL INFEASIBLE.\n" ); exit( EXIT_FAILURE ); } if (solver->isPrimalObjectiveLimitReached()) { fprintf( stderr, "LP solver says isPrimalObjectiveLimitReached.\n" ); exit( EXIT_FAILURE ); } if (solver->isDualObjectiveLimitReached()) { fprintf( stderr, "LP solver says isDualObjectiveLimitReached.\n" ); exit( EXIT_FAILURE ); } if (solver->isIterationLimitReached()) { fprintf( stderr, "LP solver says isIterationLimitReached.\n" ); exit( EXIT_FAILURE ); } fprintf( stderr, "ERROR: Could not solve LP relaxation to optimality. Checking status...\n" ); exit( EXIT_FAILURE ); } double initialBound = solver->getObjValue(); printf("%.2lf %d %d %.7lf", ((double)(clock()-start)) / ((double)CLOCKS_PER_SEC), pass, 0, solver->getObjValue()); if(!optFile.empty()) { printf(" %.7lf %.7lf", opt, abs_mip_gap(solver->getObjValue(), opt)); } printf("\n"); do { clock_t startSep = clock(); newCuts = 0; switch (sepMethod) { case Npsep: { CglEClique cliqueGen; OsiCuts cuts; CglTreeInfo info; info.level = 0; info.pass = 1; vector<string> varNames = getVarNames(solver->getColNames(), numCols); cliqueGen.parseParameters( argc, (const char**)argv ); cliqueGen.setCGraph( cgraph ); cliqueGen.setGenOddHoles( true ); //allow (or not) inserting odd hole cuts cliqueGen.colNames = &varNames; cliqueGen.generateCuts( *solver, cuts, info ); newCuts = cuts.sizeCuts(); solver->applyCuts( cuts ); } break; case CglSepM: { CglClique cliqueGen; OsiCuts cuts; CglTreeInfo info; info.level = 0; info.pass = 1; cliqueGen.setMinViolation( MIN_VIOLATION ); cliqueGen.setStarCliqueReport(false); cliqueGen.setRowCliqueReport(false); cliqueGen.generateCuts( *solver, cuts, info ); newCuts = cuts.sizeCuts(); solver->applyCuts( cuts ); } break; Default: { fprintf( stderr, "Separation Method does not recognized!\n" ); exit( EXIT_FAILURE ); } } pTime = ((double)(clock()-start)) / ((double)CLOCKS_PER_SEC); if(pTime > MAX_TIME) break; totalCuts += newCuts; ++pass; if (newCuts) { solver->resolve(); if (!solver->isProvenOptimal()) { if (solver->isAbandoned()) { fprintf( stderr, "LP solver abandoned due to numerical dificulties.\n" ); exit( EXIT_FAILURE ); } if (solver->isProvenPrimalInfeasible()) { fprintf( stderr, "LP solver says PRIMAL INFEASIBLE.\n" ); exit( EXIT_FAILURE ); } if (solver->isProvenDualInfeasible()) { fprintf( stderr, "LP solver says DUAL INFEASIBLE.\n" ); exit( EXIT_FAILURE ); } if (solver->isPrimalObjectiveLimitReached()) { fprintf( stderr, "LP solver says isPrimalObjectiveLimitReached.\n" ); exit( EXIT_FAILURE ); } if (solver->isDualObjectiveLimitReached()) { fprintf( stderr, "LP solver says isDualObjectiveLimitReached.\n" ); exit( EXIT_FAILURE ); } if (solver->isIterationLimitReached()) { fprintf( stderr, "LP solver says isIterationLimitReached.\n" ); exit( EXIT_FAILURE ); } fprintf( stderr, "ERROR: Could not solve LP relaxation. Exiting.\n" ); exit( EXIT_FAILURE ); } pTime = ((double)(clock()-start)) / ((double)CLOCKS_PER_SEC); if(pTime > MAX_TIME) break; double sepTime = ((double)(clock()-startSep)) / ((double)CLOCKS_PER_SEC); printf("%.2lf %d %d %.7lf", sepTime, pass, newCuts, solver->getObjValue()); if(!optFile.empty()) printf(" %.7lf %.7lf", opt, abs_mip_gap(solver->getObjValue(), opt)); printf("\n"); } } while ( (newCuts>0) && (pass<MAX_PASSES) ) ; if(log) { double totalTime = ((double)(clock()-start)) / ((double)CLOCKS_PER_SEC); fprintf(log, "%s %.2lf %d %d %.7lf", problemName, totalTime, pass - 1, totalCuts, solver->getObjValue()); if(!optFile.empty()) fprintf(log, " %.7lf", abs_mip_gap(solver->getObjValue(), opt)); fprintf(log, "\n"); } if(cgraph) cgraph_free( &cgraph ); delete realSolver; return EXIT_SUCCESS; }
//Solver function int sci_rmps(char *fname) { //creating a problem pointer using base class of OsiSolverInterface and //instantiate the object using derived class of ClpSolverInterface OsiSolverInterface* si = new OsiClpSolverInterface(); // Error management variable SciErr sciErr; //data declarations int *piAddressVarOne = NULL; //pointer used to access argument of the function char* ptr; //pointer to point to address of file name double* options_; //options to set maximum iterations CheckInputArgument(pvApiCtx, 2,2 ); //Check we have exactly two arguments as input or not CheckOutputArgument(pvApiCtx, 6, 6); //Check we have exactly six arguments on output side or not //Getting the input arguments from Scilab //Getting the MPS file path //Reading mps file getStringFromScilab(1,&ptr); std::cout<<ptr; //get options from Scilab if(getFixedSizeDoubleMatrixInList(2 , 2 , 1 , 1 , &options_)) { return 1; } //Read the MPS file si->readMps(ptr); //setting options for maximum iterations si->setIntParam(OsiMaxNumIteration,options_[0]); //Solve the problem si->initialSolve(); //Quering about the problem //get number of variables double numVars_; numVars_ = si->getNumCols(); //get number of constraint equations double numCons_; numCons_ = si->getNumRows(); //Output the solution to Scilab //get solution for x const double* xValue = si->getColSolution(); //get objective value double objValue = si->getObjValue(); //get Status value double status; if(si->isProvenOptimal()) status=0; else if(si->isProvenPrimalInfeasible()) status=1; else if(si->isProvenDualInfeasible()) status=2; else if(si->isIterationLimitReached()) status=3; else if(si->isAbandoned()) status=4; else if(si->isPrimalObjectiveLimitReached()) status=5; else if(si->isDualObjectiveLimitReached()) status=6; //get number of iterations double iterations = si->getIterationCount(); //get reduced cost const double* reducedCost = si->getReducedCost(); //get dual vector const double* dual = si->getRowPrice(); returnDoubleMatrixToScilab(1 , 1 , numVars_ , xValue); returnDoubleMatrixToScilab(2 , 1 , 1 , &objValue); returnDoubleMatrixToScilab(3 , 1 , 1 , &status); returnDoubleMatrixToScilab(4 , 1 , 1 , &iterations); returnDoubleMatrixToScilab(5 , 1 , numVars_ , reducedCost); returnDoubleMatrixToScilab(6 , 1 , numCons_ , dual); free(xValue); free(dual); free(reducedCost); }