Пример #1
0
void get_tiles_radius(gamemap const &map, std::vector<map_location> const &locs,
                      size_t radius, std::set<map_location> &res, xy_pred *pred)
{
	typedef std::set<map_location> location_set;
	location_set not_visited(locs.begin(), locs.end()), must_visit, filtered_out;
	++radius;

	for(;;) {
		location_set::const_iterator it = not_visited.begin(), it_end = not_visited.end();
		std::copy(it,it_end,std::inserter(res,res.end()));
		for(; it != it_end; ++it) {
			map_location adj[6];
			get_adjacent_tiles(*it, adj);
			for(size_t i = 0; i != 6; ++i) {
				map_location const &loc = adj[i];
				if(map.on_board(loc) && !res.count(loc) && !filtered_out.count(loc)) {
					if(!pred || (*pred)(loc)) {
						must_visit.insert(loc);
					} else {
						filtered_out.insert(loc);
					}
				}
			}
		}

		if(--radius == 0 || must_visit.empty()) {
			break;
		}

		not_visited.swap(must_visit);
		must_visit.clear();
	}
}
Пример #2
0
/**
 * Function that will add to @a result all elements of @a locs, plus all
 * on-board locations matching @a pred that are connected to elements of
 * locs by a chain of at most @a radius tiles, each of which matches @a pred.
 * @a result must be a std::set of locations.
 */
void get_tiles_radius(gamemap const &map, std::vector<map_location> const &locs,
                      size_t radius, std::set<map_location> &result,
                      bool with_border, xy_pred const &pred)
{
	typedef std::set<map_location> location_set;

	location_set must_visit, filtered_out;
	location_set not_visited(locs.begin(), locs.end());

	for ( ; radius != 0  &&  !not_visited.empty(); --radius )
	{
		location_set::const_iterator it = not_visited.begin();
		location_set::const_iterator it_end = not_visited.end();

		result.insert(it, it_end);
		for(; it != it_end; ++it) {
			map_location adj[6];
			get_adjacent_tiles(*it, adj);
			for(size_t i = 0; i != 6; ++i) {
				map_location const &loc = adj[i];
				if ( with_border ? map.on_board_with_border(loc) :
				                   map.on_board(loc) ) {
					if ( !result.count(loc) && !filtered_out.count(loc) ) {
						if ( pred(loc) )
							must_visit.insert(loc);
						else
							filtered_out.insert(loc);
					}
				}
			}
		}

		not_visited.swap(must_visit);
		must_visit.clear();
	}

	result.insert(not_visited.begin(), not_visited.end());
}
Пример #3
0
/**
 * Runs the NN_TSP algorithm.
 *
 * @param[in,out] pop input/output pagmo::population to be evolved.
 */
void nn_tsp::evolve(population &pop) const
{
	const problem::base_tsp* prob;
	//check if problem is of type pagmo::problem::base_tsp
	try
	{
	    prob = &dynamic_cast<const problem::base_tsp &>(pop.problem());
	}
	catch (const std::bad_cast& e)
	{
		pagmo_throw(value_error,"Problem not of type pagmo::problem::tsp, nn_tsp can only be called on problem::tsp problems");
	}

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

	//create individuals
	decision_vector best_tour(Nv);
	decision_vector new_tour(Nv);

	//check input parameter
	if (m_start_city < -1 || m_start_city > static_cast<int>(Nv-1)) {
		pagmo_throw(value_error,"invalid value for the first vertex");
	}


	size_t first_city, Nt;
	if(m_start_city == -1){
		first_city = 0;  
	  		Nt = Nv;
	}
	else{
		first_city = m_start_city; 
		Nt = m_start_city+1;
	}

	int length_best_tour, length_new_tour;
	size_t nxt_city, min_idx;
	std::vector<int> not_visited(Nv);
	length_best_tour = 0;

	//main loop
	for (size_t i = first_city; i < Nt; i++) {
		length_new_tour = 0;
		for (size_t j = 0; j < Nv; j++) {
			not_visited[j] = j;
		}
		new_tour[0] = i;
		std::swap(not_visited[new_tour[0]],not_visited[Nv-1]);
		for (size_t j = 1; j < Nv-1; j++) {
			min_idx = 0;
			nxt_city = not_visited[0];
			for (size_t l = 1; l < Nv-j; l++) {
				if(prob->distance(new_tour[j-1], not_visited[l]) < prob->distance(new_tour[j-1], nxt_city) )
			{
					min_idx = l;		
					nxt_city = not_visited[l];}
			}
			new_tour[j] = nxt_city;
			length_new_tour += prob->distance(new_tour[j-1], nxt_city);
			std::swap(not_visited[min_idx],not_visited[Nv-j-1]);
		}
		new_tour[Nv-1] = not_visited[0];
		length_new_tour += prob->distance(new_tour[Nv-2], new_tour[Nv-1]);
		length_new_tour += prob->distance(new_tour[Nv-1], new_tour[0]);
		if(i == first_city || length_new_tour < length_best_tour){
			best_tour = new_tour;
			length_best_tour = length_new_tour;
		}
	}
		
	//change representation of tour
	population::size_type best_idx = pop.get_best_idx();
	switch( prob->get_encoding() ) {
	    case problem::base_tsp::FULL:
	        pop.set_x(best_idx,prob->cities2full(best_tour));
	        break;
	    case problem::base_tsp::RANDOMKEYS:
	        pop.set_x(best_idx,prob->cities2randomkeys(best_tour,pop.get_individual(best_idx).cur_x));
	        break;
	    case problem::base_tsp::CITIES:
	        pop.set_x(best_idx,best_tour);
	        break;
	}

} // end of evolve
Пример #4
0
__kernel                                            
void findRoute(__global double *graph,
			__global double* next_moves,                        
			__global double *output,
			__global int* constK,
			__global double* messages,
			__global double* rands
			)                        
{ 	
	int k = constK[0];
	//next_moves has size k*2*k
	// graph has size edges*4
	// output has size k*k
	int num_edges = k*(k-1)/2;
	double alpha = 2.0;
	double beta = 2.0;             
	int idx = get_global_id(0);
	int idy = get_global_id(1);
	int current_position = idx;
	add_to_array(output, k, current_position, idx, messages);
	bool possible_to_move = true;
	int count = 0;
	
	while(possible_to_move){
		possible_to_move = false;
		double sum = 0.0;
		for (int i = 0; i < num_edges; i++){
			int edge_start = i*4;
			int possible_goal;
			bool fits = false;
			
			if (graph[edge_start]==current_position){
				possible_goal = edge_start+1;
				fits = true;
			} else if(graph[edge_start+1]==current_position) {
				possible_goal = edge_start;
				fits = true;
			}
			if (fits && not_visited(output, graph, possible_goal, k, idx)){
				possible_to_move = true;
				double cost = graph[edge_start + 2];
				double pheromones = graph[edge_start + 3];
				double thao = pow(pheromones, alpha);
				double attr = pow(cost, -beta);
				double nomin = thao * attr;
				sum = sum + nomin;
				add_nominative(next_moves, nomin, edge_start, k, idx, messages);
			}
			
		}
		if (possible_to_move){
			for (int i = idx*k*2; i < idx*k*2+k*2; i=i+2){
				next_moves[i] = next_moves[i] / sum;
			}
			double random = get_random(rands, k, idx, count);
			int edge_choice_index = get_next_move(next_moves, random, k, idx);
			// in that edge, one value is our current position and the other value
			// is the next node
			double next_node = -1.0;
			if (current_position == graph[edge_choice_index]){
				// e.g. edge 1-2 and we are in 1. Put 2 in output and into current pos
				next_node = graph[edge_choice_index + 1];
			} else {
				// e.g. edge 2-1 and we are in 1. Put 2 in output and into current pos
				next_node = graph[edge_choice_index];
			}
			add_to_array(output, k, next_node, idx, messages);
			current_position = next_node;
		} else {
			return;
		}
		clear_next_moves(next_moves, k, idx);
		count = count + 1;
	}
	
} 
Пример #5
0
    /**
     * 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::tsp* prob;
	//check if problem is of type pagmo::problem::tsp
	try
	{
		const problem::tsp& tsp_prob = dynamic_cast<const problem::tsp &>(pop.problem());
		prob = &tsp_prob;
	}
	catch (const std::bad_cast& e)
	{
		pagmo_throw(value_error,"Problem not of type pagmo::problem::tsp");
	}
	
	// Let's store some useful variables.

	const population::size_type NP = pop.size();
	const std::vector<std::vector<double> >& weights = prob->get_weights();
	const problem::base::size_type Nv = prob->get_n_cities();

	// Get out if there is nothing to do.
	if (m_gen == 0) {
		return;
	}
	
	// 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);


	//check if we have a symmetric problem (symmetric weight matrix)
	bool is_sym = true;
	for(size_t i = 0; i < Nv; i++)
	{
		for(size_t j = i+1; j < Nv; j++)
		{
			if(weights[i][j] != weights[j][i])
			{
				is_sym = false;
				goto end_loop;
			}
		}
	}
	end_loop:	
	
	//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::tsp::FULL:
			        my_pop[i] = prob->full2cities(pop.get_individual(i).cur_x);
			        break;
			    case problem::tsp::RANDOMKEYS:
			        my_pop[i] = prob->randomkeys2cities(pop.get_individual(i).cur_x);
			        break;
			    case problem::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
			int nxt_city;
			size_t min_idx;
			std::vector<int> not_visited(Nv);
			for (size_t ii = 0; ii < not_feasible.size(); ii++) {
				i = not_feasible[ii];
				for (size_t j = 0; j < Nv; j++) {
					not_visited[j] = j;
				}
				my_pop[i][0] = unif_Nv();
				std::swap(not_visited[my_pop[i][0]],not_visited[Nv-1]);
				for (size_t j = 1; j < Nv-1; j++) {
					min_idx = 0;
					nxt_city = not_visited[0];
					for (size_t l = 1; l < Nv-j; l++) {
						if(weights[my_pop[i][j-1]][not_visited[l]] < weights[my_pop[i][j-1]][nxt_city]){
							min_idx = l;		
							nxt_city = not_visited[l];}
					}
					my_pop[i][j] = nxt_city;
					std::swap(not_visited[min_idx],not_visited[Nv-j-1]);
				}
				my_pop[i][Nv-1] = not_visited[0];
			}
			break;
		}
		default:
			pagmo_throw(value_error,"Invalid initialization type");
	}

	//compute fitness of individuals (necessary if weight matrix is not symmetric)
	std::vector<double>  fitness(NP, 0);
	if(!is_sym){
		for(size_t i=0; i < NP; i++){
    			fitness[i] = weights[my_pop[i][Nv-1]][my_pop[i][0]];
    			for(size_t k=1; k < Nv; k++){
        			fitness[i] += weights[my_pop[i][k-1]][my_pop[i][k]];
			}
		}
	}	
	
	decision_vector tmp_tour(Nv);
	bool stop;
	size_t rnd_num, i2, pos1_c1, pos1_c2, pos2_c1, pos2_c2; //pos2_c1 denotes the position of city1 in parent2
	double fitness_change, fitness_tmp = 0;

	//InverOver main loop
	for(int iter = 0; iter < m_gen; iter++){
		for(size_t i1 = 0; i1 < NP; i1++){
			fitness_change = 0;
			tmp_tour = my_pop[i1];
			pos1_c1 = unif_Nv();
			stop = 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 || abs(pos1_c1-pos1_c2)==Nv-1);
				if(!stop){
					
					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]);}
						if(is_sym){
							fitness_change -= weights[tmp_tour[pos1_c1]][tmp_tour[pos1_c2]] + weights[tmp_tour[pos1_c1+1]][tmp_tour[pos1_c2+1 - (pos1_c2+1 > Nv-1? Nv:0)]];
							fitness_change += weights[tmp_tour[pos1_c1]][tmp_tour[pos1_c1+1]] + weights[tmp_tour[pos1_c2]][tmp_tour[pos1_c2+1 - (pos1_c2+1 > Nv-1? Nv:0)]];
						}
					}
					else{
						//inverts the section from c1 to c2 (see documentation Note3)
						
						for(size_t l=0; l < (double (Nv-(pos1_c1-pos1_c2)-1)/2); l++){
							std::swap(tmp_tour[pos1_c1+1+l - (pos1_c1+1+l>Nv-1? Nv:0)],tmp_tour[pos1_c2-l + (pos1_c2<l? Nv:0)]);}
						if(is_sym){
							fitness_change -= weights[tmp_tour[pos1_c1]][tmp_tour[pos1_c2]] + weights[tmp_tour[pos1_c1+1 - (pos1_c1+1 > Nv-1? Nv:0)]][tmp_tour[pos1_c2+1]];
							fitness_change += weights[tmp_tour[pos1_c1]][tmp_tour[pos1_c1+1 - (pos1_c1+1 > Nv-1? Nv:0)]] + weights[tmp_tour[pos1_c2]][tmp_tour[pos1_c2+1]];
						}
						
					}
					pos1_c1 = pos1_c2; //better performance than original Inver-Over (shorter tour in less time)
				}
			} //end of while loop (looping over a single indvidual)
			if(!is_sym){ //compute fitness of the temporary tour
    				fitness_tmp = weights[tmp_tour[Nv-1]][tmp_tour[0]];
    				for(size_t k=1; k < Nv; k++){
        				fitness_tmp += weights[tmp_tour[k-1]][tmp_tour[k]];
				}
				fitness_change = fitness_tmp - fitness[i1]; 
			}
	
			if(fitness_change < 0){ //replace individual?
				my_pop[i1] = tmp_tour;
				if(!is_sym){
					fitness[i1] = fitness_tmp;
				}
			}
			
			
		} //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::tsp::FULL:
			        pop.set_x(ii,prob->cities2full(my_pop[ii]));
			        break;
			    case problem::tsp::RANDOMKEYS:
			        pop.set_x(ii,prob->cities2randomkeys(my_pop[ii],pop.get_individual(ii).cur_x));
			        break;
			    case problem::tsp::CITIES:
			        pop.set_x(ii,my_pop[ii]);
			        break;
			}
		}

    } // end of evolve