easylocaltemplates.cpp

来自「一个tabu search算法框架」· C++ 代码 · 共 2,039 行 · 第 1/5 页

CPP
2,039
字号
  { 
    p_in = in;
    internal_state.SetInput(in); 
  }

  /** 
      Returns the cost of the internal state.
      
      @return the cost of the internal state
  */
  template <class Input, class Output, class State>
  fvalue LocalSearchSolver<Input,Output,State>::InternalStateCost() 
  { return internal_state_cost; }

  /**
     Constructs a local search solver by providing it a state manager,
     an output manager, an input object, and an output object.

     @param sm a pointer to a compatible state manager
     @param om a pointer to a compatible output manager
     @param in a pointer to an input object
     @param out a pointer to an output object
  */
  template <class Input, class Output, class State>
  LocalSearchSolver<Input,Output,State>::LocalSearchSolver(StateManager<Input,State>* sm, OutputManager<Input,Output,State>* om, Input* in, Output* out) 
    : Solver<Input, Output>(in,out), p_sm(sm),  p_om(om), 
    number_of_init_trials(1)
  {
    if (in != NULL)
      internal_state.SetInput(in); 
  }

  /**
     The output is delivered by converting the final internal state
     to an output object by means of the output manager.
  */
  template <class Input, class Output, class State>
  void LocalSearchSolver<Input,Output,State>::DeliverOutput() 
  { p_om->OutputState(internal_state,*p_out); }

  /**
     The initial state is generated by delegating this task to 
     the state manager. The function invokes the SampleState function.
  */
  template <class Input, class Output, class State>
  void LocalSearchSolver<Input,Output,State>::FindInitialState() 
  { internal_state_cost = p_sm->SampleState(internal_state,number_of_init_trials); }

  /**
     The cost of the internal state is computed by the state manager.
  */
  template <class Input, class Output, class State>
  void LocalSearchSolver<Input,Output,State>::ComputeCost() 
  { internal_state_cost = p_sm->CostFunction(internal_state); }


  /**
     Checks wether the object state is consistent with all the related
     objects.
  */
  template <class Input, class Output, class State>
  void LocalSearchSolver<Input,Output,State>::Check()
  {
    assert(p_in != NULL);
    assert(p_in == p_sm->GetInput());
    assert(p_in == p_om->GetInput());
  }

  /**
     Sets the runner employed for solving the problem to the one passed as
     parameter.

     @param r the new runner to be used
  */
  template <class Input, class Output, class State>
  void SimpleLocalSearch<Input,Output,State>::SetRunner(Runner<Input,State> *r) 
  { p_runner = r; }


  /**
     Constructs a simple local search solver by providing it links to
     a state manager, an output manager, a runner, an input,
     and an output object.

     @param sm a pointer to a compatible state manager
     @param om a pointer to a compatible output manager
     @param r a pointer to a compatible runner
     @param in a pointer to an input object
     @param out a pointer to an output object
  */
  template <class Input, class Output, class State>
  SimpleLocalSearch<Input,Output,State>::SimpleLocalSearch(StateManager<Input,State>* sm, OutputManager<Input,Output,State>* om, Runner<Input,State>* r, Input* in, Output* out)
    : LocalSearchSolver<Input,Output,State>(sm,om,in,out) 
  { p_runner = r; }


  /**
     Constructs a simple local search solver by providing it links to
     a state manager, an output manager, an input, and an output object.

     @param sm a pointer to a compatible state manager
     @param om a pointer to a compatible output manager
     @param in a pointer to an input object
     @param out a pointer to an output object
  */
  template <class Input, class Output, class State>
  SimpleLocalSearch<Input,Output,State>::SimpleLocalSearch(StateManager<Input,State>* sm, OutputManager<Input,Output,State>* om, Input* in, Output* out)
    : LocalSearchSolver<Input,Output,State>(sm,om,in,out) 
  { p_runner = NULL; }


  /** 
      Returns the number of iterations performed by the attached runner.
      
      @return the number of iterations elapsed.
  */
  template <class Input, class Output, class State>
  unsigned long SimpleLocalSearch<Input,Output,State>::NumberOfIterations() const 
  { return p_runner->NumberOfIterations(); }

  /**
     Lets the runner Go, and then collects the best state found.
  */
  template <class Input, class Output, class State>
  void SimpleLocalSearch<Input,Output,State>::Run()
  {
    p_runner->SetCurrentState(internal_state);
    p_runner->Go();
    internal_state = p_runner->GetBestState();
    internal_state_cost = p_runner->BestStateCost();
  }

  /**
     Performs a full solving procedure by finding an initial state, 
     running the attached runner and delivering the output.
  */
  template <class Input, class Output, class State>
  void LocalSearchSolver<Input,Output,State>::Solve()
  {
    FindInitialState();
    Run();
    DeliverOutput();
  }
  
  /**
     Start again a solving procedure, running the attached runner from
     the current internal state.
  */
  template <class Input, class Output, class State>
  void LocalSearchSolver<Input,Output,State>::ReSolve()
  {
    Run();
    DeliverOutput();
  }

  /**
     Tries multiple runs on different initial states and records the
     best one.
     
     @param n the number of trials
   */
  template <class Input, class Output, class State>
  void LocalSearchSolver<Input,Output,State>::MultiStartSolve(unsigned int n)
  { 
    State best_state;
    fvalue best_state_cost = 0; // we assign it a value only to prevent
                                // warnings from "smart" compilers
    for (unsigned int i = 0; i < n; i++)
      { 
	FindInitialState();
	Run();
	if (i == 0 || internal_state_cost < best_state_cost)
	  { 
	    best_state = internal_state;
	    best_state_cost = internal_state_cost;
	  }
      }
    internal_state = best_state;
    internal_state_cost = best_state_cost;
    DeliverOutput();
  }

  /**
     In the case of multi-runner solvers, the number of iterations is the
     overall number of iterations performed by any runner.
  */
  template <class Input, class Output, class State>
  unsigned long MultiRunnerSolver<Input,Output,State>::NumberOfIterations() const 
  { return total_iterations; }


  /**
     Constructs a multi runner solver by providing it links to
     a state manager, an output manager, an input, and an output object.

     @param sm a pointer to a compatible state manager
     @param om a pointer to a compatible output manager
     @param in a pointer to an input object
     @param out a pointer to an output object
  */
  template <class Input, class Output, class State>
  MultiRunnerSolver<Input,Output,State>::MultiRunnerSolver(StateManager<Input,State>* sm, OutputManager<Input,Output,State>* om, Input* in, Output* out)
    : LocalSearchSolver<Input,Output,State>(sm,om,in,out), 
    total_iterations(0)
  { runners.clear(); }

  /**
     Sets the i-th runner managed by the solver to the passed parameter.

     @param r a pointer to a compatible runner
     @param i the runner position to set with r
  */
  template <class Input, class Output, class State>
  void MultiRunnerSolver<Input,Output,State>::SetRunner(Runner<Input,State> *r, unsigned int i) 
  { 
    assert(i < runners.size());
    runners[i] = r; 
  }

  /**
     Adds the given runner to the list of the managed runners.

     @param r a pointer to a compatible runner to add
   */
  template <class Input, class Output, class State>
  void MultiRunnerSolver<Input,Output,State>::AddRunner(Runner<Input,State> *r)
  { runners.push_back(r); }

  /**
     Clears the vector of runners managed by the solver.
  */
  template <class Input, class Output, class State>
  void MultiRunnerSolver<Input,Output,State>::ClearRunners()
  { runners.clear(); }

  /**
     Lets all the managed runners Go, and then it collects the best state
     found.
   */
  template <class Input, class Output, class State>
  void ComparativeSolver<Input,Output,State>::Run()
  { 
    int i;
    start_state = internal_state;
    runners[0]->SetCurrentState(start_state);
    runners[0]->Go();
    runners[0]->ComputeCost();
    internal_state = runners[0]->GetBestState();
    internal_state_cost = runners[0]->BestStateCost();
	
    for (i = 1; i < runners.size(); i++)
      {
	runners[i]->SetCurrentState(start_state);
	runners[i]->Go();
	runners[i]->ComputeCost();
	total_iterations += runners[i]->NumberOfIterations();
	if (runners[i]->BestStateCost() < internal_state_cost)
	  {
	    internal_state = runners[i]->GetBestState();
	    internal_state_cost = runners[i]->BestStateCost();
	  }
      }
  }

  /**
     Sets the number of rounds to the given value.
     
     @param r the number of rounds.
  */
  template <class Input, class Output, class State>
  void TokenRingSolver<Input,Output,State>::SetRounds(unsigned int r) 
  { max_idle_rounds = r; }

  /**
     Starts the token-ring from the i-th runner.
     
     @param i the runner which to start form
  */
  template <class Input, class Output, class State>
  void TokenRingSolver<Input,Output,State>::SetStartRunner(unsigned int i)
  { start_runner = i; }


  /**
     Constructs a token-ring runner solver by providing it links to
     a state manager, an output manager, an input, and an output object.

     @param sm a pointer to a compatible state manager
     @param om a pointer to a compatible output manager
     @param in a pointer to an input object
     @param out a pointer to an output object
  */
  template <class Input, class Output, class State>
  TokenRingSolver<Input,Output,State>::TokenRingSolver(StateManager<Input,State>* sm, OutputManager<Input,Output,State>* om, Input* in, Output* out) 
    : MultiRunnerSolver<Input,Output,State>(sm,om,in,out), 
    max_idle_rounds(1) 
  {}

  /**
     Checks wether the object state is consistent with all the related
     objects.
  */
  template <class Input, class Output, class State>
  void TokenRingSolver<Input,Output,State>::Check()
  {
    LocalSearchSolver<Input,Output,State>::Check();
    for (unsigned int i = 0; i < runners.size(); i++)
      {
	runners[i]->Check();
	assert(runners[i]->GetInput() == p_in);
      }
  }

  /**
     Outputs the solver state on a given output stream.

     @param os the output stream
  */
  template <class Input, class Output, class State>
  void TokenRingSolver<Input,Output,State>::Print(std::ostream& os) const
  {
    os << "Solver State" << std::endl;
    for (unsigned int i = 0; i < runners.size(); i++)
      {
	os << "Runner " << i << std::endl;
	runners[i]->Print(os);
      }
  }

  /**
     Runs all the managed runners one after another till no improvement
     has produced in a given number of rounds
  */
  template <class Input, class Output, class State>
  void TokenRingSolver<Input,Output,State>::Run()
  {
    assert(start_runner < runners.size());
  	
    // i is the current runner, j is the previous one;
    unsigned int i = start_runner, j = (start_runner >= 1) ?
      (start_runner - 1) : runners.size() - 1;
    int idle_rounds = 0;
    bool interrupt_search = false;
    bool improvement_found = false;
	
    ComputeCost(); // Set internal_state_cost
    // internal_state_cost is used to check
    // whether a full round has produces improvements or not
    runners[i]->SetCurrentState(internal_state);
	
    while (idle_rounds < max_idle_rounds && !interrupt_search)
      { 
        do
	  {
	    runners[i]->Go();
	    if (runners[i]->BestStateCost() < internal_state_cost) 
	      { 
	        internal_state = runners[i]->GetBestState(); 
	        internal_state_cost = runners[i]->BestStateCost(); 
	        improvement_found = true;
	      } 
	    total_iterations += runners[i]->NumberOfIterations();
	    if (runners[i]->LowerBoundReached() || runners.size() == 1)
	      {
	        interrupt_search = true;
	        break;
	      }
	    j = i;
	    i = (i + 1) % runners.size();
	    runners[i]->SetCurrentState(runners[j]->GetBestState());
  	  }
        while (i != start_runner);
		
        if (!interrupt_search)
	  {
	    if (improvement_found)
	      idle_rounds = 0;
	    else
  	      idle_rounds++;
  	    improvement_found = false;
  	  }
      }
  }

  // Abstract Move Tester

  /**
     Constructs an abstract move tester and assign it a name passed 
     as parameter.
     @param s the name of the tester
  */
  template <class Input, class Output, class State>
  AbstractMoveTester<Input,Output,State>::AbstractMoveTester(std::string s) 
  { name = s; }

  /**
     Gets the name of the tester.
     @returns the name of the tester
  */
  template <class Input, class Output, class State>
  std::string AbstractMoveTester<Input,Output,State>::Name() 
  { return name; }

  // Move Tester

  /**
     Constructs a move t

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?