1 #ifndef LEMON_GREEDY_TSP_H
2 #define LEMON_GREEDY_TSP_H
4 #include <lemon/path.h>
5 #include <lemon/full_graph.h>
6 #include <lemon/unionfind.h>
11 namespace greedy_tsp_helper {
13 template <typename CostMap>
15 typedef typename CostMap::Key Key;
19 KeyComp(const CostMap &_cost) : cost(_cost) {}
21 bool operator() (const Key &a, const Key &b) const {
22 return cost[a] < cost[b];
28 L vectorConvert(const std::vector<FullGraph::Node> &_path) {
29 return L(_path.begin(), _path.end());
33 std::vector<FullGraph::Node> vectorConvert(const std::vector<FullGraph::Node> &_path) {
40 template <typename CM>
43 GRAPH_TYPEDEFS(FullGraph);
47 typedef typename CM::Value Cost;
49 GreedyTsp(const FullGraph &gr, const CostMap &cost) : _gr(gr), _cost(cost) {}
52 typedef UnionFind<FullGraph::NodeMap<int> > Union;
55 std::vector<int> path;
56 path.resize(_gr.nodeNum()*2, -1);
58 std::vector<typename CostMap::Key> sorted_edges;
59 sorted_edges.reserve(_gr.edgeNum());
60 for (EdgeIt n(_gr); n != INVALID; ++n)
61 sorted_edges.push_back(n);
63 std::sort(sorted_edges.begin(), sorted_edges.end(), greedy_tsp_helper::KeyComp<CostMap>(_cost));
65 FullGraph::NodeMap<int> nodemap(_gr);
66 Union unionfind(nodemap);
68 for (NodeIt n(_gr); n != INVALID; ++n)
71 FullGraph::NodeMap<int> degree(_gr, 0);
73 int nodesNum = 0, i = 0;
75 while ( nodesNum != _gr.nodeNum()-1 ) {
76 const Edge &e = sorted_edges[i];
78 const Node u = _gr.u(e),
81 if (degree[u]<=1 && degree[v]<=1) {
82 if (unionfind.join(u, v)) {
87 const int uid = _gr.id(u),
91 path[uid*2 + (path[uid*2]==-1 ? 0 : 1)] = vid;
92 path[vid*2 + (path[vid*2]==-1 ? 0 : 1)] = uid;
100 for (int i=0, n=-1; i<_gr.nodeNum()*2; ++i) {
113 for (int i=0, j=0, last=-1; i!=_gr.nodeNum(); ++i) {
114 _nodes.push_back(_gr.nodeFromId(j));
116 if (path[2*j] != last) {
125 _sum = _cost[_gr.edge(_nodes.back(), _nodes.front())];
126 for (unsigned int i=0; i<_nodes.size()-1; ++i)
127 _sum += _cost[_gr.edge(_nodes[i], _nodes[i+1])];
134 template <typename L>
135 void tourNodes(L &container) {
136 container(greedy_tsp_helper::vectorConvert<L>(_nodes));
139 template <template <typename> class L>
140 L<Node> tourNodes() {
141 return greedy_tsp_helper::vectorConvert<L<Node> >(_nodes);
144 const std::vector<Node>& tourNodes() {
148 Path<FullGraph> tour() {
153 for (unsigned int i=0; i<_nodes.size()-1; ++i) {
154 p.addBack(_gr.arc(_nodes[i], _nodes[i+1]));
157 p.addBack(_gr.arc(_nodes.back(), _nodes.front()));
168 const FullGraph &_gr;
169 const CostMap &_cost;
171 std::vector<Node> _nodes;
174 }; // namespace lemon