1 #ifndef LEMON_INSERTION_TSP_H
2 #define LEMON_INSERTION_TSP_H
4 #include <lemon/full_graph.h>
5 #include <lemon/path.h>
6 #include <lemon/maps.h>
7 #include <lemon/random.h>
12 namespace insertion_tsp_helper {
15 L vectorConvert(const std::vector<FullGraph::Node> &_path) {
16 return L(_path.begin(), _path.end());
20 std::vector<FullGraph::Node> vectorConvert(
21 const std::vector<FullGraph::Node> &_path) {
27 template <typename CM>
30 GRAPH_TYPEDEFS(FullGraph);
34 typedef typename CM::Value Cost;
36 InsertionTsp(const FullGraph &gr, const CostMap &cost) :
37 _gr(gr), _cost(cost) {}
39 enum InsertionMethod {
46 Cost run(InsertionMethod method = INSERT_FARTHEST) {
49 start<InitTour<true>, NearestSelection, DefaultInsert>();
52 start<InitTour<false>, FarthestSelection, DefaultInsert>();
55 start<InitTour<true>, CheapestSelection, CheapestInsert>();
58 start<InitTour<true>, RandomSelection, DefaultInsert>();
65 void tourNodes(L &container) {
66 container(insertion_tsp_helper::vectorConvert<L>(nodesPath));
69 template <template <typename> class L>
71 return insertion_tsp_helper::vectorConvert<L<Node> >(nodesPath);
74 const std::vector<Node>& tourNodes() {
78 Path<FullGraph> tour() {
80 if (nodesPath.size()<2)
83 for (unsigned int i=0; i<nodesPath.size()-1; ++i)
84 p.addBack(_gr.arc(nodesPath[i], nodesPath[i+1]));
86 p.addBack(_gr.arc(nodesPath.back(), nodesPath.front()));
100 InitTour(const FullGraph &gr, const CostMap &cost,
101 std::vector<Node> &used, std::vector<Node> ¬used,
103 _gr(gr), _cost(cost), _used(used), _notused(notused),
104 _fullcost(fullcost) {}
106 std::vector<Node> init() const {
107 Edge min = (MIN) ? mapMin(_gr, _cost) : mapMax(_gr, _cost);
108 std::vector<Node> path;
109 path.push_back(_gr.u(min));
110 path.push_back(_gr.v(min));
114 for (NodeIt n(_gr); n!=INVALID; ++n) {
115 if (n != _gr.u(min) && n != _gr.v(min)) {
116 _notused.push_back(n);
119 _used.push_back(_gr.u(min));
120 _used.push_back(_gr.v(min));
122 _fullcost = _cost[min]*2;
127 const FullGraph &_gr;
128 const CostMap &_cost;
129 std::vector<Node> &_used;
130 std::vector<Node> &_notused;
134 class NearestSelection {
136 NearestSelection(const FullGraph &gr, const CostMap &cost,
137 std::vector<Node> &used, std::vector<Node> ¬used) :
138 _gr(gr), _cost(cost), _used(used), _notused(notused) {}
140 Node select() const {
143 std::numeric_limits<Cost>::max();
144 int insert_node = -1;
146 for (unsigned int i=0; i<_notused.size(); ++i) {
147 Cost min_val = _cost[_gr.edge(_notused[i], _used[0])];
150 for (unsigned int j=1; j<_used.size(); ++j) {
151 if (min_val > _cost[_gr.edge(_notused[i], _used[j])]) {
152 min_val = _cost[_gr.edge(_notused[i], _used[j])];
157 if (insert_val > min_val) {
158 insert_val = min_val;
163 Node n = _notused[insert_node];
164 _notused.erase(_notused.begin()+insert_node);
170 const FullGraph &_gr;
171 const CostMap &_cost;
172 std::vector<Node> &_used;
173 std::vector<Node> &_notused;
176 class FarthestSelection {
178 FarthestSelection(const FullGraph &gr, const CostMap &cost,
179 std::vector<Node> &used, std::vector<Node> ¬used) :
180 _gr(gr), _cost(cost), _used(used), _notused(notused) {}
182 Node select() const {
185 std::numeric_limits<Cost>::min();
186 int insert_node = -1;
188 for (unsigned int i=0; i<_notused.size(); ++i) {
189 Cost min_val = _cost[_gr.edge(_notused[i], _used[0])];
192 for (unsigned int j=1; j<_used.size(); ++j) {
193 if (min_val > _cost[_gr.edge(_notused[i], _used[j])]) {
194 min_val = _cost[_gr.edge(_notused[i], _used[j])];
199 if (insert_val < min_val || insert_node == -1) {
200 insert_val = min_val;
205 Node n = _notused[insert_node];
206 _notused.erase(_notused.begin()+insert_node);
212 const FullGraph &_gr;
213 const CostMap &_cost;
214 std::vector<Node> &_used;
215 std::vector<Node> &_notused;
219 class CheapestSelection {
221 Cost costDiff(Node u, Node v, Node w) const {
223 _cost[_gr.edge(u, w)] +
224 _cost[_gr.edge(v, w)] -
225 _cost[_gr.edge(u, v)];
229 CheapestSelection(const FullGraph &gr, const CostMap &cost,
230 std::vector<Node> &used, std::vector<Node> ¬used) :
231 _gr(gr), _cost(cost), _used(used), _notused(notused) {}
233 Cost select() const {
234 int insert_notused = -1;
235 int best_insert_index = -1;
237 std::numeric_limits<Cost>::max();
239 for (unsigned int i=0; i<_notused.size(); ++i) {
241 int best_insert_tmp = 0;
243 costDiff(_used.front(), _used.back(), _notused[i]);
245 for (unsigned int j=1; j<_used.size(); ++j) {
247 costDiff(_used[j-1], _used[j], _notused[i]);
256 if (insert_val > min_val) {
257 insert_notused = min;
258 insert_val = min_val;
259 best_insert_index = best_insert_tmp;
263 _used.insert(_used.begin()+best_insert_index, _notused[insert_notused]);
264 _notused.erase(_notused.begin()+insert_notused);
270 const FullGraph &_gr;
271 const CostMap &_cost;
272 std::vector<Node> &_used;
273 std::vector<Node> &_notused;
276 class RandomSelection {
278 RandomSelection(const FullGraph &, const CostMap &,
279 std::vector<Node> &, std::vector<Node> ¬used) :
284 Node select() const {
285 const int index = rnd[_notused.size()];
286 Node n = _notused[index];
287 _notused.erase(_notused.begin()+index);
291 std::vector<Node> &_notused;
295 class DefaultInsert {
297 Cost costDiff(Node u, Node v, Node w) const {
299 _cost[_gr.edge(u, w)] +
300 _cost[_gr.edge(v, w)] -
301 _cost[_gr.edge(u, v)];
305 DefaultInsert(const FullGraph &gr, const CostMap &cost,
306 std::vector<Node> &path, Cost &fullcost) :
307 _gr(gr), _cost(cost), _path(path), _fullcost(fullcost) {}
309 void insert(Node n) const {
312 costDiff(_path.front(), _path.back(), n);
314 for (unsigned int i=1; i<_path.size(); ++i) {
315 Cost tmp = costDiff(_path[i-1], _path[i], n);
322 _path.insert(_path.begin()+min, n);
323 _fullcost += min_val;
327 const FullGraph &_gr;
328 const CostMap &_cost;
329 std::vector<Node> &_path;
333 class CheapestInsert {
334 TEMPLATE_GRAPH_TYPEDEFS(FullGraph);
336 CheapestInsert(const FullGraph &, const CostMap &,
337 std::vector<Node> &, Cost &fullcost) :
338 _fullcost(fullcost) {}
340 void insert(Cost diff) const {
349 template <class InitFunctor, class SelectionFunctor, class InsertFunctor>
351 InitFunctor init(_gr, _cost, nodesPath, notused, sum);
352 SelectionFunctor selectNode(_gr, _cost, nodesPath, notused);
353 InsertFunctor insertNode(_gr, _cost, nodesPath, sum);
355 nodesPath = init.init();
357 for (int i=0; i<_gr.nodeNum()-2; ++i) {
358 insertNode.insert(selectNode.select());
361 sum = _cost[ _gr.edge(nodesPath.front(), nodesPath.back()) ];
362 for (unsigned int i=0; i<nodesPath.size()-1; ++i)
363 sum += _cost[ _gr.edge(nodesPath[i], nodesPath[i+1]) ];
366 const FullGraph &_gr;
367 const CostMap &_cost;
368 std::vector<Node> notused;
369 std::vector<Node> nodesPath;
373 }; // namespace lemon