예제 #1
0
population random_breeder::breed(const population &generation, const std::vector<double> &fitnesses) const
{
  using namespace std;  
  
  population ret;
  tree_crossover_reproducer repr;
  node_crossover_reproducer mrepr;
  builder random_builder;
  experimental_parameters e = exp_params();
  const uint32_t growth_tree_min = e["growth_tree_min"];
  const uint32_t growth_tree_max = e["growth_tree_max"];
  while(ret.size() < generation.size())
  {
    const agent &mother = generation[rand() % generation.size()];
    const agent &father = generation[rand() % generation.size()];
    agent mutant      = random_builder.grow(program_types_set, growth_tree_min, growth_tree_max);
    const vector<agent> children = repr.reproduce(vector<agent> { mother, father });
    if(children.size() > 0)
    {
      agent res0        = mrepr.reproduce(vector<agent> { children[0], mutant })[0];
      ret.push_back(res0);
    }
    if(children.size() > 1)
    {
      agent res1        = mrepr.reproduce(vector<agent> { children[1], mutant })[0];
      ret.push_back(res1);
    }
  }
  return ret;
}
예제 #2
0
family_vector rnd_selector::select(const population&p,const int fcount)
{
  family_vector result(fcount);
  for(int i=0;i<fcount;i++)
    result[i]=std::make_pair(m_random.uniform(0,p.size()-1),
			     m_random.uniform(0,p.size()-1));
  return result;
}
예제 #3
0
파일: problem.cpp 프로젝트: pthomalla/evo
void adapt_population(population& p)
{
  float F_min = min_element(p.begin(),p.end(),eval_comp)->eval;
  for(unsigned int i=0; i<p.size(); i++)
  {
    float sum = 0.0;
    for(unsigned int j=0; j<p.size(); j++)
      sum += p[j].eval - F_min;
    p[i].adapt = (p[i].eval - F_min)/sum;
  }
}
예제 #4
0
파일: problem.cpp 프로젝트: pthomalla/evo
void report(population& p)
{
  switch(cfg.report_every)
  {
    case config::report::none:
      break;
    case config::report::avg:
      {
        float avg = 0.0;
        for(auto i = p.begin(); i != p.end(); ++i)
          avg += i->eval;
        avg /= static_cast<float>(p.size());
        std::cout << iter << ' ' << avg << '\n';
      }
      break;
    case config::report::best:
      std::cout << iter << ' ' << p[0].eval << '\n';
      break;
  }
  
  if(cfg.report_var)
  {
    std::cout << iter << ' ' << statistics::variance(p) << '\n';
  }
}
예제 #5
0
std::vector<std::pair<population::size_type,std::vector<population::individual_type>::size_type> >
	random_r_policy::select(const std::vector<population::individual_type> &immigrants, const population &dest) const
{
	const population::size_type rate_limit = std::min<population::size_type>(get_n_individuals(dest),boost::numeric_cast<population::size_type>(immigrants.size()));
	// Temporary vectors to store sorted indices of the populations.
	std::vector<population::size_type> immigrants_idx(boost::numeric_cast<std::vector<population::size_type>::size_type>(immigrants.size()));
	std::vector<population::size_type> dest_idx(boost::numeric_cast<std::vector<population::size_type>::size_type>(dest.size()));
	// Fill in the arrays of indices.
	iota(immigrants_idx.begin(),immigrants_idx.end(),population::size_type(0));
	iota(dest_idx.begin(),dest_idx.end(),population::size_type(0));
	// Permute the indices (immigrants).
	for (population::size_type i = 0; i < rate_limit; ++i) {
		population::size_type next_idx = i + (m_urng() % (rate_limit - i));
		if (next_idx != i) {
			std::swap(immigrants_idx[i], immigrants_idx[next_idx]);
		}
	}
	// Permute the indices (destination).
	for (population::size_type i = 0; i < rate_limit; ++i) {
		population::size_type next_idx = i + (m_urng() % (dest.size() - i));
		if (next_idx != i) {
			std::swap(dest_idx[i], dest_idx[next_idx]);
		}
	}
	// Return value.
	std::vector<std::pair<population::size_type,std::vector<population::individual_type>::size_type> >
		retval;
	for (population::size_type i = 0; i < rate_limit; ++i) {
		retval.push_back(std::make_pair(dest_idx[i],immigrants_idx[i]));
	}
	return retval;
}
예제 #6
0
파일: base.cpp 프로젝트: DominicDirkx/pagmo
/**
 * @param[in] pop input population.
 *
 * @return the number of individuals to be migrated from/to the population according to the current migration rate and type.
 */
population::size_type base::get_n_individuals(const population &pop) const
{
	population::size_type retval = 0;
	switch (m_type) {
		case absolute:
			retval = boost::numeric_cast<population::size_type>(m_rate);
			if (retval > pop.size()) {
				pagmo_throw(value_error,"absolute migration rate is higher than population size");
			}
			break;
		case fractional:
			retval = boost::numeric_cast<population::size_type>(double_to_int::convert(m_rate * pop.size()));
			pagmo_assert(retval <= pop.size());
	}
	return retval;
}
예제 #7
0
파일: ms.cpp 프로젝트: DominicDirkx/pagmo
void ms::evolve(population &pop) const
{
	// Let's store some useful variables.
	const population::size_type NP = pop.size();

	// Get out if there is nothing to do.
	if (m_starts == 0 || NP == 0) {
		return;
	}

	// Local population used in the algorithm iterations.
	population working_pop(pop);

	//ms main loop
	for (int i=0; i< m_starts; ++i)
	{
		working_pop.reinit();
		m_algorithm->evolve(working_pop);
		if (working_pop.problem().compare_fc(working_pop.get_individual(working_pop.get_best_idx()).cur_f,working_pop.get_individual(working_pop.get_best_idx()).cur_c,
			pop.get_individual(pop.get_worst_idx()).cur_f,pop.get_individual(pop.get_worst_idx()).cur_c
		) )
		{
			//update best population replacing its worst individual with the good one just produced.
			pop.set_x(pop.get_worst_idx(),working_pop.get_individual(working_pop.get_best_idx()).cur_x);
			pop.set_v(pop.get_worst_idx(),working_pop.get_individual(working_pop.get_best_idx()).cur_v);
		}
		if (m_screen_output)
		{
			std::cout << i << ". " << "\tCurrent iteration best: " << working_pop.get_individual(working_pop.get_best_idx()).cur_f << "\tOverall champion: " << pop.champion().f << std::endl;
		}
	}
}
예제 #8
0
/// Evolve method.
void monte_carlo::evolve(population &pop) const
{
	// Let's store some useful variables.
	const problem::base &prob = pop.problem();
	const problem::base::size_type prob_dimension = prob.get_dimension(), prob_i_dimension = prob.get_i_dimension();
	const decision_vector &lb = prob.get_lb(), &ub = prob.get_ub();
	const population::size_type pop_size = pop.size();
	// Get out if there is nothing to do.
	if (pop_size == 0 || m_max_eval == 0) {
		return;
	}
	// Initialise temporary decision vector, fitness vector and decision vector.
	decision_vector tmp_x(prob_dimension);
	fitness_vector tmp_f(prob.get_f_dimension());
	constraint_vector tmp_c(prob.get_c_dimension());
	// Main loop.
	for (std::size_t i = 0; i < m_max_eval; ++i) {
		// Generate a random decision vector.
		for (problem::base::size_type j = 0; j < prob_dimension - prob_i_dimension; ++j) {
			tmp_x[j] = boost::uniform_real<double>(lb[j],ub[j])(m_drng);
		}
		for (problem::base::size_type j = prob_dimension - prob_i_dimension; j < prob_dimension; ++j) {
			tmp_x[j] = boost::uniform_int<int>(lb[j],ub[j])(m_urng);
		}
		// Compute fitness and constraints.
		prob.objfun(tmp_f,tmp_x);
		prob.compute_constraints(tmp_c,tmp_x);
		// Locate the worst individual.
		const population::size_type worst_idx = pop.get_worst_idx();
		if (prob.compare_fc(tmp_f,tmp_c,pop.get_individual(worst_idx).cur_f,pop.get_individual(worst_idx).cur_c)) {
			pop.set_x(worst_idx,tmp_x);
		}
	}
}
예제 #9
0
void reallocate_stra(population &pop,int stra_idx,int size,double val)
{
	int pop_size=pop.size();
	int i;
	for ( i=0;i<pop_size;i++ )
		pop[i].stra[stra_idx].assign(size,val);
}
예제 #10
0
void allocate_pop(population &pop,size_t NumDims,int stra_num,int num_obj)
{
	size_t pop_size=pop.size();
	size_t i;
	for ( i=0;i<pop_size;i++ )
		allocate_ind(pop[i],NumDims,stra_num,num_obj);
}
예제 #11
0
void reallocate_stra(population &pop,population &trial_pop,int stra_idx,int size,double val)
{
	int pop_size=pop.size();
	int tri_pop_size=trial_pop.size();
	if ( pop_size!=tri_pop_size )
	{
		stringstream ss_err;
		ss_err<<"\n"
			<<"Error in reallocate_stra:"
			<<"pop and trial_pop's size mismatch."
			<<"\n";
		throw logic_error(ss_err.str());
	}
	int i;
	for ( i=0;i<pop_size;i++ )
	{
		pop[i].stra[stra_idx].assign(size,val);
		trial_pop[i].stra[stra_idx].assign(size,val);
	}
}
예제 #12
0
파일: niche_ga.cpp 프로젝트: lysevi/concret
family_vector niche_ga::select(const population&p,int count)
{
  dna_cmeans::u_vector data=fill_data_vector(p);

  int cluster_count=static_cast<int>(p.size()*0.10);
  dna_cmeans::result r;
  if(call_nums>=10){
    call_nums=0;
    cm.m_center_sequence.erase(cm.m_center_sequence.begin(),cm.m_center_sequence.end());
  }
    
  if(cm.m_center_sequence.size()==0){
    r=cm.cluster(dna_distance,cluster_count,data.begin(),data.end(),data.size(),1.0);
  }
  else{
    r=cm.cluster(dna_distance,data.begin(),data.end(),data.size());
  }
  call_nums++;
  clusters cls=dna_cmeans::u2clsuters(r.u);

  Random rnd;
  family_vector result(count);
  int c=0; // сколько мы уже отобрали для скрещивания

  while(c!=count){
    int father_cluster=rnd.uniform(0,cls.size()-1);
    if(cls[father_cluster].size()<2)
      continue;

    int father_index=rnd.uniform(0,cls[father_cluster].size()-1);

    int mather_cluster=father_cluster;

    int mather_index=rnd.uniform(0,cls[mather_cluster].size()-1);

   
    result[c]=std::make_pair(cls[father_cluster][father_index].first,
			     cls[mather_cluster][mather_index].first);
    c++;
  }

  return result;
}
예제 #13
0
std::vector<population::individual_type> best_kill_s_policy::select(population &pop) const
{
	pagmo_assert(get_n_individuals(pop) <= pop.size());
	// Gets the number of individuals to select
	const population::size_type migration_rate = get_n_individuals(pop);
	// Create a temporary array of individuals.
	std::vector<population::individual_type> result;
	// Gets the indexes of the best individuals
	std::vector<population::size_type> best_idx = pop.get_best_idx(migration_rate);
	// Puts the best individuals in results
	for (population::size_type i =0; i< migration_rate; ++i) {
		result.push_back(pop.get_individual(best_idx[i]));
	}
	// Remove them from the original population 
	// (note: the champion will still carry information on the best guy ...)
	for (population::size_type i=0 ; i<migration_rate; ++i) {
		pop.reinit(best_idx[i]);
	}
	return result;
}
예제 #14
0
		// perform (\lambda+\mu) -> (\lambda) selection
		void dgea_alg::select(population& pop, population& child_pop)
		{
			int pop_size=pop.size();
			int num_dims=m_ppara->get_dim();
			int i;
			population pop_merged(pop_size);
			vector<vector<double> > prev_x(pop_size);
			for ( i=0;i<pop_size;i++ )
			{
				prev_x[i].resize(num_dims);
				pop_merged[i]=pop[i];
				// record previous x
				prev_x[i]=pop[i].x;
			}// for every individual

			// push child population at the tail of merged population
			copy( child_pop.begin(),child_pop.end(),back_inserter(pop_merged) );

			nth_element(pop_merged.begin(), pop_merged.begin()+pop_size, pop_merged.end());
			//// heap sorting
			//make_heap(pop_merged.begin(),pop_merged.end());
			//for ( i=0;i<pop_size;i++ )
			//{
			//	// record delta x for stat purpose
			//	pop_heap(pop_merged.begin(),pop_merged.end());
			//	pop_merged.pop_back();
			//	const individual& new_ind=pop_merged.front();
			//	pop[i]=new_ind;
			//	m_alg_stat.delta_x[i]=pop[i].x-prev_x[i];// pop_merged:{parents,offsprings}
			//}

			for ( i=0;i<pop_size;i++ )
			{
				pop[i]=pop_merged[i];
				// record delta x
				m_alg_stat.delta_x[i] = (pop[i].x-prev_x[i]);
			}// for every individual
		}// end function select
예제 #15
0
/**
 * Updates the constraints scaling vector with the given population.
 * @param[in] population pop.
 */
void cstrs_self_adaptive::update_c_scaling(const population &pop)
{
	if(*m_original_problem != pop.problem()) {
		pagmo_throw(value_error,"The problem linked to the population is not the same as the problem given in argument.");
	}

	// Let's store some useful variables.
	const population::size_type pop_size = pop.size();

	// get the constraints dimension
	//constraint_vector c(m_original_problem->get_c_dimension(), 0.);
	problem::base::c_size_type prob_c_dimension = m_original_problem->get_c_dimension();
	problem::base::c_size_type number_of_eq_constraints =
			m_original_problem->get_c_dimension() -
			m_original_problem->get_ic_dimension();

	const std::vector<double> &c_tol = m_original_problem->get_c_tol();

	m_c_scaling.resize(m_original_problem->get_c_dimension());
	std::fill(m_c_scaling.begin(),m_c_scaling.end(),0.);

	// evaluates the scaling factor
	for(population::size_type i=0; i<pop_size; i++) {
		// updates the current constraint vector
		const population::individual_type &current_individual = pop.get_individual(i);

		const constraint_vector &c = current_individual.cur_c;

		// computes scaling with the right definition of the constraints (can be in base problem? currently used
		// by con2mo as well)
		for(problem::base::c_size_type j=0; j<number_of_eq_constraints; j++) {
			m_c_scaling[j] = std::max(m_c_scaling[j], std::max(0., (std::abs(c.at(j)) - c_tol.at(j))) );
		}
		for(problem::base::c_size_type j=number_of_eq_constraints; j<prob_c_dimension; j++) {
			m_c_scaling[j] = std::max(m_c_scaling[j], std::max(0., c.at(j) - c_tol.at(j)) );
		}
	}
}
예제 #16
0
bool simpleLSM_job::eval_population_fitness(population &pop)
{
    char pwd[FILENAME_MAX];
    getcwd(pwd, sizeof(pwd));
    log.debug("Current working directory", pwd);
    float cputime=0;
    float walltime=0;
    for (sample &s : pop)
    {
        prepare_work_dir_for_sample(s);
        boost::timer::cpu_timer timer;
        eval_sample_fitness(s);
        boost::timer::cpu_times elapsed = timer.elapsed();
        log.debug(" CPU TIME: ",  (elapsed.user + elapsed.system) / 1e9, " seconds", ", WALLCLOCK TIME: ", elapsed.wall / 1e9, " seconds");
        cputime+=((elapsed.user + elapsed.system) / 1e9);
        walltime+=(elapsed.wall / 1e9);

    }

    log.debug("total CPU TIME:", cputime, "total WALLCLOCK TIME:", walltime);        
    log.debug("avergae CPU TIME:", cputime/pop.size(), "avergae WALLCLOCK TIME:", walltime/pop.size());
    return true;
}
예제 #17
0
파일: snopt.cpp 프로젝트: esa/pagmo
void snopt::evolve(population &pop) const
{
    // Let's store some useful variables.
    const problem::base &prob = pop.problem();
    const problem::base::size_type D = prob.get_dimension(), prob_i_dimension = prob.get_i_dimension(), prob_c_dimension = prob.get_c_dimension(), prob_f_dimension = prob.get_f_dimension();
    const decision_vector &lb = prob.get_lb(), &ub = prob.get_ub();
    const population::size_type NP = pop.size();
    const problem::base::size_type Dc = D - prob_i_dimension;
    const std::vector<double>::size_type D_ineqc = prob.get_ic_dimension();
    const std::vector<double>::size_type D_eqc = prob_c_dimension - D_ineqc;
    const std::string name = prob.get_name();

    //We perform some checks to determine wether the problem/population are suitable for SNOPT
    if ( prob_i_dimension != 0  ) {
        pagmo_throw(value_error,"No integer part allowed yet....");
    }

    if ( Dc == 0  ) {
        pagmo_throw(value_error,"No continuous part....");
    }

    if ( prob_f_dimension != 1 ) {
        pagmo_throw(value_error,"The problem is not single objective and SNOPT is not suitable to solve it");
    }

    // Get out if there is nothing to do.
    if (NP == 0 || m_major == 0) {
        return;
    }

    // We allocate memory for the decision vector that will be used in the snopt_function_
    di_comodo.x.resize(Dc);
    di_comodo.c.resize(prob_c_dimension);
    di_comodo.f.resize(prob_f_dimension);


    // We construct a SnoptProblem_PAGMO passing the pointers to the problem and the allocated
    //memory area for the di_comodo vector
    snoptProblem_PAGMO SnoptProblem(prob, &di_comodo);

    // Allocate and initialize;
    integer n     =  Dc;

    // Box-constrained non-linear optimization
    integer neF   =  1 + prob_c_dimension;

    //Memory sizing of A
    integer lenA  = Dc * (1 + prob_c_dimension); //overestimate
    integer *iAfun = new integer[lenA];
    integer *jAvar = new integer[lenA];
    doublereal *A  = new doublereal[lenA];


    //Memory sizing of G
    int lenG =Dc * (1 + prob_c_dimension); //overestimate
    integer *iGfun = new integer[lenG];
    integer *jGvar = new integer[lenG];



    //Decision vector memory allocation
    doublereal *x      = new doublereal[n];
    doublereal *xlow   = new doublereal[n];
    doublereal *xupp   = new doublereal[n];
    doublereal *xmul   = new doublereal[n];
    integer    *xstate = new    integer[n];

    //Objective function memory allocation
    doublereal *F      = new doublereal[neF];
    doublereal *Flow   = new doublereal[neF];
    doublereal *Fupp   = new doublereal[neF];
    doublereal *Fmul   = new doublereal[neF];
    integer    *Fstate = new integer[neF];

    integer nxnames = 1;
    integer nFnames = 1;
    char *xnames = new char[nxnames*8];
    char *Fnames = new char[nFnames*8];

    integer    ObjRow = 0;
    doublereal ObjAdd = 0;

    // Set the upper and lower bounds. And The initial Guess
    int bestidx = pop.get_best_idx();
    for (pagmo::problem::base::size_type i = 0; i < Dc; i++) {
        xlow[i]   = lb[i];
        xupp[i]   = ub[i];
        xstate[i] =    0;
        x[i] = pop.get_individual(bestidx).cur_x[i];
    }

    // Set the bounds for objective, equality and inequality constraints
    // 1 - Objective function
    Flow[0] = -std::numeric_limits<double>::max();
    Fupp[0] = std::numeric_limits<double>::max();
    F[0] = pop.get_individual(bestidx).cur_f[0];
    // 2 - Equality constraints
    for (pagmo::problem::base::size_type i=0; i<D_eqc; ++i) {
        Flow[i+1] = 0;
        Fupp[i+1] = 0;
    }
    // 3 - Inequality constraints
    for (pagmo::problem::base::size_type i=0; i<D_ineqc; ++i) {
        Flow[i+1+D_eqc] = -std::numeric_limits<double>::max();
        Fupp[i+1+D_eqc] = 0;
    }

    // Load the data for SnoptProblem ...
    SnoptProblem.setProblemSize( n, neF );
    SnoptProblem.setNeG( lenG );
    SnoptProblem.setNeA( lenA );
    SnoptProblem.setA          ( lenA, iAfun, jAvar, A );
    SnoptProblem.setG          ( lenG, iGfun, jGvar );
    SnoptProblem.setObjective  ( ObjRow, ObjAdd );
    SnoptProblem.setX          ( x, xlow, xupp, xmul, xstate );
    SnoptProblem.setF          ( F, Flow, Fupp, Fmul, Fstate );
    SnoptProblem.setXNames     ( xnames, nxnames );
    SnoptProblem.setFNames     ( Fnames, nFnames );
    SnoptProblem.setProbName   ( name.c_str() ); //This is limited to be 8 characters!!!
    SnoptProblem.setUserFun    ( snopt_function_ );

    //We set some parameters
    if (m_screen_output) SnoptProblem.setIntParameter("Summary file",6);
    if (m_file_out)   SnoptProblem.setPrintFile   ( name.c_str() );
    SnoptProblem.setIntParameter ( "Derivative option", 0 );
    SnoptProblem.setIntParameter ( "Major iterations limit", m_major);
    SnoptProblem.setIntParameter ( "Iterations limit",100000);
    SnoptProblem.setRealParameter( "Major feasibility tolerance", m_feas);
    SnoptProblem.setRealParameter( "Major optimality tolerance", m_opt);


    //We set the sparsity structure
    int neG;
    try
    {
        std::vector<int> iGfun_vect, jGvar_vect;
        prob.set_sparsity(neG,iGfun_vect,jGvar_vect);
        for (int i=0; i < neG; i++)
        {
            iGfun[i] = iGfun_vect[i];
            jGvar[i] = jGvar_vect[i];
        }
        SnoptProblem.setNeG( neG );
        SnoptProblem.setNeA( 0 );
        SnoptProblem.setG( lenG, iGfun, jGvar );

    } //the user did implement the sparsity in the problem
    catch (not_implemented_error)
    {
        SnoptProblem.computeJac();
        neG = SnoptProblem.getNeG();
    } //the user did not implement the sparsity in the problem


    if (m_screen_output)
    {
        std::cout << "PaGMO 4 SNOPT:" << std::endl << std::endl;
        std::cout << "Sparsity pattern set, NeG = " << neG << std::endl;
        std::cout << "iGfun: [";
        for (int i=0; i<neG-1; ++i) std::cout << iGfun[i] << ",";
        std::cout << iGfun[neG-1] << "]" << std::endl;
        std::cout << "jGvar: [";
        for (int i=0; i<neG-1; ++i) std::cout << jGvar[i] << ",";
        std::cout << jGvar[neG-1] << "]" << std::endl;
    }

    integer Cold = 0;

    //HERE WE CALL snoptA routine!!!!!
    SnoptProblem.solve( Cold );

    //Save the final point making sure it is within the linear bounds
    std::copy(x,x+n,di_comodo.x.begin());
    decision_vector newx = di_comodo.x;
    std::transform(di_comodo.x.begin(), di_comodo.x.end(), pop.get_individual(bestidx).cur_x.begin(), di_comodo.x.begin(),std::minus<double>());
    for (integer i=0; i<n; i++)
    {
        newx[i] = std::min(std::max(lb[i],newx[i]),ub[i]);
    }

    pop.set_x(bestidx,newx);
    pop.set_v(bestidx,di_comodo.x);

    //Clean up memory allocated to call the snoptA routine
    delete []iAfun;
    delete []jAvar;
    delete []A;
    delete []iGfun;
    delete []jGvar;

    delete []x;
    delete []xlow;
    delete []xupp;
    delete []xmul;
    delete []xstate;

    delete []F;
    delete []Flow;
    delete []Fupp;
    delete []Fmul;
    delete []Fstate;

    delete []xnames;
    delete []Fnames;

}
예제 #18
0
void bee_colony::evolve(population &pop) const
{
	// Let's store some useful variables.
	const problem::base &prob = pop.problem();
	const problem::base::size_type prob_i_dimension = prob.get_i_dimension(), D = prob.get_dimension(), Dc = D - prob_i_dimension, prob_c_dimension = prob.get_c_dimension();
	const decision_vector &lb = prob.get_lb(), &ub = prob.get_ub();
	const population::size_type NP = (int) pop.size();

	//We perform some checks to determine wether the problem/population are suitable for ABC
	if ( Dc == 0 ) {
		pagmo_throw(value_error,"There is no continuous part in the problem decision vector for ABC to optimise");
	}

	if ( prob.get_f_dimension() != 1 ) {
		pagmo_throw(value_error,"The problem is not single objective and ABC is not suitable to solve it");
	}

	if ( prob_c_dimension != 0 ) {
		pagmo_throw(value_error,"The problem is not box constrained and ABC is not suitable to solve it");
	}

	if (NP < 2) {
		pagmo_throw(value_error,"for ABC at least 2 individuals in the population are needed");
	}

	// Get out if there is nothing to do.
	if (m_iter == 0) {
		return;
	}

	// Some vectors used during evolution are allocated here.
	fitness_vector fnew(prob.get_f_dimension());
	decision_vector dummy(D,0);			//used for initialisation purposes
	std::vector<decision_vector > X(NP,dummy);	//set of food sources
	std::vector<fitness_vector> fit(NP);		//food sources fitness

	decision_vector temp_solution(D,0);

	std::vector<int> trial(NP,0);

	std::vector<double> probability(NP);

	population::size_type neighbour = 0;

	decision_vector::size_type param2change = 0;

	std::vector<double> selectionfitness(NP), cumsum(NP), cumsumTemp(NP);
	std::vector <population::size_type> selection(NP);


	double r = 0;

	// Copy the food sources position and their fitness
	for ( population::size_type i = 0; i<NP; i++ ) {
		X[i]	=	pop.get_individual(i).cur_x;
		fit[i]	=	pop.get_individual(i).cur_f;
	}

	// Main ABC loop
	for (int j = 0; j < m_iter; ++j) {
		//1- Send employed bees
		for (population::size_type ii = 0; ii< NP; ++ii) {
			//selects a random component (only of the continuous part) of the decision vector
			param2change = boost::uniform_int<decision_vector::size_type>(0,Dc-1)(m_urng);
			//randomly chose a solution to be used to produce a mutant solution of solution ii
			//randomly selected solution must be different from ii
			do{
				neighbour = boost::uniform_int<population::size_type>(0,NP-1)(m_urng);
			}
			while(neighbour == ii);

			//copy local solution into temp_solution (the whole decision_vector, also the integer part)
			for(population::size_type i=0; i<D; ++i) {
				temp_solution[i] = X[ii][i];
			}

			//mutate temp_solution
			temp_solution[param2change] = X[ii][param2change] + boost::uniform_real<double>(-1,1)(m_drng) * (X[ii][param2change] - X[neighbour][param2change]);

			//if generated parameter value is out of boundaries, it is shifted onto the boundaries*/
			if (temp_solution[param2change]<lb[param2change]) {
				temp_solution[param2change] = lb[param2change];
			}
			if (temp_solution[param2change]>ub[param2change]) {
				temp_solution[param2change] = ub[param2change];
			}

			//Calling void prob.objfun(fitness_vector,decision_vector) is more efficient as no memory allocation occur
			//A call to fitness_vector prob.objfun(decision_vector) allocates memory for the return value.
			prob.objfun(fnew,temp_solution);
			//If the new solution is better than the old one replace it with the mutant one and reset its trial counter
			if(prob.compare_fitness(fnew, fit[ii])) {
				X[ii][param2change] = temp_solution[param2change];
				pop.set_x(ii,X[ii]);
				prob.objfun(fit[ii], X[ii]); //update the fitness vector
				trial[ii] = 0;
			}
			else {
				trial[ii]++; //if the solution can't be improved incrase its trial counter
			}
		} //End of loop on the population members

		//2 - Send onlooker bees
		//We scale all fitness values from 0 (worst) to absolute value of the best fitness
		fitness_vector worstfit=fit[0];
		for (pagmo::population::size_type i = 1; i < NP;i++) {
			if (prob.compare_fitness(worstfit,fit[i])) worstfit=fit[i];
		}

		for (pagmo::population::size_type i = 0; i < NP; i++) {
			selectionfitness[i] = fabs(worstfit[0] - fit[i][0]) + 1.;
		}

		// We build and normalise the cumulative sum
		cumsumTemp[0] = selectionfitness[0];
		for (pagmo::population::size_type i = 1; i< NP; i++) {
			cumsumTemp[i] = cumsumTemp[i - 1] + selectionfitness[i];
		}
		for (pagmo::population::size_type i = 0; i < NP; i++) {
			cumsum[i] = cumsumTemp[i]/cumsumTemp[NP-1];
		}

		for (pagmo::population::size_type i = 0; i < NP; i++) {
			r = m_drng();
			for (pagmo::population::size_type j = 0; j < NP; j++) {
				if (cumsum[j] > r) {
					selection[i]=j;
					break;
				}
			}
		}

		for(pagmo::population::size_type t = 0; t < NP; ++t) {
			r = m_drng();
			pagmo::population::size_type ii = selection[t];
			//selects a random component (only of the continuous part) of the decision vector
			param2change = boost::uniform_int<decision_vector::size_type>(0,Dc-1)(m_urng);
			//randomly chose a solution to be used to produce a mutant solution of solution ii
			//randomly selected solution must be different from ii
			do{
				neighbour = boost::uniform_int<population::size_type>(0,NP-1)(m_urng);
			}
			while(neighbour == ii);

			//copy local solution into temp_solution (also integer part)
			for(population::size_type i=0; i<D; ++i) {
				temp_solution[i] = X[ii][i];
			}

			//mutate temp_solution
			temp_solution[param2change] = X[ii][param2change] + boost::uniform_real<double>(-1,1)(m_drng) * (X[ii][param2change] - X[neighbour][param2change]);

			/*if generated parameter value is out of boundaries, it is shifted onto the boundaries*/
			if (temp_solution[param2change]<lb[param2change]) {
				temp_solution[param2change] = lb[param2change];
			}
			if (temp_solution[param2change]>ub[param2change]) {
				temp_solution[param2change] = ub[param2change];
			}

			//Calling void prob.objfun(fitness_vector,decision_vector) is more efficient as no memory allocation occur
			//A call to fitness_vector prob.objfun(decision_vector) allocates memory for the return value.
			prob.objfun(fnew,temp_solution);
			//If the new solution is better than the old one replace it with the mutant one and reset its trial counter
			if(prob.compare_fitness(fnew, fit[ii])) {
				X[ii][param2change] = temp_solution[param2change];
				pop.set_x(ii,X[ii]);
				prob.objfun(fit[ii], X[ii]); //update the fitness vector
				trial[ii] = 0;
			}
			else {
				trial[ii]++; //if the solution can't be improved incrase its  trial counter
			}
		}

		//3 - Send scout bees
		int maxtrialindex = 0;
		for (population::size_type ii=1; ii<NP; ++ii)
		{
			if (trial[ii] > trial[maxtrialindex]) {
				maxtrialindex = ii;
			}
		}
		if(trial[maxtrialindex] >= m_limit)
		{
			//select a new random solution
			for(problem::base::size_type jj = 0; jj < Dc; ++jj) {
				X[maxtrialindex][jj] = boost::uniform_real<double>(lb[jj],ub[jj])(m_drng);
			}
			trial[maxtrialindex] = 0;
			pop.set_x(maxtrialindex,X[maxtrialindex]);
		}




	} // end of main ABC loop

}
예제 #19
0
/**
 * Run the co-evolution algorithm
 *
 * @param[in,out] pop input/output pagmo::population to be evolved.
 */
void cstrs_co_evolution::evolve(population &pop) const
{	
	// Let's store some useful variables.
	const problem::base &prob = pop.problem();
	const population::size_type pop_size = pop.size();
	const problem::base::size_type prob_dimension = prob.get_dimension();

	// get the constraints dimension
	problem::base::c_size_type prob_c_dimension = prob.get_c_dimension();

	//We perform some checks to determine wether the problem/population are suitable for co-evolution
	if(prob_c_dimension < 1) {
		pagmo_throw(value_error,"The problem is not constrained and co-evolution is not suitable to solve it");
	}
	if(prob.get_f_dimension() != 1) {
		pagmo_throw(value_error,"The problem is multiobjective and co-evolution is not suitable to solve it");
	}

	// Get out if there is nothing to do.
	if(pop_size == 0) {
		return;
	}

	//get the dimension of the chromosome of P2
	unsigned int pop_2_dim = 0;
	switch(m_method)
	{
	case algorithm::cstrs_co_evolution::SIMPLE:
	{
		pop_2_dim = 2;
		break;
	}
	case algorithm::cstrs_co_evolution::SPLIT_NEQ_EQ:
	{
		pop_2_dim = 4;
		break;
	}
	case algorithm::cstrs_co_evolution::SPLIT_CONSTRAINTS:
		pop_2_dim = 2*prob.get_c_dimension();
		break;
	default: 
		pagmo_throw(value_error,"The constraints co-evolutionary method is not valid.");
		break;
	}

	// split the population into two populations
	// the population P1 associated to the modified problem with penalized fitness
	// and population P2 encoding the penalty weights
	
	// Populations size
	population::size_type pop_1_size = pop_size;
	population::size_type pop_2_size = m_pop_penalties_size;

	//Creates problem associated to P2
	problem::cstrs_co_evolution_penalty prob_2(prob,pop_2_dim,pop_2_size);
	prob_2.set_bounds(m_pen_lower_bound,m_pen_upper_bound);

	//random initialization of the P2 chromosome (needed for the fist generation)
	std::vector<decision_vector> pop_2_x(pop_2_size);
	std::vector<fitness_vector> pop_2_f(pop_2_size);

	for(population::size_type j=0; j<pop_2_size; j++) {
		pop_2_x[j] = decision_vector(pop_2_dim,0.);
		// choose random coefficients between lower bound and upper bound
		for(population::size_type i=0; i<pop_2_dim;i++) {
			pop_2_x[j][i] = boost::uniform_real<double>(m_pen_lower_bound,m_pen_upper_bound)(m_drng);
		}
	}

	//vector of the population P1. Initialized with clones of the original population
	std::vector<population> pop_1_vector;
	for(population::size_type i=0; i<pop_2_size; i++){
		pop_1_vector.push_back(population(pop));
	}

	// Main Co-Evolution loop
	for(int k=0; k<m_gen; k++) {
		// for each individuals of pop 2, evolve the current population,
		// and store the position of the feasible idx
		for(population::size_type j=0; j<pop_2_size; j++) {

			problem::cstrs_co_evolution prob_1(prob, pop_1_vector.at(j), m_method);

			// modify the problem by setting decision vector encoding penalty
			// coefficients w1 and w2 in prob 1
			prob_1.set_penalty_coeff(pop_2_x.at(j));

			// creating the POPULATION 1 instance based on the
			// updated prob 1

			// prob_1 is a BASE_META???? THE CLONE OF prob_1 IN POP_1 IS AT THE LEVEL OF
			// THE BASE CLASS AND NOT AT THE LEVEL OF THE BASE_META, NO?!?
			population pop_1(prob_1,0);

			// initialize P1 chromosomes. The fitnesses related to problem 1 are computed
			for(population::size_type i=0; i<pop_1_size; i++) {
				pop_1.push_back(pop_1_vector.at(j).get_individual(i).cur_x);
			}

			// evolve the P1 instance
			m_original_algo->evolve(pop_1);

			//updating the original problem population (computation of fitness and constraints)
			pop_1_vector.at(j).clear();
			for(population::size_type i=0; i<pop_1_size; i++){
				pop_1_vector.at(j).push_back(pop_1.get_individual(i).cur_x);
			}

			// set up penalization variables needs for the population 2
			// the constraints has not been evaluated yet.
			prob_2.update_penalty_coeff(j,pop_2_x.at(j),pop_1_vector.at(j));

		}
		// creating the POPULATION 2 instance based on the
		// updated prob 2
		population pop_2(prob_2,0);

		// compute the fitness values of the second population
		for(population::size_type i=0; i<pop_2_size; i++) {
			pop_2.push_back(pop_2_x[i]);
		}

		m_original_algo_penalties->evolve(pop_2);

		// store the new chromosomes
		for(population::size_type i=0; i<pop_2_size; i++) {
			pop_2_x[i] = pop_2.get_individual(i).cur_x;
			pop_2_f[i] = pop_2.get_individual(i).cur_f;
		}

		// Check the exit conditions (every 40 generations, just as DE)
		if(k % 40 == 0) {
			// finds the best population
			population::size_type best_idx = 0;
			for(population::size_type j=1; j<pop_2_size; j++) {
				if(pop_2_f[j][0] < pop_2_f[best_idx][0]) {
					best_idx = j;
				}
			}

			const population &current_population = pop_1_vector.at(best_idx);

			decision_vector tmp(prob_dimension);

			double dx = 0;
			for(decision_vector::size_type i=0; i<prob_dimension; i++) {
				tmp[i] = current_population.get_individual(current_population.get_worst_idx()).best_x[i] -
						current_population.get_individual(current_population.get_best_idx()).best_x[i];
				dx += std::fabs(tmp[i]);
			}

			if(dx < m_xtol ) {
				if (m_screen_output) {
					std::cout << "Exit condition -- xtol < " << m_xtol << std::endl;
				}
				break;
			}

			double mah = std::fabs(current_population.get_individual(current_population.get_worst_idx()).best_f[0] -
					current_population.get_individual(current_population.get_best_idx()).best_f[0]);

			if(mah < m_ftol) {
				if(m_screen_output) {
					std::cout << "Exit condition -- ftol < " << m_ftol << std::endl;
				}
				break;
			}

			// outputs current values
			if(m_screen_output) {
				std::cout << "Generation " << k << " ***" << std::endl;
				std::cout << "    Best global fitness: " << current_population.champion().f << std::endl;
				std::cout << "    xtol: " << dx << ", ftol: " << mah << std::endl;
				std::cout << "    xtol: " << dx << ", ftol: " << mah << std::endl;
			}
		}
	}

	// find the best fitness population in the final pop
	population::size_type best_idx = 0;
	for(population::size_type j=1; j<pop_2_size; j++) {
		if(pop_2_f[j][0] < pop_2_f[best_idx][0]) { 
			best_idx = j;
		}
	}

	// store the final population in the main population
	// can't avoid to recompute the vectors here, otherwise we
	// clone the problem stored in the population with the
	// pop = operator!
	pop.clear();
	for(population::size_type i=0; i<pop_1_size; i++) {
		pop.push_back(pop_1_vector.at(best_idx).get_individual(i).cur_x);
	}
}
예제 #20
0
population choosiness_breeder::breed(const population &generation, const std::vector<double> &fitnesses) const
{
  using namespace std;
  
  population ret;
  tree_crossover_reproducer repr;
  node_crossover_reproducer mrepr;
  builder random_builder;
  
  deque<const agent *> mut_gen;
  for(const auto &a : generation) mut_gen.push_back(&a);
  
  experimental_parameters e = exp_params();
  const uint32_t growth_tree_min = e["growth_tree_min"];
  const uint32_t growth_tree_max = e["growth_tree_max"];
  
  const double max_dist = sqrt(_maze.rows() * _maze.rows() + _maze.columns() * _maze.columns());
  
  _phenotypes.clear();
  for(const auto &a : mut_gen) _phenotypes.at(a->final_state().row, a->final_state().col).push_back(a);
  
  map<const agent *, vector<const agent *> > matches;
  for(auto ait = mut_gen.begin(); ait != mut_gen.end();)
  {
    const agent *const a = *ait;
    const vector<vector<const agent *> > plausible_mates =
      _phenotypes.find_in_range(a->final_state().row, a->final_state().col,
        a->chromosomes()[0]);
    
    vector<const agent *> flattened_mates;
    for(const auto &v : plausible_mates) flattened_mates.insert(flattened_mates.end(), v.begin(), v.end());
    
    for(auto it = flattened_mates.begin(); it != flattened_mates.end();)
    {
      if(distance((*it)->final_state().col, (*it)->final_state().row,
        a->final_state().col, a->final_state().row) > (*it)->chromosomes()[0])
      {
        it = flattened_mates.erase(it);
        continue;
      }
      ++it;
    }
    
    if(flattened_mates.empty())
    {
      ait = mut_gen.erase(ait);
      continue;
    }
    
    matches[a] = flattened_mates;
    ++ait;
  }
  
  const population::size_type new_size = generation.size();
  
  random_shuffle(mut_gen.begin(), mut_gen.end());
  while(ret.size() < new_size)
  {
    for(const auto &mother : mut_gen)
    {
      if(ret.size() >= new_size) break;
    
      const vector<const agent *> &fathers = matches[mother];
      if(fathers.empty()) continue;
      
      const agent &father = *fathers[rand() % fathers.size()];
    
      agent mutant  = random_builder.grow(program_types_set, growth_tree_min, growth_tree_max);
      mutant.set_chromosomes(vector<double> { rand_normal() * max_dist });
    
      vector<agent> children   = repr.reproduce(vector<agent> { *mother, father });
      if(children.empty()) continue;
      agent &child = children[0];
      child.set_chromosomes(vector<double> { (mother->chromosomes()[0] + father.chromosomes()[0]) / 2.0 });
    
      agent res     = mrepr.reproduce(vector<agent> { child, mutant })[0];
      res.set_chromosomes(vector<double> { (child.chromosomes()[0] + mutant.chromosomes()[0]) / 2.0 });
    
      ret.push_back(res);
    }
  }
  
  return ret;
}
예제 #21
0
/**
 * Updates the penalty coefficients with the given population.
 * @param[in] population pop.
 */
void cstrs_self_adaptive::update_penalty_coeff(const population &pop)
{
	if(*m_original_problem != pop.problem()) {
		pagmo_throw(value_error,"The problem linked to the population is not the same as the problem given in argument.");
	}

	// Let's store some useful variables.
	const population::size_type pop_size = pop.size();

	// Get out if there is nothing to do.
	if (pop_size == 0) {
		return;
	}

	m_map_fitness.clear();
	m_map_constraint.clear();
	// store f and c in maps depending on the the x hash
	for(population::size_type i=0; i<pop_size; i++) {
		const population::individual_type &current_individual = pop.get_individual(i);
		// m_map_fitness.insert(std::pair<std::size_t, fitness_vector>(m_decision_vector_hash(current_individual.cur_x),current_individual.cur_f));
		m_map_fitness[m_decision_vector_hash(current_individual.cur_x)]=current_individual.cur_f;
		m_map_constraint[m_decision_vector_hash(current_individual.cur_x)]=current_individual.cur_c;
	}

	std::vector<population::size_type> feasible_idx(0);
	std::vector<population::size_type> infeasible_idx(0);

	// store indexes of feasible and non feasible individuals
	for(population::size_type i=0; i<pop_size; i++) {
		const population::individual_type &current_individual = pop.get_individual(i);

		if(m_original_problem->feasibility_c(current_individual.cur_c)) {
			feasible_idx.push_back(i);
		} else {
			infeasible_idx.push_back(i);
		}
	}

	// if the population is only feasible, then nothing is done
	if(infeasible_idx.size() == 0) {
		update_c_scaling(pop);		
		m_apply_penalty_1 = false;
		m_scaling_factor = 0.;
		return;
	}
	m_apply_penalty_1 = false;
	m_scaling_factor = 0.;

	// updates the c_scaling, needed for solution infeasibility computation
	update_c_scaling(pop);

	// evaluate solutions infeasibility
	//compute_pop_solution_infeasibility(solution_infeasibility, pop);

	std::vector<double> solution_infeasibility(pop_size);
	std::fill(solution_infeasibility.begin(),solution_infeasibility.end(),0.);

	// evaluate solutions infeasibility
	solution_infeasibility.resize(pop_size);
	std::fill(solution_infeasibility.begin(),solution_infeasibility.end(),0.);

	for(population::size_type i=0; i<pop_size; i++) {
		const population::individual_type &current_individual = pop.get_individual(i);

		// compute the infeasibility of the constraint
		solution_infeasibility[i] = compute_solution_infeasibility(current_individual.cur_c);
	}

	// search position of x_hat_down, x_hat_up and x_hat_round
	population::size_type hat_down_idx = -1;
	population::size_type hat_up_idx = -1;
	population::size_type hat_round_idx = -1;

	// first case, the population contains at least one feasible solution
	if(feasible_idx.size() > 0) {
		// initialize hat_down_idx
		hat_down_idx = feasible_idx.at(0);

		// x_hat_down = feasible individual with lowest objective value in p
		for(population::size_type i=0; i<feasible_idx.size(); i++) {
			const population::size_type current_idx = feasible_idx.at(i);
			const population::individual_type &current_individual = pop.get_individual(current_idx);

			if(m_original_problem->compare_fitness(current_individual.cur_f, pop.get_individual(hat_down_idx).cur_f)) {
				hat_down_idx = current_idx;
			}
		}

		// hat down is now available
		fitness_vector f_hat_down = pop.get_individual(hat_down_idx).cur_f;

		// x_hat_up value depends if the population contains infeasible individual with objective
		// function better than f_hat_down
		bool pop_contains_infeasible_f_better_x_hat_down = false;
		for(population::size_type i=0; i<infeasible_idx.size(); i++) {
			const population::size_type current_idx = infeasible_idx.at(i);
			const population::individual_type &current_individual = pop.get_individual(current_idx);

			if(m_original_problem->compare_fitness(current_individual.cur_f, f_hat_down)) {
				pop_contains_infeasible_f_better_x_hat_down = true;

				// initialize hat_up_idx
				hat_up_idx = current_idx;

				break;
			}
		}

		if(pop_contains_infeasible_f_better_x_hat_down) {
			// hat_up_idx is already initizalized

			// gets the individual with maximum infeasibility and objfun lower than f_hat_down
			for(population::size_type i=0; i<infeasible_idx.size(); i++) {
				const population::size_type current_idx = infeasible_idx.at(i);
				const population::individual_type &current_individual = pop.get_individual(current_idx);

				if(m_original_problem->compare_fitness(current_individual.cur_f, f_hat_down) &&
					(solution_infeasibility.at(current_idx) >= solution_infeasibility.at(hat_up_idx)) ) {

					if(solution_infeasibility.at(current_idx) == solution_infeasibility.at(hat_up_idx)) {
						if(m_original_problem->compare_fitness(current_individual.cur_f, pop.get_individual(hat_up_idx).cur_f)) {
							hat_up_idx = current_idx;
						}
					} else {
						hat_up_idx = current_idx;
					}
				}
			}

			// apply penalty 1
			m_apply_penalty_1 = true;

		} else {
			// all the infeasible soutions have an objective function value greater than f_hat_down
			// the worst is the one that has the maximum infeasibility
			// initialize hat_up_idx
			hat_up_idx = infeasible_idx.at(0);

			for(population::size_type i=0; i<infeasible_idx.size(); i++) {
				const population::size_type current_idx = infeasible_idx.at(i);
				const population::individual_type &current_individual = pop.get_individual(current_idx);

				if(solution_infeasibility.at(current_idx) >= solution_infeasibility.at(hat_up_idx)) {
					if(solution_infeasibility.at(current_idx) == solution_infeasibility.at(hat_up_idx)) {
						if(m_original_problem->compare_fitness(pop.get_individual(hat_up_idx).cur_f, current_individual.cur_f)) {
							hat_up_idx = current_idx;
						}
					} else {
						hat_up_idx = current_idx;
					}
				}
			}

			// do not apply penalty 1
			m_apply_penalty_1 = false;
		}

	} else { // case where there is no feasible solution in the population
		// best is the individual with the lowest infeasibility
		hat_down_idx = 0;
		hat_up_idx = 0;

		for(population::size_type i=0; i<pop_size; i++) {
			const population::individual_type &current_individual = pop.get_individual(i);

			if(solution_infeasibility.at(i) <= solution_infeasibility.at(hat_down_idx)) {
				if(solution_infeasibility.at(i) == solution_infeasibility.at(hat_down_idx)) {
					if(m_original_problem->compare_fitness(current_individual.cur_f, pop.get_individual(hat_down_idx).cur_f)) {
						hat_down_idx = i;
					}
				} else {
					hat_down_idx = i;
				}
			}
		}

		// worst individual
		for(population::size_type i=0; i<pop_size; i++) {
			const population::individual_type &current_individual = pop.get_individual(i);

			if(solution_infeasibility.at(i) >= solution_infeasibility.at(hat_up_idx)) {
				if(solution_infeasibility.at(i) == solution_infeasibility.at(hat_up_idx)) {
					if(m_original_problem->compare_fitness(pop.get_individual(hat_up_idx).cur_f, current_individual.cur_f)) {
						hat_up_idx = i;
					}
				} else {
					hat_up_idx = i;
				}
			}
		}

		// apply penalty 1 to the population
		m_apply_penalty_1 = true;
	}

	// stores the hat round idx, i.e. the solution with highest objective
	// function value in the population
	hat_round_idx = 0;
	for(population::size_type i=0; i<pop_size; i++) {
		const population::individual_type &current_individual = pop.get_individual(i);

		if(m_original_problem->compare_fitness(pop.get_individual(hat_round_idx).cur_f, current_individual.cur_f)) {
			hat_round_idx = i;
		}
	}

	// get the objective function values of the three individuals
	m_f_hat_round = pop.get_individual(hat_round_idx).cur_f;
	m_f_hat_down =  pop.get_individual(hat_down_idx).cur_f;
	m_f_hat_up = pop.get_individual(hat_up_idx).cur_f;

	// get the solution infeasibility values of the three individuals
	m_i_hat_round = solution_infeasibility.at(hat_round_idx);
	m_i_hat_down = solution_infeasibility.at(hat_down_idx);
	m_i_hat_up = solution_infeasibility.at(hat_up_idx);

	// computes the scaling factor
	m_scaling_factor = 0.;
	// evaluates scaling factor
	if(m_original_problem->compare_fitness(m_f_hat_down, m_f_hat_up)) {
		m_scaling_factor = (m_f_hat_round[0] - m_f_hat_up[0]) / m_f_hat_up[0];
	} else {
		m_scaling_factor = (m_f_hat_round[0] - m_f_hat_down[0]) / m_f_hat_down[0];
	}
	if(m_f_hat_up[0] == m_f_hat_round[0]) {
		m_scaling_factor = 0.;
	}

}
예제 #22
0
/**
 * The best member of the population will be used as starting point for the minimisation process. The algorithm will stop
 * if the gradient falls below the grad_tol parameter, if the maximum number of iterations max_iter is exceeded or if
 * the inner GSL routine call reports an error (which will be logged on std::cout). After the end of the minimisation process,
 * the minimised decision vector will replace the best individual in the population, after being modified to fall within
 * the problem bounds if necessary.
 *
 * @param[in,out] pop population to evolve.
 */
void gsl_gradient::evolve(population &pop) const
{
	// Do nothing if the population is empty.
	if (!pop.size()) {
		return;
	}
	// Useful variables.
	const problem::base &problem = pop.problem();
	if (problem.get_f_dimension() != 1) {
		pagmo_throw(value_error,"this algorithm does not support multi-objective optimisation");
	}
	if (problem.get_c_dimension()) {
		pagmo_throw(value_error,"this algorithm does not support constrained optimisation");
	}
	const problem::base::size_type cont_size = problem.get_dimension() - problem.get_i_dimension();
	if (!cont_size) {
		pagmo_throw(value_error,"the problem has no continuous part");
	}
	// Extract the best individual.
	const population::size_type best_ind_idx = pop.get_best_idx();
	const population::individual_type &best_ind = pop.get_individual(best_ind_idx);
	// GSL wrapper parameters structure.
	objfun_wrapper_params params;
	params.p = &problem;
	// Integer part of the temporay decision vector must be filled with the integer part of the best individual,
	// which will not be optimised.
	params.x.resize(problem.get_dimension());
	std::copy(best_ind.cur_x.begin() + cont_size, best_ind.cur_x.end(), params.x.begin() + cont_size);
	params.f.resize(1);
	params.step_size = m_numdiff_step_size;
	// GSL function structure.
	gsl_multimin_function_fdf gsl_func;
	gsl_func.n = boost::numeric_cast<std::size_t>(cont_size);
	gsl_func.f = &objfun_wrapper;
	gsl_func.df = &d_objfun_wrapper;
	gsl_func.fdf = &fd_objfun_wrapper;
	gsl_func.params = (void *)&params;
	// Minimiser.
	gsl_multimin_fdfminimizer *s = 0;
	// This will be the starting point.
	gsl_vector *x = 0;
	// Here we start the allocations.
	// Recast as size_t here, in order to avoid potential overflows later.
	const std::size_t s_cont_size = boost::numeric_cast<std::size_t>(cont_size);
	// Allocate and check the allocation results.
	x = gsl_vector_alloc(s_cont_size);
	const gsl_multimin_fdfminimizer_type *minimiser = get_gsl_minimiser_ptr();
	pagmo_assert(minimiser);
	s = gsl_multimin_fdfminimizer_alloc(minimiser,s_cont_size);
	// Check the allocations.
	check_allocs(x,s);
	// Fill in the starting point (from the best individual).
	for (std::size_t i = 0; i < s_cont_size; ++i) {
		gsl_vector_set(x,i,best_ind.cur_x[i]);
	}
	// Init the solver.
	gsl_multimin_fdfminimizer_set(s,&gsl_func,x,m_step_size,m_tol);
	// Iterate.
	std::size_t iter = 0;
	int status;
	try {
		do
		{
			++iter;
			status = gsl_multimin_fdfminimizer_iterate(s);
			if (status) {
				break;
			}
			status = gsl_multimin_test_gradient(s->gradient,m_grad_tol);
		} while (status == GSL_CONTINUE && iter < m_max_iter);
	} catch (const std::exception &e) {
		// Cleanup and re-throw.
		cleanup(x,s);
		throw e;
	} catch (...) {
		// Cleanup and throw.
		cleanup(x,s);
		pagmo_throw(std::runtime_error,"unknown exception caught in gsl_gradient::evolve");
	}
	// Free up resources.
	cleanup(x,s);
	// Check the generated individual and change it to respect the bounds as necessary.
	for (problem::base::size_type i = 0; i < cont_size; ++i) {
		if (params.x[i] < problem.get_lb()[i]) {
			params.x[i] = problem.get_lb()[i];
		}
		if (params.x[i] > problem.get_ub()[i]) {
			params.x[i] = problem.get_ub()[i];
		}
	}
	// Replace the best individual.
	pop.set_x(best_ind_idx,params.x);
}
예제 #23
0
void sa_corana::evolve(population &pop) const {

	// Let's store some useful variables.
	const problem::base &prob = pop.problem();
	const problem::base::size_type D = prob.get_dimension(), prob_i_dimension = prob.get_i_dimension(), prob_c_dimension = prob.get_c_dimension(), prob_f_dimension = prob.get_f_dimension();
	const decision_vector &lb = prob.get_lb(), &ub = prob.get_ub();
	const population::size_type NP = pop.size();
	const problem::base::size_type Dc = D - prob_i_dimension;

	//We perform some checks to determine wether the problem/population are suitable for sa_corana
	if ( Dc == 0 ) {
		pagmo_throw(value_error,"There is no continuous part in the problem decision vector for sa_corana to optimise");
	}

	if ( prob_c_dimension != 0 ) {
		pagmo_throw(value_error,"The problem is not box constrained and sa_corana is not suitable to solve it");
	}

	if ( prob_f_dimension != 1 ) {
		pagmo_throw(value_error,"The problem is not single objective and sa_corana is not suitable to solve it");
	}

	//Determines the number of temperature adjustment for the annealing procedure
	const size_t n_T = m_niter / (m_step_adj * m_bin_size * Dc);

	// Get out if there is nothing to do.
	if (NP == 0 || m_niter == 0) {
		return;
	}
	if (n_T == 0) {
		pagmo_throw(value_error,"n_T is zero, increase niter");
	}

	//Starting point is the best individual
	const int bestidx = pop.get_best_idx();
	const decision_vector &x0 = pop.get_individual(bestidx).cur_x;
	const fitness_vector &fit0 = pop.get_individual(bestidx).cur_f;
	//Determines the coefficient to dcrease the temperature
	const double Tcoeff = std::pow(m_Tf/m_Ts,1.0/(double)(n_T));
	//Stores the current and new points
	decision_vector xNEW = x0, xOLD = xNEW;
	fitness_vector fNEW = fit0, fOLD = fNEW;
	//Stores the adaptive steps of each component (integer part included but not used)
	decision_vector step(D,m_range);

	//Stores the number of accepted points per component (integer part included but not used)
	std::vector<int> acp(D,0) ;
	double ratio = 0, currentT = m_Ts, probab = 0;

	//Main SA loops
	for (size_t jter = 0; jter < n_T; ++jter) {
		for (int mter = 0; mter < m_step_adj; ++mter) {
			for (int kter = 0; kter < m_bin_size; ++kter) {
				size_t nter = boost::uniform_int<int>(0,Dc-1)(m_urng);
				for (size_t numb = 0; numb < Dc ; ++numb) {
					nter = (nter + 1) % Dc;
					//We modify the current point actsol by mutating its nter component within
					//a step that we will later adapt
					xNEW[nter] = xOLD[nter] + boost::uniform_real<double>(-1,1)(m_drng) * step[nter] * (ub[nter]-lb[nter]);

					// If new solution produced is infeasible ignore it
					if ((xNEW[nter] > ub[nter]) || (xNEW[nter] < lb[nter])) {
						xNEW[nter]=xOLD[nter];
						continue;
					}
					//And we valuate the objective function for the new point
					prob.objfun(fNEW,xNEW);

					// We decide wether to accept or discard the point
					if (prob.compare_fitness(fNEW,fOLD) ) {
						//accept
						xOLD[nter] = xNEW[nter];
						fOLD = fNEW;
						acp[nter]++;	//Increase the number of accepted values
					} else {
						//test it with Boltzmann to decide the acceptance
						probab = exp ( - fabs(fOLD[0] - fNEW[0] ) / currentT );

						// we compare prob with a random probability.
						if (probab > m_drng()) {
							xOLD[nter] = xNEW[nter];
							fOLD = fNEW;
							acp[nter]++;	//Increase the number of accepted values
						} else {
							xNEW[nter] = xOLD[nter];
						}
					} // end if
				} // end for(nter = 0; ...
			} // end for(kter = 0; ...
			// adjust the step (adaptively)
			for (size_t iter = 0; iter < Dc; ++iter) {
				ratio = (double)acp[iter]/(double)m_bin_size;
				acp[iter] = 0;  //reset the counter
				if (ratio > .6) {
					//too many acceptances, increase the step by a factor 3 maximum
					step[iter] = step [iter] * (1 + 2 *(ratio - .6)/.4);
				} else {
					if (ratio < .4) {
						//too few acceptance, decrease the step by a factor 3 maximum
						step [iter]= step [iter] / (1 + 2 * ((.4 - ratio)/.4));
					};
				};
				//And if it becomes too large, reset it to its initial value
				if ( step[iter] > m_range ) {
					step [iter] = m_range;
				};
			}
		}
		// Cooling schedule
		currentT *= Tcoeff;
	}
	if ( prob.compare_fitness(fOLD,fit0) ){
		pop.set_x(bestidx,xOLD); //new evaluation is possible here......
		std::transform(xOLD.begin(), xOLD.end(), pop.get_individual(bestidx).cur_x.begin(), xOLD.begin(),std::minus<double>());
		pop.set_v(bestidx,xOLD);
	}
}
예제 #24
0
파일: ihs.cpp 프로젝트: YS-L/pagmo
void ihs::evolve(population &pop) const
{
	// Let's store some useful variables.
	const problem::base &prob = pop.problem();
	const problem::base::size_type prob_dimension = prob.get_dimension(), prob_i_dimension = prob.get_i_dimension();
	const decision_vector &lb = prob.get_lb(), &ub = prob.get_ub();
	const population::size_type pop_size = pop.size();
	// Get out if there is nothing to do.
	if (pop_size == 0 || m_gen == 0) {
		return;
	}
	decision_vector lu_diff(prob_dimension);
	for (problem::base::size_type i = 0; i < prob_dimension; ++i) {
		lu_diff[i] = ub[i] - lb[i];
	}
	// Int distribution to be used when picking random individuals.
	boost::uniform_int<population::size_type> uni_int(0,pop_size - 1);
	const double c = std::log(m_bw_min/m_bw_max) / m_gen;
	// Temporary individual used during evolution.
	population::individual_type tmp;
	tmp.cur_x.resize(prob_dimension);
	tmp.cur_f.resize(prob.get_f_dimension());
	tmp.cur_c.resize(prob.get_c_dimension());
	for (std::size_t g = 0; g < m_gen; ++g) {
		const double ppar_cur = m_ppar_min + ((m_ppar_max - m_ppar_min) * g) / m_gen, bw_cur = m_bw_max * std::exp(c * g);
		// Continuous part.
		for (problem::base::size_type i = 0; i < prob_dimension - prob_i_dimension; ++i) {
			if (m_drng() < m_phmcr) {
				// tmp's i-th chromosome element is the one from a randomly chosen individual.
				tmp.cur_x[i] = pop.get_individual(uni_int(m_urng)).cur_x[i];
				// Do pitch adjustment with ppar_cur probability.
				if (m_drng() < ppar_cur) {
					// Randomly, add or subtract pitch from the current chromosome element.
					if (m_drng() > .5) {
						tmp.cur_x[i] += m_drng() * bw_cur * lu_diff[i];
					} else {
						tmp.cur_x[i] -= m_drng() * bw_cur * lu_diff[i];
					}
					// Handle the case in which we added or subtracted too much and ended up out
					// of boundaries.
					if (tmp.cur_x[i] > ub[i]) {
						tmp.cur_x[i] = boost::uniform_real<double>(lb[i],ub[i])(m_drng);
					} else if (tmp.cur_x[i] < lb[i]) {
						tmp.cur_x[i] = boost::uniform_real<double>(lb[i],ub[i])(m_drng);
					}
				}
			} else {
				// Pick randomly within the bounds.
				tmp.cur_x[i] = boost::uniform_real<double>(lb[i],ub[i])(m_drng);
			}
		}

		//Integer Part
		for (problem::base::size_type i = prob_dimension - prob_i_dimension; i < prob_dimension; ++i) {
			if (m_drng() < m_phmcr) {
				tmp.cur_x[i] = pop.get_individual(uni_int(m_urng)).cur_x[i];
				if (m_drng() < ppar_cur) {
					if (m_drng() > .5) {
						tmp.cur_x[i] += double_to_int::convert(m_drng() * bw_cur * lu_diff[i]);
					} else {
						tmp.cur_x[i] -= double_to_int::convert(m_drng() * bw_cur * lu_diff[i]);
					}
					// Wrap over in case we went past the bounds.
					if (tmp.cur_x[i] > ub[i]) {
						tmp.cur_x[i] = lb[i] + double_to_int::convert(tmp.cur_x[i] - ub[i]) % static_cast<int>(lu_diff[i]);
					} else if (tmp.cur_x[i] < lb[i]) {
						tmp.cur_x[i] = ub[i] - double_to_int::convert(lb[i] - tmp.cur_x[i]) % static_cast<int>(lu_diff[i]);
					}
				}
			} else {
				// Pick randomly within the bounds.
				tmp.cur_x[i] = boost::uniform_int<int>(lb[i],ub[i])(m_urng);
			}
		}
		// And we push him back
		pop.push_back(tmp.cur_x);
		// We locate the worst individual.
		const population::size_type worst_idx = pop.get_worst_idx();
		// And we get rid of him :)
		pop.erase(worst_idx);
	}
}
예제 #25
0
파일: ipopt.cpp 프로젝트: DinCahill/pagmo
void ipopt::evolve(population &pop) const
{
	// Let's store some useful variables.
	const problem::base &prob = pop.problem();
	const problem::base::size_type D = prob.get_dimension(), prob_i_dimension = prob.get_i_dimension(), prob_f_dimension = prob.get_f_dimension();
	const population::size_type NP = pop.size();
	const problem::base::size_type Dc = D - prob_i_dimension;
	const std::string name = prob.get_name();

	//We perform some checks to determine wether the problem/population are suitable for IPOPT
	if ( prob_i_dimension != 0  ) {
		pagmo_throw(value_error,"No integer part allowed yet....");
	}

	if ( Dc == 0  ) {
		pagmo_throw(value_error,"No continuous part....");
	}

	if ( prob_f_dimension != 1 ) {
		pagmo_throw(value_error,"The problem is not single objective and IPOPT is not suitable to solve it");
	}

	// Get out if there is nothing to do.
	if (NP == 0 || m_max_iter == 0) {
		return;
	}

	//create an instance of the ipopt_problem
	::Ipopt::SmartPtr< ::Ipopt::TNLP> pagmo_nlp = new ipopt_problem(&pop);

	//create an instance of the IpoptApplication
	::Ipopt::SmartPtr< ::Ipopt::IpoptApplication> m_app = new ::Ipopt::IpoptApplication(m_screen_output,false);

	if (!m_nlp_scaling_method) {
		m_app->Options()->SetStringValue("nlp_scaling_method", "none");
	}
	m_app->Options()->SetStringValue("hessian_approximation", "limited-memory");
	m_app->Options()->SetIntegerValue("print_level", 5);

	// Termination Criteria 1: iterations
	m_app->Options()->SetIntegerValue("max_iter", m_max_iter);

	// Termination Criteria 2: tolerance
	m_app->Options()->SetNumericValue("tol", 1.);
	m_app->Options()->SetNumericValue("dual_inf_tol", m_dual_inf_tol);
	m_app->Options()->SetNumericValue("constr_viol_tol", m_constr_viol_tol);
	m_app->Options()->SetNumericValue("compl_inf_tol", m_compl_inf_tol);
	m_app->Options()->SetNumericValue("obj_scaling_factor", m_obj_scaling_factor);
	m_app->Options()->SetNumericValue("mu_init", m_mu_init);



	// Intialize the IpoptApplication and process the options
	Ipopt::ApplicationReturnStatus status;
	status = m_app->Initialize();
	if (status != Ipopt::Solve_Succeeded) {
		pagmo_throw(value_error, "Error during IPOPT initialization!");
	}

	// Ask Ipopt to solve the problem
	status = m_app->OptimizeTNLP(pagmo_nlp);
}
예제 #26
0
파일: inverover.cpp 프로젝트: esa/pagmo
/**
 * Runs the Inverover algorithm for the number of generations specified in the constructor.
 *
 * @param[in,out] pop input/output pagmo::population to be evolved.
 */
void inverover::evolve(population &pop) const
{
	const problem::base_tsp* prob;
	//check if problem is of type pagmo::problem::base_tsp
	try {
		const problem::base_tsp& tsp_prob = dynamic_cast<const problem::base_tsp &>(pop.problem());
		prob = &tsp_prob;
	}
	catch (const std::bad_cast& e) {
		pagmo_throw(value_error,"Problem not of type pagmo::problem::base_tsp");
	}

	// Let's store some useful variables.
	const population::size_type NP = pop.size();
	const problem::base::size_type Nv = prob->get_n_cities();

	// Initializing the random number generators
	boost::uniform_real<double> uniform(0.0, 1.0);
	boost::variate_generator<boost::lagged_fibonacci607 &, boost::uniform_real<double> > unif_01(m_drng, uniform);
	boost::uniform_int<int> NPless1(0, NP - 2);
	boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > unif_NPless1(m_urng, NPless1);
	boost::uniform_int<int> Nv_(0, Nv - 1);
	boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > unif_Nv(m_urng, Nv_);
	boost::uniform_int<int> Nvless1(0, Nv - 2);
	boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > unif_Nvless1(m_urng, Nvless1);

	//create own local population
	std::vector<decision_vector> my_pop(NP, decision_vector(Nv));

	//check if some individuals in the population that is passed as a function input are feasible.
	bool feasible;
	std::vector<int> not_feasible;
	for (size_t i = 0; i < NP; i++) {
		feasible = prob->feasibility_x(pop.get_individual(i).cur_x);
		if(feasible) { //if feasible store it in my_pop
			switch(prob->get_encoding()) {
				case problem::base_tsp::FULL:
					my_pop[i] = prob->full2cities(pop.get_individual(i).cur_x);
					break;
				case problem::base_tsp::RANDOMKEYS:
					my_pop[i] = prob->randomkeys2cities(pop.get_individual(i).cur_x);
					break;
				case problem::base_tsp::CITIES:
					my_pop[i] = pop.get_individual(i).cur_x;
					break;
			}
		} else {
			not_feasible.push_back(i);
		}
	}

	//replace the not feasible individuals by feasible ones
	int i;
	switch (m_ini_type) {
		case 0:
		{
		//random initialization (produces feasible individuals)
			for (size_t ii = 0; ii < not_feasible.size(); ii++) {
				i = not_feasible[ii];
				for (size_t j = 0; j < Nv; j++) {
					my_pop[i][j] = j;
				}
			}
			int tmp;
			size_t rnd_idx;
			for (size_t j = 1; j < Nv-1; j++) {
					boost::uniform_int<int> dist_(j, Nv - 1);
					boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > dist(m_urng,dist_);
					
				for (size_t ii = 0; ii < not_feasible.size(); ii++) {
					i = not_feasible[ii];
					rnd_idx = dist();
					tmp = my_pop[i][j];
					my_pop[i][j] = my_pop[i][rnd_idx];
					my_pop[i][rnd_idx] = tmp;
				}

			}
			break;
		}
		case 1:
		{
		//initialize with nearest neighbor algorithm
		std::vector<int> starting_notes(std::max(Nv,not_feasible.size()));
			for (size_t j = 0; j < starting_notes.size(); j++) {
					starting_notes[j] = j;
			}
			//std::shuffle(starting_notes.begin(), starting_notes.end(), m_urng);
			for (size_t ii = 0; ii < not_feasible.size(); ii++) {
				i = not_feasible[ii];
				pagmo::population one_ind_pop(pop.problem(), 1);
				std::cout << starting_notes[i] << ' ';
				pagmo::algorithm::nn_tsp algo(starting_notes[i] % Nv);
				algo.evolve(one_ind_pop);
				switch( prob->get_encoding() ) {
					case problem::base_tsp::FULL:
						my_pop[i] = prob->full2cities(one_ind_pop.get_individual(0).cur_x);
						break;
					case problem::base_tsp::RANDOMKEYS:
						my_pop[i] = prob->randomkeys2cities(one_ind_pop.get_individual(0).cur_x);
						break;
					case problem::base_tsp::CITIES:
						my_pop[i] = one_ind_pop.get_individual(0).cur_x;
						break;
				}
				std::cout << i << ' ' << one_ind_pop.get_individual(0).cur_f << std::endl;
			}
			break;
		}
		default:
			pagmo_throw(value_error,"Invalid initialization type");
	}

	std::vector<fitness_vector>  fitness(NP, fitness_vector(1));
	for(size_t i=0; i < NP; i++){
		switch( prob->get_encoding() ) {
			case problem::base_tsp::FULL:
				fitness[i] = prob->objfun(prob->full2cities(my_pop[i]));
				break;
			case problem::base_tsp::RANDOMKEYS:
				fitness[i] = prob->objfun(prob->cities2randomkeys(my_pop[i], pop.get_individual(i).cur_x));
				break;
			case problem::base_tsp::CITIES:
				fitness[i] = prob->objfun(my_pop[i]);
				break;
		}
	}


	decision_vector tmp_tour(Nv);
	bool stop, changed;
	size_t rnd_num, i2, pos1_c1, pos1_c2, pos2_c1, pos2_c2; //pos2_c1 denotes the position of city1 in parent2
	fitness_vector fitness_tmp;

	//InverOver main loop
	for(int iter = 0; iter < m_gen; iter++) {
		for(size_t i1 = 0; i1 < NP; i1++) {
			tmp_tour = my_pop[i1];
			pos1_c1 = unif_Nv();
			stop = false;
			changed = false;
			while(!stop){
				if(unif_01() < m_ri) {
					rnd_num = unif_Nvless1();
					pos1_c2 = (rnd_num == pos1_c1? Nv-1:rnd_num);
				} else {
					i2 = unif_NPless1();
					i2 = (i2 == i1? NP-1:i2);
					pos2_c1 = std::find(my_pop[i2].begin(),my_pop[i2].end(),tmp_tour[pos1_c1])-my_pop[i2].begin();
					pos2_c2 = (pos2_c1 == Nv-1? 0:pos2_c1+1);
					pos1_c2 = std::find(tmp_tour.begin(),tmp_tour.end(),my_pop[i2][pos2_c2])-tmp_tour.begin();
				}
				stop = (abs(pos1_c1-pos1_c2)==1 || static_cast<problem::base::size_type>(abs(pos1_c1-pos1_c2))==Nv-1);
				if(!stop) {
					changed = true;
					if(pos1_c1<pos1_c2) {
						for(size_t l=0; l < (double (pos1_c2-pos1_c1-1)/2); l++) {
							std::swap(tmp_tour[pos1_c1+1+l],tmp_tour[pos1_c2-l]);
						}
						pos1_c1 = pos1_c2;
					} else {
						//inverts the section from c1 to c2 (see documentation Note3)
						for(size_t l=0; l < (double (pos1_c1-pos1_c2-1)/2); l++) {
							std::swap(tmp_tour[pos1_c2+l],tmp_tour[pos1_c1-l-1]);
						}
						pos1_c1 = (pos1_c2 == 0? Nv-1:pos1_c2-1);
					}
					
				}
			} //end of while loop (looping over a single indvidual)
			if(changed) {
				switch(prob->get_encoding()) {
					case problem::base_tsp::FULL:
						fitness_tmp = prob->objfun(prob->full2cities(tmp_tour));
						break;
					case problem::base_tsp::RANDOMKEYS: //using "randomly" index 0 as a temporary template
						fitness_tmp = prob->objfun(prob->cities2randomkeys(tmp_tour, pop.get_individual(0).cur_x));
						break;
					case problem::base_tsp::CITIES:
						fitness_tmp = prob->objfun(tmp_tour);
						break;
				}
				if(prob->compare_fitness(fitness_tmp,fitness[i1])) { //replace individual?
					my_pop[i1] = tmp_tour;
					fitness[i1][0] = fitness_tmp[0];
				}
			}
		} // end of loop over population
	} // end of loop over generations

	//change representation of tour
	for (size_t ii = 0; ii < NP; ii++) {
		switch(prob->get_encoding()) {
			case problem::base_tsp::FULL:
				pop.set_x(ii,prob->cities2full(my_pop[ii]));
				break;
			case problem::base_tsp::RANDOMKEYS:
				pop.set_x(ii,prob->cities2randomkeys(my_pop[ii],pop.get_individual(ii).cur_x));
				break;
			case problem::base_tsp::CITIES:
				pop.set_x(ii,my_pop[ii]);
				break;
		}
	}
} // end of evolve
예제 #27
0
// Selection implementation.
std::vector<std::pair<population::size_type,std::vector<population::individual_type>::size_type> >
worst_r_policy::select(const std::vector<population::individual_type> &immigrants, const population &dest) const
{
    const population::size_type rate_limit = std::min<population::size_type>(get_n_individuals(dest),boost::numeric_cast<population::size_type>(immigrants.size()));
    // Temporary vectors to store sorted indices of the populations.
    std::vector<population::size_type> immigrants_idx(boost::numeric_cast<std::vector<population::size_type>::size_type>(immigrants.size()));
    std::vector<population::size_type> dest_idx(boost::numeric_cast<std::vector<population::size_type>::size_type>(dest.size()));
    // Fill in the arrays of indices.
    iota(immigrants_idx.begin(),immigrants_idx.end(),population::size_type(0));
    iota(dest_idx.begin(),dest_idx.end(),population::size_type(0));
    // Sort the arrays of indices.
    // From best to worst.
    std::sort(immigrants_idx.begin(),immigrants_idx.end(),indirect_individual_sorter<std::vector<population::individual_type> >(immigrants,dest));
    // From worst to best.
    std::sort(dest_idx.begin(),dest_idx.end(),indirect_individual_sorter<population>(dest,dest));
    std::reverse(dest_idx.begin(),dest_idx.end());
    // Create the result.
    std::vector<std::pair<population::size_type,std::vector<population::individual_type>::size_type> > result;
    for (population::size_type i = 0; i < rate_limit; ++i) {
        // Similar to fair policy, but replace unconditionally, without checking if the incoming individuals are better.
        result.push_back(std::make_pair(dest_idx[i],immigrants_idx[i]));
    }
    return result;
}
예제 #28
0
파일: problem.cpp 프로젝트: pthomalla/evo
void evaluate_population(population& p)
{
  for(unsigned int i=0; i<p.size(); i++)
    p[i].eval = evaluation(p[i].perm);
}
예제 #29
0
// Selection implementation.
std::vector<std::pair<population::size_type,std::vector<population::individual_type>::size_type> >
hv_fair_r_policy::select(const std::vector<population::individual_type> &immigrants, const population &dest) const
{
    // Fall back to fair_r_policy when facing a single-objective problem.
    if (dest.problem().get_f_dimension() == 1) {
        return fair_r_policy(m_rate, m_type).select(immigrants, dest);
    }

    std::vector<population::individual_type> filtered_immigrants;
    filtered_immigrants.reserve(immigrants.size());

    // Keeps information on the original indexing of immigrants after we filter out the duplicates
    std::vector<unsigned int> original_immigrant_indices;
    original_immigrant_indices.reserve(immigrants.size());

    // Remove the duplicates from the set of immigrants
    std::vector<population::individual_type>::iterator im_it = (const_cast<std::vector<population::individual_type> &>(immigrants)).begin();
    unsigned int im_idx = 0;
    for( ; im_it != immigrants.end() ; ++im_it) {
        decision_vector im_x((*im_it).cur_x);

        bool equal = true;
        for ( unsigned int idx = 0 ; idx < dest.size() ; ++idx ) {
            decision_vector isl_x(dest.get_individual(idx).cur_x);
            equal = true;
            for (unsigned int d_idx = 0 ; d_idx < im_x.size() ; ++d_idx) {
                if (im_x[d_idx] != isl_x[d_idx]) {
                    equal = false;
                    break;
                }
            }
            if (equal) {
                break;
            }
        }
        if (!equal) {
            filtered_immigrants.push_back(*im_it);
            original_immigrant_indices.push_back(im_idx);
        }
        ++im_idx;
    }

    // Computes the number of immigrants to be selected (accounting for the destination pop size)
    const population::size_type rate_limit = std::min<population::size_type>(get_n_individuals(dest), boost::numeric_cast<population::size_type>(filtered_immigrants.size()));

    // Defines the retvalue
    std::vector<std::pair<population::size_type, std::vector<population::individual_type>::size_type> > result;

    // Skip the remaining computation if there's nothing to do
    if (rate_limit == 0) {
        return result;
    }

    // Makes a copy of the destination population
    population pop_copy(dest);

    // Merge the immigrants to the copy of the destination population
    for (population::size_type i  = 0; i < rate_limit; ++i) {
        pop_copy.push_back(filtered_immigrants[i].cur_x);
    }

    // Population fronts stored as indices of individuals.
    std::vector< std::vector<population::size_type> > fronts_i = pop_copy.compute_pareto_fronts();

    // Population fronts stored as fitness vectors of individuals.
    std::vector< std::vector<fitness_vector> > fronts_f (fronts_i.size());

    // Nadir point is established manually later, first point is a first "safe" candidate.
    fitness_vector refpoint(pop_copy.get_individual(0).cur_f);

    // Fill fronts_f with fitness vectors and establish the nadir point
    for (unsigned int f_idx = 0 ; f_idx < fronts_i.size() ; ++f_idx) {
        fronts_f[f_idx].resize(fronts_i[f_idx].size());
        for (unsigned int p_idx = 0 ; p_idx < fronts_i[f_idx].size() ; ++p_idx) {
            fronts_f[f_idx][p_idx] = fitness_vector(pop_copy.get_individual(fronts_i[f_idx][p_idx]).cur_f);

            // Update the nadir point manually for efficiency.
            for (unsigned int d_idx = 0 ; d_idx < fronts_f[f_idx][p_idx].size() ; ++d_idx) {
                refpoint[d_idx] = std::max(refpoint[d_idx], fronts_f[f_idx][p_idx][d_idx]);
            }
        }
    }

    // Epsilon is added to nadir point
    for (unsigned int d_idx = 0 ; d_idx < refpoint.size() ; ++d_idx) {
        refpoint[d_idx] += m_nadir_eps;
    }

    // Vector for maintaining the original indices of points for augmented population as 0 and 1
    std::vector<unsigned int> g_orig_indices(pop_copy.size(), 1);

    unsigned int no_discarded_immigrants = 0;

    // Store which front we process (start with the last front) and the number of processed individuals.
    unsigned int front_idx = fronts_i.size(); // front_idx is equal to the size, since it's decremented right in the main loop
    unsigned int processed_individuals = 0;

    // Pairs of (islander index, islander exclusive hypervolume)
    // Second item is updated later
    std::vector<std::pair<unsigned int, double> > discarded_islanders;

    std::vector<std::pair<unsigned int, double> > point_pairs;
    // index of currently processed point in the point_pair vector.
    // Initiated to its size (=0) in order to enforce the initial computation on penultimate front.
    unsigned int current_point = point_pairs.size();

    // Stops when we reduce the augmented population to the size of the original population or when the number of discarded islanders reaches the limit
    while (processed_individuals < filtered_immigrants.size() && discarded_islanders.size() < rate_limit) {

        // if current front was exhausted, load next one
        if (current_point == point_pairs.size()) {
            --front_idx;

            // Compute contributions
            std::vector<double> c;

            // If there exist a dominated front for front at index front_idx
            if (front_idx + 1 < fronts_f.size()) {
                std::vector<fitness_vector> merged_front;
                // Reserve the memory and copy the fronts
                merged_front.reserve(fronts_f[front_idx].size() + fronts_f[front_idx + 1].size());

                copy(fronts_f[front_idx].begin(), fronts_f[front_idx].end(), back_inserter(merged_front));
                copy(fronts_f[front_idx + 1].begin(), fronts_f[front_idx +1].end(), back_inserter(merged_front));

                hypervolume hv(merged_front, false);
                c = hv.contributions(refpoint);
            } else {
                hypervolume hv(fronts_f[front_idx], false);
                c = hv.contributions(refpoint);
            }

            // Initiate the pairs and sort by second item (exclusive volume)
            point_pairs.resize(fronts_f[front_idx].size());
            for(unsigned int i = 0 ; i < fronts_f[front_idx].size() ; ++i) {
                point_pairs[i] = std::make_pair(i, c[i]);
            }
            current_point = 0;
            std::sort(point_pairs.begin(), point_pairs.end(), sort_point_pairs_asc);
        }

        unsigned int orig_lc_idx = fronts_i[front_idx][point_pairs[current_point].first];

        if (orig_lc_idx < dest.size()) {
            discarded_islanders.push_back(std::make_pair(orig_lc_idx, 0.0));
        } else {
            ++no_discarded_immigrants;
        }

        // Flag given individual as discarded
        g_orig_indices[orig_lc_idx] = 0;

        ++processed_individuals;
        ++current_point;
    }

    // Number of non-discarded immigrants
    unsigned int no_available_immigrants = boost::numeric_cast<unsigned int>(filtered_immigrants.size() - no_discarded_immigrants);

    // Pairs of (immigrant index, immigrant exclusive hypervolume)
    // Second item is updated later
    std::vector<std::pair<unsigned int, double> > available_immigrants;
    available_immigrants.reserve(no_available_immigrants);
    for(unsigned int idx = dest.size() ; idx < pop_copy.size() ; ++idx) {
        // If the immigrant was not discarded add it to the available set
        if ( g_orig_indices[idx] == 1 ) {
            available_immigrants.push_back(std::make_pair(idx, 0.0));
        }
    }

    // Aggregate all points to establish the hypervolume contribution of available immigrants and discarded islanders
    std::vector<fitness_vector> merged_fronts;
    merged_fronts.reserve(pop_copy.size());

    for(unsigned int idx = 0 ; idx < pop_copy.size() ; ++idx) {
        merged_fronts.push_back(pop_copy.get_individual(idx).cur_f);
    }

    hypervolume hv(merged_fronts, false);
    std::vector<std::pair<unsigned int, double> >::iterator it;

    for(it = available_immigrants.begin() ; it != available_immigrants.end() ; ++it) {
        (*it).second = hv.exclusive((*it).first, refpoint);
    }

    for(it = discarded_islanders.begin() ; it != discarded_islanders.end() ; ++it) {
        (*it).second = hv.exclusive((*it).first, refpoint);
    }

    // Sort islanders and immigrants according to exclusive hypervolume
    sort(available_immigrants.begin(), available_immigrants.end(), hv_fair_r_policy::ind_cmp);
    sort(discarded_islanders.begin(), discarded_islanders.end(), hv_fair_r_policy::ind_cmp);

    // Number of exchanges is the minimum of the number of non discarded immigrants and the number of discarded islanders
    unsigned int no_exchanges = std::min(boost::numeric_cast<unsigned int>(available_immigrants.size()), boost::numeric_cast<unsigned int>(discarded_islanders.size()));

    it = available_immigrants.begin();
    std::vector<std::pair<unsigned int, double> >::reverse_iterator r_it = discarded_islanders.rbegin();

    // Match the best immigrant (forward iterator) with the worst islander (reverse iterator) no_exchanges times.
    for(unsigned int i = 0 ; i < no_exchanges ; ++i) {
        // Break if any islander is better than an immigrant
        if ((*r_it).second > (*it).second) {
            break;
        }
        // Push the pair (islander_idx, fixed_immigrant_idx) to the results
        result.push_back(std::make_pair((*r_it).first, original_immigrant_indices[(*it).first - dest.size()]));
        ++r_it;
        ++it;
    }

    return result;
}
예제 #30
0
// Evolve method.
void base_nlopt::evolve(population &pop) const
{
	// Useful variables.
	const problem::base &problem = pop.problem();
	if (problem.get_f_dimension() != 1) {
		pagmo_throw(value_error,"this algorithm does not support multi-objective optimisation");
	}
	const problem::base::c_size_type c_size = problem.get_c_dimension();
	const problem::base::c_size_type ec_size = problem.get_c_dimension() - problem.get_ic_dimension();
	if (c_size && !m_constrained) {
		pagmo_throw(value_error,"this algorithm does not support constraints");
	}
	if (ec_size && m_only_ineq) {
		pagmo_throw(value_error,"this algorithm does not support equality constraints");
	}
	const problem::base::size_type cont_size = problem.get_dimension() - problem.get_i_dimension();
	if (!cont_size) {
		pagmo_throw(value_error,"the problem has no continuous part");
	}
	// Do nothing if the population is empty.
	if (!pop.size()) {
		return;
	}
	// Extract the best individual and set the inital point
	const population::size_type best_ind_idx = pop.get_best_idx();
	const population::individual_type &best_ind = pop.get_individual(best_ind_idx);

	
	// Structure to pass data to the objective function wrapper.
	nlopt_wrapper_data data_objfun;

	data_objfun.prob = &problem;
	data_objfun.x.resize(problem.get_dimension());
	data_objfun.dx.resize(problem.get_dimension());
	data_objfun.f.resize(1);
	
	// Structure to pass data to the constraint function wrapper.
	std::vector<nlopt_wrapper_data> data_constrfun(boost::numeric_cast<std::vector<nlopt_wrapper_data>::size_type>(c_size));
	for (problem::base::c_size_type i = 0; i < c_size; ++i) {
		data_constrfun[i].prob = &problem;
		data_constrfun[i].x.resize(problem.get_dimension());
		data_constrfun[i].dx.resize(problem.get_dimension());
		data_constrfun[i].c.resize(problem.get_c_dimension());
		data_constrfun[i].c_comp = i;
	}

	// Main NLopt call.
	nlopt::opt opt(m_algo, problem.get_dimension());
	m_opt = opt;
	// Sets local optimizer for aug_lag methods, do nothing otherwise
	set_local(problem.get_dimension());
	m_opt.set_lower_bounds(problem.get_lb());
	m_opt.set_upper_bounds(problem.get_ub());
	m_opt.set_min_objective(objfun_wrapper, &data_objfun);
	for (problem::base::c_size_type i =0; i<ec_size; ++i) {
		m_opt.add_equality_constraint(constraints_wrapper, &data_constrfun[i], problem.get_c_tol().at(i));
	}
	for (problem::base::c_size_type i =ec_size; i<c_size; ++i) {
		m_opt.add_inequality_constraint(constraints_wrapper, &data_constrfun[i], problem.get_c_tol().at(i));
	}

	m_opt.set_ftol_abs(m_ftol);
	m_opt.set_xtol_abs(m_xtol);
	m_opt.set_maxeval(m_max_iter);

	//nlopt::result result;
	double dummy;
	decision_vector x0(best_ind.cur_x);
	m_opt.optimize(x0, dummy);
	pop.set_x(best_ind_idx,x0);
}