3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
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 #ifndef LEMON_SUB_GRAPH_H
20 #define LEMON_SUB_GRAPH_H
22 #include <lemon/graph_adaptor.h>
26 /// \brief Base for the SubGraph.
28 /// Base for the SubGraph.
29 template <typename _Graph>
30 class SubGraphBase : public GraphAdaptorBase<const _Graph> {
33 typedef SubGraphBase<_Graph> SubGraph;
34 typedef GraphAdaptorBase<const _Graph> Parent;
37 typedef typename Parent::Node Node;
38 typedef typename Parent::Edge Edge;
48 void construct(const Graph& _graph, NodesImpl& _nodes, EdgesImpl& _edges) {
49 Parent::setGraph(_graph);
56 while (node != INVALID) {
57 (*nodes)[node].prev = node;
58 (*nodes)[node].firstIn = INVALID;
59 (*nodes)[node].firstOut = INVALID;
65 while (edge != INVALID) {
66 (*edges)[edge].prevOut = edge;
73 void first(Node& node) const {
76 void next(Node& node) const {
77 node = (*nodes)[node].next;
80 void first(Edge& edge) const {
81 Node node = firstNode;
82 while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
83 node = (*nodes)[node].next;
85 if (node == INVALID) {
88 edge = (*nodes)[node].firstOut;
91 void next(Edge& edge) const {
92 if ((*edges)[edge].nextOut != INVALID) {
93 edge = (*edges)[edge].nextOut;
95 Node node = (*nodes)[source(edge)].next;
96 while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
97 node = (*nodes)[node].next;
99 if (node == INVALID) {
102 edge = (*nodes)[node].firstOut;
107 void firstOut(Edge& edge, const Node& node) const {
108 edge = (*nodes)[node].firstOut;
110 void nextOut(Edge& edge) const {
111 edge = (*edges)[edge].nextOut;
114 void firstIn(Edge& edge, const Node& node) const {
115 edge = (*nodes)[node].firstIn;
117 void nextIn(Edge& edge) const {
118 edge = (*edges)[edge].nextIn;
121 /// \brief Returns true when the given node is hidden.
123 /// Returns true when the given node is hidden.
124 bool hidden(const Node& node) const {
125 return (*nodes)[node].prev == node;
128 /// \brief Hide the given node in the sub-graph.
130 /// Hide the given node in the sub graph. It just lace out from
131 /// the linked lists the given node. If there are incoming or outgoing
132 /// edges into or from this node then all of these will be hidden.
133 void hide(const Node& node) {
134 if (hidden(node)) return;
136 firstOut(edge, node);
137 while (edge != INVALID) {
139 firstOut(edge, node);
142 firstOut(edge, node);
143 while (edge != INVALID) {
145 firstOut(edge, node);
147 if ((*nodes)[node].prev != INVALID) {
148 (*nodes)[(*nodes)[node].prev].next = (*nodes)[node].next;
150 firstNode = (*nodes)[node].next;
152 if ((*nodes)[node].next != INVALID) {
153 (*nodes)[(*nodes)[node].next].prev = (*nodes)[node].prev;
155 (*nodes)[node].prev = node;
156 (*nodes)[node].firstIn = INVALID;
157 (*nodes)[node].firstOut = INVALID;
160 /// \brief Unhide the given node in the sub-graph.
162 /// Unhide the given node in the sub graph. It just lace in the given
163 /// node into the linked lists.
164 void unHide(const Node& node) {
165 if (!hidden(node)) return;
166 (*nodes)[node].next = firstNode;
167 (*nodes)[node].prev = INVALID;
168 if ((*nodes)[node].next != INVALID) {
169 (*nodes)[(*nodes)[node].next].prev = node;
174 /// \brief Returns true when the given edge is hidden.
176 /// Returns true when the given edge is hidden.
177 bool hidden(const Edge& edge) const {
178 return (*edges)[edge].prevOut == edge;
181 /// \brief Hide the given edge in the sub-graph.
183 /// Hide the given edge in the sub graph. It just lace out from
184 /// the linked lists the given edge.
185 void hide(const Edge& edge) {
186 if (hidden(edge)) return;
187 if ((*edges)[edge].prevOut == edge) return;
188 if ((*edges)[edge].prevOut != INVALID) {
189 (*edges)[(*edges)[edge].prevOut].nextOut = (*edges)[edge].nextOut;
191 (*nodes)[source(edge)].firstOut = (*edges)[edge].nextOut;
193 if ((*edges)[edge].nextOut != INVALID) {
194 (*edges)[(*edges)[edge].nextOut].prevOut = (*edges)[edge].prevOut;
197 if ((*edges)[edge].prevIn != INVALID) {
198 (*edges)[(*edges)[edge].prevIn].nextIn = (*edges)[edge].nextIn;
200 (*nodes)[target(edge)].firstIn = (*edges)[edge].nextIn;
202 if ((*edges)[edge].nextIn != INVALID) {
203 (*edges)[(*edges)[edge].nextIn].prevIn = (*edges)[edge].prevIn;
205 (*edges)[edge].next = edge;
208 /// \brief Unhide the given edge in the sub-graph.
210 /// Unhide the given edge in the sub graph. It just lace in the given
211 /// edge into the linked lists. If the source or the target of the
212 /// node is hidden then it will unhide it.
213 void unHide(const Edge& edge) {
214 if (!hidden(edge)) return;
218 node = Parent::source(edge);
220 (*edges)[edge].nextOut = (*nodes)[node].firstOut;
221 (*edges)[edge].prevOut = INVALID;
222 if ((*edges)[edge].nextOut != INVALID) {
223 (*edges)[(*edges)[edge].nextOut].prevOut = edge;
225 (*nodes)[node].firstOut = edge;
227 node = Parent::target(edge);
229 (*edges)[edge].nextIn = (*nodes)[node].firstIn;
230 (*edges)[edge].prevIn = INVALID;
231 if ((*edges)[edge].nextIn != INVALID) {
232 (*edges)[(*edges)[edge].nextIn].prevIn = edge;
234 (*nodes)[node].firstIn = edge;
237 typedef False NodeNumTag;
238 typedef False EdgeNumTag;
243 Edge firstIn, firstOut;
245 class NodesImpl : public Graph::template NodeMap<NodeT> {
246 friend class SubGraphBase;
248 typedef typename Graph::template NodeMap<NodeT> Parent;
250 NodesImpl(SubGraph& _adaptor, const Graph& _graph)
251 : Parent(_graph), adaptor(_adaptor) {}
253 virtual ~NodesImpl() {}
255 virtual void build() {
258 adaptor.Base::first(node);
259 while (node != INVALID) {
260 Parent::operator[](node).prev = node;
261 Parent::operator[](node).firstIn = INVALID;
262 Parent::operator[](node).firstOut = INVALID;
263 adaptor.Base::next(node);
267 virtual void clear() {
268 adaptor.firstNode = INVALID;
272 virtual void add(const Node& node) {
274 Parent::operator[](node).prev = node;
275 Parent::operator[](node).firstIn = INVALID;
276 Parent::operator[](node).firstOut = INVALID;
278 virtual void add(const std::vector<Node>& nodes) {
280 for (int i = 0; i < (int)nodes.size(); ++i) {
281 Parent::operator[](nodes[i]).prev = nodes[i];
282 Parent::operator[](nodes[i]).firstIn = INVALID;
283 Parent::operator[](nodes[i]).firstOut = INVALID;
287 virtual void erase(const Node& node) {
292 virtual void erase(const std::vector<Node>& nodes) {
293 for (int i = 0; i < (int)nodes.size(); ++i) {
294 adaptor.hide(nodes[i]);
296 Parent::erase(nodes);
304 Edge prevOut, nextOut;
307 class EdgesImpl : public Graph::template EdgeMap<EdgeT> {
308 friend class SubGraphBase;
310 typedef typename Graph::template EdgeMap<EdgeT> Parent;
312 EdgesImpl(SubGraph& _adaptor, const Graph& _graph)
313 : Parent(_graph), adaptor(_adaptor) {}
315 virtual ~EdgesImpl() {}
317 virtual void build() {
320 adaptor.Base::first(edge);
321 while (edge != INVALID) {
322 Parent::operator[](edge).prevOut = edge;
323 adaptor.Base::next(edge);
327 virtual void clear() {
330 while (node != INVALID) {
331 (*adaptor.nodes).firstIn = INVALID;
332 (*adaptor.nodes).firstOut = INVALID;
338 virtual void add(const Edge& edge) {
340 Parent::operator[](edge).prevOut = edge;
343 virtual void add(const std::vector<Edge>& edges) {
345 for (int i = 0; i < (int)edges.size(); ++i) {
346 Parent::operator[](edges[i]).prevOut = edges[i];
350 virtual void erase(const Edge& edge) {
355 virtual void erase(const std::vector<Edge>& edges) {
356 for (int i = 0; i < (int)edges.size(); ++i) {
357 adaptor.hide(edges[i]);
371 /// \ingroup semi_adaptors
373 /// \brief Graph which uses a subset of an other graph's nodes and edges.
375 /// Graph which uses a subset of an other graph's nodes and edges. This class
376 /// is an alternative to the SubGraphAdaptor which is created for the
377 /// same reason. The main difference between the two class that it
378 /// makes linked lists on the unhidden nodes and edges what cause that
379 /// on sparse subgraphs the algorithms can be more efficient and some times
380 /// provide better time complexity. On other way this implemetation is
381 /// less efficient in most case when the subgraph filters out only
382 /// a few nodes or edges.
384 /// \see SubGraphAdaptor
385 /// \see EdgeSubGraphBase
386 template <typename Graph>
388 : public IterableGraphExtender< SubGraphBase<Graph> > {
390 typedef IterableGraphExtender< SubGraphBase<Graph> > Parent;
392 /// \brief Constructor for sub-graph.
394 /// Constructor for sub-graph. Initially all the edges and nodes
395 /// are hidden in the graph.
396 SubGraph(const Graph& _graph)
397 : Parent(), nodes(*this, _graph), edges(*this, _graph) {
398 Parent::construct(_graph, nodes, edges);
401 typename Parent::NodesImpl nodes;
402 typename Parent::EdgesImpl edges;
405 /// \brief Base for the EdgeSubGraph.
407 /// Base for the EdgeSubGraph.
408 template <typename _Graph>
409 class EdgeSubGraphBase : public GraphAdaptorBase<const _Graph> {
411 typedef _Graph Graph;
412 typedef EdgeSubGraphBase<_Graph> SubGraph;
413 typedef GraphAdaptorBase<const _Graph> Parent;
416 typedef typename Parent::Node Node;
417 typedef typename Parent::Edge Edge;
425 EdgeSubGraphBase() {}
427 void construct(const Graph& _graph, NodesImpl& _nodes, EdgesImpl& _edges) {
428 Parent::setGraph(_graph);
434 while (node != INVALID) {
435 (*nodes)[node].firstIn = INVALID;
436 (*nodes)[node].firstOut = INVALID;
442 while (edge != INVALID) {
443 (*edges)[edge].prevOut = edge;
450 void first(Node& node) const {
453 void next(Node& node) const {
457 void first(Edge& edge) const {
460 while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
463 if (node == INVALID) {
466 edge = (*nodes)[node].firstOut;
469 void next(Edge& edge) const {
470 if ((*edges)[edge].nextOut != INVALID) {
471 edge = (*edges)[edge].nextOut;
473 Node node = source(edge);
475 while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
478 if (node == INVALID) {
481 edge = (*nodes)[node].firstOut;
486 void firstOut(Edge& edge, const Node& node) const {
487 edge = (*nodes)[node].firstOut;
489 void nextOut(Edge& edge) const {
490 edge = (*edges)[edge].nextOut;
493 void firstIn(Edge& edge, const Node& node) const {
494 edge = (*nodes)[node].firstIn;
496 void nextIn(Edge& edge) const {
497 edge = (*edges)[edge].nextIn;
500 /// \brief Returns true when the given edge is hidden.
502 /// Returns true when the given edge is hidden.
503 bool hidden(const Edge& edge) const {
504 return (*edges)[edge].prevOut == edge;
507 /// \brief Hide the given edge in the sub-graph.
509 /// Hide the given edge in the sub graph. It just lace out from
510 /// the linked lists the given edge.
511 void hide(const Edge& edge) {
512 if (hidden(edge)) return;
513 if ((*edges)[edge].prevOut != INVALID) {
514 (*edges)[(*edges)[edge].prevOut].nextOut = (*edges)[edge].nextOut;
516 (*nodes)[source(edge)].firstOut = (*edges)[edge].nextOut;
518 if ((*edges)[edge].nextOut != INVALID) {
519 (*edges)[(*edges)[edge].nextOut].prevOut = (*edges)[edge].prevOut;
522 if ((*edges)[edge].prevIn != INVALID) {
523 (*edges)[(*edges)[edge].prevIn].nextIn = (*edges)[edge].nextIn;
525 (*nodes)[target(edge)].firstIn = (*edges)[edge].nextIn;
527 if ((*edges)[edge].nextIn != INVALID) {
528 (*edges)[(*edges)[edge].nextIn].prevIn = (*edges)[edge].prevIn;
530 (*edges)[edge].prevOut = edge;
533 /// \brief Unhide the given edge in the sub-graph.
535 /// Unhide the given edge in the sub graph. It just lace in the given
536 /// edge into the linked lists.
537 void unHide(const Edge& edge) {
538 if (!hidden(edge)) return;
541 node = Parent::source(edge);
542 (*edges)[edge].nextOut = (*nodes)[node].firstOut;
543 (*edges)[edge].prevOut = INVALID;
544 if ((*edges)[edge].nextOut != INVALID) {
545 (*edges)[(*edges)[edge].nextOut].prevOut = edge;
547 (*nodes)[node].firstOut = edge;
549 node = Parent::target(edge);
550 (*edges)[edge].nextIn = (*nodes)[node].firstIn;
551 (*edges)[edge].prevIn = INVALID;
552 if ((*edges)[edge].nextIn != INVALID) {
553 (*edges)[(*edges)[edge].nextIn].prevIn = edge;
555 (*nodes)[node].firstIn = edge;
560 Edge firstIn, firstOut;
562 class NodesImpl : public Graph::template NodeMap<NodeT> {
563 friend class EdgeSubGraphBase;
565 typedef typename Graph::template NodeMap<NodeT> Parent;
567 NodesImpl(SubGraph& _adaptor, const Graph& _graph)
568 : Parent(_graph), adaptor(_adaptor) {}
570 virtual ~NodesImpl() {}
572 virtual void build() {
575 adaptor.Base::first(node);
576 while (node != INVALID) {
577 Parent::operator[](node).firstIn = INVALID;
578 Parent::operator[](node).firstOut = INVALID;
579 adaptor.Base::next(node);
583 virtual void add(const Node& node) {
585 Parent::operator[](node).firstIn = INVALID;
586 Parent::operator[](node).firstOut = INVALID;
594 Edge prevOut, nextOut;
597 class EdgesImpl : public Graph::template EdgeMap<EdgeT> {
598 friend class EdgeSubGraphBase;
600 typedef typename Graph::template EdgeMap<EdgeT> Parent;
602 EdgesImpl(SubGraph& _adaptor, const Graph& _graph)
603 : Parent(_graph), adaptor(_adaptor) {}
605 virtual ~EdgesImpl() {}
607 virtual void build() {
610 adaptor.Base::first(edge);
611 while (edge != INVALID) {
612 Parent::operator[](edge).prevOut = edge;
613 adaptor.Base::next(edge);
617 virtual void clear() {
619 adaptor.Base::first(node);
620 while (node != INVALID) {
621 (*adaptor.nodes)[node].firstIn = INVALID;
622 (*adaptor.nodes)[node].firstOut = INVALID;
623 adaptor.Base::next(node);
628 virtual void add(const Edge& edge) {
630 Parent::operator[](edge).prevOut = edge;
633 virtual void add(const std::vector<Edge>& edges) {
635 for (int i = 0; i < (int)edges.size(); ++i) {
636 Parent::operator[](edges[i]).prevOut = edges[i];
640 virtual void erase(const Edge& edge) {
645 virtual void erase(const std::vector<Edge>& edges) {
646 for (int i = 0; i < (int)edges.size(); ++i) {
647 adaptor.hide(edges[i]);
660 /// \ingroup semi_adaptors
662 /// \brief Graph which uses a subset of an other graph's edges.
664 /// Graph which uses a subset of an other graph's edges. This class
665 /// is an alternative to the EdgeSubGraphAdaptor which is created for the
666 /// same reason. The main difference between the two class that it
667 /// makes linked lists on the unhidden edges what cause that
668 /// on sparse subgraphs the algorithms can be more efficient and some times
669 /// provide better time complexity. On other way this implemetation is
670 /// less efficient in most case when the subgraph filters out only
673 /// \see EdgeSubGraphAdaptor
674 /// \see EdgeSubGraphBase
675 template <typename Graph>
677 : public IterableGraphExtender< EdgeSubGraphBase<Graph> > {
679 typedef IterableGraphExtender< EdgeSubGraphBase<Graph> > Parent;
681 /// \brief Constructor for sub-graph.
683 /// Constructor for sub-graph. Initially all the edges are hidden in the
685 EdgeSubGraph(const Graph& _graph)
686 : Parent(), nodes(*this, _graph), edges(*this, _graph) {
687 Parent::construct(_graph, nodes, edges);
690 typename Parent::NodesImpl nodes;
691 typename Parent::EdgesImpl edges;
695 // template<typename Graph, typename Number,
696 // typename CapacityMap, typename FlowMap>
698 // : public IterableGraphExtender<EdgeSubGraphBase<
699 // UGraphAdaptor<Graph> > > {
701 // typedef IterableGraphExtender<EdgeSubGraphBase<
702 // UGraphAdaptor<Graph> > > Parent;
705 // UGraphAdaptor<Graph> u;
707 // const CapacityMap* capacity;
710 // typename Parent::NodesImpl nodes;
711 // typename Parent::EdgesImpl edges;
713 // void setCapacityMap(const CapacityMap& _capacity) {
714 // capacity=&_capacity;
717 // void setFlowMap(FlowMap& _flow) {
723 // typedef typename UGraphAdaptor<Graph>::Node Node;
724 // typedef typename UGraphAdaptor<Graph>::Edge Edge;
725 // typedef typename UGraphAdaptor<Graph>::UEdge UEdge;
727 // ResGraphAdaptor(Graph& _graph,
728 // const CapacityMap& _capacity, FlowMap& _flow)
729 // : Parent(), u(_graph), capacity(&_capacity), flow(&_flow),
730 // nodes(*this, _graph), edges(*this, _graph) {
731 // Parent::construct(u, nodes, edges);
732 // setFlowMap(_flow);
733 // setCapacityMap(_capacity);
734 // typename Graph::Edge edge;
735 // for (_graph.first(edge); edge != INVALID; _graph.next(edge)) {
736 // if ((*flow)[edge] != (*capacity)[edge]) {
737 // Parent::unHide(direct(edge, true));
739 // if ((*flow)[edge] != 0) {
740 // Parent::unHide(direct(edge, false));
745 // void augment(const Edge& e, Number a) {
746 // if (direction(e)) {
747 // flow->set(e, (*flow)[e]+a);
749 // flow->set(e, (*flow)[e]-a);
751 // if ((*flow)[e] == (*capacity)[e]) {
754 // Parent::unHide(e);
756 // if ((*flow)[e] == 0) {
757 // Parent::hide(oppositeEdge(e));
759 // Parent::unHide(oppositeEdge(e));
763 // Number resCap(const Edge& e) {
764 // if (direction(e)) {
765 // return (*capacity)[e]-(*flow)[e];
767 // return (*flow)[e];
771 // bool direction(const Edge& edge) const {
772 // return Parent::getGraph().direction(edge);
775 // Edge direct(const UEdge& edge, bool direction) const {
776 // return Parent::getGraph().direct(edge, direction);
779 // Edge direct(const UEdge& edge, const Node& node) const {
780 // return Parent::getGraph().direct(edge, node);
783 // Edge oppositeEdge(const Edge& edge) const {
784 // return Parent::getGraph().oppositeEdge(edge);
787 // /// \brief Residual capacity map.
789 // /// In generic residual graphs the residual capacity can be obtained
793 // const ResGraphAdaptor* res_graph;
795 // typedef Number Value;
797 // ResCap(const ResGraphAdaptor& _res_graph)
798 // : res_graph(&_res_graph) {}
799 // Number operator[](const Edge& e) const {
800 // return res_graph->resCap(e);