f4c3@1031
|
1 |
#ifndef LEMON_GREEDY_TSP_H
|
f4c3@1031
|
2 |
#define LEMON_GREEDY_TSP_H
|
f4c3@1031
|
3 |
|
f4c3@1031
|
4 |
#include <lemon/path.h>
|
f4c3@1031
|
5 |
#include <lemon/full_graph.h>
|
f4c3@1031
|
6 |
#include <lemon/unionfind.h>
|
f4c3@1031
|
7 |
#include <algorithm>
|
f4c3@1031
|
8 |
|
f4c3@1031
|
9 |
namespace lemon {
|
f4c3@1031
|
10 |
|
f4c3@1031
|
11 |
namespace greedy_tsp_helper {
|
f4c3@1031
|
12 |
|
f4c3@1031
|
13 |
template <typename CostMap>
|
f4c3@1031
|
14 |
class KeyComp {
|
f4c3@1031
|
15 |
typedef typename CostMap::Key Key;
|
f4c3@1031
|
16 |
const CostMap &cost;
|
f4c3@1031
|
17 |
|
f4c3@1031
|
18 |
public:
|
f4c3@1031
|
19 |
KeyComp(const CostMap &_cost) : cost(_cost) {}
|
f4c3@1031
|
20 |
|
f4c3@1031
|
21 |
bool operator() (const Key &a, const Key &b) const {
|
f4c3@1031
|
22 |
return cost[a] < cost[b];
|
f4c3@1031
|
23 |
}
|
f4c3@1031
|
24 |
};
|
f4c3@1031
|
25 |
|
f4c3@1031
|
26 |
|
f4c3@1031
|
27 |
template <class L>
|
f4c3@1031
|
28 |
L vectorConvert(const std::vector<FullGraph::Node> &_path) {
|
f4c3@1031
|
29 |
return L(_path.begin(), _path.end());
|
f4c3@1031
|
30 |
}
|
f4c3@1031
|
31 |
|
f4c3@1031
|
32 |
template <>
|
f4c3@1031
|
33 |
std::vector<FullGraph::Node> vectorConvert(const std::vector<FullGraph::Node> &_path) {
|
f4c3@1031
|
34 |
return _path;
|
f4c3@1031
|
35 |
}
|
f4c3@1031
|
36 |
|
f4c3@1031
|
37 |
}
|
f4c3@1031
|
38 |
|
f4c3@1031
|
39 |
|
f4c3@1031
|
40 |
template <typename CM>
|
f4c3@1031
|
41 |
class GreedyTsp {
|
f4c3@1031
|
42 |
private:
|
f4c3@1031
|
43 |
GRAPH_TYPEDEFS(FullGraph);
|
f4c3@1031
|
44 |
|
f4c3@1031
|
45 |
public:
|
f4c3@1031
|
46 |
typedef CM CostMap;
|
f4c3@1031
|
47 |
typedef typename CM::Value Cost;
|
f4c3@1031
|
48 |
|
f4c3@1031
|
49 |
GreedyTsp(const FullGraph &gr, const CostMap &cost) : _gr(gr), _cost(cost) {}
|
f4c3@1031
|
50 |
|
f4c3@1031
|
51 |
Cost run() {
|
f4c3@1031
|
52 |
typedef UnionFind<FullGraph::NodeMap<int> > Union;
|
f4c3@1031
|
53 |
_nodes.clear();
|
f4c3@1031
|
54 |
|
f4c3@1031
|
55 |
std::vector<int> path;
|
f4c3@1031
|
56 |
path.resize(_gr.nodeNum()*2, -1);
|
f4c3@1031
|
57 |
|
f4c3@1031
|
58 |
std::vector<typename CostMap::Key> sorted_edges;
|
f4c3@1031
|
59 |
sorted_edges.reserve(_gr.edgeNum());
|
f4c3@1031
|
60 |
for (EdgeIt n(_gr); n != INVALID; ++n)
|
f4c3@1031
|
61 |
sorted_edges.push_back(n);
|
f4c3@1031
|
62 |
|
f4c3@1031
|
63 |
std::sort(sorted_edges.begin(), sorted_edges.end(), greedy_tsp_helper::KeyComp<CostMap>(_cost));
|
f4c3@1031
|
64 |
|
f4c3@1031
|
65 |
FullGraph::NodeMap<int> nodemap(_gr);
|
f4c3@1031
|
66 |
Union unionfind(nodemap);
|
f4c3@1031
|
67 |
|
f4c3@1031
|
68 |
for (NodeIt n(_gr); n != INVALID; ++n)
|
f4c3@1031
|
69 |
unionfind.insert(n);
|
f4c3@1031
|
70 |
|
f4c3@1031
|
71 |
FullGraph::NodeMap<int> degree(_gr, 0);
|
f4c3@1031
|
72 |
|
f4c3@1031
|
73 |
int nodesNum = 0, i = 0;
|
f4c3@1031
|
74 |
|
f4c3@1031
|
75 |
while ( nodesNum != _gr.nodeNum()-1 ) {
|
f4c3@1031
|
76 |
const Edge &e = sorted_edges[i];
|
f4c3@1031
|
77 |
|
f4c3@1031
|
78 |
const Node u = _gr.u(e),
|
f4c3@1031
|
79 |
v = _gr.v(e);
|
f4c3@1031
|
80 |
|
f4c3@1031
|
81 |
if (degree[u]<=1 && degree[v]<=1) {
|
f4c3@1031
|
82 |
if (unionfind.join(u, v)) {
|
f4c3@1031
|
83 |
++degree[u];
|
f4c3@1031
|
84 |
++degree[v];
|
f4c3@1031
|
85 |
++nodesNum;
|
f4c3@1031
|
86 |
|
f4c3@1031
|
87 |
const int uid = _gr.id(u),
|
f4c3@1031
|
88 |
vid = _gr.id(v);
|
f4c3@1031
|
89 |
|
f4c3@1031
|
90 |
|
f4c3@1031
|
91 |
path[uid*2 + (path[uid*2]==-1 ? 0 : 1)] = vid;
|
f4c3@1031
|
92 |
path[vid*2 + (path[vid*2]==-1 ? 0 : 1)] = uid;
|
f4c3@1031
|
93 |
}
|
f4c3@1031
|
94 |
}
|
f4c3@1031
|
95 |
|
f4c3@1031
|
96 |
++i;
|
f4c3@1031
|
97 |
}
|
f4c3@1031
|
98 |
|
f4c3@1031
|
99 |
|
f4c3@1031
|
100 |
for (int i=0, n=-1; i<_gr.nodeNum()*2; ++i) {
|
f4c3@1031
|
101 |
if (path[i] == -1) {
|
f4c3@1031
|
102 |
if (n==-1) {
|
f4c3@1031
|
103 |
n = i;
|
f4c3@1031
|
104 |
} else {
|
f4c3@1031
|
105 |
path[n] = i/2;
|
f4c3@1031
|
106 |
path[i] = n/2;
|
f4c3@1031
|
107 |
break;
|
f4c3@1031
|
108 |
}
|
f4c3@1031
|
109 |
}
|
f4c3@1031
|
110 |
}
|
f4c3@1031
|
111 |
|
f4c3@1031
|
112 |
|
f4c3@1031
|
113 |
for (int i=0, j=0, last=-1; i!=_gr.nodeNum(); ++i) {
|
f4c3@1031
|
114 |
_nodes.push_back(_gr.nodeFromId(j));
|
f4c3@1031
|
115 |
|
f4c3@1031
|
116 |
if (path[2*j] != last) {
|
f4c3@1031
|
117 |
last = j;
|
f4c3@1031
|
118 |
j = path[2*j];
|
f4c3@1031
|
119 |
} else {
|
f4c3@1031
|
120 |
last = j;
|
f4c3@1031
|
121 |
j = path[2*j+1];
|
f4c3@1031
|
122 |
}
|
f4c3@1031
|
123 |
}
|
f4c3@1031
|
124 |
|
f4c3@1031
|
125 |
_sum = _cost[_gr.edge(_nodes.back(), _nodes.front())];
|
f4c3@1031
|
126 |
for (unsigned int i=0; i<_nodes.size()-1; ++i)
|
f4c3@1031
|
127 |
_sum += _cost[_gr.edge(_nodes[i], _nodes[i+1])];
|
f4c3@1031
|
128 |
|
f4c3@1031
|
129 |
return _sum;
|
f4c3@1031
|
130 |
}
|
f4c3@1031
|
131 |
|
f4c3@1031
|
132 |
|
f4c3@1031
|
133 |
|
f4c3@1031
|
134 |
template <typename L>
|
f4c3@1031
|
135 |
void tourNodes(L &container) {
|
f4c3@1031
|
136 |
container(greedy_tsp_helper::vectorConvert<L>(_nodes));
|
f4c3@1031
|
137 |
}
|
f4c3@1031
|
138 |
|
f4c3@1031
|
139 |
template <template <typename> class L>
|
f4c3@1031
|
140 |
L<Node> tourNodes() {
|
f4c3@1031
|
141 |
return greedy_tsp_helper::vectorConvert<L<Node> >(_nodes);
|
f4c3@1031
|
142 |
}
|
f4c3@1031
|
143 |
|
f4c3@1031
|
144 |
const std::vector<Node>& tourNodes() {
|
f4c3@1031
|
145 |
return _nodes;
|
f4c3@1031
|
146 |
}
|
f4c3@1031
|
147 |
|
f4c3@1031
|
148 |
Path<FullGraph> tour() {
|
f4c3@1031
|
149 |
Path<FullGraph> p;
|
f4c3@1031
|
150 |
if (_nodes.size()<2)
|
f4c3@1031
|
151 |
return p;
|
f4c3@1031
|
152 |
|
f4c3@1031
|
153 |
for (unsigned int i=0; i<_nodes.size()-1; ++i) {
|
f4c3@1031
|
154 |
p.addBack(_gr.arc(_nodes[i], _nodes[i+1]));
|
f4c3@1031
|
155 |
}
|
f4c3@1031
|
156 |
|
f4c3@1031
|
157 |
p.addBack(_gr.arc(_nodes.back(), _nodes.front()));
|
f4c3@1031
|
158 |
|
f4c3@1031
|
159 |
return p;
|
f4c3@1031
|
160 |
}
|
f4c3@1031
|
161 |
|
f4c3@1031
|
162 |
Cost tourCost() {
|
f4c3@1031
|
163 |
return _sum;
|
f4c3@1031
|
164 |
}
|
f4c3@1031
|
165 |
|
f4c3@1031
|
166 |
|
f4c3@1031
|
167 |
private:
|
f4c3@1031
|
168 |
const FullGraph &_gr;
|
f4c3@1031
|
169 |
const CostMap &_cost;
|
f4c3@1031
|
170 |
Cost _sum;
|
f4c3@1031
|
171 |
std::vector<Node> _nodes;
|
f4c3@1031
|
172 |
};
|
f4c3@1031
|
173 |
|
f4c3@1031
|
174 |
}; // namespace lemon
|
f4c3@1031
|
175 |
|
f4c3@1031
|
176 |
#endif
|