diff -r 4980b05606bd -r ae0b056593a7 lemon/greedy_tsp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/greedy_tsp.h Sat Jan 08 21:59:56 2011 +0100 @@ -0,0 +1,176 @@ +#ifndef LEMON_GREEDY_TSP_H +#define LEMON_GREEDY_TSP_H + +#include +#include +#include +#include + +namespace lemon { + + namespace greedy_tsp_helper { + + template + class KeyComp { + typedef typename CostMap::Key Key; + const CostMap &cost; + + public: + KeyComp(const CostMap &_cost) : cost(_cost) {} + + bool operator() (const Key &a, const Key &b) const { + return cost[a] < cost[b]; + } + }; + + + template + L vectorConvert(const std::vector &_path) { + return L(_path.begin(), _path.end()); + } + + template <> + std::vector vectorConvert(const std::vector &_path) { + return _path; + } + + } + + + template + class GreedyTsp { + private: + GRAPH_TYPEDEFS(FullGraph); + + public: + typedef CM CostMap; + typedef typename CM::Value Cost; + + GreedyTsp(const FullGraph &gr, const CostMap &cost) : _gr(gr), _cost(cost) {} + + Cost run() { + typedef UnionFind > Union; + _nodes.clear(); + + std::vector path; + path.resize(_gr.nodeNum()*2, -1); + + std::vector sorted_edges; + sorted_edges.reserve(_gr.edgeNum()); + for (EdgeIt n(_gr); n != INVALID; ++n) + sorted_edges.push_back(n); + + std::sort(sorted_edges.begin(), sorted_edges.end(), greedy_tsp_helper::KeyComp(_cost)); + + FullGraph::NodeMap nodemap(_gr); + Union unionfind(nodemap); + + for (NodeIt n(_gr); n != INVALID; ++n) + unionfind.insert(n); + + FullGraph::NodeMap degree(_gr, 0); + + int nodesNum = 0, i = 0; + + while ( nodesNum != _gr.nodeNum()-1 ) { + const Edge &e = sorted_edges[i]; + + const Node u = _gr.u(e), + v = _gr.v(e); + + if (degree[u]<=1 && degree[v]<=1) { + if (unionfind.join(u, v)) { + ++degree[u]; + ++degree[v]; + ++nodesNum; + + const int uid = _gr.id(u), + vid = _gr.id(v); + + + path[uid*2 + (path[uid*2]==-1 ? 0 : 1)] = vid; + path[vid*2 + (path[vid*2]==-1 ? 0 : 1)] = uid; + } + } + + ++i; + } + + + for (int i=0, n=-1; i<_gr.nodeNum()*2; ++i) { + if (path[i] == -1) { + if (n==-1) { + n = i; + } else { + path[n] = i/2; + path[i] = n/2; + break; + } + } + } + + + for (int i=0, j=0, last=-1; i!=_gr.nodeNum(); ++i) { + _nodes.push_back(_gr.nodeFromId(j)); + + if (path[2*j] != last) { + last = j; + j = path[2*j]; + } else { + last = j; + j = path[2*j+1]; + } + } + + _sum = _cost[_gr.edge(_nodes.back(), _nodes.front())]; + for (unsigned int i=0; i<_nodes.size()-1; ++i) + _sum += _cost[_gr.edge(_nodes[i], _nodes[i+1])]; + + return _sum; + } + + + + template + void tourNodes(L &container) { + container(greedy_tsp_helper::vectorConvert(_nodes)); + } + + template