1 #ifndef LEMON_OPT2_TSP_H
2 #define LEMON_OPT2_TSP_H
5 #include <lemon/full_graph.h>
6 #include <lemon/path.h>
10 namespace opt2_helper {
12 L vectorConvert(const std::vector<FullGraph::Node> &_path) {
13 return L(_path.begin(), _path.end());
17 std::vector<FullGraph::Node> vectorConvert(const std::vector<FullGraph::Node> &_path) {
22 template <typename CM>
25 GRAPH_TYPEDEFS(FullGraph);
29 typedef typename CM::Value Cost;
32 Opt2Tsp(const FullGraph &gr, const CostMap &cost) : _gr(gr), _cost(cost),
33 tmppath(_gr.nodeNum()*2) {
35 for (int i=1; i<_gr.nodeNum()-1; ++i) {
39 tmppath[0] = _gr.nodeNum()-1;
41 tmppath[2*(_gr.nodeNum()-1)] = _gr.nodeNum()-2;
42 tmppath[2*(_gr.nodeNum()-1)+1] = 0;
45 Opt2Tsp(const FullGraph &gr, const CostMap &cost, const std::vector<Node> &path) :
46 _gr(gr), _cost(cost), tmppath(_gr.nodeNum()*2) {
48 for (unsigned int i=1; i<path.size()-1; ++i) {
49 tmppath[2*_gr.id(path[i])] = _gr.id(path[i-1]);
50 tmppath[2*_gr.id(path[i])+1] = _gr.id(path[i+1]);
53 tmppath[2*_gr.id(path[0])] = _gr.id(path.back());
54 tmppath[2*_gr.id(path[0])+1] = _gr.id(path[1]);
55 tmppath[2*_gr.id(path.back())] = _gr.id(path[path.size()-2]);
56 tmppath[2*_gr.id(path.back())+1] = _gr.id(path.front());
60 Cost c(int u, int v) {
61 return _cost[_gr.edge(_gr.nodeFromId(u), _gr.nodeFromId(v))];
66 It(const std::vector<int> &path, int i=0) : tmppath(path), act(i), last(tmppath[2*act]) {}
67 It(const std::vector<int> &path, int i, int l) : tmppath(path), act(i), last(l) {}
69 int next_index() const {
70 return (tmppath[2*act]==last)? 2*act+1 : 2*act;
73 int prev_index() const {
74 return (tmppath[2*act]==last)? 2*act : 2*act+1;
78 return tmppath[next_index()];
82 return tmppath[prev_index()];
92 operator int() const {
97 const std::vector<int> &tmppath;
102 bool check(std::vector<int> &path, It i, It j) {
103 if (c(i, i.next()) + c(j, j.next()) >
104 c(i, j) + c(j.next(), i.next())) {
106 path[ It(path, i.next(), i).prev_index() ] = j.next();
107 path[ It(path, j.next(), j).prev_index() ] = i.next();
109 path[i.next_index()] = j;
110 path[j.next_index()] = i;
122 if (_gr.nodeNum()>3) {
126 It j(tmppath, i, i.prev());
128 for (; j.next()!=0; ++j) {
129 if (check(tmppath, i, j))
133 for (++i; i.next()!=0; ++i) {
134 It j(tmppath, i, i.prev());
141 if (check(tmppath, i, j))
148 _path.push_back(_gr.nodeFromId(k));
150 _path.push_back(_gr.nodeFromId(k));
154 _sum = _cost[ _gr.edge(_path.back(), _path.front()) ];
155 for (unsigned int i=0; i<_path.size()-1; ++i)
156 _sum += _cost[ _gr.edge(_path[i], _path[i+1]) ];
161 template <typename L>
162 void tourNodes(L &container) {
163 container(opt2_helper::vectorConvert<L>(_path));
166 template <template <typename> class L>
167 L<Node> tourNodes() {
168 return opt2_helper::vectorConvert<L<Node> >(_path);
171 const std::vector<Node>& tourNodes() {
175 Path<FullGraph> tour() {
180 for (unsigned int i=0; i<_path.size()-1; ++i) {
181 p.addBack(_gr.arc(_path[i], _path[i+1]));
183 p.addBack(_gr.arc(_path.back(), _path.front()));
193 const FullGraph &_gr;
194 const CostMap &_cost;
196 std::vector<int> tmppath;
197 std::vector<Node> _path;
201 }; // namespace lemon