| kpeter@1201 |      1 | /* -*- mode: C++; indent-tabs-mode: nil; -*-
 | 
| kpeter@1201 |      2 |  *
 | 
| kpeter@1201 |      3 |  * This file is a part of LEMON, a generic C++ optimization library.
 | 
| kpeter@1201 |      4 |  *
 | 
| alpar@1270 |      5 |  * Copyright (C) 2003-2013
 | 
| kpeter@1201 |      6 |  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 | 
| kpeter@1201 |      7 |  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 | 
| kpeter@1201 |      8 |  *
 | 
| kpeter@1201 |      9 |  * Permission to use, modify and distribute this software is granted
 | 
| kpeter@1201 |     10 |  * provided that this copyright notice appears in all copies. For
 | 
| kpeter@1201 |     11 |  * precise terms see the accompanying LICENSE file.
 | 
| kpeter@1201 |     12 |  *
 | 
| kpeter@1201 |     13 |  * This software is provided "AS IS" with no warranty of any kind,
 | 
| kpeter@1201 |     14 |  * express or implied, and with no claim as to its suitability for any
 | 
| kpeter@1201 |     15 |  * purpose.
 | 
| kpeter@1201 |     16 |  *
 | 
| kpeter@1201 |     17 |  */
 | 
| kpeter@1201 |     18 | 
 | 
| f4c3@1199 |     19 | #ifndef LEMON_NEAREST_NEIGHBOUR_TSP_H
 | 
| f4c3@1199 |     20 | #define LEMON_NEAREST_NEIGHBOUR_TSP_H
 | 
| f4c3@1199 |     21 | 
 | 
| kpeter@1201 |     22 | /// \ingroup tsp
 | 
| kpeter@1201 |     23 | /// \file
 | 
| kpeter@1201 |     24 | /// \brief Nearest neighbor algorithm for symmetric TSP
 | 
| kpeter@1201 |     25 | 
 | 
| f4c3@1199 |     26 | #include <deque>
 | 
| kpeter@1202 |     27 | #include <vector>
 | 
| kpeter@1201 |     28 | #include <limits>
 | 
| f4c3@1199 |     29 | #include <lemon/full_graph.h>
 | 
| f4c3@1199 |     30 | #include <lemon/maps.h>
 | 
| f4c3@1199 |     31 | 
 | 
| f4c3@1199 |     32 | namespace lemon {
 | 
| f4c3@1199 |     33 | 
 | 
| kpeter@1202 |     34 |   /// \ingroup tsp
 | 
| kpeter@1202 |     35 |   ///
 | 
| kpeter@1201 |     36 |   /// \brief Nearest neighbor algorithm for symmetric TSP.
 | 
| kpeter@1201 |     37 |   ///
 | 
| kpeter@1201 |     38 |   /// NearestNeighborTsp implements the nearest neighbor heuristic for solving
 | 
| kpeter@1201 |     39 |   /// symmetric \ref tsp "TSP".
 | 
| kpeter@1201 |     40 |   ///
 | 
| kpeter@1201 |     41 |   /// This is probably the simplest TSP heuristic.
 | 
| kpeter@1201 |     42 |   /// It starts with a minimum cost edge and at each step, it connects the
 | 
| kpeter@1201 |     43 |   /// nearest unvisited node to the current path.
 | 
| kpeter@1201 |     44 |   /// Finally, it connects the two end points of the path to form a tour.
 | 
| kpeter@1201 |     45 |   ///
 | 
| kpeter@1201 |     46 |   /// This method runs in O(n<sup>2</sup>) time.
 | 
| kpeter@1204 |     47 |   /// It quickly finds a relatively short tour for most TSP instances,
 | 
| kpeter@1204 |     48 |   /// but it could also yield a really bad (or even the worst) solution
 | 
| kpeter@1204 |     49 |   /// in special cases.
 | 
| kpeter@1201 |     50 |   ///
 | 
| kpeter@1201 |     51 |   /// \tparam CM Type of the cost map.
 | 
| f4c3@1199 |     52 |   template <typename CM>
 | 
| kpeter@1201 |     53 |   class NearestNeighborTsp
 | 
| kpeter@1201 |     54 |   {
 | 
| kpeter@1201 |     55 |     public:
 | 
| kpeter@1201 |     56 | 
 | 
| kpeter@1201 |     57 |       /// Type of the cost map
 | 
| kpeter@1201 |     58 |       typedef CM CostMap;
 | 
| kpeter@1201 |     59 |       /// Type of the edge costs
 | 
| kpeter@1201 |     60 |       typedef typename CM::Value Cost;
 | 
| kpeter@1201 |     61 | 
 | 
| f4c3@1199 |     62 |     private:
 | 
| kpeter@1201 |     63 | 
 | 
| f4c3@1199 |     64 |       GRAPH_TYPEDEFS(FullGraph);
 | 
| f4c3@1199 |     65 | 
 | 
| kpeter@1201 |     66 |       const FullGraph &_gr;
 | 
| kpeter@1201 |     67 |       const CostMap &_cost;
 | 
| kpeter@1201 |     68 |       Cost _sum;
 | 
| kpeter@1202 |     69 |       std::vector<Node> _path;
 | 
| kpeter@1201 |     70 | 
 | 
| f4c3@1199 |     71 |     public:
 | 
| f4c3@1199 |     72 | 
 | 
| kpeter@1201 |     73 |       /// \brief Constructor
 | 
| kpeter@1201 |     74 |       ///
 | 
| kpeter@1201 |     75 |       /// Constructor.
 | 
| kpeter@1201 |     76 |       /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
 | 
| kpeter@1201 |     77 |       /// \param cost The cost map.
 | 
| kpeter@1201 |     78 |       NearestNeighborTsp(const FullGraph &gr, const CostMap &cost)
 | 
| kpeter@1201 |     79 |         : _gr(gr), _cost(cost) {}
 | 
| kpeter@1201 |     80 | 
 | 
| kpeter@1201 |     81 |       /// \name Execution Control
 | 
| kpeter@1201 |     82 |       /// @{
 | 
| kpeter@1201 |     83 | 
 | 
| kpeter@1201 |     84 |       /// \brief Runs the algorithm.
 | 
| kpeter@1201 |     85 |       ///
 | 
| kpeter@1201 |     86 |       /// This function runs the algorithm.
 | 
| kpeter@1201 |     87 |       ///
 | 
| kpeter@1201 |     88 |       /// \return The total cost of the found tour.
 | 
| f4c3@1199 |     89 |       Cost run() {
 | 
| f4c3@1199 |     90 |         _path.clear();
 | 
| kpeter@1202 |     91 |         if (_gr.nodeNum() == 0) {
 | 
| kpeter@1202 |     92 |           return _sum = 0;
 | 
| kpeter@1202 |     93 |         }
 | 
| kpeter@1201 |     94 |         else if (_gr.nodeNum() == 1) {
 | 
| kpeter@1201 |     95 |           _path.push_back(_gr(0));
 | 
| kpeter@1201 |     96 |           return _sum = 0;
 | 
| kpeter@1201 |     97 |         }
 | 
| kpeter@1201 |     98 | 
 | 
| kpeter@1202 |     99 |         std::deque<Node> path_dq;
 | 
| f4c3@1199 |    100 |         Edge min_edge1 = INVALID,
 | 
| f4c3@1199 |    101 |              min_edge2 = INVALID;
 | 
| kpeter@1201 |    102 | 
 | 
| f4c3@1199 |    103 |         min_edge1 = mapMin(_gr, _cost);
 | 
| kpeter@1201 |    104 |         Node n1 = _gr.u(min_edge1),
 | 
| f4c3@1199 |    105 |              n2 = _gr.v(min_edge1);
 | 
| kpeter@1202 |    106 |         path_dq.push_back(n1);
 | 
| kpeter@1202 |    107 |         path_dq.push_back(n2);
 | 
| f4c3@1199 |    108 | 
 | 
| kpeter@1201 |    109 |         FullGraph::NodeMap<bool> used(_gr, false);
 | 
| f4c3@1199 |    110 |         used[n1] = true;
 | 
| f4c3@1199 |    111 |         used[n2] = true;
 | 
| f4c3@1199 |    112 | 
 | 
| f4c3@1199 |    113 |         min_edge1 = INVALID;
 | 
| kpeter@1202 |    114 |         while (int(path_dq.size()) != _gr.nodeNum()) {
 | 
| f4c3@1199 |    115 |           if (min_edge1 == INVALID) {
 | 
| kpeter@1201 |    116 |             for (IncEdgeIt e(_gr, n1); e != INVALID; ++e) {
 | 
| kpeter@1201 |    117 |               if (!used[_gr.runningNode(e)] &&
 | 
| alpar@1294 |    118 |                   (min_edge1 == INVALID || _cost[e] < _cost[min_edge1])) {
 | 
| kpeter@1201 |    119 |                 min_edge1 = e;
 | 
| f4c3@1199 |    120 |               }
 | 
| f4c3@1199 |    121 |             }
 | 
| f4c3@1199 |    122 |           }
 | 
| f4c3@1199 |    123 | 
 | 
| f4c3@1199 |    124 |           if (min_edge2 == INVALID) {
 | 
| kpeter@1201 |    125 |             for (IncEdgeIt e(_gr, n2); e != INVALID; ++e) {
 | 
| kpeter@1201 |    126 |               if (!used[_gr.runningNode(e)] &&
 | 
| alpar@1294 |    127 |                   (min_edge2 == INVALID||_cost[e] < _cost[min_edge2])) {
 | 
| kpeter@1201 |    128 |                 min_edge2 = e;
 | 
| f4c3@1199 |    129 |               }
 | 
| f4c3@1199 |    130 |             }
 | 
| f4c3@1199 |    131 |           }
 | 
| f4c3@1199 |    132 | 
 | 
| kpeter@1201 |    133 |           if (_cost[min_edge1] < _cost[min_edge2]) {
 | 
| kpeter@1201 |    134 |             n1 = _gr.oppositeNode(n1, min_edge1);
 | 
| kpeter@1202 |    135 |             path_dq.push_front(n1);
 | 
| f4c3@1199 |    136 | 
 | 
| f4c3@1199 |    137 |             used[n1] = true;
 | 
| f4c3@1199 |    138 |             min_edge1 = INVALID;
 | 
| f4c3@1199 |    139 | 
 | 
| kpeter@1201 |    140 |             if (_gr.u(min_edge2) == n1 || _gr.v(min_edge2) == n1)
 | 
| f4c3@1199 |    141 |               min_edge2 = INVALID;
 | 
| f4c3@1199 |    142 |           } else {
 | 
| kpeter@1201 |    143 |             n2 = _gr.oppositeNode(n2, min_edge2);
 | 
| kpeter@1202 |    144 |             path_dq.push_back(n2);
 | 
| f4c3@1199 |    145 | 
 | 
| f4c3@1199 |    146 |             used[n2] = true;
 | 
| f4c3@1199 |    147 |             min_edge2 = INVALID;
 | 
| f4c3@1199 |    148 | 
 | 
| kpeter@1201 |    149 |             if (_gr.u(min_edge1) == n2 || _gr.v(min_edge1) == n2)
 | 
| f4c3@1199 |    150 |               min_edge1 = INVALID;
 | 
| f4c3@1199 |    151 |           }
 | 
| f4c3@1199 |    152 |         }
 | 
| f4c3@1199 |    153 | 
 | 
| kpeter@1202 |    154 |         n1 = path_dq.back();
 | 
| kpeter@1202 |    155 |         n2 = path_dq.front();
 | 
| kpeter@1202 |    156 |         _path.push_back(n2);
 | 
| kpeter@1202 |    157 |         _sum = _cost[_gr.edge(n1, n2)];
 | 
| kpeter@1202 |    158 |         for (int i = 1; i < int(path_dq.size()); ++i) {
 | 
| kpeter@1202 |    159 |           n1 = n2;
 | 
| kpeter@1202 |    160 |           n2 = path_dq[i];
 | 
| kpeter@1202 |    161 |           _path.push_back(n2);
 | 
| kpeter@1202 |    162 |           _sum += _cost[_gr.edge(n1, n2)];
 | 
| kpeter@1201 |    163 |         }
 | 
| f4c3@1199 |    164 | 
 | 
| f4c3@1199 |    165 |         return _sum;
 | 
| f4c3@1199 |    166 |       }
 | 
| f4c3@1199 |    167 | 
 | 
| kpeter@1201 |    168 |       /// @}
 | 
| kpeter@1201 |    169 | 
 | 
| kpeter@1201 |    170 |       /// \name Query Functions
 | 
| kpeter@1201 |    171 |       /// @{
 | 
| kpeter@1201 |    172 | 
 | 
| kpeter@1201 |    173 |       /// \brief The total cost of the found tour.
 | 
| kpeter@1201 |    174 |       ///
 | 
| kpeter@1201 |    175 |       /// This function returns the total cost of the found tour.
 | 
| kpeter@1201 |    176 |       ///
 | 
| kpeter@1201 |    177 |       /// \pre run() must be called before using this function.
 | 
| kpeter@1201 |    178 |       Cost tourCost() const {
 | 
| kpeter@1201 |    179 |         return _sum;
 | 
| f4c3@1199 |    180 |       }
 | 
| f4c3@1199 |    181 | 
 | 
| kpeter@1201 |    182 |       /// \brief Returns a const reference to the node sequence of the
 | 
| kpeter@1201 |    183 |       /// found tour.
 | 
| kpeter@1201 |    184 |       ///
 | 
| kpeter@1202 |    185 |       /// This function returns a const reference to a vector
 | 
| kpeter@1201 |    186 |       /// that stores the node sequence of the found tour.
 | 
| kpeter@1201 |    187 |       ///
 | 
| kpeter@1201 |    188 |       /// \pre run() must be called before using this function.
 | 
| kpeter@1202 |    189 |       const std::vector<Node>& tourNodes() const {
 | 
| f4c3@1199 |    190 |         return _path;
 | 
| f4c3@1199 |    191 |       }
 | 
| kpeter@1201 |    192 | 
 | 
| kpeter@1201 |    193 |       /// \brief Gives back the node sequence of the found tour.
 | 
| kpeter@1201 |    194 |       ///
 | 
| kpeter@1201 |    195 |       /// This function copies the node sequence of the found tour into
 | 
| kpeter@1205 |    196 |       /// an STL container through the given output iterator. The
 | 
| kpeter@1205 |    197 |       /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
 | 
| kpeter@1205 |    198 |       /// For example,
 | 
| kpeter@1205 |    199 |       /// \code
 | 
| kpeter@1205 |    200 |       /// std::vector<FullGraph::Node> nodes(countNodes(graph));
 | 
| kpeter@1205 |    201 |       /// tsp.tourNodes(nodes.begin());
 | 
| kpeter@1205 |    202 |       /// \endcode
 | 
| kpeter@1205 |    203 |       /// or
 | 
| kpeter@1205 |    204 |       /// \code
 | 
| kpeter@1205 |    205 |       /// std::list<FullGraph::Node> nodes;
 | 
| kpeter@1205 |    206 |       /// tsp.tourNodes(std::back_inserter(nodes));
 | 
| kpeter@1205 |    207 |       /// \endcode
 | 
| kpeter@1201 |    208 |       ///
 | 
| kpeter@1201 |    209 |       /// \pre run() must be called before using this function.
 | 
| kpeter@1205 |    210 |       template <typename Iterator>
 | 
| kpeter@1205 |    211 |       void tourNodes(Iterator out) const {
 | 
| kpeter@1205 |    212 |         std::copy(_path.begin(), _path.end(), out);
 | 
| kpeter@1201 |    213 |       }
 | 
| kpeter@1201 |    214 | 
 | 
| kpeter@1201 |    215 |       /// \brief Gives back the found tour as a path.
 | 
| kpeter@1201 |    216 |       ///
 | 
| kpeter@1201 |    217 |       /// This function copies the found tour as a list of arcs/edges into
 | 
| alpar@1250 |    218 |       /// the given \ref lemon::concepts::Path "path structure".
 | 
| kpeter@1201 |    219 |       ///
 | 
| kpeter@1201 |    220 |       /// \pre run() must be called before using this function.
 | 
| kpeter@1201 |    221 |       template <typename Path>
 | 
| kpeter@1201 |    222 |       void tour(Path &path) const {
 | 
| kpeter@1201 |    223 |         path.clear();
 | 
| kpeter@1201 |    224 |         for (int i = 0; i < int(_path.size()) - 1; ++i) {
 | 
| kpeter@1201 |    225 |           path.addBack(_gr.arc(_path[i], _path[i+1]));
 | 
| f4c3@1199 |    226 |         }
 | 
| kpeter@1201 |    227 |         if (int(_path.size()) >= 2) {
 | 
| kpeter@1201 |    228 |           path.addBack(_gr.arc(_path.back(), _path.front()));
 | 
| kpeter@1201 |    229 |         }
 | 
| f4c3@1199 |    230 |       }
 | 
| f4c3@1199 |    231 | 
 | 
| kpeter@1201 |    232 |       /// @}
 | 
| kpeter@1201 |    233 | 
 | 
| f4c3@1199 |    234 |   };
 | 
| f4c3@1199 |    235 | 
 | 
| f4c3@1199 |    236 | }; // namespace lemon
 | 
| f4c3@1199 |    237 | 
 | 
| f4c3@1199 |    238 | #endif
 |