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; }
void LinearCutsGenerator::initialize(BabSetupBase & s){ assert(dynamic_cast<TMINLP2TNLPQuadCuts *> (s.nonlinearSolver()->problem())); int freq; s.options()->GetIntegerValue("Gomory_cuts", freq,"bonmin."); if (freq) { Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod; cg->frequency = freq; CglGomory * gom = new CglGomory; cg->cgl = gom; gom->setLimitAtRoot(512); gom->setLimit(50); cg->id = "Mixed Integer Gomory"; methods_.push_back(cg); } s.options()->GetIntegerValue("mir_cuts",freq,"bonmin."); if (freq) { Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod; cg->frequency = freq; CglMixedIntegerRounding2 * mir = new CglMixedIntegerRounding2; cg->cgl = mir; cg->id = "Mixed Integer Rounding"; methods_.push_back(cg); } s.options()->GetIntegerValue("2mir_cuts",freq,"bonmin."); if (freq) { Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod; cg->frequency = freq; CglTwomir * mir2 = new CglTwomir; cg->cgl = mir2; cg->id = "2-MIR"; methods_.push_back(cg); } s.options()->GetIntegerValue("cover_cuts",freq,"bonmin."); if (freq) { Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod; cg->frequency = freq; CglKnapsackCover * cover = new CglKnapsackCover; cg->cgl = cover; cg->id = "Cover"; methods_.push_back(cg); } s.options()->GetIntegerValue("clique_cuts",freq,"bonmin."); if (freq) { Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod; cg->frequency = freq; CglClique * clique = new CglClique; clique->setStarCliqueReport(false); clique->setRowCliqueReport(false); clique->setMinViolation(0.1); cg->cgl = clique; cg->id = "Clique"; methods_.push_back(cg); } s.options()->GetIntegerValue("flow_cover_cuts",freq,"bonmin."); if (freq) { Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod; cg->frequency = freq; CglFlowCover * flow = new CglFlowCover; cg->cgl = flow; cg->id = "Flow Covers"; methods_.push_back(cg); } s.options()->GetIntegerValue("lift_and_project_cuts",freq,"bonmin."); if (freq) { Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod; cg->frequency = freq; CglLandP * landp = new CglLandP; cg->cgl = landp; cg->id = "Lift-and-Project"; methods_.push_back(cg); } s.options()->GetIntegerValue("reduce_and_split_cuts",freq,"bonmin."); if (freq) { Coin::SmartPtr<CuttingMethod> cg = new CuttingMethod; cg->frequency = freq; CglRedSplit * rands = new CglRedSplit; cg->cgl = rands; cg->id = "Reduce-and-Split"; methods_.push_back(cg); } }