288 Parent::nextOut(i); |
278 Parent::nextOut(i); |
289 while (i!=INVALID && (!(*edge_filter_map)[i] |
279 while (i!=INVALID && (!(*edge_filter_map)[i] |
290 || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i); |
280 || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i); |
291 } |
281 } |
292 |
282 |
293 /// This function hides \c n in the graph, i.e. the iteration |
283 //x\e |
294 /// jumps over it. This is done by simply setting the value of \c n |
284 |
295 /// to be false in the corresponding node-map. |
285 //x This function hides \c n in the graph, i.e. the iteration |
|
286 //x jumps over it. This is done by simply setting the value of \c n |
|
287 //x to be false in the corresponding node-map. |
296 void hide(const Node& n) const { node_filter_map->set(n, false); } |
288 void hide(const Node& n) const { node_filter_map->set(n, false); } |
297 |
289 |
298 /// This function hides \c e in the graph, i.e. the iteration |
290 //x\e |
299 /// jumps over it. This is done by simply setting the value of \c e |
291 |
300 /// to be false in the corresponding edge-map. |
292 //x This function hides \c e in the graph, i.e. the iteration |
|
293 //x jumps over it. This is done by simply setting the value of \c e |
|
294 //x to be false in the corresponding edge-map. |
301 void hide(const Edge& e) const { edge_filter_map->set(e, false); } |
295 void hide(const Edge& e) const { edge_filter_map->set(e, false); } |
302 |
296 |
303 /// The value of \c n is set to be true in the node-map which stores |
297 //x\e |
304 /// hide information. If \c n was hidden previuosly, then it is shown |
298 |
305 /// again |
299 //x The value of \c n is set to be true in the node-map which stores |
|
300 //x hide information. If \c n was hidden previuosly, then it is shown |
|
301 //x again |
306 void unHide(const Node& n) const { node_filter_map->set(n, true); } |
302 void unHide(const Node& n) const { node_filter_map->set(n, true); } |
307 |
303 |
308 /// The value of \c e is set to be true in the edge-map which stores |
304 //x\e |
309 /// hide information. If \c e was hidden previuosly, then it is shown |
305 |
310 /// again |
306 //x The value of \c e is set to be true in the edge-map which stores |
|
307 //x hide information. If \c e was hidden previuosly, then it is shown |
|
308 //x again |
311 void unHide(const Edge& e) const { edge_filter_map->set(e, true); } |
309 void unHide(const Edge& e) const { edge_filter_map->set(e, true); } |
312 |
310 |
313 /// Returns true if \c n is hidden. |
311 //x Returns true if \c n is hidden. |
|
312 |
|
313 //x\e |
|
314 //x |
314 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; } |
315 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; } |
315 |
316 |
316 /// Returns true if \c n is hidden. |
317 //x Returns true if \c n is hidden. |
|
318 |
|
319 //x\e |
|
320 //x |
317 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; } |
321 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; } |
318 |
322 |
319 typedef False NodeNumTag; |
323 typedef False NodeNumTag; |
320 typedef False EdgeNumTag; |
324 typedef False EdgeNumTag; |
321 }; |
325 }; |
380 void nextOut(Edge& i) const { |
384 void nextOut(Edge& i) const { |
381 Parent::nextOut(i); |
385 Parent::nextOut(i); |
382 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i); |
386 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i); |
383 } |
387 } |
384 |
388 |
385 /// This function hides \c n in the graph, i.e. the iteration |
389 //x\e |
386 /// jumps over it. This is done by simply setting the value of \c n |
390 |
387 /// to be false in the corresponding node-map. |
391 //x This function hides \c n in the graph, i.e. the iteration |
|
392 //x jumps over it. This is done by simply setting the value of \c n |
|
393 //x to be false in the corresponding node-map. |
388 void hide(const Node& n) const { node_filter_map->set(n, false); } |
394 void hide(const Node& n) const { node_filter_map->set(n, false); } |
389 |
395 |
390 /// This function hides \c e in the graph, i.e. the iteration |
396 //x\e |
391 /// jumps over it. This is done by simply setting the value of \c e |
397 |
392 /// to be false in the corresponding edge-map. |
398 //x This function hides \c e in the graph, i.e. the iteration |
|
399 //x jumps over it. This is done by simply setting the value of \c e |
|
400 //x to be false in the corresponding edge-map. |
393 void hide(const Edge& e) const { edge_filter_map->set(e, false); } |
401 void hide(const Edge& e) const { edge_filter_map->set(e, false); } |
394 |
402 |
395 /// The value of \c n is set to be true in the node-map which stores |
403 //x\e |
396 /// hide information. If \c n was hidden previuosly, then it is shown |
404 |
397 /// again |
405 //x The value of \c n is set to be true in the node-map which stores |
|
406 //x hide information. If \c n was hidden previuosly, then it is shown |
|
407 //x again |
398 void unHide(const Node& n) const { node_filter_map->set(n, true); } |
408 void unHide(const Node& n) const { node_filter_map->set(n, true); } |
399 |
409 |
400 /// The value of \c e is set to be true in the edge-map which stores |
410 //x\e |
401 /// hide information. If \c e was hidden previuosly, then it is shown |
411 |
402 /// again |
412 //x The value of \c e is set to be true in the edge-map which stores |
|
413 //x hide information. If \c e was hidden previuosly, then it is shown |
|
414 //x again |
403 void unHide(const Edge& e) const { edge_filter_map->set(e, true); } |
415 void unHide(const Edge& e) const { edge_filter_map->set(e, true); } |
404 |
416 |
405 /// Returns true if \c n is hidden. |
417 //x Returns true if \c n is hidden. |
|
418 |
|
419 //x\e |
|
420 //x |
406 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; } |
421 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; } |
407 |
422 |
408 /// Returns true if \c n is hidden. |
423 //x Returns true if \c n is hidden. |
|
424 |
|
425 //x\e |
|
426 //x |
409 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; } |
427 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; } |
410 |
428 |
411 typedef False NodeNumTag; |
429 typedef False NodeNumTag; |
412 typedef False EdgeNumTag; |
430 typedef False EdgeNumTag; |
413 }; |
431 }; |
414 |
432 |
415 /*! \brief A graph adaptor for hiding nodes and edges from a graph. |
433 //x\brief A graph adaptor for hiding nodes and edges from a graph. |
416 |
434 //x\ingroup graph_adaptors |
417 \warning Graph adaptors are in even more experimental state than the other |
435 //x |
418 parts of the lib. Use them at you own risk. |
436 //x\warning Graph adaptors are in even more experimental |
419 |
437 //xstate than the other |
420 SubGraphAdaptor shows the graph with filtered node-set and |
438 //xparts of the lib. Use them at you own risk. |
421 edge-set. If the \c checked parameter is true then it filters the edgeset |
439 //x |
422 to do not get invalid edges without source or target. |
440 //xSubGraphAdaptor shows the graph with filtered node-set and |
423 Let \f$G=(V, A)\f$ be a directed graph |
441 //xedge-set. If the \c checked parameter is true then it filters the edgeset |
424 and suppose that the graph instance \c g of type ListGraph implements |
442 //xto do not get invalid edges without source or target. |
425 \f$G\f$. |
443 //xLet \f$G=(V, A)\f$ be a directed graph |
426 Let moreover \f$b_V\f$ and |
444 //xand suppose that the graph instance \c g of type ListGraph implements |
427 \f$b_A\f$ be bool-valued functions resp. on the node-set and edge-set. |
445 //x\f$G\f$. |
428 SubGraphAdaptor<...>::NodeIt iterates |
446 //x/Let moreover \f$b_V\f$ and |
429 on the node-set \f$\{v\in V : b_V(v)=true\}\f$ and |
447 //x\f$b_A\f$ be bool-valued functions resp. on the node-set and edge-set. |
430 SubGraphAdaptor<...>::EdgeIt iterates |
448 //xSubGraphAdaptor<...>::NodeIt iterates |
431 on the edge-set \f$\{e\in A : b_A(e)=true\}\f$. Similarly, |
449 //xon the node-set \f$\{v\in V : b_V(v)=true\}\f$ and |
432 SubGraphAdaptor<...>::OutEdgeIt and SubGraphAdaptor<...>::InEdgeIt iterates |
450 //xSubGraphAdaptor<...>::EdgeIt iterates |
433 only on edges leaving and entering a specific node which have true value. |
451 //xon the edge-set \f$\{e\in A : b_A(e)=true\}\f$. Similarly, |
434 |
452 //xSubGraphAdaptor<...>::OutEdgeIt and |
435 If the \c checked template parameter is false then we have to note that |
453 //xSubGraphAdaptor<...>::InEdgeIt iterates |
436 the node-iterator cares only the filter on the node-set, and the |
454 //xonly on edges leaving and entering a specific node which have true value. |
437 edge-iterator cares only the filter on the edge-set. This way the edge-map |
455 //x |
438 should filter all edges which's source or target is filtered by the |
456 //xIf the \c checked template parameter is false then we have to note that |
439 node-filter. |
457 //xthe node-iterator cares only the filter on the node-set, and the |
440 \code |
458 //xedge-iterator cares only the filter on the edge-set. |
441 typedef ListGraph Graph; |
459 //xThis way the edge-map |
442 Graph g; |
460 //xshould filter all edges which's source or target is filtered by the |
443 typedef Graph::Node Node; |
461 //xnode-filter. |
444 typedef Graph::Edge Edge; |
462 //x\code |
445 Node u=g.addNode(); //node of id 0 |
463 //xtypedef ListGraph Graph; |
446 Node v=g.addNode(); //node of id 1 |
464 //xGraph g; |
447 Node e=g.addEdge(u, v); //edge of id 0 |
465 //xtypedef Graph::Node Node; |
448 Node f=g.addEdge(v, u); //edge of id 1 |
466 //xtypedef Graph::Edge Edge; |
449 Graph::NodeMap<bool> nm(g, true); |
467 //xNode u=g.addNode(); //node of id 0 |
450 nm.set(u, false); |
468 //xNode v=g.addNode(); //node of id 1 |
451 Graph::EdgeMap<bool> em(g, true); |
469 //xNode e=g.addEdge(u, v); //edge of id 0 |
452 em.set(e, false); |
470 //xNode f=g.addEdge(v, u); //edge of id 1 |
453 typedef SubGraphAdaptor<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW; |
471 //xGraph::NodeMap<bool> nm(g, true); |
454 SubGW gw(g, nm, em); |
472 //xnm.set(u, false); |
455 for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl; |
473 //xGraph::EdgeMap<bool> em(g, true); |
456 std::cout << ":-)" << std::endl; |
474 //xem.set(e, false); |
457 for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl; |
475 //xtypedef SubGraphAdaptor<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW; |
458 \endcode |
476 //xSubGW gw(g, nm, em); |
459 The output of the above code is the following. |
477 //xfor (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl; |
460 \code |
478 //xstd::cout << ":-)" << std::endl; |
461 1 |
479 //xfor (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl; |
462 :-) |
480 //x\endcode |
463 1 |
481 //xThe output of the above code is the following. |
464 \endcode |
482 //x\code |
465 Note that \c n is of type \c SubGW::NodeIt, but it can be converted to |
483 //x1 |
466 \c Graph::Node that is why \c g.id(n) can be applied. |
484 //x:-) |
467 |
485 //x1 |
468 For other examples see also the documentation of NodeSubGraphAdaptor and |
486 //x\endcode |
469 EdgeSubGraphAdaptor. |
487 //xNote that \c n is of type \c SubGW::NodeIt, but it can be converted to |
470 |
488 //x\c Graph::Node that is why \c g.id(n) can be applied. |
471 \author Marton Makai |
489 //x |
472 */ |
490 //xFor other examples see also the documentation of NodeSubGraphAdaptor and |
|
491 //xEdgeSubGraphAdaptor. |
|
492 //x |
|
493 //x\author Marton Makai |
|
494 |
473 template<typename _Graph, typename NodeFilterMap, |
495 template<typename _Graph, typename NodeFilterMap, |
474 typename EdgeFilterMap, bool checked = true> |
496 typename EdgeFilterMap, bool checked = true> |
475 class SubGraphAdaptor : |
497 class SubGraphAdaptor : |
476 public IterableGraphExtender< |
498 public IterableGraphExtender< |
477 SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, checked> > { |
499 SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, checked> > { |
521 Parent::setEdgeFilterMap(const_true_map); |
545 Parent::setEdgeFilterMap(const_true_map); |
522 } |
546 } |
523 }; |
547 }; |
524 |
548 |
525 |
549 |
526 /*! \brief An adaptor for hiding edges from a graph. |
550 //x\brief An adaptor for hiding edges from a graph. |
527 |
551 //x |
528 \warning Graph adaptors are in even more experimental state than the other |
552 //x\warning Graph adaptors are in even more experimental state |
529 parts of the lib. Use them at you own risk. |
553 //xthan the other parts of the lib. Use them at you own risk. |
530 |
554 //x |
531 An adaptor for hiding edges from a graph. |
555 //xAn adaptor for hiding edges from a graph. |
532 This adaptor specializes SubGraphAdaptor in the way that only the edge-set |
556 //xThis adaptor specializes SubGraphAdaptor in the way that |
533 can be filtered. The usefulness of this adaptor is demonstrated in the |
557 //xonly the edge-set |
534 problem of searching a maximum number of edge-disjoint shortest paths |
558 //xcan be filtered. The usefulness of this adaptor is demonstrated in the |
535 between |
559 //xproblem of searching a maximum number of edge-disjoint shortest paths |
536 two nodes \c s and \c t. Shortest here means being shortest w.r.t. |
560 //xbetween |
537 non-negative edge-lengths. Note that |
561 //xtwo nodes \c s and \c t. Shortest here means being shortest w.r.t. |
538 the comprehension of the presented solution |
562 //xnon-negative edge-lengths. Note that |
539 need's some elementary knowledge from combinatorial optimization. |
563 //xthe comprehension of the presented solution |
540 |
564 //xneed's some elementary knowledge from combinatorial optimization. |
541 If a single shortest path is to be |
565 //x |
542 searched between \c s and \c t, then this can be done easily by |
566 //xIf a single shortest path is to be |
543 applying the Dijkstra algorithm. What happens, if a maximum number of |
567 //xsearched between \c s and \c t, then this can be done easily by |
544 edge-disjoint shortest paths is to be computed. It can be proved that an |
568 //xapplying the Dijkstra algorithm. What happens, if a maximum number of |
545 edge can be in a shortest path if and only if it is tight with respect to |
569 //xedge-disjoint shortest paths is to be computed. It can be proved that an |
546 the potential function computed by Dijkstra. Moreover, any path containing |
570 //xedge can be in a shortest path if and only |
547 only such edges is a shortest one. Thus we have to compute a maximum number |
571 //xif it is tight with respect to |
548 of edge-disjoint paths between \c s and \c t in the graph which has edge-set |
572 //xthe potential function computed by Dijkstra. |
549 all the tight edges. The computation will be demonstrated on the following |
573 //xMoreover, any path containing |
550 graph, which is read from the dimacs file \c sub_graph_adaptor_demo.dim. |
574 //xonly such edges is a shortest one. |
551 The full source code is available in \ref sub_graph_adaptor_demo.cc. |
575 //xThus we have to compute a maximum number |
552 If you are interested in more demo programs, you can use |
576 //xof edge-disjoint paths between \c s and \c t in |
553 \ref dim_to_dot.cc to generate .dot files from dimacs files. |
577 //xthe graph which has edge-set |
554 The .dot file of the following figure was generated by |
578 //xall the tight edges. The computation will be demonstrated |
555 the demo program \ref dim_to_dot.cc. |
579 //xon the following |
556 |
580 //xgraph, which is read from the dimacs file \c sub_graph_adaptor_demo.dim. |
557 \dot |
581 //xThe full source code is available in \ref sub_graph_adaptor_demo.cc. |
558 digraph lemon_dot_example { |
582 //xIf you are interested in more demo programs, you can use |
559 node [ shape=ellipse, fontname=Helvetica, fontsize=10 ]; |
583 //x\ref dim_to_dot.cc to generate .dot files from dimacs files. |
560 n0 [ label="0 (s)" ]; |
584 //xThe .dot file of the following figure was generated by |
561 n1 [ label="1" ]; |
585 //xthe demo program \ref dim_to_dot.cc. |
562 n2 [ label="2" ]; |
586 //x |
563 n3 [ label="3" ]; |
587 //x\dot |
564 n4 [ label="4" ]; |
588 //xdigraph lemon_dot_example { |
565 n5 [ label="5" ]; |
589 //xnode [ shape=ellipse, fontname=Helvetica, fontsize=10 ]; |
566 n6 [ label="6 (t)" ]; |
590 //xn0 [ label="0 (s)" ]; |
567 edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ]; |
591 //xn1 [ label="1" ]; |
568 n5 -> n6 [ label="9, length:4" ]; |
592 //xn2 [ label="2" ]; |
569 n4 -> n6 [ label="8, length:2" ]; |
593 //xn3 [ label="3" ]; |
570 n3 -> n5 [ label="7, length:1" ]; |
594 //xn4 [ label="4" ]; |
571 n2 -> n5 [ label="6, length:3" ]; |
595 //xn5 [ label="5" ]; |
572 n2 -> n6 [ label="5, length:5" ]; |
596 //xn6 [ label="6 (t)" ]; |
573 n2 -> n4 [ label="4, length:2" ]; |
597 //xedge [ shape=ellipse, fontname=Helvetica, fontsize=10 ]; |
574 n1 -> n4 [ label="3, length:3" ]; |
598 //xn5 -> n6 [ label="9, length:4" ]; |
575 n0 -> n3 [ label="2, length:1" ]; |
599 //xn4 -> n6 [ label="8, length:2" ]; |
576 n0 -> n2 [ label="1, length:2" ]; |
600 //xn3 -> n5 [ label="7, length:1" ]; |
577 n0 -> n1 [ label="0, length:3" ]; |
601 //xn2 -> n5 [ label="6, length:3" ]; |
578 } |
602 //xn2 -> n6 [ label="5, length:5" ]; |
579 \enddot |
603 //xn2 -> n4 [ label="4, length:2" ]; |
580 |
604 //xn1 -> n4 [ label="3, length:3" ]; |
581 \code |
605 //xn0 -> n3 [ label="2, length:1" ]; |
582 Graph g; |
606 //xn0 -> n2 [ label="1, length:2" ]; |
583 Node s, t; |
607 //xn0 -> n1 [ label="0, length:3" ]; |
584 LengthMap length(g); |
608 //x} |
585 |
609 //x\enddot |
586 readDimacs(std::cin, g, length, s, t); |
610 //x |
587 |
611 //x\code |
588 cout << "edges with lengths (of form id, source--length->target): " << endl; |
612 //xGraph g; |
589 for(EdgeIt e(g); e!=INVALID; ++e) |
613 //xNode s, t; |
590 cout << g.id(e) << ", " << g.id(g.source(e)) << "--" |
614 //xLengthMap length(g); |
591 << length[e] << "->" << g.id(g.target(e)) << endl; |
615 //x |
592 |
616 //xreadDimacs(std::cin, g, length, s, t); |
593 cout << "s: " << g.id(s) << " t: " << g.id(t) << endl; |
617 //x |
594 \endcode |
618 //xcout << "edges with lengths (of form id, source--length->target): " << endl; |
595 Next, the potential function is computed with Dijkstra. |
619 //xfor(EdgeIt e(g); e!=INVALID; ++e) |
596 \code |
620 //x cout << g.id(e) << ", " << g.id(g.source(e)) << "--" |
597 typedef Dijkstra<Graph, LengthMap> Dijkstra; |
621 //x << length[e] << "->" << g.id(g.target(e)) << endl; |
598 Dijkstra dijkstra(g, length); |
622 //x |
599 dijkstra.run(s); |
623 //xcout << "s: " << g.id(s) << " t: " << g.id(t) << endl; |
600 \endcode |
624 //x\endcode |
601 Next, we consrtruct a map which filters the edge-set to the tight edges. |
625 //xNext, the potential function is computed with Dijkstra. |
602 \code |
626 //x\code |
603 typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap> |
627 //xtypedef Dijkstra<Graph, LengthMap> Dijkstra; |
604 TightEdgeFilter; |
628 //xDijkstra dijkstra(g, length); |
605 TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length); |
629 //xdijkstra.run(s); |
606 |
630 //x\endcode |
607 typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW; |
631 //xNext, we consrtruct a map which filters the edge-set to the tight edges. |
608 SubGW gw(g, tight_edge_filter); |
632 //x\code |
609 \endcode |
633 //xtypedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap> |
610 Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed |
634 //x TightEdgeFilter; |
611 with a max flow algorithm Preflow. |
635 //xTightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length); |
612 \code |
636 //x |
613 ConstMap<Edge, int> const_1_map(1); |
637 //xtypedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW; |
614 Graph::EdgeMap<int> flow(g, 0); |
638 //xSubGW gw(g, tight_edge_filter); |
615 |
639 //x\endcode |
616 Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> > |
640 //xThen, the maximum nimber of edge-disjoint \c s-\c t paths are computed |
617 preflow(gw, s, t, const_1_map, flow); |
641 //xwith a max flow algorithm Preflow. |
618 preflow.run(); |
642 //x\code |
619 \endcode |
643 //xConstMap<Edge, int> const_1_map(1); |
620 Last, the output is: |
644 //xGraph::EdgeMap<int> flow(g, 0); |
621 \code |
645 //x |
622 cout << "maximum number of edge-disjoint shortest path: " |
646 //xPreflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> > |
623 << preflow.flowValue() << endl; |
647 //x preflow(gw, s, t, const_1_map, flow); |
624 cout << "edges of the maximum number of edge-disjoint shortest s-t paths: " |
648 //xpreflow.run(); |
625 << endl; |
649 //x\endcode |
626 for(EdgeIt e(g); e!=INVALID; ++e) |
650 //xLast, the output is: |
627 if (flow[e]) |
651 //x\code |
628 cout << " " << g.id(g.source(e)) << "--" |
652 //xcout << "maximum number of edge-disjoint shortest path: " |
629 << length[e] << "->" << g.id(g.target(e)) << endl; |
653 //x << preflow.flowValue() << endl; |
630 \endcode |
654 //xcout << "edges of the maximum number of edge-disjoint shortest s-t paths: " |
631 The program has the following (expected :-)) output: |
655 //x << endl; |
632 \code |
656 //xfor(EdgeIt e(g); e!=INVALID; ++e) |
633 edges with lengths (of form id, source--length->target): |
657 //x if (flow[e]) |
634 9, 5--4->6 |
658 //x cout << " " << g.id(g.source(e)) << "--" |
635 8, 4--2->6 |
659 //x << length[e] << "->" << g.id(g.target(e)) << endl; |
636 7, 3--1->5 |
660 //x\endcode |
637 6, 2--3->5 |
661 //xThe program has the following (expected :-)) output: |
638 5, 2--5->6 |
662 //x\code |
639 4, 2--2->4 |
663 //xedges with lengths (of form id, source--length->target): |
640 3, 1--3->4 |
664 //x 9, 5--4->6 |
641 2, 0--1->3 |
665 //x 8, 4--2->6 |
642 1, 0--2->2 |
666 //x 7, 3--1->5 |
643 0, 0--3->1 |
667 //x 6, 2--3->5 |
644 s: 0 t: 6 |
668 //x 5, 2--5->6 |
645 maximum number of edge-disjoint shortest path: 2 |
669 //x 4, 2--2->4 |
646 edges of the maximum number of edge-disjoint shortest s-t paths: |
670 //x 3, 1--3->4 |
647 9, 5--4->6 |
671 //x 2, 0--1->3 |
648 8, 4--2->6 |
672 //x 1, 0--2->2 |
649 7, 3--1->5 |
673 //x 0, 0--3->1 |
650 4, 2--2->4 |
674 //xs: 0 t: 6 |
651 2, 0--1->3 |
675 //xmaximum number of edge-disjoint shortest path: 2 |
652 1, 0--2->2 |
676 //xedges of the maximum number of edge-disjoint shortest s-t paths: |
653 \endcode |
677 //x 9, 5--4->6 |
654 |
678 //x 8, 4--2->6 |
655 \author Marton Makai |
679 //x 7, 3--1->5 |
656 */ |
680 //x 4, 2--2->4 |
|
681 //x 2, 0--1->3 |
|
682 //x 1, 0--2->2 |
|
683 //x\endcode |
|
684 //x |
|
685 //x\author Marton Makai |
657 template<typename Graph, typename EdgeFilterMap> |
686 template<typename Graph, typename EdgeFilterMap> |
658 class EdgeSubGraphAdaptor : |
687 class EdgeSubGraphAdaptor : |
659 public SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>, |
688 public SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>, |
660 EdgeFilterMap, false> { |
689 EdgeFilterMap, false> { |
661 public: |
690 public: |
791 // edge_filter_map(&edge_filter_map) { } |
821 // edge_filter_map(&edge_filter_map) { } |
792 |
822 |
793 typedef typename Parent::Node Node; |
823 typedef typename Parent::Node Node; |
794 typedef typename _Graph::Edge GraphEdge; |
824 typedef typename _Graph::Edge GraphEdge; |
795 template <typename T> class EdgeMap; |
825 template <typename T> class EdgeMap; |
796 /// SubBidirGraphAdaptorBase<..., ..., ...>::Edge is inherited from |
826 // SubBidirGraphAdaptorBase<..., ..., ...>::Edge is inherited from |
797 /// _Graph::Edge. It contains an extra bool flag which is true |
827 // _Graph::Edge. It contains an extra bool flag which is true |
798 /// if and only if the |
828 // if and only if the |
799 /// edge is the backward version of the original edge. |
829 // edge is the backward version of the original edge. |
800 class Edge : public _Graph::Edge { |
830 class Edge : public _Graph::Edge { |
801 friend class SubBidirGraphAdaptorBase< |
831 friend class SubBidirGraphAdaptorBase< |
802 Graph, ForwardFilterMap, BackwardFilterMap>; |
832 Graph, ForwardFilterMap, BackwardFilterMap>; |
803 template<typename T> friend class EdgeMap; |
833 template<typename T> friend class EdgeMap; |
804 protected: |
834 protected: |
805 bool backward; //true, iff backward |
835 bool backward; //true, iff backward |
806 public: |
836 public: |
807 Edge() { } |
837 Edge() { } |
808 /// \todo =false is needed, or causes problems? |
838 // \todo =false is needed, or causes problems? |
809 /// If \c _backward is false, then we get an edge corresponding to the |
839 // If \c _backward is false, then we get an edge corresponding to the |
810 /// original one, otherwise its oppositely directed pair is obtained. |
840 // original one, otherwise its oppositely directed pair is obtained. |
811 Edge(const typename _Graph::Edge& e, bool _backward/*=false*/) : |
841 Edge(const typename _Graph::Edge& e, bool _backward/*=false*/) : |
812 _Graph::Edge(e), backward(_backward) { } |
842 _Graph::Edge(e), backward(_backward) { } |
813 Edge(Invalid i) : _Graph::Edge(i), backward(true) { } |
843 Edge(Invalid i) : _Graph::Edge(i), backward(true) { } |
814 bool operator==(const Edge& v) const { |
844 bool operator==(const Edge& v) const { |
815 return (this->backward==v.backward && |
845 return (this->backward==v.backward && |
1000 }; |
1037 }; |
1001 |
1038 |
1002 }; |
1039 }; |
1003 |
1040 |
1004 |
1041 |
1005 ///\brief An adaptor for composing a subgraph of a |
1042 //x\brief An adaptor for composing a subgraph of a |
1006 /// bidirected graph made from a directed one. |
1043 //x bidirected graph made from a directed one. |
1007 /// |
1044 //x\ingroup graph_adaptors |
1008 /// An adaptor for composing a subgraph of a |
1045 //x |
1009 /// bidirected graph made from a directed one. |
1046 //x An adaptor for composing a subgraph of a |
1010 /// |
1047 //x bidirected graph made from a directed one. |
1011 ///\warning Graph adaptors are in even more experimental state than the other |
1048 //x |
1012 ///parts of the lib. Use them at you own risk. |
1049 //x\warning Graph adaptors are in even more experimental state |
1013 /// |
1050 //xthan the other |
1014 /// Let \f$G=(V, A)\f$ be a directed graph and for each directed edge |
1051 //xparts of the lib. Use them at you own risk. |
1015 /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by |
1052 //x |
1016 /// reversing its orientation. We are given moreover two bool valued |
1053 //x Let \f$G=(V, A)\f$ be a directed graph and for each directed edge |
1017 /// maps on the edge-set, |
1054 //x \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by |
1018 /// \f$forward\_filter\f$, and \f$backward\_filter\f$. |
1055 //x reversing its orientation. We are given moreover two bool valued |
1019 /// SubBidirGraphAdaptor implements the graph structure with node-set |
1056 //x maps on the edge-set, |
1020 /// \f$V\f$ and edge-set |
1057 //x \f$forward\_filter\f$, and \f$backward\_filter\f$. |
1021 /// \f$\{e : e\in A \mbox{ and } forward\_filter(e) \mbox{ is true}\}+\{\bar e : e\in A \mbox{ and } backward\_filter(e) \mbox{ is true}\}\f$. |
1058 //x SubBidirGraphAdaptor implements the graph structure with node-set |
1022 /// The purpose of writing + instead of union is because parallel |
1059 //x \f$V\f$ and edge-set |
1023 /// edges can arise. (Similarly, antiparallel edges also can arise). |
1060 //x \f$\{e : e\in A \mbox{ and } forward\_filter(e) \mbox{ is true}\}+\{\bar e : e\in A \mbox{ and } backward\_filter(e) \mbox{ is true}\}\f$. |
1024 /// In other words, a subgraph of the bidirected graph obtained, which |
1061 //x The purpose of writing + instead of union is because parallel |
1025 /// is given by orienting the edges of the original graph in both directions. |
1062 //x edges can arise. (Similarly, antiparallel edges also can arise). |
1026 /// As the oppositely directed edges are logically different, |
1063 //x In other words, a subgraph of the bidirected graph obtained, which |
1027 /// the maps are able to attach different values for them. |
1064 //x is given by orienting the edges of the original graph in both directions. |
1028 /// |
1065 //x As the oppositely directed edges are logically different, |
1029 /// An example for such a construction is \c RevGraphAdaptor where the |
1066 //x the maps are able to attach different values for them. |
1030 /// forward_filter is everywhere false and the backward_filter is |
1067 //x |
1031 /// everywhere true. We note that for sake of efficiency, |
1068 //x An example for such a construction is \c RevGraphAdaptor where the |
1032 /// \c RevGraphAdaptor is implemented in a different way. |
1069 //x forward_filter is everywhere false and the backward_filter is |
1033 /// But BidirGraphAdaptor is obtained from |
1070 //x everywhere true. We note that for sake of efficiency, |
1034 /// SubBidirGraphAdaptor by considering everywhere true |
1071 //x \c RevGraphAdaptor is implemented in a different way. |
1035 /// valued maps both for forward_filter and backward_filter. |
1072 //x But BidirGraphAdaptor is obtained from |
1036 /// |
1073 //x SubBidirGraphAdaptor by considering everywhere true |
1037 /// The most important application of SubBidirGraphAdaptor |
1074 //x valued maps both for forward_filter and backward_filter. |
1038 /// is ResGraphAdaptor, which stands for the residual graph in directed |
1075 //x |
1039 /// flow and circulation problems. |
1076 //x The most important application of SubBidirGraphAdaptor |
1040 /// As adaptors usually, the SubBidirGraphAdaptor implements the |
1077 //x is ResGraphAdaptor, which stands for the residual graph in directed |
1041 /// above mentioned graph structure without its physical storage, |
1078 //x flow and circulation problems. |
1042 /// that is the whole stuff is stored in constant memory. |
1079 //x As adaptors usually, the SubBidirGraphAdaptor implements the |
|
1080 //x above mentioned graph structure without its physical storage, |
|
1081 //x that is the whole stuff is stored in constant memory. |
1043 template<typename _Graph, |
1082 template<typename _Graph, |
1044 typename ForwardFilterMap, typename BackwardFilterMap> |
1083 typename ForwardFilterMap, typename BackwardFilterMap> |
1045 class SubBidirGraphAdaptor : |
1084 class SubBidirGraphAdaptor : |
1046 public IterableGraphExtender< |
1085 public IterableGraphExtender< |
1047 SubBidirGraphAdaptorBase<_Graph, ForwardFilterMap, BackwardFilterMap> > { |
1086 SubBidirGraphAdaptorBase<_Graph, ForwardFilterMap, BackwardFilterMap> > { |
1137 return (Number(0) < Number((*flow)[e])); |
1178 return (Number(0) < Number((*flow)[e])); |
1138 } |
1179 } |
1139 }; |
1180 }; |
1140 |
1181 |
1141 |
1182 |
1142 /*! \brief An adaptor for composing the residual graph for directed flow and circulation problems. |
1183 //x\brief An adaptor for composing the residual |
1143 |
1184 //xgraph for directed flow and circulation problems. |
1144 An adaptor for composing the residual graph for directed flow and circulation problems. |
1185 //x\ingroup graph_adaptors |
1145 Let \f$G=(V, A)\f$ be a directed graph and let \f$F\f$ be a |
1186 //x |
1146 number type. Let moreover |
1187 //xAn adaptor for composing the residual graph for |
1147 \f$f,c:A\to F\f$, be functions on the edge-set. |
1188 //xdirected flow and circulation problems. |
1148 In the appications of ResGraphAdaptor, \f$f\f$ usually stands for a flow |
1189 //xLet \f$G=(V, A)\f$ be a directed graph and let \f$F\f$ be a |
1149 and \f$c\f$ for a capacity function. |
1190 //xnumber type. Let moreover |
1150 Suppose that a graph instange \c g of type |
1191 //x\f$f,c:A\to F\f$, be functions on the edge-set. |
1151 \c ListGraph implements \f$G\f$. |
1192 //xIn the appications of ResGraphAdaptor, \f$f\f$ usually stands for a flow |
1152 \code |
1193 //xand \f$c\f$ for a capacity function. |
1153 ListGraph g; |
1194 //xSuppose that a graph instange \c g of type |
1154 \endcode |
1195 //x\c ListGraph implements \f$G\f$ . |
1155 Then RevGraphAdaptor implements the graph structure with node-set |
1196 //x\code |
1156 \f$V\f$ and edge-set \f$A_{forward}\cup A_{backward}\f$, where |
1197 //x ListGraph g; |
1157 \f$A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\}\f$ and |
1198 //x\endcode |
1158 \f$A_{backward}=\{vu : uv\in A, f(uv)>0\}\f$, |
1199 //xThen RevGraphAdaptor implements the graph structure with node-set |
1159 i.e. the so called residual graph. |
1200 //x\f$V\f$ and edge-set \f$A_{forward}\cup A_{backward}\f$, where |
1160 When we take the union \f$A_{forward}\cup A_{backward}\f$, |
1201 //x\f$A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\}\f$ and |
1161 multilicities are counted, i.e. if an edge is in both |
1202 //x\f$A_{backward}=\{vu : uv\in A, f(uv)>0\}\f$, |
1162 \f$A_{forward}\f$ and \f$A_{backward}\f$, then in the adaptor it |
1203 //xi.e. the so called residual graph. |
1163 appears twice. |
1204 //xWhen we take the union \f$A_{forward}\cup A_{backward}\f$, |
1164 The following code shows how |
1205 //xmultilicities are counted, i.e. if an edge is in both |
1165 such an instance can be constructed. |
1206 //x\f$A_{forward}\f$ and \f$A_{backward}\f$, then in the adaptor it |
1166 \code |
1207 //xappears twice. |
1167 typedef ListGraph Graph; |
1208 //xThe following code shows how |
1168 Graph::EdgeMap<int> f(g); |
1209 //xsuch an instance can be constructed. |
1169 Graph::EdgeMap<int> c(g); |
1210 //x\code |
1170 ResGraphAdaptor<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > gw(g); |
1211 //xtypedef ListGraph Graph; |
1171 \endcode |
1212 //xGraph::EdgeMap<int> f(g); |
1172 \author Marton Makai |
1213 //xGraph::EdgeMap<int> c(g); |
1173 */ |
1214 //xResGraphAdaptor<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > gw(g); |
|
1215 //x\endcode |
|
1216 //x\author Marton Makai |
|
1217 //x |
1174 template<typename Graph, typename Number, |
1218 template<typename Graph, typename Number, |
1175 typename CapacityMap, typename FlowMap> |
1219 typename CapacityMap, typename FlowMap> |
1176 class ResGraphAdaptor : |
1220 class ResGraphAdaptor : |
1177 public SubBidirGraphAdaptor< |
1221 public SubBidirGraphAdaptor< |
1178 Graph, |
1222 Graph, |