예제 #1
0
  void
  ScriptBase<Space>::runMeta(const Options& o, Script* s) {
    using namespace std;

    ofstream sol_file, log_file;

    ostream& s_out = select_ostream(o.out_file(), sol_file);
    ostream& l_out = select_ostream(o.log_file(), log_file);

    try {
      switch (o.mode()) {
      case SM_GIST:
#ifdef GECODE_HAS_GIST
        {
          Gist::Print<Script> pi(o.name());
          Gist::VarComparator<Script> vc(o.name());
          Gist::Options opt;
          opt.inspect.click(&pi);
          opt.inspect.compare(&vc);
          opt.clone = false;
          opt.c_d   = o.c_d();
          opt.a_d   = o.a_d();
          for (int i=0; o.inspect.click(i) != NULL; i++)
            opt.inspect.click(o.inspect.click(i));
          for (int i=0; o.inspect.solution(i) != NULL; i++)
            opt.inspect.solution(o.inspect.solution(i));
          for (int i=0; o.inspect.move(i) != NULL; i++)
            opt.inspect.move(o.inspect.move(i));
          for (int i=0; o.inspect.compare(i) != NULL; i++)
            opt.inspect.compare(o.inspect.compare(i));
          if (s == NULL)
            s = new Script(o);
          (void) GistEngine<Engine<Script> >::explore(s, opt);
        }
        break;
        // If Gist is not available, fall through
#endif
      case SM_SOLUTION:
        {
          l_out << o.name() << endl;
          Support::Timer t;
          int i = o.solutions();
          t.start();
          if (s == NULL)
            s = new Script(o);
          unsigned int n_p = s->propagators();
          unsigned int n_b = s->branchers();
          Search::Options so;
          so.threads = o.threads();
          so.c_d     = o.c_d();
          so.a_d     = o.a_d();
          so.stop    = CombinedStop::create(o.node(),o.fail(), o.time(), 
                                            o.interrupt());
          so.cutoff  = createCutoff(o);
          so.clone   = false;
          so.nogoods_limit = o.nogoods() ? o.nogoods_limit() : 0U;
          if (o.interrupt())
            CombinedStop::installCtrlHandler(true);
          {
            Meta<Engine,Script> e(s,so);
            if (o.print_last()) {
              Script* px = NULL;
              do {
                Script* ex = e.next();
                if (ex == NULL) {
                  if (px != NULL) {
                    px->print(s_out);
                    delete px;
                  }
                  break;
                } else {
                  delete px;
                  px = ex;
                }
              } while (--i != 0);
            } else {
              do {
                Script* ex = e.next();
                if (ex == NULL)
                  break;
                ex->print(s_out);
                delete ex;
              } while (--i != 0);
            }
            if (o.interrupt())
              CombinedStop::installCtrlHandler(false);
            Search::Statistics stat = e.statistics();
            s_out << endl;
            if (e.stopped()) {
              l_out << "Search engine stopped..." << endl
                    << "\treason: ";
              int r = static_cast<CombinedStop*>(so.stop)->reason(stat,so);
              if (r & CombinedStop::SR_INT)
                l_out << "user interrupt " << endl;
              else {
                if (r & CombinedStop::SR_NODE)
                  l_out << "node ";
                if (r & CombinedStop::SR_FAIL)
                  l_out << "fail ";
                if (r & CombinedStop::SR_TIME)
                  l_out << "time ";
                l_out << "limit reached" << endl << endl;
              }
            }
            l_out << "Initial" << endl
                  << "\tpropagators: " << n_p << endl
                  << "\tbranchers:   " << n_b << endl
                  << endl
                  << "Summary" << endl
                  << "\truntime:      ";
            stop(t, l_out);
            l_out << endl
                  << "\tsolutions:    "
                  << ::abs(static_cast<int>(o.solutions()) - i) << endl
                  << "\tpropagations: " << stat.propagate << endl
                  << "\tnodes:        " << stat.node << endl
                  << "\tfailures:     " << stat.fail << endl
                  << "\trestarts:     " << stat.restart << endl
                  << "\tno-goods:     " << stat.nogood << endl
                  << "\tpeak depth:   " << stat.depth << endl
#ifdef GECODE_PEAKHEAP
                  << "\tpeak memory:  "
                  << static_cast<int>((heap.peak()+1023) / 1024) << " KB"
                  << endl
#endif
                  << endl;
          }
          delete so.stop;
        }
        break;
      case SM_STAT:
        {
          l_out << o.name() << endl;
          Support::Timer t;
          int i = o.solutions();
          t.start();
          if (s == NULL)
            s = new Script(o);
          unsigned int n_p = s->propagators();
          unsigned int n_b = s->branchers();
          Search::Options so;
          so.clone   = false;
          so.threads = o.threads();
          so.c_d     = o.c_d();
          so.a_d     = o.a_d();
          so.stop    = CombinedStop::create(o.node(),o.fail(), o.time(),
                                            o.interrupt());
          so.cutoff  = createCutoff(o);
          so.nogoods_limit = o.nogoods() ? o.nogoods_limit() : 0U;
          if (o.interrupt())
            CombinedStop::installCtrlHandler(true);
          {
            Meta<Engine,Script> e(s,so);
            do {
              Script* ex = e.next();
              if (ex == NULL)
                break;
              delete ex;
            } while (--i != 0);
            if (o.interrupt())
              CombinedStop::installCtrlHandler(false);
            Search::Statistics stat = e.statistics();
            l_out << endl
                  << "\tpropagators:  " << n_p << endl
                  << "\tbranchers:    " << n_b << endl
                  << "\truntime:      ";
            stop(t, l_out);
            l_out << endl
                  << "\tsolutions:    "
                  << ::abs(static_cast<int>(o.solutions()) - i) << endl
                  << "\tpropagations: " << stat.propagate << endl
                  << "\tnodes:        " << stat.node << endl
                  << "\tfailures:     " << stat.fail << endl
                  << "\trestarts:     " << stat.restart << endl
                  << "\tno-goods:     " << stat.nogood << endl
                  << "\tpeak depth:   " << stat.depth << endl
#ifdef GECODE_PEAKHEAP
                  << "\tpeak memory:  "
                  << static_cast<int>((heap.peak()+1023) / 1024) << " KB"
                  << endl
#endif
                  << endl;
          }
          delete so.stop;
        }
        break;
      case SM_TIME:
        {
          l_out << o.name() << endl;
          Support::Timer t;
          double* ts = new double[o.samples()];
          bool stopped = false;
          for (unsigned int s = o.samples(); !stopped && s--; ) {
            t.start();
            for (unsigned int k = o.iterations(); !stopped && k--; ) {
              unsigned int i = o.solutions();
              Script* s = new Script(o);
              Search::Options so;
              so.clone   = false;
              so.threads = o.threads();
              so.c_d     = o.c_d();
              so.a_d     = o.a_d();
              so.stop    = CombinedStop::create(o.node(),o.fail(), o.time(), 
                                                false);
              so.cutoff  = createCutoff(o);
              so.nogoods_limit = o.nogoods() ? o.nogoods_limit() : 0U;
              {
                Meta<Engine,Script> e(s,so);
                do {
                  Script* ex = e.next();
                  if (ex == NULL)
                    break;
                  delete ex;
                } while (--i != 0);
                if (e.stopped())
                  stopped = true;
              }
              delete so.stop;
            }
            ts[s] = t.stop() / o.iterations();
          }
          if (stopped) {
            l_out << "\tSTOPPED" << endl;
          } else {
            double m = am(ts,o.samples());
            double d = dev(ts,o.samples()) * 100.0;
            l_out << "\truntime: "
                 << setw(20) << right
                 << showpoint << fixed
                 << setprecision(6) << m << "ms"
                 << setprecision(2) << " (" << d << "% deviation)"
                 << endl;
          }
          delete [] ts;
        }
        break;
      }
    } catch (Exception& e) {
      cerr << "Exception: " << e.what() << "." << endl
           << "Stopping..." << endl;
      if (sol_file.is_open())
        sol_file.close();
      if (log_file.is_open())
        log_file.close();
      exit(EXIT_FAILURE);
    }
    if (sol_file.is_open())
      sol_file.close();
    if (log_file.is_open())
      log_file.close();
  }