benchmark/edge_lookup_test.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2235 48801095a410
child 2252 133028e83940
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
alpar@2235
     1
/* -*- C++ -*-
alpar@2235
     2
 *
alpar@2235
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@2235
     4
 *
alpar@2235
     5
 * Copyright (C) 2003-2006
alpar@2235
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@2235
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@2235
     8
 *
alpar@2235
     9
 * Permission to use, modify and distribute this software is granted
alpar@2235
    10
 * provided that this copyright notice appears in all copies. For
alpar@2235
    11
 * precise terms see the accompanying LICENSE file.
alpar@2235
    12
 *
alpar@2235
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@2235
    14
 * express or implied, and with no claim as to its suitability for any
alpar@2235
    15
 * purpose.
alpar@2235
    16
 *
alpar@2235
    17
 */
alpar@2235
    18
alpar@2235
    19
#ifndef LEMON_EDGE_LOOKUP_H
alpar@2235
    20
#define LEMON_EDGE_LOOKUP_H
alpar@2235
    21
alpar@2235
    22
#include<lemon/graph_utils.h>
alpar@2235
    23
#include<algorithm>
alpar@2235
    24
#include<vector>
alpar@2235
    25
alpar@2235
    26
namespace lemon {
alpar@2235
    27
  template<class G>
alpar@2235
    28
  class EdgeLookUp2
alpar@2235
    29
  {
alpar@2235
    30
  public:
alpar@2235
    31
    GRAPH_TYPEDEFS(typename G)
alpar@2235
    32
    typedef G Graph;
alpar@2235
    33
alpar@2235
    34
  private:
alpar@2235
    35
    const Graph &_g;
alpar@2235
    36
    typename Graph::template NodeMap<int> _start;
alpar@2235
    37
    typename Graph::template NodeMap<int> _end;
alpar@2235
    38
    std::vector<Edge> _edges;
alpar@2235
    39
    
alpar@2235
    40
    class EdgeLess {
alpar@2235
    41
      const Graph &g;
alpar@2235
    42
    public:
alpar@2235
    43
      EdgeLess(const Graph &_g) : g(_g) {}
alpar@2235
    44
      bool operator()(Edge a,Edge b) const 
alpar@2235
    45
      {
alpar@2235
    46
	return g.target(a)<g.target(b);
alpar@2235
    47
      }
alpar@2235
    48
    };
alpar@2235
    49
    
alpar@2235
    50
  public:
alpar@2235
    51
    
alpar@2235
    52
    ///Constructor
alpar@2235
    53
    EdgeLookUp2(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
alpar@2235
    54
    
alpar@2235
    55
  public:
alpar@2235
    56
    ///Refresh the data structure at a node.
alpar@2235
    57
    void refresh(Node n) 
alpar@2235
    58
    {
alpar@2235
    59
      const int bi = _start[n] = _edges.size();
alpar@2235
    60
      for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
alpar@2235
    61
      const typename std::vector<Edge>::iterator ei=_edges.end();
alpar@2235
    62
      _end[n]=_edges.size();
alpar@2235
    63
      std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
alpar@2235
    64
    }
alpar@2235
    65
    ///Refresh the full data structure.
alpar@2235
    66
    void refresh() 
alpar@2235
    67
    {
alpar@2235
    68
      _edges.clear();
alpar@2235
    69
      for(NodeIt n(_g);n!=INVALID;++n) refresh(n);
alpar@2235
    70
    }
alpar@2235
    71
    
alpar@2235
    72
    ///Find an edge between two nodes.
alpar@2235
    73
    
alpar@2235
    74
    ///Find an edge between two nodes.
alpar@2235
    75
    ///\param s The source node
alpar@2235
    76
    ///\param t The target node
alpar@2235
    77
    ///\return An edge from \c s to \c t if there exists,
alpar@2235
    78
    ///\ref INVALID otherwise.
alpar@2235
    79
alpar@2235
    80
    Edge operator()(Node s, Node t) 
alpar@2235
    81
    {
alpar@2235
    82
      int a=_start[s];
alpar@2235
    83
      int b=_end[s];
alpar@2235
    84
      while(a<b) 
alpar@2235
    85
	{
alpar@2235
    86
	  int n=(a+b)/2;
alpar@2235
    87
	  Node tt = _g.target(_edges[n]);
alpar@2235
    88
	  if(tt==t) return _edges[n];
alpar@2235
    89
	  else if(tt<t) a=n+1;
alpar@2235
    90
	  else b=n;
alpar@2235
    91
	}
alpar@2235
    92
      return INVALID;
alpar@2235
    93
    }
alpar@2235
    94
alpar@2235
    95
    ///Find the next edge
alpar@2235
    96
      
alpar@2235
    97
      ///\warning This function is unimplemented.
alpar@2235
    98
    Edge operator()(Node s, Node t, Edge prev) 
alpar@2235
    99
    {
alpar@2235
   100
      return prev==INVALID?(*this)(s,t):INVALID;
alpar@2235
   101
    }
alpar@2235
   102
      
alpar@2235
   103
  };
alpar@2235
   104
alpar@2235
   105
  template<class G>
alpar@2235
   106
  class EdgeLookUp3
alpar@2235
   107
  {
alpar@2235
   108
  public:
alpar@2235
   109
    GRAPH_TYPEDEFS(typename G)
alpar@2235
   110
    typedef G Graph;
alpar@2235
   111
alpar@2235
   112
  private:
alpar@2235
   113
    const Graph &_g;
alpar@2235
   114
    typename Graph::template NodeMap<Edge*> _start;
alpar@2235
   115
    typename Graph::template NodeMap<Edge*> _end;
alpar@2235
   116
    std::vector<Edge> _edges;
alpar@2235
   117
    
alpar@2235
   118
    class EdgeLess {
alpar@2235
   119
      const Graph &g;
alpar@2235
   120
    public:
alpar@2235
   121
      EdgeLess(const Graph &_g) : g(_g) {}
alpar@2235
   122
      bool operator()(Edge a,Edge b) const 
alpar@2235
   123
      {
alpar@2235
   124
	return g.target(a)<g.target(b);
alpar@2235
   125
      }
alpar@2235
   126
    };
alpar@2235
   127
    
alpar@2235
   128
  public:
alpar@2235
   129
    
alpar@2235
   130
    ///Constructor
alpar@2235
   131
    EdgeLookUp3(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
alpar@2235
   132
    
alpar@2235
   133
  public:
alpar@2235
   134
    ///Refresh the data structure at a node.
alpar@2235
   135
    void refresh(Node n) 
alpar@2235
   136
    {
alpar@2235
   137
      const int bi = _start[n] = _edges.size();
alpar@2235
   138
      for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
alpar@2235
   139
      const typename std::vector<Edge>::iterator ei=_edges.end();
alpar@2235
   140
      _end[n]=_edges.size();
alpar@2235
   141
      std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
alpar@2235
   142
    }
alpar@2235
   143
    ///Refresh the full data structure.
alpar@2235
   144
    void refresh() 
alpar@2235
   145
    {
alpar@2235
   146
      _edges.resize(countEdges(_g));
alpar@2235
   147
      int l=0;
alpar@2235
   148
      for(NodeIt n(_g);n!=INVALID;++n)
alpar@2235
   149
	{
alpar@2235
   150
	  int ls = l;
alpar@2235
   151
	  _start[n]=&(_edges[l]);	
alpar@2235
   152
	  for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e;
alpar@2235
   153
	  _end[n]=&(_edges[l]);
alpar@2235
   154
	  std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g));
alpar@2235
   155
	}
alpar@2235
   156
      
alpar@2235
   157
    }
alpar@2235
   158
    
alpar@2235
   159
    ///Find an edge between two nodes.
alpar@2235
   160
    
alpar@2235
   161
    ///Find an edge between two nodes.
alpar@2235
   162
    ///\param s The source node
alpar@2235
   163
    ///\param t The target node
alpar@2235
   164
    ///\return An edge from \c s to \c t if there exists,
alpar@2235
   165
    ///\ref INVALID otherwise.
alpar@2235
   166
alpar@2235
   167
    Edge operator()(Node s, Node t) 
alpar@2235
   168
    {
alpar@2235
   169
      Edge *a=_start[s];
alpar@2235
   170
      Edge *b=_end[s];
alpar@2235
   171
      while(a!=b) 
alpar@2235
   172
	{
alpar@2235
   173
 	  Edge *m=a+((b-a)/2);
alpar@2235
   174
	  Node tt = _g.target(*m);
alpar@2235
   175
	  if(tt==t) return *m;
alpar@2235
   176
	  else if(tt<t) a=m+1;
alpar@2235
   177
	  else b=m;
alpar@2235
   178
	}
alpar@2235
   179
      return INVALID;
alpar@2235
   180
    }
alpar@2235
   181
alpar@2235
   182
    ///Find the next edge
alpar@2235
   183
      
alpar@2235
   184
      ///\warning This function is unimplemented.
alpar@2235
   185
    Edge operator()(Node s, Node t, Edge prev) 
alpar@2235
   186
    {
alpar@2235
   187
      return prev==INVALID?(*this)(s,t):INVALID;
alpar@2235
   188
    }
alpar@2235
   189
      
alpar@2235
   190
  };
alpar@2235
   191
alpar@2239
   192
//   template<class G>
alpar@2239
   193
//   class EdgeLookUp4
alpar@2239
   194
//   {
alpar@2239
   195
//   public:
alpar@2239
   196
//     GRAPH_TYPEDEFS(typename G)
alpar@2239
   197
//     typedef G Graph;
alpar@2235
   198
alpar@2239
   199
//   private:
alpar@2239
   200
//     const Graph &_g;
alpar@2239
   201
//     typename Graph::template NodeMap<Edge*> _start;
alpar@2239
   202
//     typename Graph::template NodeMap<Edge*> _end;
alpar@2239
   203
//     std::vector<Edge> _edges;
alpar@2235
   204
    
alpar@2239
   205
//     class EdgeLess {
alpar@2239
   206
//       const Graph &g;
alpar@2239
   207
//     public:
alpar@2239
   208
//       EdgeLess(const Graph &_g) : g(_g) {}
alpar@2239
   209
//       bool operator()(Edge a,Edge b) const 
alpar@2239
   210
//       {
alpar@2239
   211
// 	return g.target(a)<g.target(b);
alpar@2239
   212
//       }
alpar@2239
   213
//     };
alpar@2235
   214
    
alpar@2239
   215
//   public:
alpar@2235
   216
    
alpar@2239
   217
//     ///Constructor
alpar@2239
   218
//     EdgeLookUp4(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
alpar@2235
   219
    
alpar@2239
   220
//   public:
alpar@2239
   221
//     ///Refresh the data structure at a node.
alpar@2239
   222
//     void refresh(Node n) 
alpar@2239
   223
//     {
alpar@2239
   224
//       const int bi = _start[n] = _edges.size();
alpar@2239
   225
//       for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
alpar@2239
   226
//       const typename std::vector<Edge>::iterator ei=_edges.end();
alpar@2239
   227
//       _end[n]=_edges.size();
alpar@2239
   228
//       std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
alpar@2239
   229
//     }
alpar@2239
   230
//     ///Refresh the full data structure.
alpar@2239
   231
//     void refresh() 
alpar@2239
   232
//     {
alpar@2239
   233
//       _edges.resize(countEdges(_g));
alpar@2239
   234
//       int l=0;
alpar@2239
   235
//       for(NodeIt n(_g);n!=INVALID;++n)
alpar@2239
   236
// 	{
alpar@2239
   237
// 	  int ls = l;
alpar@2239
   238
// 	  _start[n]=&(_edges[l]);	
alpar@2239
   239
// 	  for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e;
alpar@2239
   240
// 	  _end[n]=&(_edges[l]);
alpar@2239
   241
// 	  std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g));
alpar@2239
   242
// 	}
alpar@2235
   243
      
alpar@2239
   244
//     }
alpar@2235
   245
    
alpar@2239
   246
//     ///Find an edge between two nodes.
alpar@2235
   247
    
alpar@2239
   248
//     ///Find an edge between two nodes.
alpar@2239
   249
//     ///\param s The source node
alpar@2239
   250
//     ///\param t The target node
alpar@2239
   251
//     ///\return An edge from \c s to \c t if there exists,
alpar@2239
   252
//     ///\ref INVALID otherwise.
alpar@2235
   253
alpar@2239
   254
//     Edge operator()(Node s, Node t) 
alpar@2239
   255
//     {
alpar@2239
   256
//       Edge *a=_start[s];
alpar@2239
   257
//       Edge *b=_end[s];
alpar@2239
   258
//       while(a!=b) 
alpar@2239
   259
// 	{
alpar@2239
   260
// 	  Edge *m=(Edge*)(((unsigned int)a+(unsigned int)b)/2 & 0xfffffffc);
alpar@2239
   261
// 	  Node tt = _g.target(*m);
alpar@2239
   262
// 	  if(tt==t) return *m;
alpar@2239
   263
// 	  else if(tt<t) a=m+1;
alpar@2239
   264
// 	  else b=m;
alpar@2239
   265
// 	}
alpar@2239
   266
//       return INVALID;
alpar@2239
   267
//     }
alpar@2235
   268
alpar@2239
   269
//     ///Find the next edge
alpar@2235
   270
      
alpar@2239
   271
//       ///\warning This function is unimplemented.
alpar@2239
   272
//     Edge operator()(Node s, Node t, Edge prev) 
alpar@2239
   273
//     {
alpar@2239
   274
//       return prev==INVALID?(*this)(s,t):INVALID;
alpar@2239
   275
//     }
alpar@2235
   276
      
alpar@2239
   277
//   };
alpar@2235
   278
alpar@2235
   279
}
alpar@2235
   280
alpar@2235
   281
#endif