COIN-OR::LEMON - Graph Library

source: lemon-0.x/benchmark/edge_lookup.cc @ 2272:f6b352fdc6b1

Last change on this file since 2272:f6b352fdc6b1 was 2272:f6b352fdc6b1, checked in by Alpar Juttner, 17 years ago

Turn off 32 bit only tests.

File size: 11.2 KB
RevLine 
[2235]1#include<lemon/smart_graph.h>
2#include<vector>
3#include<lemon/time_measure.h>
[2242]4#include<lemon/random.h>
[2271]5#include<lemon/graph_utils.h>
6#include<algorithm>
[2235]7
8using namespace lemon;
9
[2271]10  template<class G>
11  class EdgeLookUp2
12  {
13  public:
14    GRAPH_TYPEDEFS(typename G)
15    typedef G Graph;
16
17  private:
18    const Graph &_g;
19    typename Graph::template NodeMap<int> _start;
20    typename Graph::template NodeMap<int> _end;
21    std::vector<Edge> _edges;
22   
23    class EdgeLess {
24      const Graph &g;
25    public:
26      EdgeLess(const Graph &_g) : g(_g) {}
27      bool operator()(Edge a,Edge b) const
28      {
29        return g.target(a)<g.target(b);
30      }
31    };
32   
33  public:
34   
35    ///Constructor
36    EdgeLookUp2(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
37   
38  public:
39    ///Refresh the data structure at a node.
40    void refresh(Node n)
41    {
42      const int bi = _start[n] = _edges.size();
43      for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
44      const typename std::vector<Edge>::iterator ei=_edges.end();
45      _end[n]=_edges.size();
46      std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
47    }
48    ///Refresh the full data structure.
49    void refresh()
50    {
51      _edges.clear();
52      for(NodeIt n(_g);n!=INVALID;++n) refresh(n);
53    }
54   
55    ///Find an edge between two nodes.
56   
57    ///Find an edge between two nodes.
58    ///\param s The source node
59    ///\param t The target node
60    ///\return An edge from \c s to \c t if there exists,
61    ///\ref INVALID otherwise.
62
63    Edge operator()(Node s, Node t)
64    {
65      int a=_start[s];
66      int b=_end[s];
67      while(a<b)
68        {
69          int n=(a+b)/2;
70          Node tt = _g.target(_edges[n]);
71          if(tt==t) return _edges[n];
72          else if(tt<t) a=n+1;
73          else b=n;
74        }
75      return INVALID;
76    }
77
78    ///Find the next edge
79     
80      ///\warning This function is unimplemented.
81    Edge operator()(Node s, Node t, Edge prev)
82    {
83      return prev==INVALID?(*this)(s,t):INVALID;
84    }
85     
86  };
87
88  template<class G>
89  class EdgeLookUp3
90  {
91  public:
92    GRAPH_TYPEDEFS(typename G)
93    typedef G Graph;
94
95  private:
96    const Graph &_g;
97    typename Graph::template NodeMap<Edge*> _start;
98    typename Graph::template NodeMap<Edge*> _end;
99    std::vector<Edge> _edges;
100   
101    class EdgeLess {
102      const Graph &g;
103    public:
104      EdgeLess(const Graph &_g) : g(_g) {}
105      bool operator()(Edge a,Edge b) const
106      {
107        return g.target(a)<g.target(b);
108      }
109    };
110   
111  public:
112   
113    ///Constructor
114    EdgeLookUp3(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
115   
116  public:
117    ///Refresh the data structure at a node.
118    void refresh(Node n)
119    {
120      const int bi = _start[n] = _edges.size();
121      for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
122      const typename std::vector<Edge>::iterator ei=_edges.end();
123      _end[n]=_edges.size();
124      std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
125    }
126    ///Refresh the full data structure.
127    void refresh()
128    {
129      _edges.resize(countEdges(_g));
130      int l=0;
131      for(NodeIt n(_g);n!=INVALID;++n)
132        {
133          int ls = l;
134          _start[n]=&(_edges[l]);       
135          for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e;
136          _end[n]=&(_edges[l]);
137          std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g));
138        }
139     
140    }
141   
142    ///Find an edge between two nodes.
143   
144    ///Find an edge between two nodes.
145    ///\param s The source node
146    ///\param t The target node
147    ///\return An edge from \c s to \c t if there exists,
148    ///\ref INVALID otherwise.
149
150    Edge operator()(Node s, Node t)
151    {
152      Edge *a=_start[s];
153      Edge *b=_end[s];
154      while(a!=b)
155        {
156          Edge *m=a+((b-a)/2);
157          Node tt = _g.target(*m);
158          if(tt==t) return *m;
159          else if(tt<t) a=m+1;
160          else b=m;
161        }
162      return INVALID;
163    }
164
165    ///Find the next edge
166     
167      ///\warning This function is unimplemented.
168    Edge operator()(Node s, Node t, Edge prev)
169    {
170      return prev==INVALID?(*this)(s,t):INVALID;
171    }
172     
173  };
174
[2272]175//   template<class G>
176//   class EdgeLookUp4
177//   {
178//   public:
179//     GRAPH_TYPEDEFS(typename G)
180//     typedef G Graph;
[2271]181   
[2272]182//   private:
183//     const Graph &_g;
184//     typename Graph::template NodeMap<Edge*> _start;
185//     typename Graph::template NodeMap<Edge*> _end;
186//     std::vector<Edge> _edges;
[2271]187   
[2272]188//     class EdgeLess {
189//       const Graph &g;
190//     public:
191//       EdgeLess(const Graph &_g) : g(_g) {}
192//       bool operator()(Edge a,Edge b) const
193//       {
194//      return g.target(a)<g.target(b);
195//       }
196//     };
[2271]197   
[2272]198//   public:
[2271]199   
[2272]200//     ///Constructor
201//     EdgeLookUp4(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
[2271]202   
[2272]203//   public:
204//     ///Refresh the data structure at a node.
205//     void refresh(Node n)
206//     {
207//       const int bi = _start[n] = _edges.size();
208//       for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
209//       const typename std::vector<Edge>::iterator ei=_edges.end();
210//       _end[n]=_edges.size();
211//       std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
212//     }
213//     ///Refresh the full data structure.
214//     void refresh()
215//     {
216//       _edges.resize(countEdges(_g));
217//       int l=0;
218//       for(NodeIt n(_g);n!=INVALID;++n)
219//      {
220//        int ls = l;
221//        _start[n]=&(_edges[l]);       
222//        for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e;
223//        _end[n]=&(_edges[l]);
224//        std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g));
225//      }
[2271]226     
[2272]227//     }
[2271]228   
[2272]229//     ///Find an edge between two nodes.
[2271]230   
[2272]231//     ///Find an edge between two nodes.
232//     ///\param s The source node
233//     ///\param t The target node
234//     ///\return An edge from \c s to \c t if there exists,
235//     ///\ref INVALID otherwise.
[2271]236
[2272]237//     Edge operator()(Node s, Node t)
238//     {
239//       Edge *a=_start[s];
240//       Edge *b=_end[s];
241//       while(a!=b)
242//      {
243// // #ifdef X86
244//        Edge *m=(Edge*)(((unsigned int)a+(unsigned int)b)/2 & 0xfffffffc);
245// // #elif X86_64
246// //     Edge *m=(Edge*)(((unsigned long)a+(undigned long)b)/2 & 0xfffffffc);
247// // #else
248// //     Edge *m=a+((b-a)/2);
249// // #endif
250//        Node tt = _g.target(*m);
251//        if(tt==t) return *m;
252//        else if(tt<t) a=m+1;
253//        else b=m;
254//      }
255//       return INVALID;
256//     }
[2271]257
[2272]258//     ///Find the next edge
[2271]259     
[2272]260//       ///\warning This function is unimplemented.
261//     Edge operator()(Node s, Node t, Edge prev)
262//     {
263//       return prev==INVALID?(*this)(s,t):INVALID;
264//     }
[2271]265     
[2272]266//   };
[2271]267
[2272]268//   template<class G>
269//   class EdgeLookUp5
270//   {
271//   public:
272//     GRAPH_TYPEDEFS(typename G)
273//     typedef G Graph;
[2271]274   
[2272]275//   private:
276//     const Graph &_g;
277//     typename Graph::template NodeMap<Edge*> _start;
278//     typename Graph::template NodeMap<Edge*> _end;
279//     std::vector<Edge> _edges;
[2271]280   
[2272]281//     class EdgeLess {
282//       const Graph &g;
283//     public:
284//       EdgeLess(const Graph &_g) : g(_g) {}
285//       bool operator()(Edge a,Edge b) const
286//       {
287//      return g.target(a)<g.target(b);
288//       }
289//     };
[2271]290   
[2272]291//   public:
[2271]292   
[2272]293//     ///Constructor
294//     EdgeLookUp5(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
[2271]295   
[2272]296//   public:
297//     ///Refresh the data structure at a node.
298//     void refresh(Node n)
299//     {
300//       const int bi = _start[n] = _edges.size();
301//       for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
302//       const typename std::vector<Edge>::iterator ei=_edges.end();
303//       _end[n]=_edges.size();
304//       std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
305//     }
306//     ///Refresh the full data structure.
307//     void refresh()
308//     {
309//       _edges.resize(countEdges(_g));
310//       int l=0;
311//       for(NodeIt n(_g);n!=INVALID;++n)
312//      {
313//        int ls = l;
314//        _start[n]=&(_edges[l]);       
315//        for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e;
316//        _end[n]=&(_edges[l]);
317//        std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g));
318//      }
[2271]319     
[2272]320//     }
[2271]321   
[2272]322//     ///Find an edge between two nodes.
[2271]323   
[2272]324//     ///Find an edge between two nodes.
325//     ///\param s The source node
326//     ///\param t The target node
327//     ///\return An edge from \c s to \c t if there exists,
328//     ///\ref INVALID otherwise.
[2271]329
[2272]330//     Edge operator()(Node s, Node t)
331//     {
332//       Edge *a=_start[s];
333//       Edge *b=_end[s];
334//       while(a!=b)
335//      {
336// // #ifdef X86
337//        Edge *m=(Edge*)((((unsigned int)a>>1)+((unsigned int)b)>>1)
338//                        & 0xfffffffc);
339// // #elif X86_64
340// //     Edge *m=(Edge*)(((unsigned long)a>>1+(undigned long)b)>>1)&0xfffffffc);
341// // #else
342// //     Edge *m=a+((b-a)/2);
343// // #endif
344//        Node tt = _g.target(*m);
345//        if(tt==t) return *m;
346//        else if(tt<t) a=m+1;
347//        else b=m;
348//      }
349//       return INVALID;
350//     }
[2271]351
[2272]352//     ///Find the next edge
[2271]353     
[2272]354//       ///\warning This function is unimplemented.
355//     Edge operator()(Node s, Node t, Edge prev)
356//     {
357//       return prev==INVALID?(*this)(s,t):INVALID;
358//     }
[2271]359     
[2272]360//   };
[2271]361
[2235]362GRAPH_TYPEDEFS(SmartGraph)
363typedef SmartGraph Graph;
364
365class FE
366{
367public:
368  Graph &_g;
369  FE(Graph &g) :_g(g) {}
370  void operator()()
371  {
372    Edge e;
373   
374    for(NodeIt v(_g);v!=INVALID;++v)
375      for(NodeIt u(_g);u!=INVALID;++u)
376        e=findEdge(_g,u,v);
377  }
378 
379};
380
381class EL
382{
383public:
384  Graph &_g;
385  EdgeLookUp<Graph> _el;
386  EL(Graph &g) :_g(g), _el(g) {}
387  void operator()()
388  {
389    Edge e;
390   
391    for(NodeIt v(_g);v!=INVALID;++v)
392      for(NodeIt u(_g);u!=INVALID;++u)
393        e=_el(u,v);
394  }
395 
396};
397class EL2
398{
399public:
400  Graph &_g;
401  EdgeLookUp2<Graph> _el;
402  EL2(Graph &g) :_g(g), _el(g) {}
403  void operator()()
404  {
405    Edge e;
406   
407    for(NodeIt v(_g);v!=INVALID;++v)
408      for(NodeIt u(_g);u!=INVALID;++u)
409        e=_el(u,v);
410  }
411 
412};
413
414class EL3
415{
416public:
417  Graph &_g;
418  EdgeLookUp3<Graph> _el;
419  EL3(Graph &g) :_g(g), _el(g) {}
420  void operator()()
421  {
422    Edge e;
423   
424    for(NodeIt v(_g);v!=INVALID;++v)
425      for(NodeIt u(_g);u!=INVALID;++u)
426        e=_el(u,v);
427  }
428 
429};
430
[2252]431class EL4
432{
433public:
434  Graph &_g;
435  EdgeLookUp4<Graph> _el;
436  EL4(Graph &g) :_g(g), _el(g) {}
437  void operator()()
438  {
439    Edge e;
[2235]440   
[2252]441    for(NodeIt v(_g);v!=INVALID;++v)
442      for(NodeIt u(_g);u!=INVALID;++u)
443        e=_el(u,v);
444  }
[2235]445 
[2252]446};
[2235]447
[2271]448class EL5
449{
450public:
451  Graph &_g;
452  EdgeLookUp5<Graph> _el;
453  EL5(Graph &g) :_g(g), _el(g) {}
454  void operator()()
455  {
456    Edge e;
457   
458    for(NodeIt v(_g);v!=INVALID;++v)
459      for(NodeIt u(_g);u!=INVALID;++u)
460        e=_el(u,v);
461  }
462 
463};
464
[2238]465int main(int, char**argv)
[2235]466{
467  int N=atoi(argv[1]);
468  int M=int(N*atof(argv[2]));
469 
470  Graph g;
471 
472  std::vector<Node> v;
473  for(int i=0;i<N;i++) v.push_back(g.addNode());
[2242]474  for(int i=0;i<M;i++) g.addEdge(v[rnd[N]],v[rnd[N]]);
[2235]475
476//   {
477//     Edge e;
478   
479//     TimeReport t("findEdge: ");
480//     for(NodeIt u(g);u!=INVALID;++u)
481//       for(NodeIt v(g);v!=INVALID;++v)
482//      e=findEdge(g,u,v);
483//   }
484//   {
485//     Edge e;
486//     EdgeLookUp<Graph> el(g);
487   
488//     TimeReport t("EdgeLookUp: ");
489//     for(NodeIt u(g);u!=INVALID;++u)
490//       for(NodeIt v(g);v!=INVALID;++v)
491//      e=el(u,v);
492//   }
493
494
495  TimeStamp t1 = runningTimeTest(FE(g),1);
496  TimeStamp t2 = runningTimeTest(EL(g),1);
497  TimeStamp t3 = runningTimeTest(EL2(g),1);
498  TimeStamp t4 = runningTimeTest(EL3(g),1);
[2272]499//   TimeStamp t5 = runningTimeTest(EL4(g),1);
500//   TimeStamp t6 = runningTimeTest(EL5(g),1);
[2235]501
502  std::cout << t1.userTime()/N/N << ' '
503            << t2.userTime()/N/N << ' '
504            << t3.userTime()/N/N << ' '
505            << t4.userTime()/N/N << ' '
[2272]506//          << t5.userTime()/N/N << ' '
507//          << t6.userTime()/N/N
[2240]508            << std::endl;
[2235]509}
510
Note: See TracBrowser for help on using the repository browser.