PaGMO  1.1.5
nn_tsp.cpp
1 /*****************************************************************************
2  * Copyright (C) 2004-2015 The PaGMO development team, *
3  * Advanced Concepts Team (ACT), European Space Agency (ESA) *
4  * *
5  * https://github.com/esa/pagmo *
6  * *
7  * act@esa.int *
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17  * GNU General Public License for more details. *
18  * *
19  * You should have received a copy of the GNU General Public License *
20  * along with this program; if not, write to the *
21  * Free Software Foundation, Inc., *
22  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23  *****************************************************************************/
24 
25 #include <algorithm>
26 
27 #include "../config.h"
28 #include "../serialization.h"
29 #include "../population.h"
30 #include "../problem/tsp.h"
31 #include "base.h"
32 #include "nn_tsp.h"
33 
34 namespace pagmo { namespace algorithm {
35 
37 
43 nn_tsp::nn_tsp(int start_city) : base(),m_start_city(start_city)
44 {
45 }
46 
47 
50 {
51 return base_ptr(new nn_tsp(*this));
52 }
53 
55 
60 void nn_tsp::evolve(population &pop) const
61 {
62  const problem::base_tsp* prob;
63  //check if problem is of type pagmo::problem::base_tsp
64  try
65  {
66  prob = &dynamic_cast<const problem::base_tsp &>(pop.problem());
67  }
68  catch (const std::bad_cast& e)
69  {
70  pagmo_throw(value_error,"Problem not of type pagmo::problem::tsp, nn_tsp can only be called on problem::tsp problems");
71  }
72 
73  // Let's store some useful variables.
74  const problem::base::size_type Nv = prob->get_n_cities();
75 
76  //create individuals
77  decision_vector best_tour(Nv);
78  decision_vector new_tour(Nv);
79 
80  //check input parameter
81  if (m_start_city < -1 || m_start_city > static_cast<int>(Nv-1)) {
82  pagmo_throw(value_error,"invalid value for the first vertex");
83  }
84 
85 
86  size_t first_city, Nt;
87  if(m_start_city == -1){
88  first_city = 0;
89  Nt = Nv;
90  }
91  else{
92  first_city = m_start_city;
93  Nt = m_start_city+1;
94  }
95 
96  int length_best_tour, length_new_tour;
97  size_t nxt_city, min_idx;
98  std::vector<int> not_visited(Nv);
99  length_best_tour = 0;
100 
101  //main loop
102  for (size_t i = first_city; i < Nt; i++) {
103  length_new_tour = 0;
104  for (size_t j = 0; j < Nv; j++) {
105  not_visited[j] = j;
106  }
107  new_tour[0] = i;
108  std::swap(not_visited[new_tour[0]],not_visited[Nv-1]);
109  for (size_t j = 1; j < Nv-1; j++) {
110  min_idx = 0;
111  nxt_city = not_visited[0];
112  for (size_t l = 1; l < Nv-j; l++) {
113  if(prob->distance(new_tour[j-1], not_visited[l]) < prob->distance(new_tour[j-1], nxt_city) )
114  {
115  min_idx = l;
116  nxt_city = not_visited[l];}
117  }
118  new_tour[j] = nxt_city;
119  length_new_tour += prob->distance(new_tour[j-1], nxt_city);
120  std::swap(not_visited[min_idx],not_visited[Nv-j-1]);
121  }
122  new_tour[Nv-1] = not_visited[0];
123  length_new_tour += prob->distance(new_tour[Nv-2], new_tour[Nv-1]);
124  length_new_tour += prob->distance(new_tour[Nv-1], new_tour[0]);
125  if(i == first_city || length_new_tour < length_best_tour){
126  best_tour = new_tour;
127  length_best_tour = length_new_tour;
128  }
129  }
130 
131  //change representation of tour
132  population::size_type best_idx = pop.get_best_idx();
133  switch( prob->get_encoding() ) {
135  pop.set_x(best_idx,prob->cities2full(best_tour));
136  break;
138  pop.set_x(best_idx,prob->cities2randomkeys(best_tour,pop.get_individual(best_idx).cur_x));
139  break;
141  pop.set_x(best_idx,best_tour);
142  break;
143  }
144 
145 } // end of evolve
146 
147 
148 
150  std::string nn_tsp::get_name() const
151  {
152  return "Nearest neighbour algorithm";
153  }
154 
155 }} //namespaces
156 
157 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::algorithm::nn_tsp)
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
Root PaGMO namespace.
std::vector< double > decision_vector
Decision vector type.
Definition: types.h:40
const individual_type & get_individual(const size_type &) const
Get constant reference to individual at position n.
Definition: population.cpp:277
Base algorithm class.
Population class.
Definition: population.h:70
std::string get_name() const
Algorithm name.
Definition: nn_tsp.cpp:150
As a vector of doubles in [0,1].
Definition: base_tsp.h:69
decision_vector::size_type get_n_cities() const
Getter for m_n_cities.
Definition: base_tsp.cpp:193
pagmo::decision_vector cities2full(const pagmo::decision_vector &) const
From CITIES to FULL encoding.
Definition: base_tsp.cpp:98
Nearest Neighbor Algorithm (NN)
Definition: nn_tsp.h:45
base_ptr clone() const
Clone method.
Definition: nn_tsp.cpp:49
void evolve(population &) const
Evolve implementation.
Definition: nn_tsp.cpp:60
nn_tsp(int start_city=-1)
Constructor.
Definition: nn_tsp.cpp:43
container_type::size_type size_type
Population size type.
Definition: population.h:192
decision_vector cur_x
Current decision vector.
Definition: population.h:83
As a matrix with ones and zeros.
Definition: base_tsp.h:70
Base TSP (Travelling Salesman Problem).
Definition: base_tsp.h:64
As a sequence of cities ids.
Definition: base_tsp.h:71
pagmo::decision_vector cities2randomkeys(const pagmo::decision_vector &, const pagmo::decision_vector &) const
From CITIES to RANDOMKEYS encoding.
Definition: base_tsp.cpp:156
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
Definition: problem/base.h:160
encoding_type get_encoding() const
Getter for m_encoding.
Definition: base_tsp.cpp:184