benchmark/edge_lookup_test.h
author alpar
Tue, 17 Oct 2006 10:31:20 +0000
changeset 2243 5deb7b22a0ec
parent 2235 48801095a410
child 2252 133028e83940
permissions -rw-r--r--
Change for better measurement very fast operations (enable a higher
number of iterations in runningTimeTest())
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