Exemplo n.º 1
0
/// Local search method: heuristic to locally improve a solution; usually this is not
/// part of the base version of the algorithms, but it is used to improve the algorithms
/// as hibridize them. Note that during local search we might decide to add some non-dominated
/// solutions to the external non-dominated set.
// Note that it might be useful to specify
/// the number of solutions examined in the local search, otherwise we might end up spending
/// too much time in the local search function. The k neighbour solutions to be examined are
/// randomly chosen. We used the local search as described in Murata's paper.
/// In case a linear scalarizing function is used, the direction of the local search is given
/// by the weights of the function.
/// TODO: set max number of moves that I want to perform durin local search
void TDSESolution::LocalSearch(TPoint & ReferencePoint, TNondominatedSet & NondominatedSet){
    /// I do not want to spend too much time in local search, otherwise I
    /// loose the effectiveness of the rest of the algorithm;
    /// lets say that for each parameter I try to move forward or backward
    /// with respect to the current position; for each intermediate solution found
    /// I also check if it is non-dominated and, in case, I add it to the non-dominated set
    double currentOptimalValue = TSolution::ScalarizingFunction(ReferencePoint);
    boost::uniform_int<> degen_dist(0, 1);
    boost::variate_generator<boost::minstd_rand&, boost::uniform_int<> > deg(Problem.generator, degen_dist);
    std::map<std::string, std::string>::iterator solIter, solEnd;
    for(solIter = this->param2Value.begin(), solEnd = this->param2Value.end(); solIter != solEnd; solIter++){
        // First I save the old solution
        std::map<std::string, std::string> oldSolution = this->param2Value;
        SaveObjectiveValues();
        // I now randomly choose whether to take the value from the first or the second parent
        if(deg() == 0)
            solIter->second = TDSESolution::findPrevious(solIter->first, solIter->second);
        else
            solIter->second = TDSESolution::findSuccessive(solIter->first, solIter->second);
        if(this->param2Value[solIter->first] != this->oldSolution[solIter->first])
            this->updateObjectives();
        double newObjValue = TSolution::ScalarizingFunction(ReferencePoint);
        // Now I check to see if the current solution is a non dominated one
        this->addToNonDominated(NondominatedSet);
        if(newObjValue < currentOptimalValue)
            break;
        else{
            this->param2Value = oldSolution;
            RestoreObjectiveValues();
        }
    }
}
Exemplo n.º 2
0
    //Simple systemc thread which keeps on generating interrupts;
    //the number of the interrupt is printed to the screen before sending it to
    //the processor
    void generateIrq() {
        while(true) {

            //An interrupt transaction is composed of a data pointer (containing
            //0 if the interrupt has to be lowered, different if raised) and an
            //address, corrisponding to the ID of the interrupt
            if(this->lastIrq == -1) {
                unsigned char data = 1;
                tlm::tlm_generic_payload trans;
                boost::uniform_int<> degen_dist(0x1, 0xe);
                boost::variate_generator<boost::minstd_rand&, boost::uniform_int<> > deg(this->generator, degen_dist);
                this->lastIrq = deg();
                std::cerr << "Sending out IRQ id=" << std::hex << std::showbase << this->lastIrq << std::endl;
                trans.set_address(this->lastIrq);
                trans.set_data_ptr(&data);
                trans.set_data_length(0);
                trans.set_byte_enable_ptr(0);
                trans.set_dmi_allowed(false);
                trans.set_response_status( tlm::TLM_INCOMPLETE_RESPONSE );
                sc_time delay;
                this->init_socket->b_transport(trans, delay);

                if(trans.is_response_error()) {
                    std::string errorStr("Error in generateIrq, response status = " + trans.get_response_string());
                    SC_REPORT_ERROR("TLM-2", errorStr.c_str());
                }
            }
            wait(this->latency);
        }
    }
Exemplo n.º 3
0
void TDSESolution::createRandom(TDSESolution &solution){
    std::map<std::string, std::vector<std::string> >::iterator paramsIter, paramsEnd;
    for(paramsIter = Problem.parameters.begin(), paramsEnd = Problem.parameters.end(); paramsIter != paramsEnd; paramsIter++){
        boost::uniform_int<> degen_dist(0, paramsIter->second.size() - 1);
        boost::variate_generator<boost::minstd_rand&, boost::uniform_int<> > deg(Problem.generator, degen_dist);
        solution.param2Value[paramsIter->first] = paramsIter->second[deg()];
    }
}
Exemplo n.º 4
0
Int Primes::GenPrime(Int size, boost::mt19937 *randNumGen)
{
	Int beg = 1;

	boost::uniform_int<> degen_dist(1 << (size-1), 1 << size);
	boost::variate_generator<boost::mt19937&, boost::uniform_int<> > sampler(*randNumGen, degen_dist);

	beg = sampler();
	beg = NextPrime(beg);

	return beg;
}
Exemplo n.º 5
0
/// Mutates the solution; this method is used by the NSGA and SPEA algorithms. The mutation
/// consists in a random change of a random parameter of the solution. Note that mutation is not
/// necessary; we might configure the probability of performing it.
/// TODO: set probability of mutation
void TDSESolution::Mutate(){
    /// I randomly choose one parameter and randomly choose the value for this parameter;
    /// then I change the value
    boost::uniform_int<> params_dist(0, this->param2Value.size() - 1);
    boost::variate_generator<boost::minstd_rand&, boost::uniform_int<> > params_generator(Problem.generator, params_dist);
    std::map<std::string, std::string>::iterator solIter = this->param2Value.begin();
    unsigned int randomParam = params_generator();
    for(unsigned int i = 0; i < randomParam; solIter++, i++);
    // I now randomly choose whether to take the value from the first or the second parent
    boost::uniform_int<> degen_dist(0, Problem.parameters[solIter->first].size() - 1);
    boost::variate_generator<boost::minstd_rand&, boost::uniform_int<> > deg(Problem.generator, degen_dist);
    solIter->second = Problem.parameters[solIter->first][deg()];
    this->updateObjectives();
}
Exemplo n.º 6
0
/// Given two parents it composed them into solution
void TDSESolution::crossSolution(TDSESolution & solution, TDSESolution & Parent1, TDSESolution & Parent2){
    // I simply take a random element among the two solutions and create the new solution
    // which is a combination of the two
    boost::uniform_int<> degen_dist(0, 1);
    boost::variate_generator<boost::minstd_rand&, boost::uniform_int<> > deg(Problem.generator, degen_dist);
    std::map<std::string, std::string>::iterator solIter, solEnd;
    for(solIter = Parent1.param2Value.begin(), solEnd = Parent1.param2Value.end(); solIter != solEnd; solIter++){
        //I now randomly choose whether to take the value from the first or the second parent
        if(deg() == 0)
            solution.param2Value[solIter->first] = solIter->second;
        else
            solution.param2Value[solIter->first] = Parent2.param2Value[solIter->first];
    }
}
Exemplo n.º 7
0
/// We perform a single random local move; method used by PSA, SMOSA, MOSA.
/// This method actually performs the move; in case the move has to be undone,
/// the RejectLocalMove method is called.
void TDSESolution::FindLocalMove(){
    /// I simply choose randomly one parameter and the direction (whether to
    /// increment or decrement the value)
    boost::uniform_int<> params_dist(0, this->param2Value.size() - 1);
    boost::variate_generator<boost::minstd_rand&, boost::uniform_int<> > params_generator(Problem.generator, params_dist);
    std::map<std::string, std::string>::iterator solIter = this->param2Value.begin();
    unsigned int randomParam = params_generator();
    for(unsigned int i = 0; i < randomParam; solIter++, i++);
    // First I save the old solution
    this->oldSolution = this->param2Value;
    SaveObjectiveValues();
    // I now randomly choose whether to take the value from the first or the second parent
    boost::uniform_int<> degen_dist(0, 1);
    boost::variate_generator<boost::minstd_rand&, boost::uniform_int<> > deg(Problem.generator, degen_dist);
    if(deg() == 0)
        solIter->second = TDSESolution::findPrevious(solIter->first, solIter->second);
    else
        solIter->second = TDSESolution::findSuccessive(solIter->first, solIter->second);
    if(this->param2Value[solIter->first] != this->oldSolution[solIter->first])
        this->updateObjectives();
}
Exemplo n.º 8
0
int main()
{
  // Define a random number generator and initialize it with a reproducible
  // seed.
  base_generator_type generator(42);

  std::cout << "10 samples of a uniform distribution in [0..1):\n";

  // Define a uniform random number distribution which produces "double"
  // values between 0 and 1 (0 inclusive, 1 exclusive).
  boost::uniform_real<> uni_dist(0,1);
  boost::variate_generator<base_generator_type&, boost::uniform_real<> > uni(generator, uni_dist);

  std::cout.setf(std::ios::fixed);
  // You can now retrieve random numbers from that distribution by means
  // of a STL Generator interface, i.e. calling the generator as a zero-
  // argument function.
  for(int i = 0; i < 10; i++)
    std::cout << uni() << '\n';

  /*
   * Change seed to something else.
   *
   * Caveat: std::time(0) is not a very good truly-random seed.  When
   * called in rapid succession, it could return the same values, and
   * thus the same random number sequences could ensue.  If not the same
   * values are returned, the values differ only slightly in the
   * lowest bits.  A linear congruential generator with a small factor
   * wrapped in a uniform_smallint (see experiment) will produce the same
   * values for the first few iterations.   This is because uniform_smallint
   * takes only the highest bits of the generator, and the generator itself
   * needs a few iterations to spread the initial entropy from the lowest bits
   * to the whole state.
   */
  generator.seed(static_cast<unsigned int>(std::time(0)));

  std::cout << "\nexperiment: roll a die 10 times:\n";

  // You can save a generator's state by copy construction.
  base_generator_type saved_generator = generator;

  // When calling other functions which take a generator or distribution
  // as a parameter, make sure to always call by reference (or pointer).
  // Calling by value invokes the copy constructor, which means that the
  // sequence of random numbers at the caller is disconnected from the
  // sequence at the callee.
  experiment(generator);

  std::cout << "redo the experiment to verify it:\n";
  experiment(saved_generator);

  // After that, both generators are equivalent
  assert(generator == saved_generator);

  // as a degenerate case, you can set min = max for uniform_int
  boost::uniform_int<> degen_dist(4,4);
  boost::variate_generator<base_generator_type&, boost::uniform_int<> > deg(generator, degen_dist);
  std::cout << deg() << " " << deg() << " " << deg() << std::endl;
  
  {
    // You can save the generator state for future use.  You can read the
    // state back in at any later time using operator>>.
    std::ofstream file("rng.saved", std::ofstream::trunc);
    file << generator;
  }

  return 0;
}