예제 #1
0
파일: erdos_renyi.cpp 프로젝트: YS-L/pagmo
void erdos_renyi::connect(const vertices_size_type &n)
{
	for (std::pair<v_iterator,v_iterator> vertices = get_vertices(); vertices.first != vertices.second; ++vertices.first) {
		// Connect n bidirectionally to the other nodes with probability m_prob. Also, avoid to connect n with itself.
		if (*vertices.first != n && m_drng() < m_prob) {
			add_edge(n,*vertices.first);
			add_edge(*vertices.first,n);
		}
	}
}
예제 #2
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);
	}
}
예제 #3
0
파일: clustered_ba.cpp 프로젝트: YS-L/pagmo
void clustered_ba::connect(const vertices_size_type &idx)
{
	pagmo_assert(get_number_of_vertices() > 0);
	const vertices_size_type prev_size = get_number_of_vertices() - 1;
	if (prev_size < m_m0) {
		// If we had not built the initial m0 nodes, do it.
		// We want to connect the newcomer island with high probability, and make sure that
		// at least one connection exists (otherwise the island stays isolated).
		// NOTE: is it worth to make it a user-tunable parameter?
                const double prob = 0.0;
		// Flag indicating if at least 1 connection was added.
		bool connection_added = false;
		// Main loop.
		for (std::pair<v_iterator,v_iterator> vertices = get_vertices(); vertices.first != vertices.second; ++vertices.first) {
			// Do not consider the new vertex itself.
			if (*vertices.first != idx) {
				if (m_drng() < prob) {
					connection_added = true;
					// Add the connections
					add_edge(*vertices.first,idx);
					add_edge(idx,*vertices.first);
				}
			}
		}
		// If no connections were established and this is not the first island being inserted,
		// establish at least one connection with a random island other than n.
		if ((!connection_added) && (prev_size != 0)) {
			// Get a random vertex index between 0 and n_vertices - 1. Keep on repeating the procedure if by
			// chance we end up on idx again.
			boost::uniform_int<vertices_size_type> uni_int(0,get_number_of_vertices() - 1);
			vertices_size_type rnd;
                        do {
				rnd = uni_int(m_urng);
			} while (rnd == idx);
			// Add connections to the random vertex.
			add_edge(rnd,idx);
			add_edge(idx,rnd);
		}
	} else {
                // Now we need to add j edges, choosing the nodes with a probability
		// proportional to their number of connections. We keep track of the
		// connection established in order to avoid connecting twice to the same
		// node.
                // j is a random integer in the range 1 to m.
                boost::uniform_int<edges_size_type> uni_int2(1,m_m);
		std::size_t i = 0;
                std::size_t j = uni_int2(m_urng);
		std::pair<v_iterator,v_iterator> vertices;
		std::pair<a_iterator,a_iterator> adj_vertices;
                while (i < j) {
                        // Let's find the current total number of edges.
                        const edges_size_type n_edges = get_number_of_edges();
                        pagmo_assert(n_edges > 0);
                        boost::uniform_int<edges_size_type> uni_int(0,n_edges - 1 - i);
                        // Here we choose a random number between 0 and n_edges - 1 - i.
                        const edges_size_type rn = uni_int(m_urng);
                        edges_size_type n = 0;
			// Iterate over all vertices and accumulate the number of edges for each of them. Stop when the accumulated number of edges is greater
			// than rn. This is equivalent to giving a chance of connection to vertex v directly proportional to the number of edges departing from v.
			// You can think of this process as selecting a random edge among all the existing edges and connecting to the vertex from which the
			// selected edge departs.
			vertices = get_vertices();
			for (; vertices.first != vertices.second; ++vertices.first) {
				// Do not consider it_n.
				if (*vertices.first != idx) {
					adj_vertices = get_adjacent_vertices(*vertices.first);
					n += boost::numeric_cast<edges_size_type>(std::distance(adj_vertices.first,adj_vertices.second));
					if (n > rn) {
						break;
					}
				}
			}
			pagmo_assert(vertices.first != vertices.second);
			// If the candidate was not already connected, then add it.
			if (!are_adjacent(idx,*vertices.first)) {
                                // Connect to nodes that are already adjacent to idx with probability p.
                                // This step increases clustering in the network.
                                adj_vertices = get_adjacent_vertices(idx);
                                for(;adj_vertices.first != adj_vertices.second; ++adj_vertices.first) {
                                    if(m_drng() < m_p && *adj_vertices.first != *vertices.first && !are_adjacent(*adj_vertices.first,*vertices.first)) {
                                        add_edge(*adj_vertices.first, *vertices.first);
                                        add_edge(*vertices.first, *adj_vertices.first);
                                    }
                                }
                                // Connect to idx
				add_edge(*vertices.first,idx);
				add_edge(idx,*vertices.first);
				++i;
			}
		}
	}
}
예제 #4
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);
	}
}
예제 #5
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

}