#include #include #include #include #include #include using namespace lemon; template class EdgeLookUp2 { public: GRAPH_TYPEDEFS(typename G) typedef G Graph; private: const Graph &_g; typename Graph::template NodeMap _start; typename Graph::template NodeMap _end; std::vector _edges; class EdgeLess { const Graph &g; public: EdgeLess(const Graph &_g) : g(_g) {} bool operator()(Edge a,Edge b) const { return g.target(a)::iterator ei=_edges.end(); _end[n]=_edges.size(); std::sort(_edges.begin()+bi,ei,EdgeLess(_g)); } ///Refresh the full data structure. void refresh() { _edges.clear(); for(NodeIt n(_g);n!=INVALID;++n) refresh(n); } ///Find an edge between two nodes. ///Find an edge between two nodes. ///\param s The source node ///\param t The target node ///\return An edge from \c s to \c t if there exists, ///\ref INVALID otherwise. Edge operator()(Node s, Node t) { int a=_start[s]; int b=_end[s]; while(a class EdgeLookUp3 { public: GRAPH_TYPEDEFS(typename G) typedef G Graph; private: const Graph &_g; typename Graph::template NodeMap _start; typename Graph::template NodeMap _end; std::vector _edges; class EdgeLess { const Graph &g; public: EdgeLess(const Graph &_g) : g(_g) {} bool operator()(Edge a,Edge b) const { return g.target(a)::iterator ei=_edges.end(); _end[n]=_edges.size(); std::sort(_edges.begin()+bi,ei,EdgeLess(_g)); } ///Refresh the full data structure. void refresh() { _edges.resize(countEdges(_g)); int l=0; for(NodeIt n(_g);n!=INVALID;++n) { int ls = l; _start[n]=&(_edges[l]); for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e; _end[n]=&(_edges[l]); std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g)); } } ///Find an edge between two nodes. ///Find an edge between two nodes. ///\param s The source node ///\param t The target node ///\return An edge from \c s to \c t if there exists, ///\ref INVALID otherwise. Edge operator()(Node s, Node t) { Edge *a=_start[s]; Edge *b=_end[s]; while(a!=b) { Edge *m=a+((b-a)/2); Node tt = _g.target(*m); if(tt==t) return *m; else if(tt class EdgeLookUp4 { public: GRAPH_TYPEDEFS(typename G) typedef G Graph; private: const Graph &_g; typename Graph::template NodeMap _start; typename Graph::template NodeMap _end; std::vector _edges; class EdgeLess { const Graph &g; public: EdgeLess(const Graph &_g) : g(_g) {} bool operator()(Edge a,Edge b) const { return g.target(a)::iterator ei=_edges.end(); _end[n]=_edges.size(); std::sort(_edges.begin()+bi,ei,EdgeLess(_g)); } ///Refresh the full data structure. void refresh() { _edges.resize(countEdges(_g)); int l=0; for(NodeIt n(_g);n!=INVALID;++n) { int ls = l; _start[n]=&(_edges[l]); for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e; _end[n]=&(_edges[l]); std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g)); } } ///Find an edge between two nodes. ///Find an edge between two nodes. ///\param s The source node ///\param t The target node ///\return An edge from \c s to \c t if there exists, ///\ref INVALID otherwise. Edge operator()(Node s, Node t) { Edge *a=_start[s]; Edge *b=_end[s]; while(a!=b) { // #ifdef X86 Edge *m=(Edge*)(((unsigned int)a+(unsigned int)b)/2 & 0xfffffffc); // #elif X86_64 // Edge *m=(Edge*)(((unsigned long)a+(undigned long)b)/2 & 0xfffffffc); // #else // Edge *m=a+((b-a)/2); // #endif Node tt = _g.target(*m); if(tt==t) return *m; else if(tt class EdgeLookUp5 { public: GRAPH_TYPEDEFS(typename G) typedef G Graph; private: const Graph &_g; typename Graph::template NodeMap _start; typename Graph::template NodeMap _end; std::vector _edges; class EdgeLess { const Graph &g; public: EdgeLess(const Graph &_g) : g(_g) {} bool operator()(Edge a,Edge b) const { return g.target(a)::iterator ei=_edges.end(); _end[n]=_edges.size(); std::sort(_edges.begin()+bi,ei,EdgeLess(_g)); } ///Refresh the full data structure. void refresh() { _edges.resize(countEdges(_g)); int l=0; for(NodeIt n(_g);n!=INVALID;++n) { int ls = l; _start[n]=&(_edges[l]); for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e; _end[n]=&(_edges[l]); std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g)); } } ///Find an edge between two nodes. ///Find an edge between two nodes. ///\param s The source node ///\param t The target node ///\return An edge from \c s to \c t if there exists, ///\ref INVALID otherwise. Edge operator()(Node s, Node t) { Edge *a=_start[s]; Edge *b=_end[s]; while(a!=b) { // #ifdef X86 Edge *m=(Edge*)((((unsigned int)a>>1)+((unsigned int)b)>>1) & 0xfffffffc); // #elif X86_64 // Edge *m=(Edge*)(((unsigned long)a>>1+(undigned long)b)>>1)&0xfffffffc); // #else // Edge *m=a+((b-a)/2); // #endif Node tt = _g.target(*m); if(tt==t) return *m; else if(tt _el; EL(Graph &g) :_g(g), _el(g) {} void operator()() { Edge e; for(NodeIt v(_g);v!=INVALID;++v) for(NodeIt u(_g);u!=INVALID;++u) e=_el(u,v); } }; class EL2 { public: Graph &_g; EdgeLookUp2 _el; EL2(Graph &g) :_g(g), _el(g) {} void operator()() { Edge e; for(NodeIt v(_g);v!=INVALID;++v) for(NodeIt u(_g);u!=INVALID;++u) e=_el(u,v); } }; class EL3 { public: Graph &_g; EdgeLookUp3 _el; EL3(Graph &g) :_g(g), _el(g) {} void operator()() { Edge e; for(NodeIt v(_g);v!=INVALID;++v) for(NodeIt u(_g);u!=INVALID;++u) e=_el(u,v); } }; class EL4 { public: Graph &_g; EdgeLookUp4 _el; EL4(Graph &g) :_g(g), _el(g) {} void operator()() { Edge e; for(NodeIt v(_g);v!=INVALID;++v) for(NodeIt u(_g);u!=INVALID;++u) e=_el(u,v); } }; class EL5 { public: Graph &_g; EdgeLookUp5 _el; EL5(Graph &g) :_g(g), _el(g) {} void operator()() { Edge e; for(NodeIt v(_g);v!=INVALID;++v) for(NodeIt u(_g);u!=INVALID;++u) e=_el(u,v); } }; int main(int, char**argv) { int N=atoi(argv[1]); int M=int(N*atof(argv[2])); Graph g; std::vector v; for(int i=0;i el(g); // TimeReport t("EdgeLookUp: "); // for(NodeIt u(g);u!=INVALID;++u) // for(NodeIt v(g);v!=INVALID;++v) // e=el(u,v); // } TimeStamp t1 = runningTimeTest(FE(g),1); TimeStamp t2 = runningTimeTest(EL(g),1); TimeStamp t3 = runningTimeTest(EL2(g),1); TimeStamp t4 = runningTimeTest(EL3(g),1); TimeStamp t5 = runningTimeTest(EL4(g),1); TimeStamp t6 = runningTimeTest(EL5(g),1); std::cout << t1.userTime()/N/N << ' ' << t2.userTime()/N/N << ' ' << t3.userTime()/N/N << ' ' << t4.userTime()/N/N << ' ' << t5.userTime()/N/N << ' ' << t6.userTime()/N/N << std::endl; }