/** creates a subproblem for subscip by fixing a number of variables */
static
SCIP_RETCODE setupSubproblem(
   SCIP*                 scip,               /**< original SCIP data structure */
   SCIP*                 subscip,            /**< SCIP data structure for the subproblem */
   SCIP_VAR**            subvars,            /**< the variables of the subproblem */
   int*                  selection,          /**< pool of solutions crossover will use */
   SCIP_HEURDATA*        heurdata,           /**< primal heuristic data */
   SCIP_Bool*            success             /**< pointer to store whether the problem was created successfully */
   )
{
   SCIP_SOL** sols;                         /* array of all solutions found so far         */
   int nsols;                               /* number of all solutions found so far        */
   int nusedsols;                           /* number of solutions to use in crossover     */

   int i;
   char consname[SCIP_MAXSTRLEN];

   /* get solutions' data */
   nsols = SCIPgetNSols(scip);
   sols = SCIPgetSols(scip);
   nusedsols = heurdata->nusedsols;

   assert(nusedsols > 1);
   assert(nsols >= nusedsols);

   /* use nusedsols best solutions if randomization is deactivated or there are only nusedsols solutions at hand
    * or a good new solution was found since last call */
   if( !heurdata->randomization || nsols == nusedsols || heurdata->prevlastsol != sols[nusedsols-1] )
   {
      SOLTUPLE* elem;
      SCIP_HEUR* solheur;
      SCIP_Longint solnodenum;
      SCIP_Bool allsame;

      for( i = 0; i < nusedsols; i++ )
         selection[i] = i;
      SCIP_CALL( createSolTuple(scip, &elem, selection, nusedsols, heurdata) );

      solheur = SCIPsolGetHeur(sols[0]);
      solnodenum = SCIPsolGetNodenum(sols[0]);
      allsame = TRUE;

      /* check, whether all solutions have been found by the same heuristic at the same node; in this case we do not run
       * crossover, since it would probably just optimize over the same space as the other heuristic
       */
      for( i = 1; i < nusedsols; i++ )
      {
         if( SCIPsolGetHeur(sols[i]) != solheur || SCIPsolGetNodenum(sols[i]) != solnodenum )
            allsame = FALSE;
      }
      *success = !allsame && !SCIPhashtableExists(heurdata->hashtable, elem);

      /* check, whether solution tuple has already been tried */
      if( !SCIPhashtableExists(heurdata->hashtable, elem) )
      {
         SCIP_CALL( SCIPhashtableInsert(heurdata->hashtable, elem) );
      }

      /* if solution tuple has already been tried, randomization is allowed and enough solutions are at hand, try
       * to randomize another tuple. E.g., this can happen if the last crossover solution was among the best ones */
      if( !(*success) && heurdata->randomization && nsols > nusedsols )
      {
         SCIP_CALL( selectSolsRandomized(scip, selection, heurdata, success) );
      }

   }
   /* otherwise randomize the set of solutions */
   else
   {
      SCIP_CALL( selectSolsRandomized(scip, selection, heurdata, success) );
   }

   /* no acceptable solution tuple could be created */
   if( !(*success) )
      return SCIP_OKAY;

   /* get name of the original problem and add the string "_crossoversub" */
   (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_crossoversub", SCIPgetProbName(scip));

   /* set up the variables of the subproblem */
   SCIP_CALL( fixVariables(scip, subscip, subvars, selection, heurdata, success) );

   /* we copy the rows of the LP, if the enough variables could be fixed and we work on the MIP
      relaxation of the problem */
   if( *success && heurdata->uselprows )
   {
      SCIP_CALL( createRows(scip, subscip, subvars) );
   }

   return SCIP_OKAY;
}
예제 #2
0
bool GecodeEngine::findSolution(int TimeForGecode, bool fix) {
    //    postCovSol();
    //    this->print(std::cout);
    //    std::cout << "No branch posted " << std::endl;
    Gecode::branch(*this, AllVars, Gecode::INT_VAR_DEGREE_MAX(), INT_VAL_MIN());
    //    Gecode::branch(*this, binVars, Gecode::INT_VAR_ACTIVITY_MAX());    //    std::cout << "TimeForGecode " << TimeForGecode << std::endl;
    //    std::cout << IntVars->size() << std::endl;
    //    sleep(5);
    //    std::shared_ptr<Gecode::Search::Options> so = std::make_shared<Search::Options>();
    //    Gecode::Search::Options* so = new Gecode::Search::Options();
    std::cout << "Gecode time " << TimeForGecode << std::endl;
    Multistop* ms = new Multistop(0, 1, TimeForGecode * 1000);
    Gecode::Search::Options* so = new Gecode::Search::Options();
    so->stop = ms;
    //    this->print(std::cout);
    std::cout << "Stuck in Status? " << std::endl;
    printSpaceStatus();
    //    unsigned ub = 0;
    //    unsigned lb = 0;
    //    for (IntVar iv : AllVars) {
    //        if (iv.max() != 1) {
    //            if (iv.max() != 2147483646) {
    //                ub++;
    //                //                std::cout << iv->getUpperBound() << std::endl;
    //            }
    //        }
    //        if (iv.min() != 0) {
    //            lb++;
    //            //            std::cout << iv.min() << std::endl;
    //        }
    //    }
    //    std::cout << "lb " << lb << " ub " << ub << std::endl;


    //    this->print(std::cout);
    //    for(IntVar iv : IntVars){
    //        if(iv.assigned()){
    //            std::cout << "assigned" << std::endl;
    //        }
    //    }
    if (fix) {
        fixVariables();
    }
    //    std::cout << so->a_d << std::endl;
    //    std::cout << so->c_d << std::endl;
    //    exit(1);    

    //    so->a_d = std::max(AllVars.size() / 32, 2); // Default 2 
    //    so->c_d = std::max(AllVars.size() / 16, 8); // Default 8
    so->a_d = AllVars.size(); // Default 2 
    so->c_d = AllVars.size(); // Default 8
    //    this->print(std::cout);
    if (fix) {
        model->out->relax = 0;

        //        model->out->addToGecodePrint("0");
    }
    bool solutionFound = false;
    GecodeEngine* s;
    try {
        std::clock_t GecodeClock = std::clock();
        //        std::cout << "Before search engine" << std::endl;
        Gecode::DFS<GecodeEngine> e(this, *so);
        //        Gecode::BAB<GecodeSolver> e(this, *so);
        std::cout << "Searching for solution...." << std::endl;
        s = e.next();

        std::cout << "stop called " << ms->called << " times" << std::endl;
        if (e.stopped()) {
            std::cout << "WARNING: solver stopped, solution is not optimal!\n";

            if (so->stop->stop(e.statistics(), *so)) {
                //                    cout << "\t Solver stopped because of TIME LIMIT!\n";
                //                //                    cout << "\t Solver stopped because of  NODE LIMIT!\n";
                //                std::cout << "\t Number of nodes expanded: " << e.statistics().node << std::endl;
                //                std::cout << "\t Number of failed nodes: " << e.statistics().fail << std::endl;
                //                std::cout << "\t Number of restarts: " << e.statistics().restart << std::endl;
                //                double time = (std::clock() - GecodeClock) / (double) CLOCKS_PER_SEC;
                //                std::cout << "\t Time spend searching for solution: " << time << " seconds" << std::endl;
                //

                //                SetValues(AllVars);
                solutionFound = false;
                //                std::cout << "Gecode found solution after " << (std::clock() - GecodeClock) / (double) CLOCKS_PER_SEC << std::endl;
                //                std::cout << "Total time used so far " << (std::clock() - Clock::globalClock) / (double) CLOCKS_PER_SEC << std::endl;
                Gecode::Search::Statistics stat = e.statistics();
                print_stats(stat);
                double time = (std::clock() - GecodeClock) / (double) CLOCKS_PER_SEC;
                std::cout << "\tTime spend searching for solution: " << time << " seconds" << std::endl;

                model->out->addToGecodePrint(std::to_string(e.statistics().fail));
                model->out->addToGecodePrint(std::to_string(time));
                //                model->out->addToGecodePrint("0");

                std::cout << "## fail " << e.statistics().fail << std::endl;
                //                std::cout << "## stopped " << std::endl;
                model->out->relax++;

            }
        } else {
            //        } 
            //            s->print(std::cout);
            //            for (int i = 0; i < s->IntVars.size(); i++) {
            //                if(s->IntVars[i].val() != 0){
            //                    std::cout << i << " " << s->IntVars[i]<< " ";
            //                }

            //                std::cout << "Gecode::IntVarArgs x" << i << "(1);" << std::endl;
            //                std::cout << "x" << i << "[0] = tmpVars[" << i << "];" << std::endl;
            //                std::cout << "Gecode::linear(*this, iva, x" << i << ", Gecode::IRT_EQ, " << s->IntVars[i].val() << ", icl);" << std::endl;
            //                            Gecode::linear(*this, c, x, Gecode::IRT_EQ, upperbound, icl); //Gecode::ICL_BND);


            //            }
            //            s->print(std::cout); //            this->print(std::cout);

            solutionFound = true;
            double time = (std::clock() - GecodeClock) / (double) CLOCKS_PER_SEC;

            std::cout << "Gecode found solution after " << (std::clock() - GecodeClock) / (double) CLOCKS_PER_SEC << std::endl;
            //            std::cout << "Total time used so far " << (std::clock() - Clock::globalClock) / (double) CLOCKS_PER_SEC << std::endl;
            Gecode::Search::Statistics stat = e.statistics();
            print_stats(stat);
            std::cout << "## fail " << e.statistics().fail << std::endl;
            model->out->addToGecodePrint(std::to_string(e.statistics().fail));
            model->out->addToGecodePrint(std::to_string(time));
            //            model->out->addToGecodePrint("1");

            SetValues(s->AllVars);

        }
        //        std::cout <<  "## fail " << e.statistics().fail << std::endl;
        //        delete s; Skal det være her jeg deleter s?

    } catch (Gecode::Exception e) {
        std::cerr << "Gecode exception: " << e.what() << std::endl;
        //        return 1;
    }
    if (solutionFound) {
        model->out->solTime = (std::clock() - Clock::globalClock) / (double) CLOCKS_PER_SEC;
        delete s;
        if (fix) {
            model->out->feasible = true;
            model->out->feasibleTime = (std::clock() - Clock::globalClock) / (double) CLOCKS_PER_SEC;
//            std::cout << model->out->feasibleTime << std::endl;
//            debug;
//            model->out->feasibleVal = std::to_string(model->getEvaluationInvariantNr(0));

        }
    }
    //    std::cout << "########################################################################################" << std::endl;
    //    std::cout << "solutionFound  "<< solutionFound << std::endl;
    delete ms;
    delete so;
    //    exit(1);
    return solutionFound;
}