#ifndef LEMON_NEAREST_NEIGHBOUR_TSP_H #define LEMON_NEAREST_NEIGHBOUR_TSP_H #include #include #include #include namespace lemon { namespace nn_helper { template L dequeConvert(const std::deque &_path) { return L(_path.begin(), _path.end()); } template <> std::deque dequeConvert(const std::deque &_path) { return _path; } } template class NearestNeighborTsp { private: GRAPH_TYPEDEFS(FullGraph); public: typedef CM CostMap; typedef typename CM::Value Cost; NearestNeighborTsp(const FullGraph &gr, const CostMap &cost) : _gr(gr), _cost(cost) {} Cost run() { _path.clear(); Edge min_edge1 = INVALID, min_edge2 = INVALID; min_edge1 = mapMin(_gr, _cost); FullGraph::NodeMap used(_gr, false); Node n1 = _gr.u(min_edge1), n2 = _gr.v(min_edge1); _path.push_back(n1); _path.push_back(n2); used[n1] = true; used[n2] = true; min_edge1 = INVALID; while (int(_path.size()) != _gr.nodeNum()) { if (min_edge1 == INVALID) { for (IncEdgeIt e(_gr, n1); e!=INVALID; ++e) { if (!used[_gr.runningNode(e)]) { if (min_edge1==INVALID || _cost[min_edge1] > _cost[e]) min_edge1 = e; } } } if (min_edge2 == INVALID) { for (IncEdgeIt e(_gr, n2); e!=INVALID; ++e) { if (!used[_gr.runningNode(e)]) { if (min_edge2==INVALID || _cost[min_edge2] > _cost[e]) min_edge2 = e; } } } if ( _cost[min_edge1] < _cost[min_edge2] ) { n1 = (_gr.u(min_edge1) == n1) ? _gr.v(min_edge1) : _gr.u(min_edge1); _path.push_front(n1); used[n1] = true; min_edge1 = INVALID; if (_gr.u(min_edge2)==n1 || _gr.v(min_edge2)==n1) min_edge2 = INVALID; } else { n2 = (_gr.u(min_edge2) == n2) ? _gr.v(min_edge2) : _gr.u(min_edge2); _path.push_back(n2); used[n2] = true; min_edge2 = INVALID; if (_gr.u(min_edge1)==n2 || _gr.v(min_edge1)==n2) min_edge1 = INVALID; } } _sum = _cost[ _gr.edge(_path.back(), _path.front()) ]; for (unsigned int i=0; i<_path.size()-1; ++i) _sum += _cost[ _gr.edge(_path[i], _path[i+1]) ]; return _sum; } template void tourNodes(L &container) { container(nn_helper::dequeConvert(_path)); } template