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>
23 #include <lemon/bits/graph_adaptor_extender.h>
24 #include <lemon/bits/default_map.h>
26 /// \ingroup semi_adaptors
30 /// Graphs with filtered edge and node set.
34 /// \brief Base for the SubGraph.
36 /// Base for the SubGraph.
37 template <typename _Graph>
38 class SubGraphBase : public GraphAdaptorBase<const _Graph> {
41 typedef SubGraphBase<_Graph> SubGraph;
42 typedef GraphAdaptorBase<const _Graph> Parent;
45 typedef typename Parent::Node Node;
46 typedef typename Parent::Edge Edge;
56 void construct(const Graph& _graph, NodesImpl& _nodes, EdgesImpl& _edges) {
57 Parent::setGraph(_graph);
64 while (node != INVALID) {
65 (*nodes)[node].prev = node;
66 (*nodes)[node].firstIn = INVALID;
67 (*nodes)[node].firstOut = INVALID;
73 while (edge != INVALID) {
74 (*edges)[edge].prevOut = edge;
81 void first(Node& node) const {
84 void next(Node& node) const {
85 node = (*nodes)[node].next;
88 void first(Edge& edge) const {
89 Node node = firstNode;
90 while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
91 node = (*nodes)[node].next;
93 if (node == INVALID) {
96 edge = (*nodes)[node].firstOut;
99 void next(Edge& edge) const {
100 if ((*edges)[edge].nextOut != INVALID) {
101 edge = (*edges)[edge].nextOut;
103 Node node = (*nodes)[source(edge)].next;
104 while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
105 node = (*nodes)[node].next;
107 if (node == INVALID) {
110 edge = (*nodes)[node].firstOut;
115 void firstOut(Edge& edge, const Node& node) const {
116 edge = (*nodes)[node].firstOut;
118 void nextOut(Edge& edge) const {
119 edge = (*edges)[edge].nextOut;
122 void firstIn(Edge& edge, const Node& node) const {
123 edge = (*nodes)[node].firstIn;
125 void nextIn(Edge& edge) const {
126 edge = (*edges)[edge].nextIn;
129 /// \brief Returns true when the given node is hidden.
131 /// Returns true when the given node is hidden.
132 bool hidden(const Node& node) const {
133 return (*nodes)[node].prev == node;
136 /// \brief Hide the given node in the sub-graph.
138 /// Hide the given node in the sub graph. It just lace out from
139 /// the linked lists the given node. If there are incoming or outgoing
140 /// edges into or from this node then all of these will be hidden.
141 void hide(const Node& node) {
142 if (hidden(node)) return;
144 firstOut(edge, node);
145 while (edge != INVALID) {
147 firstOut(edge, node);
150 firstOut(edge, node);
151 while (edge != INVALID) {
153 firstOut(edge, node);
155 if ((*nodes)[node].prev != INVALID) {
156 (*nodes)[(*nodes)[node].prev].next = (*nodes)[node].next;
158 firstNode = (*nodes)[node].next;
160 if ((*nodes)[node].next != INVALID) {
161 (*nodes)[(*nodes)[node].next].prev = (*nodes)[node].prev;
163 (*nodes)[node].prev = node;
164 (*nodes)[node].firstIn = INVALID;
165 (*nodes)[node].firstOut = INVALID;
168 /// \brief Unhide the given node in the sub-graph.
170 /// Unhide the given node in the sub graph. It just lace in the given
171 /// node into the linked lists.
172 void unHide(const Node& node) {
173 if (!hidden(node)) return;
174 (*nodes)[node].next = firstNode;
175 (*nodes)[node].prev = INVALID;
176 if ((*nodes)[node].next != INVALID) {
177 (*nodes)[(*nodes)[node].next].prev = node;
182 /// \brief Returns true when the given edge is hidden.
184 /// Returns true when the given edge is hidden.
185 bool hidden(const Edge& edge) const {
186 return (*edges)[edge].prevOut == edge;
189 /// \brief Hide the given edge in the sub-graph.
191 /// Hide the given edge in the sub graph. It just lace out from
192 /// the linked lists the given edge.
193 void hide(const Edge& edge) {
194 if (hidden(edge)) return;
195 if ((*edges)[edge].prevOut == edge) return;
196 if ((*edges)[edge].prevOut != INVALID) {
197 (*edges)[(*edges)[edge].prevOut].nextOut = (*edges)[edge].nextOut;
199 (*nodes)[source(edge)].firstOut = (*edges)[edge].nextOut;
201 if ((*edges)[edge].nextOut != INVALID) {
202 (*edges)[(*edges)[edge].nextOut].prevOut = (*edges)[edge].prevOut;
205 if ((*edges)[edge].prevIn != INVALID) {
206 (*edges)[(*edges)[edge].prevIn].nextIn = (*edges)[edge].nextIn;
208 (*nodes)[target(edge)].firstIn = (*edges)[edge].nextIn;
210 if ((*edges)[edge].nextIn != INVALID) {
211 (*edges)[(*edges)[edge].nextIn].prevIn = (*edges)[edge].prevIn;
213 (*edges)[edge].next = edge;
216 /// \brief Unhide the given edge in the sub-graph.
218 /// Unhide the given edge in the sub graph. It just lace in the given
219 /// edge into the linked lists. If the source or the target of the
220 /// node is hidden then it will unhide it.
221 void unHide(const Edge& edge) {
222 if (!hidden(edge)) return;
226 node = Parent::source(edge);
228 (*edges)[edge].nextOut = (*nodes)[node].firstOut;
229 (*edges)[edge].prevOut = INVALID;
230 if ((*edges)[edge].nextOut != INVALID) {
231 (*edges)[(*edges)[edge].nextOut].prevOut = edge;
233 (*nodes)[node].firstOut = edge;
235 node = Parent::target(edge);
237 (*edges)[edge].nextIn = (*nodes)[node].firstIn;
238 (*edges)[edge].prevIn = INVALID;
239 if ((*edges)[edge].nextIn != INVALID) {
240 (*edges)[(*edges)[edge].nextIn].prevIn = edge;
242 (*nodes)[node].firstIn = edge;
245 typedef False NodeNumTag;
246 typedef False EdgeNumTag;
251 Edge firstIn, firstOut;
253 class NodesImpl : public DefaultMap<Graph, Node, NodeT> {
254 friend class SubGraphBase;
256 typedef DefaultMap<Graph, Node, NodeT> Parent;
258 NodesImpl(SubGraph& _adaptor, const Graph& _graph)
259 : Parent(_graph), adaptor(_adaptor) {}
261 virtual ~NodesImpl() {}
263 virtual void build() {
266 adaptor.Base::first(node);
267 while (node != INVALID) {
268 Parent::operator[](node).prev = node;
269 Parent::operator[](node).firstIn = INVALID;
270 Parent::operator[](node).firstOut = INVALID;
271 adaptor.Base::next(node);
275 virtual void clear() {
276 adaptor.firstNode = INVALID;
280 virtual void add(const Node& node) {
282 Parent::operator[](node).prev = node;
283 Parent::operator[](node).firstIn = INVALID;
284 Parent::operator[](node).firstOut = INVALID;
287 virtual void add(const std::vector<Node>& nodes) {
289 for (int i = 0; i < (int)nodes.size(); ++i) {
290 Parent::operator[](nodes[i]).prev = nodes[i];
291 Parent::operator[](nodes[i]).firstIn = INVALID;
292 Parent::operator[](nodes[i]).firstOut = INVALID;
296 virtual void erase(const Node& node) {
301 virtual void erase(const std::vector<Node>& nodes) {
302 for (int i = 0; i < (int)nodes.size(); ++i) {
303 adaptor.hide(nodes[i]);
305 Parent::erase(nodes);
313 Edge prevOut, nextOut;
316 class EdgesImpl : public DefaultMap<Graph, Edge, EdgeT> {
317 friend class SubGraphBase;
319 typedef DefaultMap<Graph, Edge, EdgeT> Parent;
321 EdgesImpl(SubGraph& _adaptor, const Graph& _graph)
322 : Parent(_graph), adaptor(_adaptor) {}
324 virtual ~EdgesImpl() {}
326 virtual void build() {
329 adaptor.Base::first(edge);
330 while (edge != INVALID) {
331 Parent::operator[](edge).prevOut = edge;
332 adaptor.Base::next(edge);
336 virtual void clear() {
339 while (node != INVALID) {
340 (*adaptor.nodes).firstIn = INVALID;
341 (*adaptor.nodes).firstOut = INVALID;
347 virtual void add(const Edge& edge) {
349 Parent::operator[](edge).prevOut = edge;
352 virtual void add(const std::vector<Edge>& edges) {
354 for (int i = 0; i < (int)edges.size(); ++i) {
355 Parent::operator[](edges[i]).prevOut = edges[i];
359 virtual void erase(const Edge& edge) {
364 virtual void erase(const std::vector<Edge>& edges) {
365 for (int i = 0; i < (int)edges.size(); ++i) {
366 adaptor.hide(edges[i]);
368 Parent::erase(edges);
380 /// \ingroup semi_adaptors
382 /// \brief Graph which uses a subset of another graph's nodes and edges.
384 /// Graph which uses a subset of another graph's nodes and edges. This class
385 /// is an alternative to the SubGraphAdaptor which is created for the
386 /// same reason. The main difference between the two class that it
387 /// makes linked lists on the unhidden nodes and edges what cause that
388 /// on sparse subgraphs the algorithms can be more efficient and some times
389 /// provide better time complexity. On other way this implemetation is
390 /// less efficient in most case when the subgraph filters out only
391 /// a few nodes or edges.
393 /// \see SubGraphAdaptor
394 /// \see EdgeSubGraphBase
395 template <typename Graph>
397 : public GraphAdaptorExtender< SubGraphBase<Graph> > {
399 typedef GraphAdaptorExtender< SubGraphBase<Graph> > Parent;
401 /// \brief Constructor for sub-graph.
403 /// Constructor for sub-graph. Initially all the edges and nodes
404 /// are hidden in the graph.
405 SubGraph(const Graph& _graph)
406 : Parent(), nodes(*this, _graph), edges(*this, _graph) {
407 Parent::construct(_graph, nodes, edges);
410 typename Parent::NodesImpl nodes;
411 typename Parent::EdgesImpl edges;
414 /// \brief Base for the EdgeSubGraph.
416 /// Base for the EdgeSubGraph.
417 template <typename _Graph>
418 class EdgeSubGraphBase : public GraphAdaptorBase<const _Graph> {
420 typedef _Graph Graph;
421 typedef EdgeSubGraphBase<_Graph> SubGraph;
422 typedef GraphAdaptorBase<const _Graph> Parent;
425 typedef typename Parent::Node Node;
426 typedef typename Parent::Edge Edge;
434 EdgeSubGraphBase() {}
436 void construct(const Graph& _graph, NodesImpl& _nodes, EdgesImpl& _edges) {
437 Parent::setGraph(_graph);
443 while (node != INVALID) {
444 (*nodes)[node].firstIn = INVALID;
445 (*nodes)[node].firstOut = INVALID;
451 while (edge != INVALID) {
452 (*edges)[edge].prevOut = edge;
459 void first(Node& node) const {
462 void next(Node& node) const {
466 void first(Edge& edge) const {
469 while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
472 if (node == INVALID) {
475 edge = (*nodes)[node].firstOut;
478 void next(Edge& edge) const {
479 if ((*edges)[edge].nextOut != INVALID) {
480 edge = (*edges)[edge].nextOut;
482 Node node = source(edge);
484 while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
487 if (node == INVALID) {
490 edge = (*nodes)[node].firstOut;
495 void firstOut(Edge& edge, const Node& node) const {
496 edge = (*nodes)[node].firstOut;
498 void nextOut(Edge& edge) const {
499 edge = (*edges)[edge].nextOut;
502 void firstIn(Edge& edge, const Node& node) const {
503 edge = (*nodes)[node].firstIn;
505 void nextIn(Edge& edge) const {
506 edge = (*edges)[edge].nextIn;
509 /// \brief Returns true when the given edge is hidden.
511 /// Returns true when the given edge is hidden.
512 bool hidden(const Edge& edge) const {
513 return (*edges)[edge].prevOut == edge;
516 /// \brief Hide the given edge in the sub-graph.
518 /// Hide the given edge in the sub graph. It just lace out from
519 /// the linked lists the given edge.
520 void hide(const Edge& edge) {
521 if (hidden(edge)) return;
522 if ((*edges)[edge].prevOut != INVALID) {
523 (*edges)[(*edges)[edge].prevOut].nextOut = (*edges)[edge].nextOut;
525 (*nodes)[source(edge)].firstOut = (*edges)[edge].nextOut;
527 if ((*edges)[edge].nextOut != INVALID) {
528 (*edges)[(*edges)[edge].nextOut].prevOut = (*edges)[edge].prevOut;
531 if ((*edges)[edge].prevIn != INVALID) {
532 (*edges)[(*edges)[edge].prevIn].nextIn = (*edges)[edge].nextIn;
534 (*nodes)[target(edge)].firstIn = (*edges)[edge].nextIn;
536 if ((*edges)[edge].nextIn != INVALID) {
537 (*edges)[(*edges)[edge].nextIn].prevIn = (*edges)[edge].prevIn;
539 (*edges)[edge].prevOut = edge;
542 /// \brief Unhide the given edge in the sub-graph.
544 /// Unhide the given edge in the sub graph. It just lace in the given
545 /// edge into the linked lists.
546 void unHide(const Edge& edge) {
547 if (!hidden(edge)) return;
550 node = Parent::source(edge);
551 (*edges)[edge].nextOut = (*nodes)[node].firstOut;
552 (*edges)[edge].prevOut = INVALID;
553 if ((*edges)[edge].nextOut != INVALID) {
554 (*edges)[(*edges)[edge].nextOut].prevOut = edge;
556 (*nodes)[node].firstOut = edge;
558 node = Parent::target(edge);
559 (*edges)[edge].nextIn = (*nodes)[node].firstIn;
560 (*edges)[edge].prevIn = INVALID;
561 if ((*edges)[edge].nextIn != INVALID) {
562 (*edges)[(*edges)[edge].nextIn].prevIn = edge;
564 (*nodes)[node].firstIn = edge;
569 Edge firstIn, firstOut;
571 class NodesImpl : public DefaultMap<Graph, Node, NodeT> {
572 friend class EdgeSubGraphBase;
574 typedef DefaultMap<Graph, Node, NodeT> Parent;
576 NodesImpl(SubGraph& _adaptor, const Graph& _graph)
577 : Parent(_graph), adaptor(_adaptor) {}
579 virtual ~NodesImpl() {}
581 virtual void build() {
584 adaptor.Base::first(node);
585 while (node != INVALID) {
586 Parent::operator[](node).firstIn = INVALID;
587 Parent::operator[](node).firstOut = INVALID;
588 adaptor.Base::next(node);
592 virtual void add(const Node& node) {
594 Parent::operator[](node).firstIn = INVALID;
595 Parent::operator[](node).firstOut = INVALID;
598 virtual void add(const std::vector<Node>& nodes) {
600 for (int i = 0; i < (int)nodes.size(); ++i) {
601 Parent::operator[](nodes[i]).firstIn = INVALID;
602 Parent::operator[](nodes[i]).firstOut = INVALID;
611 Edge prevOut, nextOut;
614 class EdgesImpl : public DefaultMap<Graph, Edge, EdgeT> {
615 friend class EdgeSubGraphBase;
617 typedef DefaultMap<Graph, Edge, EdgeT> Parent;
619 EdgesImpl(SubGraph& _adaptor, const Graph& _graph)
620 : Parent(_graph), adaptor(_adaptor) {}
622 virtual ~EdgesImpl() {}
624 virtual void build() {
627 adaptor.Base::first(edge);
628 while (edge != INVALID) {
629 Parent::operator[](edge).prevOut = edge;
630 adaptor.Base::next(edge);
634 virtual void clear() {
636 adaptor.Base::first(node);
637 while (node != INVALID) {
638 (*adaptor.nodes)[node].firstIn = INVALID;
639 (*adaptor.nodes)[node].firstOut = INVALID;
640 adaptor.Base::next(node);
645 virtual void add(const Edge& edge) {
647 Parent::operator[](edge).prevOut = edge;
650 virtual void add(const std::vector<Edge>& edges) {
652 for (int i = 0; i < (int)edges.size(); ++i) {
653 Parent::operator[](edges[i]).prevOut = edges[i];
657 virtual void erase(const Edge& edge) {
662 virtual void erase(const std::vector<Edge>& edges) {
663 for (int i = 0; i < (int)edges.size(); ++i) {
664 adaptor.hide(edges[i]);
666 Parent::erase(edges);
677 /// \ingroup semi_adaptors
679 /// \brief Graph which uses a subset of another graph's edges.
681 /// Graph which uses a subset of another graph's edges. This class
682 /// is an alternative to the EdgeSubGraphAdaptor which is created for the
683 /// same reason. The main difference between the two class that it
684 /// makes linked lists on the unhidden edges what cause that
685 /// on sparse subgraphs the algorithms can be more efficient and some times
686 /// provide better time complexity. On other way this implemetation is
687 /// less efficient in most case when the subgraph filters out only
690 /// \see EdgeSubGraphAdaptor
691 /// \see EdgeSubGraphBase
692 template <typename Graph>
694 : public GraphAdaptorExtender< EdgeSubGraphBase<Graph> > {
696 typedef GraphAdaptorExtender< EdgeSubGraphBase<Graph> > Parent;
698 /// \brief Constructor for sub-graph.
700 /// Constructor for sub-graph. Initially all the edges are hidden in the
702 EdgeSubGraph(const Graph& _graph)
703 : Parent(), nodes(*this, _graph), edges(*this, _graph) {
704 Parent::construct(_graph, nodes, edges);
707 typename Parent::NodesImpl nodes;
708 typename Parent::EdgesImpl edges;
712 // template<typename Graph, typename Number,
713 // typename CapacityMap, typename FlowMap>
715 // : public IterableGraphExtender<EdgeSubGraphBase<
716 // UGraphAdaptor<Graph> > > {
718 // typedef IterableGraphExtender<EdgeSubGraphBase<
719 // UGraphAdaptor<Graph> > > Parent;
722 // UGraphAdaptor<Graph> u;
724 // const CapacityMap* capacity;
727 // typename Parent::NodesImpl nodes;
728 // typename Parent::EdgesImpl edges;
730 // void setCapacityMap(const CapacityMap& _capacity) {
731 // capacity=&_capacity;
734 // void setFlowMap(FlowMap& _flow) {
740 // typedef typename UGraphAdaptor<Graph>::Node Node;
741 // typedef typename UGraphAdaptor<Graph>::Edge Edge;
742 // typedef typename UGraphAdaptor<Graph>::UEdge UEdge;
744 // ResGraphAdaptor(Graph& _graph,
745 // const CapacityMap& _capacity, FlowMap& _flow)
746 // : Parent(), u(_graph), capacity(&_capacity), flow(&_flow),
747 // nodes(*this, _graph), edges(*this, _graph) {
748 // Parent::construct(u, nodes, edges);
749 // setFlowMap(_flow);
750 // setCapacityMap(_capacity);
751 // typename Graph::Edge edge;
752 // for (_graph.first(edge); edge != INVALID; _graph.next(edge)) {
753 // if ((*flow)[edge] != (*capacity)[edge]) {
754 // Parent::unHide(direct(edge, true));
756 // if ((*flow)[edge] != 0) {
757 // Parent::unHide(direct(edge, false));
762 // void augment(const Edge& e, Number a) {
763 // if (direction(e)) {
764 // flow->set(e, (*flow)[e]+a);
766 // flow->set(e, (*flow)[e]-a);
768 // if ((*flow)[e] == (*capacity)[e]) {
771 // Parent::unHide(e);
773 // if ((*flow)[e] == 0) {
774 // Parent::hide(oppositeEdge(e));
776 // Parent::unHide(oppositeEdge(e));
780 // Number resCap(const Edge& e) {
781 // if (direction(e)) {
782 // return (*capacity)[e]-(*flow)[e];
784 // return (*flow)[e];
788 // bool direction(const Edge& edge) const {
789 // return Parent::getGraph().direction(edge);
792 // Edge direct(const UEdge& edge, bool direction) const {
793 // return Parent::getGraph().direct(edge, direction);
796 // Edge direct(const UEdge& edge, const Node& node) const {
797 // return Parent::getGraph().direct(edge, node);
800 // Edge oppositeEdge(const Edge& edge) const {
801 // return Parent::getGraph().oppositeEdge(edge);
804 // /// \brief Residual capacity map.
806 // /// In generic residual graphs the residual capacity can be obtained
810 // const ResGraphAdaptor* res_graph;
812 // typedef Number Value;
814 // ResCap(const ResGraphAdaptor& _res_graph)
815 // : res_graph(&_res_graph) {}
816 // Number operator[](const Edge& e) const {
817 // return res_graph->resCap(e);