Query improvements in the min cost flow algorithms.
- External flow and potential maps can be used.
- New query functions: flow() and potential().
- CycleCanceling also provides dual solution (node potentials).
- Doc improvements.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #include<lemon/smart_graph.h>
21 #include<lemon/time_measure.h>
22 #include<lemon/random.h>
23 #include<lemon/graph_utils.h>
26 using namespace lemon;
32 GRAPH_TYPEDEFS(typename G);
37 typename Graph::template NodeMap<int> _start;
38 typename Graph::template NodeMap<int> _end;
39 std::vector<Edge> _edges;
44 EdgeLess(const Graph &_g) : g(_g) {}
45 bool operator()(Edge a,Edge b) const
47 return g.target(a)<g.target(b);
54 EdgeLookUp2(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
57 ///Refresh the data structure at a node.
60 const int bi = _start[n] = _edges.size();
61 for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
62 const typename std::vector<Edge>::iterator ei=_edges.end();
63 _end[n]=_edges.size();
64 std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
66 ///Refresh the full data structure.
70 for(NodeIt n(_g);n!=INVALID;++n) refresh(n);
73 ///Find an edge between two nodes.
75 ///Find an edge between two nodes.
76 ///\param s The source node
77 ///\param t The target node
78 ///\return An edge from \c s to \c t if there exists,
79 ///\ref INVALID otherwise.
81 Edge operator()(Node s, Node t)
88 Node tt = _g.target(_edges[n]);
89 if(tt==t) return _edges[n];
98 ///\warning This function is unimplemented.
99 Edge operator()(Node s, Node t, Edge prev)
101 return prev==INVALID?(*this)(s,t):INVALID;
110 GRAPH_TYPEDEFS(typename G);
115 typename Graph::template NodeMap<Edge*> _start;
116 typename Graph::template NodeMap<Edge*> _end;
117 std::vector<Edge> _edges;
122 EdgeLess(const Graph &_g) : g(_g) {}
123 bool operator()(Edge a,Edge b) const
125 return g.target(a)<g.target(b);
132 EdgeLookUp3(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
135 ///Refresh the data structure at a node.
138 const int bi = _start[n] = _edges.size();
139 for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
140 const typename std::vector<Edge>::iterator ei=_edges.end();
141 _end[n]=_edges.size();
142 std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
144 ///Refresh the full data structure.
147 _edges.resize(countEdges(_g));
149 for(NodeIt n(_g);n!=INVALID;++n)
152 _start[n]=&(_edges[l]);
153 for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e;
154 _end[n]=&(_edges[l]);
155 std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g));
160 ///Find an edge between two nodes.
162 ///Find an edge between two nodes.
163 ///\param s The source node
164 ///\param t The target node
165 ///\return An edge from \c s to \c t if there exists,
166 ///\ref INVALID otherwise.
168 Edge operator()(Node s, Node t)
175 Node tt = _g.target(*m);
183 ///Find the next edge
185 ///\warning This function is unimplemented.
186 Edge operator()(Node s, Node t, Edge prev)
188 return prev==INVALID?(*this)(s,t):INVALID;
197 // GRAPH_TYPEDEFS(typename G);
202 // typename Graph::template NodeMap<Edge*> _start;
203 // typename Graph::template NodeMap<Edge*> _end;
204 // std::vector<Edge> _edges;
209 // EdgeLess(const Graph &_g) : g(_g) {}
210 // bool operator()(Edge a,Edge b) const
212 // return g.target(a)<g.target(b);
219 // EdgeLookUp4(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
222 // ///Refresh the data structure at a node.
223 // void refresh(Node n)
225 // const int bi = _start[n] = _edges.size();
226 // for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
227 // const typename std::vector<Edge>::iterator ei=_edges.end();
228 // _end[n]=_edges.size();
229 // std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
231 // ///Refresh the full data structure.
234 // _edges.resize(countEdges(_g));
236 // for(NodeIt n(_g);n!=INVALID;++n)
239 // _start[n]=&(_edges[l]);
240 // for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e;
241 // _end[n]=&(_edges[l]);
242 // std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g));
247 // ///Find an edge between two nodes.
249 // ///Find an edge between two nodes.
250 // ///\param s The source node
251 // ///\param t The target node
252 // ///\return An edge from \c s to \c t if there exists,
253 // ///\ref INVALID otherwise.
255 // Edge operator()(Node s, Node t)
257 // Edge *a=_start[s];
262 // Edge *m=(Edge*)(((unsigned int)a+(unsigned int)b)/2 & 0xfffffffc);
264 // // Edge *m=(Edge*)(((unsigned long)a+(undigned long)b)/2 & 0xfffffffc);
266 // // Edge *m=a+((b-a)/2);
268 // Node tt = _g.target(*m);
269 // if(tt==t) return *m;
270 // else if(tt<t) a=m+1;
276 // ///Find the next edge
278 // ///\warning This function is unimplemented.
279 // Edge operator()(Node s, Node t, Edge prev)
281 // return prev==INVALID?(*this)(s,t):INVALID;
290 // GRAPH_TYPEDEFS(typename G);
295 // typename Graph::template NodeMap<Edge*> _start;
296 // typename Graph::template NodeMap<Edge*> _end;
297 // std::vector<Edge> _edges;
302 // EdgeLess(const Graph &_g) : g(_g) {}
303 // bool operator()(Edge a,Edge b) const
305 // return g.target(a)<g.target(b);
312 // EdgeLookUp5(const Graph &g) :_g(g),_start(g),_end(g) {refresh();}
315 // ///Refresh the data structure at a node.
316 // void refresh(Node n)
318 // const int bi = _start[n] = _edges.size();
319 // for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges.push_back(e);
320 // const typename std::vector<Edge>::iterator ei=_edges.end();
321 // _end[n]=_edges.size();
322 // std::sort(_edges.begin()+bi,ei,EdgeLess(_g));
324 // ///Refresh the full data structure.
327 // _edges.resize(countEdges(_g));
329 // for(NodeIt n(_g);n!=INVALID;++n)
332 // _start[n]=&(_edges[l]);
333 // for(OutEdgeIt e(_g,n);e!=INVALID;++e) _edges[l++]=e;
334 // _end[n]=&(_edges[l]);
335 // std::sort(_edges.begin()+ls,_edges.begin()+l,EdgeLess(_g));
340 // ///Find an edge between two nodes.
342 // ///Find an edge between two nodes.
343 // ///\param s The source node
344 // ///\param t The target node
345 // ///\return An edge from \c s to \c t if there exists,
346 // ///\ref INVALID otherwise.
348 // Edge operator()(Node s, Node t)
350 // Edge *a=_start[s];
355 // Edge *m=(Edge*)((((unsigned int)a>>1)+((unsigned int)b)>>1)
358 // // Edge *m=(Edge*)(((unsigned long)a>>1+(undigned long)b)>>1)&0xfffffffc);
360 // // Edge *m=a+((b-a)/2);
362 // Node tt = _g.target(*m);
363 // if(tt==t) return *m;
364 // else if(tt<t) a=m+1;
370 // ///Find the next edge
372 // ///\warning This function is unimplemented.
373 // Edge operator()(Node s, Node t, Edge prev)
375 // return prev==INVALID?(*this)(s,t):INVALID;
380 GRAPH_TYPEDEFS(SmartGraph);
381 typedef SmartGraph Graph;
387 FE(Graph &g) :_g(g) {}
392 for(NodeIt v(_g);v!=INVALID;++v)
393 for(NodeIt u(_g);u!=INVALID;++u)
403 EdgeLookUp<Graph> _el;
404 EL(Graph &g) :_g(g), _el(g) {}
409 for(NodeIt v(_g);v!=INVALID;++v)
410 for(NodeIt u(_g);u!=INVALID;++u)
420 DynEdgeLookUp<Graph> _el;
421 DEL(Graph &g) :_g(g), _el(g) {}
426 for(NodeIt v(_g);v!=INVALID;++v)
427 for(NodeIt u(_g);u!=INVALID;++u)
437 EdgeLookUp2<Graph> _el;
438 EL2(Graph &g) :_g(g), _el(g) {}
443 for(NodeIt v(_g);v!=INVALID;++v)
444 for(NodeIt u(_g);u!=INVALID;++u)
454 EdgeLookUp3<Graph> _el;
455 EL3(Graph &g) :_g(g), _el(g) {}
460 for(NodeIt v(_g);v!=INVALID;++v)
461 for(NodeIt u(_g);u!=INVALID;++u)
471 // EdgeLookUp4<Graph> _el;
472 // EL4(Graph &g) :_g(g), _el(g) {}
477 // for(NodeIt v(_g);v!=INVALID;++v)
478 // for(NodeIt u(_g);u!=INVALID;++u)
488 // EdgeLookUp5<Graph> _el;
489 // EL5(Graph &g) :_g(g), _el(g) {}
494 // for(NodeIt v(_g);v!=INVALID;++v)
495 // for(NodeIt u(_g);u!=INVALID;++u)
501 int main(int, char**argv)
504 int M=int(N*atof(argv[2]));
509 for(int i=0;i<N;i++) v.push_back(g.addNode());
510 for(int i=0;i<M;i++) g.addEdge(v[rnd[N]],v[rnd[N]]);
515 // TimeReport t("findEdge: ");
516 // for(NodeIt u(g);u!=INVALID;++u)
517 // for(NodeIt v(g);v!=INVALID;++v)
518 // e=findEdge(g,u,v);
522 // EdgeLookUp<Graph> el(g);
524 // TimeReport t("EdgeLookUp: ");
525 // for(NodeIt u(g);u!=INVALID;++u)
526 // for(NodeIt v(g);v!=INVALID;++v)
531 TimeStamp t1 = runningTimeTest(FE(g),1);
532 TimeStamp t2 = runningTimeTest(EL(g),1);
533 TimeStamp t3 = runningTimeTest(DEL(g),1);
534 TimeStamp t4 = runningTimeTest(EL2(g),1);
535 TimeStamp t5 = runningTimeTest(EL3(g),1);
536 // TimeStamp t5 = runningTimeTest(EL4(g),1);
537 // TimeStamp t6 = runningTimeTest(EL5(g),1);
539 std::cout << t1.userTime() << ' '
540 << t2.userTime() << ' '
541 << t3.userTime() << ' '
542 << t4.userTime() << ' '
543 << t5.userTime() << ' '
544 // << t5.userTime() << ' '
547 std::cout << t1.userTime()/N/N << ' '
548 << t2.userTime()/N/N << ' '
549 << t3.userTime()/N/N << ' '
550 << t4.userTime()/N/N << ' '
551 << t5.userTime()/N/N << ' '
552 // << t5.userTime()/N/N << ' '
553 // << t6.userTime()/N/N