diff -r 4980b05606bd -r ae0b056593a7 lemon/opt2_tsp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/opt2_tsp.h Sat Jan 08 21:59:56 2011 +0100 @@ -0,0 +1,203 @@ +#ifndef LEMON_OPT2_TSP_H +#define LEMON_OPT2_TSP_H + +#include +#include +#include + +namespace lemon { + + namespace opt2_helper { + 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 Opt2Tsp { + private: + GRAPH_TYPEDEFS(FullGraph); + + public: + typedef CM CostMap; + typedef typename CM::Value Cost; + + + Opt2Tsp(const FullGraph &gr, const CostMap &cost) : _gr(gr), _cost(cost), + tmppath(_gr.nodeNum()*2) { + + for (int i=1; i<_gr.nodeNum()-1; ++i) { + tmppath[2*i] = i-1; + tmppath[2*i+1] = i+1; + } + tmppath[0] = _gr.nodeNum()-1; + tmppath[1] = 1; + tmppath[2*(_gr.nodeNum()-1)] = _gr.nodeNum()-2; + tmppath[2*(_gr.nodeNum()-1)+1] = 0; + } + + Opt2Tsp(const FullGraph &gr, const CostMap &cost, const std::vector &path) : + _gr(gr), _cost(cost), tmppath(_gr.nodeNum()*2) { + + for (unsigned int i=1; i &path, int i=0) : tmppath(path), act(i), last(tmppath[2*act]) {} + It(const std::vector &path, int i, int l) : tmppath(path), act(i), last(l) {} + + int next_index() const { + return (tmppath[2*act]==last)? 2*act+1 : 2*act; + } + + int prev_index() const { + return (tmppath[2*act]==last)? 2*act : 2*act+1; + } + + int next() const { + return tmppath[next_index()]; + } + + int prev() const { + return tmppath[prev_index()]; + } + + It& operator++() { + int tmp = act; + act = next(); + last = tmp; + return *this; + } + + operator int() const { + return act; + } + + private: + const std::vector &tmppath; + int act; + int last; + }; + + bool check(std::vector &path, It i, It j) { + if (c(i, i.next()) + c(j, j.next()) > + c(i, j) + c(j.next(), i.next())) { + + path[ It(path, i.next(), i).prev_index() ] = j.next(); + path[ It(path, j.next(), j).prev_index() ] = i.next(); + + path[i.next_index()] = j; + path[j.next_index()] = i; + + return true; + } + return false; + } + + public: + + Cost run() { + _path.clear(); + + if (_gr.nodeNum()>3) { + +opt2_tsp_label: + It i(tmppath); + It j(tmppath, i, i.prev()); + ++j; ++j; + for (; j.next()!=0; ++j) { + if (check(tmppath, i, j)) + goto opt2_tsp_label; + } + + for (++i; i.next()!=0; ++i) { + It j(tmppath, i, i.prev()); + if (++j==0) + break; + if (++j==0) + break; + + for (; j!=0; ++j) { + if (check(tmppath, i, j)) + goto opt2_tsp_label; + } + } + } + + It k(tmppath); + _path.push_back(_gr.nodeFromId(k)); + for (++k; k!=0; ++k) + _path.push_back(_gr.nodeFromId(k)); + + + + _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(opt2_helper::vectorConvert(_path)); + } + + template