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