benchmark/edge_lookup_test.h
author hegyi
Fri, 27 Oct 2006 15:08:58 +0000
changeset 2265 5bb8867a9351
parent 2239 18c24fe93b99
permissions -rw-r--r--
NEWS updated to Rel0.6
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@2252
   192
  template<class G>
alpar@2252
   193
  class EdgeLookUp4
alpar@2252
   194
  {
alpar@2252
   195
  public:
alpar@2252
   196
    GRAPH_TYPEDEFS(typename G)
alpar@2252
   197
    typedef G Graph;
alpar@2252
   198
    
alpar@2252
   199
  private:
alpar@2252
   200
    const Graph &_g;
alpar@2252
   201
    typename Graph::template NodeMap<Edge*> _start;
alpar@2252
   202
    typename Graph::template NodeMap<Edge*> _end;
alpar@2252
   203
    std::vector<Edge> _edges;
alpar@2252
   204
    
alpar@2252
   205
    class EdgeLess {
alpar@2252
   206
      const Graph &g;
alpar@2252
   207
    public:
alpar@2252
   208
      EdgeLess(const Graph &_g) : g(_g) {}
alpar@2252
   209
      bool operator()(Edge a,Edge b) const 
alpar@2252
   210
      {
alpar@2252
   211
	return g.target(a)<g.target(b);
alpar@2252
   212
      }
alpar@2252
   213
    };
alpar@2252
   214
    
alpar@2252
   215
  public:
alpar@2252
   216
    
alpar@2252
   217
    ///Constructor
alpar@2252
   218
    EdgeLookUp4(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
alpar@2252
   219
    
alpar@2252
   220
  public:
alpar@2252
   221
    ///Refresh the data structure at a node.
alpar@2252
   222
    void refresh(Node n) 
alpar@2252
   223
    {
alpar@2252
   224
      const int bi = _start[n] = _edges.size();
alpar@2252
   225
      for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
alpar@2252
   226
      const typename std::vector<Edge>::iterator ei=_edges.end();
alpar@2252
   227
      _end[n]=_edges.size();
alpar@2252
   228
      std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
alpar@2252
   229
    }
alpar@2252
   230
    ///Refresh the full data structure.
alpar@2252
   231
    void refresh() 
alpar@2252
   232
    {
alpar@2252
   233
      _edges.resize(countEdges(_g));
alpar@2252
   234
      int l=0;
alpar@2252
   235
      for(NodeIt n(_g);n!=INVALID;++n)
alpar@2252
   236
	{
alpar@2252
   237
	  int ls = l;
alpar@2252
   238
	  _start[n]=&(_edges[l]);	
alpar@2252
   239
	  for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e;
alpar@2252
   240
	  _end[n]=&(_edges[l]);
alpar@2252
   241
	  std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g));
alpar@2252
   242
	}
alpar@2252
   243
      
alpar@2252
   244
    }
alpar@2252
   245
    
alpar@2252
   246
    ///Find an edge between two nodes.
alpar@2252
   247
    
alpar@2252
   248
    ///Find an edge between two nodes.
alpar@2252
   249
    ///\param s The source node
alpar@2252
   250
    ///\param t The target node
alpar@2252
   251
    ///\return An edge from \c s to \c t if there exists,
alpar@2252
   252
    ///\ref INVALID otherwise.
alpar@2235
   253
alpar@2252
   254
    Edge operator()(Node s, Node t) 
alpar@2252
   255
    {
alpar@2252
   256
      Edge *a=_start[s];
alpar@2252
   257
      Edge *b=_end[s];
alpar@2252
   258
      while(a!=b) 
alpar@2252
   259
	{
alpar@2252
   260
#ifdef X86
alpar@2252
   261
 	  Edge *m=(Edge*)(((unsigned int)a+(unsigned int)b)/2 & 0xfffffffc);
alpar@2252
   262
#elif X86_64
alpar@2252
   263
	  Edge *m=(Edge*)(((unsigned long)a+(undigned long)b)/2 & 0xfffffffc);
alpar@2252
   264
#else
alpar@2252
   265
 	  Edge *m=a+((b-a)/2);
alpar@2252
   266
#endif
alpar@2252
   267
	  Node tt = _g.target(*m);
alpar@2252
   268
	  if(tt==t) return *m;
alpar@2252
   269
	  else if(tt<t) a=m+1;
alpar@2252
   270
	  else b=m;
alpar@2252
   271
	}
alpar@2252
   272
      return INVALID;
alpar@2252
   273
    }
alpar@2252
   274
alpar@2252
   275
    ///Find the next edge
alpar@2235
   276
      
alpar@2252
   277
      ///\warning This function is unimplemented.
alpar@2252
   278
    Edge operator()(Node s, Node t, Edge prev) 
alpar@2252
   279
    {
alpar@2252
   280
      return prev==INVALID?(*this)(s,t):INVALID;
alpar@2252
   281
    }
alpar@2235
   282
      
alpar@2252
   283
  };
alpar@2235
   284
alpar@2235
   285
}
alpar@2235
   286
alpar@2235
   287
#endif