Beispiel #1
0
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);
    }
  }