lemon/opt2_tsp.h
author Peter Kovacs <kpeter@inf.elte.hu>
Sat, 08 Jan 2011 22:49:09 +0100
changeset 1032 62ba43576f85
child 1033 9a51db038228
permissions -rw-r--r--
Doc group for TSP algorithms (#386)
f4c3@1031
     1
#ifndef LEMON_OPT2_TSP_H
f4c3@1031
     2
#define LEMON_OPT2_TSP_H
f4c3@1031
     3
f4c3@1031
     4
#include <vector>
f4c3@1031
     5
#include <lemon/full_graph.h>
f4c3@1031
     6
#include <lemon/path.h>
f4c3@1031
     7
f4c3@1031
     8
namespace lemon {
f4c3@1031
     9
  
f4c3@1031
    10
  namespace opt2_helper {
f4c3@1031
    11
    template <class L>
f4c3@1031
    12
    L vectorConvert(const std::vector<FullGraph::Node> &_path) {
f4c3@1031
    13
      return L(_path.begin(), _path.end());
f4c3@1031
    14
    }
f4c3@1031
    15
  
f4c3@1031
    16
    template <>
f4c3@1031
    17
    std::vector<FullGraph::Node> vectorConvert(const std::vector<FullGraph::Node> &_path) {
f4c3@1031
    18
      return _path;
f4c3@1031
    19
    }
f4c3@1031
    20
  }
f4c3@1031
    21
  
f4c3@1031
    22
  template <typename CM>
f4c3@1031
    23
  class Opt2Tsp {
f4c3@1031
    24
    private:
f4c3@1031
    25
      GRAPH_TYPEDEFS(FullGraph);
f4c3@1031
    26
f4c3@1031
    27
    public:
f4c3@1031
    28
      typedef CM CostMap;
f4c3@1031
    29
      typedef typename CM::Value Cost;
f4c3@1031
    30
      
f4c3@1031
    31
    
f4c3@1031
    32
      Opt2Tsp(const FullGraph &gr, const CostMap &cost) : _gr(gr), _cost(cost), 
f4c3@1031
    33
            tmppath(_gr.nodeNum()*2) {
f4c3@1031
    34
            
f4c3@1031
    35
        for (int i=1; i<_gr.nodeNum()-1; ++i) {
f4c3@1031
    36
          tmppath[2*i] = i-1;
f4c3@1031
    37
          tmppath[2*i+1] = i+1;
f4c3@1031
    38
        }
f4c3@1031
    39
        tmppath[0] = _gr.nodeNum()-1;
f4c3@1031
    40
        tmppath[1] = 1;
f4c3@1031
    41
        tmppath[2*(_gr.nodeNum()-1)] = _gr.nodeNum()-2;
f4c3@1031
    42
        tmppath[2*(_gr.nodeNum()-1)+1] = 0;
f4c3@1031
    43
      }
f4c3@1031
    44
      
f4c3@1031
    45
      Opt2Tsp(const FullGraph &gr, const CostMap &cost, const std::vector<Node> &path) : 
f4c3@1031
    46
              _gr(gr), _cost(cost), tmppath(_gr.nodeNum()*2) {
f4c3@1031
    47
f4c3@1031
    48
        for (unsigned int i=1; i<path.size()-1; ++i) {
f4c3@1031
    49
          tmppath[2*_gr.id(path[i])] = _gr.id(path[i-1]);
f4c3@1031
    50
          tmppath[2*_gr.id(path[i])+1] = _gr.id(path[i+1]);
f4c3@1031
    51
        }
f4c3@1031
    52
        
f4c3@1031
    53
        tmppath[2*_gr.id(path[0])] = _gr.id(path.back());
f4c3@1031
    54
        tmppath[2*_gr.id(path[0])+1] = _gr.id(path[1]);
f4c3@1031
    55
        tmppath[2*_gr.id(path.back())] = _gr.id(path[path.size()-2]);
f4c3@1031
    56
        tmppath[2*_gr.id(path.back())+1] = _gr.id(path.front());
f4c3@1031
    57
      }
f4c3@1031
    58
f4c3@1031
    59
    private:
f4c3@1031
    60
      Cost c(int u, int v) {
f4c3@1031
    61
        return _cost[_gr.edge(_gr.nodeFromId(u), _gr.nodeFromId(v))];
f4c3@1031
    62
      }
f4c3@1031
    63
      
f4c3@1031
    64
      class It {
f4c3@1031
    65
        public:
f4c3@1031
    66
          It(const std::vector<int> &path, int i=0) : tmppath(path), act(i), last(tmppath[2*act]) {}
f4c3@1031
    67
          It(const std::vector<int> &path, int i, int l) : tmppath(path), act(i), last(l) {}
f4c3@1031
    68
f4c3@1031
    69
          int next_index() const {
f4c3@1031
    70
            return (tmppath[2*act]==last)? 2*act+1 : 2*act;
f4c3@1031
    71
          }
f4c3@1031
    72
          
f4c3@1031
    73
          int prev_index() const {
f4c3@1031
    74
            return (tmppath[2*act]==last)? 2*act : 2*act+1;
f4c3@1031
    75
          }
f4c3@1031
    76
          
f4c3@1031
    77
          int next() const {
f4c3@1031
    78
            return tmppath[next_index()];
f4c3@1031
    79
          }
f4c3@1031
    80
f4c3@1031
    81
          int prev() const {
f4c3@1031
    82
            return tmppath[prev_index()];
f4c3@1031
    83
          }
f4c3@1031
    84
          
f4c3@1031
    85
          It& operator++() {
f4c3@1031
    86
            int tmp = act;
f4c3@1031
    87
            act = next();
f4c3@1031
    88
            last = tmp;
f4c3@1031
    89
            return *this;
f4c3@1031
    90
          }
f4c3@1031
    91
          
f4c3@1031
    92
          operator int() const {
f4c3@1031
    93
            return act;
f4c3@1031
    94
          }
f4c3@1031
    95
          
f4c3@1031
    96
        private:
f4c3@1031
    97
          const std::vector<int> &tmppath;
f4c3@1031
    98
          int act;
f4c3@1031
    99
          int last;
f4c3@1031
   100
      };
f4c3@1031
   101
f4c3@1031
   102
      bool check(std::vector<int> &path, It i, It j) {
f4c3@1031
   103
        if (c(i, i.next()) + c(j, j.next()) > 
f4c3@1031
   104
            c(i, j) + c(j.next(), i.next())) {
f4c3@1031
   105
f4c3@1031
   106
            path[ It(path, i.next(), i).prev_index() ] = j.next();
f4c3@1031
   107
            path[ It(path, j.next(), j).prev_index() ] = i.next();
f4c3@1031
   108
f4c3@1031
   109
            path[i.next_index()] = j;
f4c3@1031
   110
            path[j.next_index()] = i;
f4c3@1031
   111
f4c3@1031
   112
            return true;
f4c3@1031
   113
        }
f4c3@1031
   114
        return false;
f4c3@1031
   115
      }
f4c3@1031
   116
      
f4c3@1031
   117
    public:
f4c3@1031
   118
      
f4c3@1031
   119
      Cost run() {
f4c3@1031
   120
        _path.clear();
f4c3@1031
   121
f4c3@1031
   122
        if (_gr.nodeNum()>3) {
f4c3@1031
   123
f4c3@1031
   124
opt2_tsp_label:
f4c3@1031
   125
          It i(tmppath);
f4c3@1031
   126
          It j(tmppath, i, i.prev());
f4c3@1031
   127
          ++j; ++j;
f4c3@1031
   128
          for (; j.next()!=0; ++j) {
f4c3@1031
   129
            if (check(tmppath, i, j))
f4c3@1031
   130
              goto opt2_tsp_label;
f4c3@1031
   131
          }
f4c3@1031
   132
          
f4c3@1031
   133
          for (++i; i.next()!=0; ++i) {
f4c3@1031
   134
            It j(tmppath, i, i.prev());
f4c3@1031
   135
            if (++j==0)
f4c3@1031
   136
              break;
f4c3@1031
   137
            if (++j==0)
f4c3@1031
   138
              break;
f4c3@1031
   139
            
f4c3@1031
   140
            for (; j!=0; ++j) {
f4c3@1031
   141
              if (check(tmppath, i, j))
f4c3@1031
   142
                goto opt2_tsp_label;
f4c3@1031
   143
            }
f4c3@1031
   144
          }
f4c3@1031
   145
        }
f4c3@1031
   146
f4c3@1031
   147
        It k(tmppath);
f4c3@1031
   148
        _path.push_back(_gr.nodeFromId(k));
f4c3@1031
   149
        for (++k; k!=0; ++k)
f4c3@1031
   150
          _path.push_back(_gr.nodeFromId(k));
f4c3@1031
   151
f4c3@1031
   152
        
f4c3@1031
   153
f4c3@1031
   154
        _sum = _cost[ _gr.edge(_path.back(), _path.front()) ];
f4c3@1031
   155
        for (unsigned int i=0; i<_path.size()-1; ++i)
f4c3@1031
   156
          _sum += _cost[ _gr.edge(_path[i], _path[i+1]) ];
f4c3@1031
   157
        return _sum;
f4c3@1031
   158
      }
f4c3@1031
   159
f4c3@1031
   160
      
f4c3@1031
   161
      template <typename L>
f4c3@1031
   162
      void tourNodes(L &container) {
f4c3@1031
   163
        container(opt2_helper::vectorConvert<L>(_path));
f4c3@1031
   164
      }
f4c3@1031
   165
      
f4c3@1031
   166
      template <template <typename> class L>
f4c3@1031
   167
      L<Node> tourNodes() {
f4c3@1031
   168
        return opt2_helper::vectorConvert<L<Node> >(_path);
f4c3@1031
   169
      }
f4c3@1031
   170
f4c3@1031
   171
      const std::vector<Node>& tourNodes() {
f4c3@1031
   172
        return _path;
f4c3@1031
   173
      }
f4c3@1031
   174
      
f4c3@1031
   175
      Path<FullGraph> tour() {
f4c3@1031
   176
        Path<FullGraph> p;
f4c3@1031
   177
        if (_path.size()<2)
f4c3@1031
   178
          return p;
f4c3@1031
   179
f4c3@1031
   180
        for (unsigned int i=0; i<_path.size()-1; ++i) {
f4c3@1031
   181
          p.addBack(_gr.arc(_path[i], _path[i+1]));
f4c3@1031
   182
        }
f4c3@1031
   183
        p.addBack(_gr.arc(_path.back(), _path.front()));
f4c3@1031
   184
        return p;
f4c3@1031
   185
      }
f4c3@1031
   186
      
f4c3@1031
   187
      Cost tourCost() {
f4c3@1031
   188
        return _sum;
f4c3@1031
   189
      }
f4c3@1031
   190
      
f4c3@1031
   191
f4c3@1031
   192
  private:
f4c3@1031
   193
    const FullGraph &_gr;
f4c3@1031
   194
    const CostMap &_cost;
f4c3@1031
   195
    Cost _sum;
f4c3@1031
   196
    std::vector<int> tmppath;
f4c3@1031
   197
    std::vector<Node> _path;
f4c3@1031
   198
  };
f4c3@1031
   199
f4c3@1031
   200
f4c3@1031
   201
}; // namespace lemon
f4c3@1031
   202
f4c3@1031
   203
#endif