3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
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
18 #ifndef LEMON_PLANARITY_H
19 #define LEMON_PLANARITY_H
23 /// \brief Planarity checking, embedding
28 #include <lemon/dfs.h>
29 #include <lemon/radix_sort.h>
30 #include <lemon/maps.h>
31 #include <lemon/path.h>
32 #include <lemon/iterable_maps.h>
33 #include <lemon/edge_set.h>
38 namespace _planarity_bits {
40 template <typename UGraph>
41 struct PlanarityVisitor : DfsVisitor<UGraph> {
43 typedef typename UGraph::Node Node;
44 typedef typename UGraph::Edge Edge;
46 typedef typename UGraph::template NodeMap<Edge> PredMap;
48 typedef typename UGraph::template UEdgeMap<bool> TreeMap;
50 typedef typename UGraph::template NodeMap<int> OrderMap;
51 typedef std::vector<Node> OrderList;
53 typedef typename UGraph::template NodeMap<int> LowMap;
54 typedef typename UGraph::template NodeMap<int> AncestorMap;
56 PlanarityVisitor(const UGraph& ugraph,
57 PredMap& pred_map, TreeMap& tree_map,
58 OrderMap& order_map, OrderList& order_list,
59 AncestorMap& ancestor_map, LowMap& low_map)
60 : _ugraph(ugraph), _pred_map(pred_map), _tree_map(tree_map),
61 _order_map(order_map), _order_list(order_list),
62 _ancestor_map(ancestor_map), _low_map(low_map) {}
64 void reach(const Node& node) {
65 _order_map[node] = _order_list.size();
66 _low_map[node] = _order_list.size();
67 _ancestor_map[node] = _order_list.size();
68 _order_list.push_back(node);
71 void discover(const Edge& edge) {
72 Node source = _ugraph.source(edge);
73 Node target = _ugraph.target(edge);
75 _tree_map[edge] = true;
76 _pred_map[target] = edge;
79 void examine(const Edge& edge) {
80 Node source = _ugraph.source(edge);
81 Node target = _ugraph.target(edge);
83 if (_order_map[target] < _order_map[source] && !_tree_map[edge]) {
84 if (_low_map[source] > _order_map[target]) {
85 _low_map[source] = _order_map[target];
87 if (_ancestor_map[source] > _order_map[target]) {
88 _ancestor_map[source] = _order_map[target];
93 void backtrack(const Edge& edge) {
94 Node source = _ugraph.source(edge);
95 Node target = _ugraph.target(edge);
97 if (_low_map[source] > _low_map[target]) {
98 _low_map[source] = _low_map[target];
102 const UGraph& _ugraph;
105 OrderMap& _order_map;
106 OrderList& _order_list;
107 AncestorMap& _ancestor_map;
111 template <typename UGraph, bool embedding = true>
112 struct NodeDataNode {
115 typename UGraph::Edge first;
119 template <typename UGraph>
120 struct NodeDataNode<UGraph, false> {
125 template <typename UGraph>
126 struct ChildListNode {
127 typedef typename UGraph::Node Node;
132 template <typename UGraph>
133 struct EdgeListNode {
134 typename UGraph::Edge prev, next;
141 /// \brief Planarity checking of an undirected simple graph
143 /// This class implements the Boyer-Myrvold algorithm for planarity
144 /// checking of an undirected graph. This class is a simplified
145 /// version of the PlanarEmbedding algorithm class, and it does
146 /// provide neither embedding nor kuratowski subdivisons.
147 template <typename UGraph>
148 class PlanarityChecking {
151 UGRAPH_TYPEDEFS(typename UGraph);
153 const UGraph& _ugraph;
157 typedef typename UGraph::template NodeMap<Edge> PredMap;
159 typedef typename UGraph::template UEdgeMap<bool> TreeMap;
161 typedef typename UGraph::template NodeMap<int> OrderMap;
162 typedef std::vector<Node> OrderList;
164 typedef typename UGraph::template NodeMap<int> LowMap;
165 typedef typename UGraph::template NodeMap<int> AncestorMap;
167 typedef _planarity_bits::NodeDataNode<UGraph> NodeDataNode;
168 typedef std::vector<NodeDataNode> NodeData;
170 typedef _planarity_bits::ChildListNode<UGraph> ChildListNode;
171 typedef typename UGraph::template NodeMap<ChildListNode> ChildLists;
173 typedef typename UGraph::template NodeMap<std::list<int> > MergeRoots;
175 typedef typename UGraph::template NodeMap<bool> EmbedEdge;
179 /// \brief Constructor
181 /// \warining The graph should be simple, i.e. parallel and loop edge
183 PlanarityChecking(const UGraph& ugraph) : _ugraph(ugraph) {}
185 /// \brief Runs the algorithm.
187 /// Runs the algorithm.
188 /// \return %True when the graph is planar.
190 typedef _planarity_bits::PlanarityVisitor<UGraph> Visitor;
192 PredMap pred_map(_ugraph, INVALID);
193 TreeMap tree_map(_ugraph, false);
195 OrderMap order_map(_ugraph, -1);
196 OrderList order_list;
198 AncestorMap ancestor_map(_ugraph, -1);
199 LowMap low_map(_ugraph, -1);
201 Visitor visitor(_ugraph, pred_map, tree_map,
202 order_map, order_list, ancestor_map, low_map);
203 DfsVisit<UGraph, Visitor> visit(_ugraph, visitor);
206 ChildLists child_lists(_ugraph);
207 createChildLists(tree_map, order_map, low_map, child_lists);
209 NodeData node_data(2 * order_list.size());
211 EmbedEdge embed_edge(_ugraph, false);
213 MergeRoots merge_roots(_ugraph);
215 for (int i = order_list.size() - 1; i >= 0; --i) {
217 Node node = order_list[i];
220 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
221 Node target = _ugraph.target(e);
223 if (order_map[source] < order_map[target] && tree_map[e]) {
224 initFace(target, node_data, order_map, order_list);
228 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
229 Node target = _ugraph.target(e);
231 if (order_map[source] < order_map[target] && !tree_map[e]) {
232 embed_edge[target] = true;
233 walkUp(target, source, i, pred_map, low_map,
234 order_map, order_list, node_data, merge_roots);
238 for (typename MergeRoots::Value::iterator it =
239 merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
241 walkDown(rn, i, node_data, order_list, child_lists,
242 ancestor_map, low_map, embed_edge, merge_roots);
244 merge_roots[node].clear();
246 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
247 Node target = _ugraph.target(e);
249 if (order_map[source] < order_map[target] && !tree_map[e]) {
250 if (embed_edge[target]) {
262 void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
263 const LowMap& low_map, ChildLists& child_lists) {
265 for (NodeIt n(_ugraph); n != INVALID; ++n) {
268 std::vector<Node> targets;
269 for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
270 Node target = _ugraph.target(e);
272 if (order_map[source] < order_map[target] && tree_map[e]) {
273 targets.push_back(target);
277 if (targets.size() == 0) {
278 child_lists[source].first = INVALID;
279 } else if (targets.size() == 1) {
280 child_lists[source].first = targets[0];
281 child_lists[targets[0]].prev = INVALID;
282 child_lists[targets[0]].next = INVALID;
284 radixSort(targets.begin(), targets.end(), mapFunctor(low_map));
285 for (int i = 1; i < int(targets.size()); ++i) {
286 child_lists[targets[i]].prev = targets[i - 1];
287 child_lists[targets[i - 1]].next = targets[i];
289 child_lists[targets.back()].next = INVALID;
290 child_lists[targets.front()].prev = INVALID;
291 child_lists[source].first = targets.front();
296 void walkUp(const Node& node, Node root, int rorder,
297 const PredMap& pred_map, const LowMap& low_map,
298 const OrderMap& order_map, const OrderList& order_list,
299 NodeData& node_data, MergeRoots& merge_roots) {
304 na = nb = order_map[node];
305 da = true; db = false;
309 if (node_data[na].visited == rorder) break;
310 if (node_data[nb].visited == rorder) break;
312 node_data[na].visited = rorder;
313 node_data[nb].visited = rorder;
317 if (na >= int(order_list.size())) {
319 } else if (nb >= int(order_list.size())) {
326 nn = da ? node_data[na].prev : node_data[na].next;
327 da = node_data[nn].prev != na;
330 nn = db ? node_data[nb].prev : node_data[nb].next;
331 db = node_data[nn].prev != nb;
336 Node rep = order_list[rn - order_list.size()];
337 Node parent = _ugraph.source(pred_map[rep]);
339 if (low_map[rep] < rorder) {
340 merge_roots[parent].push_back(rn);
342 merge_roots[parent].push_front(rn);
345 if (parent != root) {
346 na = nb = order_map[parent];
347 da = true; db = false;
355 void walkDown(int rn, int rorder, NodeData& node_data,
356 OrderList& order_list, ChildLists& child_lists,
357 AncestorMap& ancestor_map, LowMap& low_map,
358 EmbedEdge& embed_edge, MergeRoots& merge_roots) {
360 std::vector<std::pair<int, bool> > merge_stack;
362 for (int di = 0; di < 2; ++di) {
365 int n = rd ? node_data[rn].next : node_data[rn].prev;
369 Node node = order_list[n];
371 if (embed_edge[node]) {
373 // Merging components on the critical path
374 while (!merge_stack.empty()) {
377 int cn = merge_stack.back().first;
378 bool cd = merge_stack.back().second;
379 merge_stack.pop_back();
381 // Parent of component
382 int dn = merge_stack.back().first;
383 bool dd = merge_stack.back().second;
384 merge_stack.pop_back();
386 Node parent = order_list[dn];
388 // Erasing from merge_roots
389 merge_roots[parent].pop_front();
391 Node child = order_list[cn - order_list.size()];
393 // Erasing from child_lists
394 if (child_lists[child].prev != INVALID) {
395 child_lists[child_lists[child].prev].next =
396 child_lists[child].next;
398 child_lists[parent].first = child_lists[child].next;
401 if (child_lists[child].next != INVALID) {
402 child_lists[child_lists[child].next].prev =
403 child_lists[child].prev;
406 // Merging external faces
409 cn = cd ? node_data[cn].prev : node_data[cn].next;
410 cd = node_data[cn].next == en;
414 if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
415 if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
419 bool d = pn == node_data[n].prev;
421 if (node_data[n].prev == node_data[n].next &&
422 node_data[n].inverted) {
426 // Embedding edge into external face
427 if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
428 if (d) node_data[n].prev = rn; else node_data[n].next = rn;
431 embed_edge[order_list[n]] = false;
434 if (!merge_roots[node].empty()) {
436 bool d = pn == node_data[n].prev;
438 merge_stack.push_back(std::make_pair(n, d));
440 int rn = merge_roots[node].front();
442 int xn = node_data[rn].next;
443 Node xnode = order_list[xn];
445 int yn = node_data[rn].prev;
446 Node ynode = order_list[yn];
449 if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
451 } else if (!external(ynode, rorder, child_lists,
452 ancestor_map, low_map)) {
454 } else if (pertinent(xnode, embed_edge, merge_roots)) {
460 merge_stack.push_back(std::make_pair(rn, rd));
465 } else if (!external(node, rorder, child_lists,
466 ancestor_map, low_map)) {
467 int nn = (node_data[n].next != pn ?
468 node_data[n].next : node_data[n].prev);
470 bool nd = n == node_data[nn].prev;
472 if (nd) node_data[nn].prev = pn;
473 else node_data[nn].next = pn;
475 if (n == node_data[pn].prev) node_data[pn].prev = nn;
476 else node_data[pn].next = nn;
478 node_data[nn].inverted =
479 (node_data[nn].prev == node_data[nn].next && nd != rd);
487 if (!merge_stack.empty() || n == rn) {
493 void initFace(const Node& node, NodeData& node_data,
494 const OrderMap& order_map, const OrderList& order_list) {
495 int n = order_map[node];
496 int rn = n + order_list.size();
498 node_data[n].next = node_data[n].prev = rn;
499 node_data[rn].next = node_data[rn].prev = n;
501 node_data[n].visited = order_list.size();
502 node_data[rn].visited = order_list.size();
506 bool external(const Node& node, int rorder,
507 ChildLists& child_lists, AncestorMap& ancestor_map,
509 Node child = child_lists[node].first;
511 if (child != INVALID) {
512 if (low_map[child] < rorder) return true;
515 if (ancestor_map[node] < rorder) return true;
520 bool pertinent(const Node& node, const EmbedEdge& embed_edge,
521 const MergeRoots& merge_roots) {
522 return !merge_roots[node].empty() || embed_edge[node];
529 /// \brief Planar embedding of an undirected simple graph
531 /// This class implements the Boyer-Myrvold algorithm for planar
532 /// embedding of an undirected graph. The planar embeding is an
533 /// ordering of the outgoing edges in each node, which is a possible
534 /// configuration to draw the graph in the plane. If there is not
535 /// such ordering then the graph contains a \f$ K_5 \f$ (full graph
536 /// with 5 nodes) or an \f$ K_{3,3} \f$ (complete bipartite graph on
537 /// 3 ANode and 3 BNode) subdivision.
539 /// The current implementation calculates an embedding or an
540 /// Kuratowski subdivision if the graph is not planar. The running
541 /// time of the algorithm is \f$ O(n) \f$.
542 template <typename UGraph>
543 class PlanarEmbedding {
546 UGRAPH_TYPEDEFS(typename UGraph);
548 const UGraph& _ugraph;
549 typename UGraph::template EdgeMap<Edge> _embedding;
551 typename UGraph::template UEdgeMap<bool> _kuratowski;
555 typedef typename UGraph::template NodeMap<Edge> PredMap;
557 typedef typename UGraph::template UEdgeMap<bool> TreeMap;
559 typedef typename UGraph::template NodeMap<int> OrderMap;
560 typedef std::vector<Node> OrderList;
562 typedef typename UGraph::template NodeMap<int> LowMap;
563 typedef typename UGraph::template NodeMap<int> AncestorMap;
565 typedef _planarity_bits::NodeDataNode<UGraph> NodeDataNode;
566 typedef std::vector<NodeDataNode> NodeData;
568 typedef _planarity_bits::ChildListNode<UGraph> ChildListNode;
569 typedef typename UGraph::template NodeMap<ChildListNode> ChildLists;
571 typedef typename UGraph::template NodeMap<std::list<int> > MergeRoots;
573 typedef typename UGraph::template NodeMap<Edge> EmbedEdge;
575 typedef _planarity_bits::EdgeListNode<UGraph> EdgeListNode;
576 typedef typename UGraph::template EdgeMap<EdgeListNode> EdgeLists;
578 typedef typename UGraph::template NodeMap<bool> FlipMap;
580 typedef typename UGraph::template NodeMap<int> TypeMap;
582 enum IsolatorNodeType {
585 ROOT = 10, PERTINENT = 11,
591 /// \brief The map for store of embedding
592 typedef typename UGraph::template EdgeMap<Edge> EmbeddingMap;
594 /// \brief Constructor
596 /// \warining The graph should be simple, i.e. parallel and loop edge
598 PlanarEmbedding(const UGraph& ugraph)
599 : _ugraph(ugraph), _embedding(_ugraph), _kuratowski(ugraph, false) {}
601 /// \brief Runs the algorithm.
603 /// Runs the algorithm.
604 /// \param kuratowski If the parameter is false, then the
605 /// algorithm does not calculate the isolate Kuratowski
607 ///\return %True when the graph is planar.
608 bool run(bool kuratowski = true) {
609 typedef _planarity_bits::PlanarityVisitor<UGraph> Visitor;
611 PredMap pred_map(_ugraph, INVALID);
612 TreeMap tree_map(_ugraph, false);
614 OrderMap order_map(_ugraph, -1);
615 OrderList order_list;
617 AncestorMap ancestor_map(_ugraph, -1);
618 LowMap low_map(_ugraph, -1);
620 Visitor visitor(_ugraph, pred_map, tree_map,
621 order_map, order_list, ancestor_map, low_map);
622 DfsVisit<UGraph, Visitor> visit(_ugraph, visitor);
625 ChildLists child_lists(_ugraph);
626 createChildLists(tree_map, order_map, low_map, child_lists);
628 NodeData node_data(2 * order_list.size());
630 EmbedEdge embed_edge(_ugraph, INVALID);
632 MergeRoots merge_roots(_ugraph);
634 EdgeLists edge_lists(_ugraph);
636 FlipMap flip_map(_ugraph, false);
638 for (int i = order_list.size() - 1; i >= 0; --i) {
640 Node node = order_list[i];
642 node_data[i].first = INVALID;
645 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
646 Node target = _ugraph.target(e);
648 if (order_map[source] < order_map[target] && tree_map[e]) {
649 initFace(target, edge_lists, node_data,
650 pred_map, order_map, order_list);
654 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
655 Node target = _ugraph.target(e);
657 if (order_map[source] < order_map[target] && !tree_map[e]) {
658 embed_edge[target] = e;
659 walkUp(target, source, i, pred_map, low_map,
660 order_map, order_list, node_data, merge_roots);
664 for (typename MergeRoots::Value::iterator it =
665 merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
667 walkDown(rn, i, node_data, edge_lists, flip_map, order_list,
668 child_lists, ancestor_map, low_map, embed_edge, merge_roots);
670 merge_roots[node].clear();
672 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
673 Node target = _ugraph.target(e);
675 if (order_map[source] < order_map[target] && !tree_map[e]) {
676 if (embed_edge[target] != INVALID) {
678 isolateKuratowski(e, node_data, edge_lists, flip_map,
679 order_map, order_list, pred_map, child_lists,
680 ancestor_map, low_map,
681 embed_edge, merge_roots);
689 for (int i = 0; i < int(order_list.size()); ++i) {
691 mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
692 child_lists, edge_lists);
693 storeEmbedding(order_list[i], node_data, order_map, pred_map,
694 edge_lists, flip_map);
700 /// \brief Gives back the successor of an edge
702 /// Gives back the successor of an edge. This function makes
703 /// possible to query the cyclic order of the outgoing edges from
705 Edge next(const Edge& edge) const {
706 return _embedding[edge];
709 /// \brief Gives back the calculated embedding map
711 /// The returned map contains the successor of each edge in the
713 const EmbeddingMap& embedding() const {
717 /// \brief Gives back true when the undirected edge is in the
718 /// kuratowski subdivision
720 /// Gives back true when the undirected edge is in the kuratowski
722 bool kuratowski(const UEdge& uedge) {
723 return _kuratowski[uedge];
728 void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
729 const LowMap& low_map, ChildLists& child_lists) {
731 for (NodeIt n(_ugraph); n != INVALID; ++n) {
734 std::vector<Node> targets;
735 for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
736 Node target = _ugraph.target(e);
738 if (order_map[source] < order_map[target] && tree_map[e]) {
739 targets.push_back(target);
743 if (targets.size() == 0) {
744 child_lists[source].first = INVALID;
745 } else if (targets.size() == 1) {
746 child_lists[source].first = targets[0];
747 child_lists[targets[0]].prev = INVALID;
748 child_lists[targets[0]].next = INVALID;
750 radixSort(targets.begin(), targets.end(), mapFunctor(low_map));
751 for (int i = 1; i < int(targets.size()); ++i) {
752 child_lists[targets[i]].prev = targets[i - 1];
753 child_lists[targets[i - 1]].next = targets[i];
755 child_lists[targets.back()].next = INVALID;
756 child_lists[targets.front()].prev = INVALID;
757 child_lists[source].first = targets.front();
762 void walkUp(const Node& node, Node root, int rorder,
763 const PredMap& pred_map, const LowMap& low_map,
764 const OrderMap& order_map, const OrderList& order_list,
765 NodeData& node_data, MergeRoots& merge_roots) {
770 na = nb = order_map[node];
771 da = true; db = false;
775 if (node_data[na].visited == rorder) break;
776 if (node_data[nb].visited == rorder) break;
778 node_data[na].visited = rorder;
779 node_data[nb].visited = rorder;
783 if (na >= int(order_list.size())) {
785 } else if (nb >= int(order_list.size())) {
792 nn = da ? node_data[na].prev : node_data[na].next;
793 da = node_data[nn].prev != na;
796 nn = db ? node_data[nb].prev : node_data[nb].next;
797 db = node_data[nn].prev != nb;
802 Node rep = order_list[rn - order_list.size()];
803 Node parent = _ugraph.source(pred_map[rep]);
805 if (low_map[rep] < rorder) {
806 merge_roots[parent].push_back(rn);
808 merge_roots[parent].push_front(rn);
811 if (parent != root) {
812 na = nb = order_map[parent];
813 da = true; db = false;
821 void walkDown(int rn, int rorder, NodeData& node_data,
822 EdgeLists& edge_lists, FlipMap& flip_map,
823 OrderList& order_list, ChildLists& child_lists,
824 AncestorMap& ancestor_map, LowMap& low_map,
825 EmbedEdge& embed_edge, MergeRoots& merge_roots) {
827 std::vector<std::pair<int, bool> > merge_stack;
829 for (int di = 0; di < 2; ++di) {
832 int n = rd ? node_data[rn].next : node_data[rn].prev;
836 Node node = order_list[n];
838 if (embed_edge[node] != INVALID) {
840 // Merging components on the critical path
841 while (!merge_stack.empty()) {
844 int cn = merge_stack.back().first;
845 bool cd = merge_stack.back().second;
846 merge_stack.pop_back();
848 // Parent of component
849 int dn = merge_stack.back().first;
850 bool dd = merge_stack.back().second;
851 merge_stack.pop_back();
853 Node parent = order_list[dn];
855 // Erasing from merge_roots
856 merge_roots[parent].pop_front();
858 Node child = order_list[cn - order_list.size()];
860 // Erasing from child_lists
861 if (child_lists[child].prev != INVALID) {
862 child_lists[child_lists[child].prev].next =
863 child_lists[child].next;
865 child_lists[parent].first = child_lists[child].next;
868 if (child_lists[child].next != INVALID) {
869 child_lists[child_lists[child].next].prev =
870 child_lists[child].prev;
873 // Merging edges + flipping
874 Edge de = node_data[dn].first;
875 Edge ce = node_data[cn].first;
877 flip_map[order_list[cn - order_list.size()]] = cd != dd;
879 std::swap(edge_lists[ce].prev, edge_lists[ce].next);
880 ce = edge_lists[ce].prev;
881 std::swap(edge_lists[ce].prev, edge_lists[ce].next);
885 Edge dne = edge_lists[de].next;
886 Edge cne = edge_lists[ce].next;
888 edge_lists[de].next = cne;
889 edge_lists[ce].next = dne;
891 edge_lists[dne].prev = ce;
892 edge_lists[cne].prev = de;
896 node_data[dn].first = ce;
899 // Merging external faces
902 cn = cd ? node_data[cn].prev : node_data[cn].next;
903 cd = node_data[cn].next == en;
905 if (node_data[cn].prev == node_data[cn].next &&
906 node_data[cn].inverted) {
911 if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
912 if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
916 bool d = pn == node_data[n].prev;
918 if (node_data[n].prev == node_data[n].next &&
919 node_data[n].inverted) {
925 Edge edge = embed_edge[node];
926 Edge re = node_data[rn].first;
928 edge_lists[edge_lists[re].next].prev = edge;
929 edge_lists[edge].next = edge_lists[re].next;
930 edge_lists[edge].prev = re;
931 edge_lists[re].next = edge;
934 node_data[rn].first = edge;
937 Edge rev = _ugraph.oppositeEdge(edge);
938 Edge e = node_data[n].first;
940 edge_lists[edge_lists[e].next].prev = rev;
941 edge_lists[rev].next = edge_lists[e].next;
942 edge_lists[rev].prev = e;
943 edge_lists[e].next = rev;
946 node_data[n].first = rev;
951 // Embedding edge into external face
952 if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
953 if (d) node_data[n].prev = rn; else node_data[n].next = rn;
956 embed_edge[order_list[n]] = INVALID;
959 if (!merge_roots[node].empty()) {
961 bool d = pn == node_data[n].prev;
962 if (node_data[n].prev == node_data[n].next &&
963 node_data[n].inverted) {
967 merge_stack.push_back(std::make_pair(n, d));
969 int rn = merge_roots[node].front();
971 int xn = node_data[rn].next;
972 Node xnode = order_list[xn];
974 int yn = node_data[rn].prev;
975 Node ynode = order_list[yn];
978 if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
980 } else if (!external(ynode, rorder, child_lists,
981 ancestor_map, low_map)) {
983 } else if (pertinent(xnode, embed_edge, merge_roots)) {
989 merge_stack.push_back(std::make_pair(rn, rd));
994 } else if (!external(node, rorder, child_lists,
995 ancestor_map, low_map)) {
996 int nn = (node_data[n].next != pn ?
997 node_data[n].next : node_data[n].prev);
999 bool nd = n == node_data[nn].prev;
1001 if (nd) node_data[nn].prev = pn;
1002 else node_data[nn].next = pn;
1004 if (n == node_data[pn].prev) node_data[pn].prev = nn;
1005 else node_data[pn].next = nn;
1007 node_data[nn].inverted =
1008 (node_data[nn].prev == node_data[nn].next && nd != rd);
1016 if (!merge_stack.empty() || n == rn) {
1022 void initFace(const Node& node, EdgeLists& edge_lists,
1023 NodeData& node_data, const PredMap& pred_map,
1024 const OrderMap& order_map, const OrderList& order_list) {
1025 int n = order_map[node];
1026 int rn = n + order_list.size();
1028 node_data[n].next = node_data[n].prev = rn;
1029 node_data[rn].next = node_data[rn].prev = n;
1031 node_data[n].visited = order_list.size();
1032 node_data[rn].visited = order_list.size();
1034 node_data[n].inverted = false;
1035 node_data[rn].inverted = false;
1037 Edge edge = pred_map[node];
1038 Edge rev = _ugraph.oppositeEdge(edge);
1040 node_data[rn].first = edge;
1041 node_data[n].first = rev;
1043 edge_lists[edge].prev = edge;
1044 edge_lists[edge].next = edge;
1046 edge_lists[rev].prev = rev;
1047 edge_lists[rev].next = rev;
1051 void mergeRemainingFaces(const Node& node, NodeData& node_data,
1052 OrderList& order_list, OrderMap& order_map,
1053 ChildLists& child_lists, EdgeLists& edge_lists) {
1054 while (child_lists[node].first != INVALID) {
1055 int dd = order_map[node];
1056 Node child = child_lists[node].first;
1057 int cd = order_map[child] + order_list.size();
1058 child_lists[node].first = child_lists[child].next;
1060 Edge de = node_data[dd].first;
1061 Edge ce = node_data[cd].first;
1063 if (de != INVALID) {
1064 Edge dne = edge_lists[de].next;
1065 Edge cne = edge_lists[ce].next;
1067 edge_lists[de].next = cne;
1068 edge_lists[ce].next = dne;
1070 edge_lists[dne].prev = ce;
1071 edge_lists[cne].prev = de;
1074 node_data[dd].first = ce;
1079 void storeEmbedding(const Node& node, NodeData& node_data,
1080 OrderMap& order_map, PredMap& pred_map,
1081 EdgeLists& edge_lists, FlipMap& flip_map) {
1083 if (node_data[order_map[node]].first == INVALID) return;
1085 if (pred_map[node] != INVALID) {
1086 Node source = _ugraph.source(pred_map[node]);
1087 flip_map[node] = flip_map[node] != flip_map[source];
1090 Edge first = node_data[order_map[node]].first;
1093 Edge edge = flip_map[node] ?
1094 edge_lists[prev].prev : edge_lists[prev].next;
1096 _embedding[prev] = edge;
1098 while (edge != first) {
1099 Edge next = edge_lists[edge].prev == prev ?
1100 edge_lists[edge].next : edge_lists[edge].prev;
1101 prev = edge; edge = next;
1102 _embedding[prev] = edge;
1107 bool external(const Node& node, int rorder,
1108 ChildLists& child_lists, AncestorMap& ancestor_map,
1110 Node child = child_lists[node].first;
1112 if (child != INVALID) {
1113 if (low_map[child] < rorder) return true;
1116 if (ancestor_map[node] < rorder) return true;
1121 bool pertinent(const Node& node, const EmbedEdge& embed_edge,
1122 const MergeRoots& merge_roots) {
1123 return !merge_roots[node].empty() || embed_edge[node] != INVALID;
1126 int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
1127 AncestorMap& ancestor_map, LowMap& low_map) {
1130 Node child = child_lists[node].first;
1132 if (child != INVALID) {
1133 low_point = low_map[child];
1135 low_point = order_map[node];
1138 if (low_point > ancestor_map[node]) {
1139 low_point = ancestor_map[node];
1145 int findComponentRoot(Node root, Node node, ChildLists& child_lists,
1146 OrderMap& order_map, OrderList& order_list) {
1148 int order = order_map[root];
1149 int norder = order_map[node];
1151 Node child = child_lists[root].first;
1152 while (child != INVALID) {
1153 int corder = order_map[child];
1154 if (corder > order && corder < norder) {
1157 child = child_lists[child].next;
1159 return order + order_list.size();
1162 Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
1163 EmbedEdge& embed_edge, MergeRoots& merge_roots) {
1164 Node wnode =_ugraph.target(node_data[order_map[node]].first);
1165 while (!pertinent(wnode, embed_edge, merge_roots)) {
1166 wnode = _ugraph.target(node_data[order_map[wnode]].first);
1172 Node findExternal(Node node, int rorder, OrderMap& order_map,
1173 ChildLists& child_lists, AncestorMap& ancestor_map,
1174 LowMap& low_map, NodeData& node_data) {
1175 Node wnode =_ugraph.target(node_data[order_map[node]].first);
1176 while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
1177 wnode = _ugraph.target(node_data[order_map[wnode]].first);
1182 void markCommonPath(Node node, int rorder, Node& wnode, Node& znode,
1183 OrderList& order_list, OrderMap& order_map,
1184 NodeData& node_data, EdgeLists& edge_lists,
1185 EmbedEdge& embed_edge, MergeRoots& merge_roots,
1186 ChildLists& child_lists, AncestorMap& ancestor_map,
1190 Node pred = INVALID;
1194 bool pert = pertinent(cnode, embed_edge, merge_roots);
1195 bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
1198 if (!merge_roots[cnode].empty()) {
1199 int cn = merge_roots[cnode].back();
1201 if (low_map[order_list[cn - order_list.size()]] < rorder) {
1202 Edge edge = node_data[cn].first;
1203 _kuratowski.set(edge, true);
1206 cnode = _ugraph.target(edge);
1211 wnode = znode = cnode;
1217 while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
1218 Edge edge = node_data[order_map[cnode]].first;
1220 if (_ugraph.target(edge) == pred) {
1221 edge = edge_lists[edge].next;
1223 _kuratowski.set(edge, true);
1225 Node next = _ugraph.target(edge);
1226 pred = cnode; cnode = next;
1235 while (!pertinent(cnode, embed_edge, merge_roots)) {
1236 Edge edge = node_data[order_map[cnode]].first;
1238 if (_ugraph.target(edge) == pred) {
1239 edge = edge_lists[edge].next;
1241 _kuratowski.set(edge, true);
1243 Node next = _ugraph.target(edge);
1244 pred = cnode; cnode = next;
1251 Edge edge = node_data[order_map[cnode]].first;
1253 if (_ugraph.target(edge) == pred) {
1254 edge = edge_lists[edge].next;
1256 _kuratowski.set(edge, true);
1258 Node next = _ugraph.target(edge);
1259 pred = cnode; cnode = next;
1266 void orientComponent(Node root, int rn, OrderMap& order_map,
1267 PredMap& pred_map, NodeData& node_data,
1268 EdgeLists& edge_lists, FlipMap& flip_map,
1269 TypeMap& type_map) {
1270 node_data[order_map[root]].first = node_data[rn].first;
1273 std::vector<Node> st, qu;
1276 while (!st.empty()) {
1277 Node node = st.back();
1281 Edge edge = node_data[order_map[node]].first;
1283 if (type_map[_ugraph.target(edge)] == 0) {
1284 st.push_back(_ugraph.target(edge));
1285 type_map[_ugraph.target(edge)] = 1;
1288 Edge last = edge, pred = edge;
1289 edge = edge_lists[edge].next;
1290 while (edge != last) {
1292 if (type_map[_ugraph.target(edge)] == 0) {
1293 st.push_back(_ugraph.target(edge));
1294 type_map[_ugraph.target(edge)] = 1;
1297 Edge next = edge_lists[edge].next != pred ?
1298 edge_lists[edge].next : edge_lists[edge].prev;
1299 pred = edge; edge = next;
1305 flip_map[root] = false;
1307 for (int i = 1; i < int(qu.size()); ++i) {
1311 while (type_map[node] != 2) {
1314 node = _ugraph.source(pred_map[node]);
1317 bool flip = flip_map[node];
1319 while (!st.empty()) {
1323 flip_map[node] = flip != flip_map[node];
1324 flip = flip_map[node];
1327 Edge edge = node_data[order_map[node]].first;
1328 std::swap(edge_lists[edge].prev, edge_lists[edge].next);
1329 edge = edge_lists[edge].prev;
1330 std::swap(edge_lists[edge].prev, edge_lists[edge].next);
1331 node_data[order_map[node]].first = edge;
1336 for (int i = 0; i < int(qu.size()); ++i) {
1338 Edge edge = node_data[order_map[qu[i]]].first;
1339 Edge last = edge, pred = edge;
1341 edge = edge_lists[edge].next;
1342 while (edge != last) {
1344 if (edge_lists[edge].next == pred) {
1345 std::swap(edge_lists[edge].next, edge_lists[edge].prev);
1347 pred = edge; edge = edge_lists[edge].next;
1353 void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
1354 OrderMap& order_map, NodeData& node_data,
1355 TypeMap& type_map) {
1356 Node node = _ugraph.target(node_data[order_map[root]].first);
1358 while (node != ynode) {
1359 type_map[node] = HIGHY;
1360 node = _ugraph.target(node_data[order_map[node]].first);
1363 while (node != wnode) {
1364 type_map[node] = LOWY;
1365 node = _ugraph.target(node_data[order_map[node]].first);
1368 node = _ugraph.target(node_data[order_map[wnode]].first);
1370 while (node != xnode) {
1371 type_map[node] = LOWX;
1372 node = _ugraph.target(node_data[order_map[node]].first);
1374 type_map[node] = LOWX;
1376 node = _ugraph.target(node_data[order_map[xnode]].first);
1377 while (node != root) {
1378 type_map[node] = HIGHX;
1379 node = _ugraph.target(node_data[order_map[node]].first);
1382 type_map[wnode] = PERTINENT;
1383 type_map[root] = ROOT;
1386 void findInternalPath(std::vector<Edge>& ipath,
1387 Node wnode, Node root, TypeMap& type_map,
1388 OrderMap& order_map, NodeData& node_data,
1389 EdgeLists& edge_lists) {
1390 std::vector<Edge> st;
1394 while (node != root) {
1395 Edge edge = edge_lists[node_data[order_map[node]].first].next;
1397 node = _ugraph.target(edge);
1401 Edge edge = st.back();
1402 if (type_map[_ugraph.target(edge)] == LOWX ||
1403 type_map[_ugraph.target(edge)] == HIGHX) {
1406 if (type_map[_ugraph.target(edge)] == 2) {
1407 type_map[_ugraph.target(edge)] = 3;
1409 edge = edge_lists[_ugraph.oppositeEdge(edge)].next;
1413 edge = edge_lists[edge].next;
1415 while (_ugraph.oppositeEdge(edge) == st.back()) {
1418 edge = edge_lists[edge].next;
1424 for (int i = 0; i < int(st.size()); ++i) {
1425 if (type_map[_ugraph.target(st[i])] != LOWY &&
1426 type_map[_ugraph.target(st[i])] != HIGHY) {
1427 for (; i < int(st.size()); ++i) {
1428 ipath.push_back(st[i]);
1434 void setInternalFlags(std::vector<Edge>& ipath, TypeMap& type_map) {
1435 for (int i = 1; i < int(ipath.size()); ++i) {
1436 type_map[_ugraph.source(ipath[i])] = INTERNAL;
1440 void findPilePath(std::vector<Edge>& ppath,
1441 Node root, TypeMap& type_map, OrderMap& order_map,
1442 NodeData& node_data, EdgeLists& edge_lists) {
1443 std::vector<Edge> st;
1445 st.push_back(_ugraph.oppositeEdge(node_data[order_map[root]].first));
1446 st.push_back(node_data[order_map[root]].first);
1448 while (st.size() > 1) {
1449 Edge edge = st.back();
1450 if (type_map[_ugraph.target(edge)] == INTERNAL) {
1453 if (type_map[_ugraph.target(edge)] == 3) {
1454 type_map[_ugraph.target(edge)] = 4;
1456 edge = edge_lists[_ugraph.oppositeEdge(edge)].next;
1460 edge = edge_lists[edge].next;
1462 while (!st.empty() && _ugraph.oppositeEdge(edge) == st.back()) {
1465 edge = edge_lists[edge].next;
1471 for (int i = 1; i < int(st.size()); ++i) {
1472 ppath.push_back(st[i]);
1477 int markExternalPath(Node node, OrderMap& order_map,
1478 ChildLists& child_lists, PredMap& pred_map,
1479 AncestorMap& ancestor_map, LowMap& low_map) {
1480 int lp = lowPoint(node, order_map, child_lists,
1481 ancestor_map, low_map);
1483 if (ancestor_map[node] != lp) {
1484 node = child_lists[node].first;
1485 _kuratowski[pred_map[node]] = true;
1487 while (ancestor_map[node] != lp) {
1488 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
1489 Node tnode = _ugraph.target(e);
1490 if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
1492 _kuratowski[e] = true;
1499 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
1500 if (order_map[_ugraph.target(e)] == lp) {
1501 _kuratowski[e] = true;
1509 void markPertinentPath(Node node, OrderMap& order_map,
1510 NodeData& node_data, EdgeLists& edge_lists,
1511 EmbedEdge& embed_edge, MergeRoots& merge_roots) {
1512 while (embed_edge[node] == INVALID) {
1513 int n = merge_roots[node].front();
1514 Edge edge = node_data[n].first;
1516 _kuratowski.set(edge, true);
1519 node = _ugraph.target(edge);
1520 while (!pertinent(node, embed_edge, merge_roots)) {
1521 edge = node_data[order_map[node]].first;
1522 if (_ugraph.target(edge) == pred) {
1523 edge = edge_lists[edge].next;
1525 _kuratowski.set(edge, true);
1527 node = _ugraph.target(edge);
1530 _kuratowski.set(embed_edge[node], true);
1533 void markPredPath(Node node, Node snode, PredMap& pred_map) {
1534 while (node != snode) {
1535 _kuratowski.set(pred_map[node], true);
1536 node = _ugraph.source(pred_map[node]);
1540 void markFacePath(Node ynode, Node xnode,
1541 OrderMap& order_map, NodeData& node_data) {
1542 Edge edge = node_data[order_map[ynode]].first;
1543 Node node = _ugraph.target(edge);
1544 _kuratowski.set(edge, true);
1546 while (node != xnode) {
1547 edge = node_data[order_map[node]].first;
1548 _kuratowski.set(edge, true);
1549 node = _ugraph.target(edge);
1553 void markInternalPath(std::vector<Edge>& path) {
1554 for (int i = 0; i < int(path.size()); ++i) {
1555 _kuratowski.set(path[i], true);
1559 void markPilePath(std::vector<Edge>& path) {
1560 for (int i = 0; i < int(path.size()); ++i) {
1561 _kuratowski.set(path[i], true);
1565 void isolateKuratowski(Edge edge, NodeData& node_data,
1566 EdgeLists& edge_lists, FlipMap& flip_map,
1567 OrderMap& order_map, OrderList& order_list,
1568 PredMap& pred_map, ChildLists& child_lists,
1569 AncestorMap& ancestor_map, LowMap& low_map,
1570 EmbedEdge& embed_edge, MergeRoots& merge_roots) {
1572 Node root = _ugraph.source(edge);
1573 Node enode = _ugraph.target(edge);
1575 int rorder = order_map[root];
1577 TypeMap type_map(_ugraph, 0);
1579 int rn = findComponentRoot(root, enode, child_lists,
1580 order_map, order_list);
1582 Node xnode = order_list[node_data[rn].next];
1583 Node ynode = order_list[node_data[rn].prev];
1587 while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
1589 if (!merge_roots[xnode].empty()) {
1591 rn = merge_roots[xnode].front();
1594 rn = merge_roots[ynode].front();
1597 xnode = order_list[node_data[rn].next];
1598 ynode = order_list[node_data[rn].prev];
1601 if (root != _ugraph.source(edge)) {
1602 orientComponent(root, rn, order_map, pred_map,
1603 node_data, edge_lists, flip_map, type_map);
1604 markFacePath(root, root, order_map, node_data);
1605 int xlp = markExternalPath(xnode, order_map, child_lists,
1606 pred_map, ancestor_map, low_map);
1607 int ylp = markExternalPath(ynode, order_map, child_lists,
1608 pred_map, ancestor_map, low_map);
1609 markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1610 Node lwnode = findPertinent(ynode, order_map, node_data,
1611 embed_edge, merge_roots);
1613 markPertinentPath(lwnode, order_map, node_data, edge_lists,
1614 embed_edge, merge_roots);
1620 orientComponent(root, rn, order_map, pred_map,
1621 node_data, edge_lists, flip_map, type_map);
1623 Node wnode = findPertinent(ynode, order_map, node_data,
1624 embed_edge, merge_roots);
1625 setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
1629 if (!merge_roots[wnode].empty()) {
1630 int cn = merge_roots[wnode].back();
1631 Node rep = order_list[cn - order_list.size()];
1632 if (low_map[rep] < rorder) {
1633 markFacePath(root, root, order_map, node_data);
1634 int xlp = markExternalPath(xnode, order_map, child_lists,
1635 pred_map, ancestor_map, low_map);
1636 int ylp = markExternalPath(ynode, order_map, child_lists,
1637 pred_map, ancestor_map, low_map);
1639 Node lwnode, lznode;
1640 markCommonPath(wnode, rorder, lwnode, lznode, order_list,
1641 order_map, node_data, edge_lists, embed_edge,
1642 merge_roots, child_lists, ancestor_map, low_map);
1644 markPertinentPath(lwnode, order_map, node_data, edge_lists,
1645 embed_edge, merge_roots);
1646 int zlp = markExternalPath(lznode, order_map, child_lists,
1647 pred_map, ancestor_map, low_map);
1649 int minlp = xlp < ylp ? xlp : ylp;
1650 if (zlp < minlp) minlp = zlp;
1652 int maxlp = xlp > ylp ? xlp : ylp;
1653 if (zlp > maxlp) maxlp = zlp;
1655 markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1661 Node pxnode, pynode;
1662 std::vector<Edge> ipath;
1663 findInternalPath(ipath, wnode, root, type_map, order_map,
1664 node_data, edge_lists);
1665 setInternalFlags(ipath, type_map);
1666 pynode = _ugraph.source(ipath.front());
1667 pxnode = _ugraph.target(ipath.back());
1669 wnode = findPertinent(pynode, order_map, node_data,
1670 embed_edge, merge_roots);
1674 if (type_map[_ugraph.source(ipath.front())] == HIGHY) {
1675 if (type_map[_ugraph.target(ipath.back())] == HIGHX) {
1676 markFacePath(xnode, pxnode, order_map, node_data);
1678 markFacePath(root, xnode, order_map, node_data);
1679 markPertinentPath(wnode, order_map, node_data, edge_lists,
1680 embed_edge, merge_roots);
1681 markInternalPath(ipath);
1682 int xlp = markExternalPath(xnode, order_map, child_lists,
1683 pred_map, ancestor_map, low_map);
1684 int ylp = markExternalPath(ynode, order_map, child_lists,
1685 pred_map, ancestor_map, low_map);
1686 markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1690 if (type_map[_ugraph.target(ipath.back())] == HIGHX) {
1691 markFacePath(ynode, root, order_map, node_data);
1692 markPertinentPath(wnode, order_map, node_data, edge_lists,
1693 embed_edge, merge_roots);
1694 markInternalPath(ipath);
1695 int xlp = markExternalPath(xnode, order_map, child_lists,
1696 pred_map, ancestor_map, low_map);
1697 int ylp = markExternalPath(ynode, order_map, child_lists,
1698 pred_map, ancestor_map, low_map);
1699 markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1704 std::vector<Edge> ppath;
1705 findPilePath(ppath, root, type_map, order_map, node_data, edge_lists);
1708 if (!ppath.empty()) {
1709 markFacePath(ynode, xnode, order_map, node_data);
1710 markPertinentPath(wnode, order_map, node_data, edge_lists,
1711 embed_edge, merge_roots);
1712 markPilePath(ppath);
1713 markInternalPath(ipath);
1714 int xlp = markExternalPath(xnode, order_map, child_lists,
1715 pred_map, ancestor_map, low_map);
1716 int ylp = markExternalPath(ynode, order_map, child_lists,
1717 pred_map, ancestor_map, low_map);
1718 markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1725 if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
1726 Node znode = findExternal(pynode, rorder, order_map,
1727 child_lists, ancestor_map,
1728 low_map, node_data);
1730 if (type_map[znode] == LOWY) {
1731 markFacePath(root, xnode, order_map, node_data);
1732 markPertinentPath(wnode, order_map, node_data, edge_lists,
1733 embed_edge, merge_roots);
1734 markInternalPath(ipath);
1735 int xlp = markExternalPath(xnode, order_map, child_lists,
1736 pred_map, ancestor_map, low_map);
1737 int zlp = markExternalPath(znode, order_map, child_lists,
1738 pred_map, ancestor_map, low_map);
1739 markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
1741 markFacePath(ynode, root, order_map, node_data);
1742 markPertinentPath(wnode, order_map, node_data, edge_lists,
1743 embed_edge, merge_roots);
1744 markInternalPath(ipath);
1745 int ylp = markExternalPath(ynode, order_map, child_lists,
1746 pred_map, ancestor_map, low_map);
1747 int zlp = markExternalPath(znode, order_map, child_lists,
1748 pred_map, ancestor_map, low_map);
1749 markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
1754 int xlp = markExternalPath(xnode, order_map, child_lists,
1755 pred_map, ancestor_map, low_map);
1756 int ylp = markExternalPath(ynode, order_map, child_lists,
1757 pred_map, ancestor_map, low_map);
1758 int wlp = markExternalPath(wnode, order_map, child_lists,
1759 pred_map, ancestor_map, low_map);
1761 if (wlp > xlp && wlp > ylp) {
1762 markFacePath(root, root, order_map, node_data);
1763 markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1767 markInternalPath(ipath);
1768 markPertinentPath(wnode, order_map, node_data, edge_lists,
1769 embed_edge, merge_roots);
1771 if (xlp > ylp && xlp > wlp) {
1772 markFacePath(root, pynode, order_map, node_data);
1773 markFacePath(wnode, xnode, order_map, node_data);
1774 markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
1778 if (ylp > xlp && ylp > wlp) {
1779 markFacePath(pxnode, root, order_map, node_data);
1780 markFacePath(ynode, wnode, order_map, node_data);
1781 markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
1785 if (pynode != ynode) {
1786 markFacePath(pxnode, wnode, order_map, node_data);
1788 int minlp = xlp < ylp ? xlp : ylp;
1789 if (wlp < minlp) minlp = wlp;
1791 int maxlp = xlp > ylp ? xlp : ylp;
1792 if (wlp > maxlp) maxlp = wlp;
1794 markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1798 if (pxnode != xnode) {
1799 markFacePath(wnode, pynode, order_map, node_data);
1801 int minlp = xlp < ylp ? xlp : ylp;
1802 if (wlp < minlp) minlp = wlp;
1804 int maxlp = xlp > ylp ? xlp : ylp;
1805 if (wlp > maxlp) maxlp = wlp;
1807 markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1811 markFacePath(root, root, order_map, node_data);
1812 int minlp = xlp < ylp ? xlp : ylp;
1813 if (wlp < minlp) minlp = wlp;
1814 markPredPath(root, order_list[minlp], pred_map);
1822 namespace _planarity_bits {
1824 template <typename UGraph, typename EmbeddingMap>
1825 void makeConnected(UGraph& ugraph, EmbeddingMap& embedding) {
1826 DfsVisitor<UGraph> null_visitor;
1827 DfsVisit<UGraph, DfsVisitor<UGraph> > dfs(ugraph, null_visitor);
1830 typename UGraph::Node u = INVALID;
1831 for (typename UGraph::NodeIt n(ugraph); n != INVALID; ++n) {
1832 if (!dfs.reached(n)) {
1838 typename UGraph::Node v = n;
1840 typename UGraph::Edge ue = typename UGraph::OutEdgeIt(ugraph, u);
1841 typename UGraph::Edge ve = typename UGraph::OutEdgeIt(ugraph, v);
1843 typename UGraph::Edge e = ugraph.direct(ugraph.addEdge(u, v), true);
1845 if (ue != INVALID) {
1846 embedding[e] = embedding[ue];
1852 if (ve != INVALID) {
1853 embedding[ugraph.oppositeEdge(e)] = embedding[ve];
1854 embedding[ve] = ugraph.oppositeEdge(e);
1856 embedding[ugraph.oppositeEdge(e)] = ugraph.oppositeEdge(e);
1863 template <typename UGraph, typename EmbeddingMap>
1864 void makeBiNodeConnected(UGraph& ugraph, EmbeddingMap& embedding) {
1865 typename UGraph::template EdgeMap<bool> processed(ugraph);
1867 std::vector<typename UGraph::Edge> edges;
1868 for (typename UGraph::EdgeIt e(ugraph); e != INVALID; ++e) {
1872 IterableBoolMap<UGraph, typename UGraph::Node> visited(ugraph, false);
1874 for (int i = 0; i < int(edges.size()); ++i) {
1875 typename UGraph::Edge pp = edges[i];
1876 if (processed[pp]) continue;
1878 typename UGraph::Edge e = embedding[ugraph.oppositeEdge(pp)];
1879 processed[e] = true;
1880 visited.set(ugraph.source(e), true);
1882 typename UGraph::Edge p = e, l = e;
1883 e = embedding[ugraph.oppositeEdge(e)];
1886 processed[e] = true;
1888 if (visited[ugraph.source(e)]) {
1890 typename UGraph::Edge n =
1891 ugraph.direct(ugraph.addEdge(ugraph.source(p),
1892 ugraph.target(e)), true);
1894 embedding[ugraph.oppositeEdge(pp)] = n;
1896 embedding[ugraph.oppositeEdge(n)] =
1897 embedding[ugraph.oppositeEdge(e)];
1898 embedding[ugraph.oppositeEdge(e)] =
1899 ugraph.oppositeEdge(n);
1902 e = embedding[ugraph.oppositeEdge(n)];
1904 visited.set(ugraph.source(e), true);
1907 e = embedding[ugraph.oppositeEdge(e)];
1910 visited.setAll(false);
1915 template <typename UGraph, typename EmbeddingMap>
1916 void makeMaxPlanar(UGraph& ugraph, EmbeddingMap& embedding) {
1918 typename UGraph::template NodeMap<int> degree(ugraph);
1920 for (typename UGraph::NodeIt n(ugraph); n != INVALID; ++n) {
1921 degree[n] = countIncEdges(ugraph, n);
1924 typename UGraph::template EdgeMap<bool> processed(ugraph);
1925 IterableBoolMap<UGraph, typename UGraph::Node> visited(ugraph, false);
1927 std::vector<typename UGraph::Edge> edges;
1928 for (typename UGraph::EdgeIt e(ugraph); e != INVALID; ++e) {
1932 for (int i = 0; i < int(edges.size()); ++i) {
1933 typename UGraph::Edge e = edges[i];
1935 if (processed[e]) continue;
1936 processed[e] = true;
1938 typename UGraph::Edge mine = e;
1939 int mind = degree[ugraph.source(e)];
1943 typename UGraph::Edge l = e;
1944 e = embedding[ugraph.oppositeEdge(e)];
1946 processed[e] = true;
1950 if (degree[ugraph.source(e)] < mind) {
1952 mind = degree[ugraph.source(e)];
1955 e = embedding[ugraph.oppositeEdge(e)];
1958 if (face_size < 4) {
1962 typename UGraph::Node s = ugraph.source(mine);
1963 for (typename UGraph::OutEdgeIt e(ugraph, s); e != INVALID; ++e) {
1964 visited.set(ugraph.target(e), true);
1967 typename UGraph::Edge oppe = INVALID;
1969 e = embedding[ugraph.oppositeEdge(mine)];
1970 e = embedding[ugraph.oppositeEdge(e)];
1971 while (ugraph.target(e) != s) {
1972 if (visited[ugraph.source(e)]) {
1976 e = embedding[ugraph.oppositeEdge(e)];
1978 visited.setAll(false);
1980 if (oppe == INVALID) {
1982 e = embedding[ugraph.oppositeEdge(mine)];
1983 typename UGraph::Edge pn = mine, p = e;
1985 e = embedding[ugraph.oppositeEdge(e)];
1986 while (ugraph.target(e) != s) {
1987 typename UGraph::Edge n =
1988 ugraph.direct(ugraph.addEdge(s, ugraph.source(e)), true);
1991 embedding[ugraph.oppositeEdge(n)] = e;
1992 embedding[ugraph.oppositeEdge(p)] = ugraph.oppositeEdge(n);
1997 e = embedding[ugraph.oppositeEdge(e)];
2000 embedding[ugraph.oppositeEdge(e)] = pn;
2004 mine = embedding[ugraph.oppositeEdge(mine)];
2005 s = ugraph.source(mine);
2006 oppe = embedding[ugraph.oppositeEdge(oppe)];
2007 typename UGraph::Node t = ugraph.source(oppe);
2009 typename UGraph::Edge ce = ugraph.direct(ugraph.addEdge(s, t), true);
2010 embedding[ce] = mine;
2011 embedding[ugraph.oppositeEdge(ce)] = oppe;
2013 typename UGraph::Edge pn = ce, p = oppe;
2014 e = embedding[ugraph.oppositeEdge(oppe)];
2015 while (ugraph.target(e) != s) {
2016 typename UGraph::Edge n =
2017 ugraph.direct(ugraph.addEdge(s, ugraph.source(e)), true);
2020 embedding[ugraph.oppositeEdge(n)] = e;
2021 embedding[ugraph.oppositeEdge(p)] = ugraph.oppositeEdge(n);
2026 e = embedding[ugraph.oppositeEdge(e)];
2029 embedding[ugraph.oppositeEdge(e)] = pn;
2031 pn = ugraph.oppositeEdge(ce), p = mine;
2032 e = embedding[ugraph.oppositeEdge(mine)];
2033 while (ugraph.target(e) != t) {
2034 typename UGraph::Edge n =
2035 ugraph.direct(ugraph.addEdge(t, ugraph.source(e)), true);
2038 embedding[ugraph.oppositeEdge(n)] = e;
2039 embedding[ugraph.oppositeEdge(p)] = ugraph.oppositeEdge(n);
2044 e = embedding[ugraph.oppositeEdge(e)];
2047 embedding[ugraph.oppositeEdge(e)] = pn;
2056 /// \brief Schnyder's planar drawing algorithms
2058 /// The planar drawing algorithm calculates location for each node
2059 /// in the plane, which coordinates satisfies that if each edge is
2060 /// represented with a straight line then the edges will not
2061 /// intersect each other.
2063 /// Scnyder's algorithm embeds the graph on \c (n-2,n-2) size grid,
2064 /// ie. each node will be located in the \c [0,n-2]x[0,n-2] square.
2065 /// The time complexity of the algorithm is O(n).
2066 template <typename UGraph>
2067 class PlanarDrawing {
2070 UGRAPH_TYPEDEFS(typename UGraph);
2072 /// \brief The point type for store coordinates
2073 typedef dim2::Point<int> Point;
2074 /// \brief The map type for store coordinates
2075 typedef typename UGraph::template NodeMap<Point> PointMap;
2078 /// \brief Constructor
2081 /// \pre The ugraph should be simple, ie. loop and parallel edge free.
2082 PlanarDrawing(const UGraph& ugraph)
2083 : _ugraph(ugraph), _point_map(ugraph) {}
2087 template <typename AuxUGraph, typename AuxEmbeddingMap>
2088 void drawing(const AuxUGraph& ugraph,
2089 const AuxEmbeddingMap& next,
2090 PointMap& point_map) {
2091 UGRAPH_TYPEDEFS(typename AuxUGraph);
2093 typename AuxUGraph::template EdgeMap<Edge> prev(ugraph);
2095 for (NodeIt n(ugraph); n != INVALID; ++n) {
2096 Edge e = OutEdgeIt(ugraph, n);
2109 Node anode, bnode, cnode;
2112 Edge e = EdgeIt(ugraph);
2113 anode = ugraph.source(e);
2114 bnode = ugraph.target(e);
2115 cnode = ugraph.target(next[ugraph.oppositeEdge(e)]);
2118 IterableBoolMap<AuxUGraph, Node> proper(ugraph, false);
2119 typename AuxUGraph::template NodeMap<int> conn(ugraph, -1);
2121 conn[anode] = conn[bnode] = -2;
2123 for (OutEdgeIt e(ugraph, anode); e != INVALID; ++e) {
2124 Node m = ugraph.target(e);
2125 if (conn[m] == -1) {
2131 for (OutEdgeIt e(ugraph, bnode); e != INVALID; ++e) {
2132 Node m = ugraph.target(e);
2133 if (conn[m] == -1) {
2135 } else if (conn[m] != -2) {
2137 Edge pe = ugraph.oppositeEdge(e);
2138 if (conn[ugraph.target(next[pe])] == -2) {
2141 if (conn[ugraph.target(prev[pe])] == -2) {
2145 proper.set(m, conn[m] == 1);
2151 typename AuxUGraph::template EdgeMap<int> angle(ugraph, -1);
2153 while (proper.trueNum() != 0) {
2154 Node n = typename IterableBoolMap<AuxUGraph, Node>::TrueIt(proper);
2155 proper.set(n, false);
2158 for (OutEdgeIt e(ugraph, n); e != INVALID; ++e) {
2159 Node m = ugraph.target(e);
2160 if (conn[m] == -1) {
2162 } else if (conn[m] != -2) {
2164 Edge pe = ugraph.oppositeEdge(e);
2165 if (conn[ugraph.target(next[pe])] == -2) {
2168 if (conn[ugraph.target(prev[pe])] == -2) {
2172 proper.set(m, conn[m] == 1);
2177 Edge e = OutEdgeIt(ugraph, n);
2183 if (conn[ugraph.target(e)] == -2 && conn[ugraph.target(p)] == -2) {
2186 f = next[ugraph.oppositeEdge(f)];
2188 f = next[ugraph.oppositeEdge(f)];
2196 if (conn[ugraph.target(e)] == -2 && conn[ugraph.target(p)] == -2) {
2199 f = next[ugraph.oppositeEdge(f)];
2201 f = next[ugraph.oppositeEdge(f)];
2207 typename AuxUGraph::template NodeMap<Node> apred(ugraph, INVALID);
2208 typename AuxUGraph::template NodeMap<Node> bpred(ugraph, INVALID);
2209 typename AuxUGraph::template NodeMap<Node> cpred(ugraph, INVALID);
2211 typename AuxUGraph::template NodeMap<int> apredid(ugraph, -1);
2212 typename AuxUGraph::template NodeMap<int> bpredid(ugraph, -1);
2213 typename AuxUGraph::template NodeMap<int> cpredid(ugraph, -1);
2215 for (EdgeIt e(ugraph); e != INVALID; ++e) {
2216 if (angle[e] == angle[next[e]]) {
2219 apred[ugraph.target(e)] = ugraph.source(e);
2220 apredid[ugraph.target(e)] = ugraph.id(ugraph.source(e));
2223 bpred[ugraph.target(e)] = ugraph.source(e);
2224 bpredid[ugraph.target(e)] = ugraph.id(ugraph.source(e));
2227 cpred[ugraph.target(e)] = ugraph.source(e);
2228 cpredid[ugraph.target(e)] = ugraph.id(ugraph.source(e));
2234 cpred[anode] = INVALID;
2235 cpred[bnode] = INVALID;
2237 std::vector<Node> aorder, border, corder;
2240 typename AuxUGraph::template NodeMap<bool> processed(ugraph, false);
2241 std::vector<Node> st;
2242 for (NodeIt n(ugraph); n != INVALID; ++n) {
2243 if (!processed[n] && n != bnode && n != cnode) {
2245 processed[n] = true;
2247 while (m != INVALID && !processed[m]) {
2249 processed[m] = true;
2252 while (!st.empty()) {
2253 aorder.push_back(st.back());
2261 typename AuxUGraph::template NodeMap<bool> processed(ugraph, false);
2262 std::vector<Node> st;
2263 for (NodeIt n(ugraph); n != INVALID; ++n) {
2264 if (!processed[n] && n != cnode && n != anode) {
2266 processed[n] = true;
2268 while (m != INVALID && !processed[m]) {
2270 processed[m] = true;
2273 while (!st.empty()) {
2274 border.push_back(st.back());
2282 typename AuxUGraph::template NodeMap<bool> processed(ugraph, false);
2283 std::vector<Node> st;
2284 for (NodeIt n(ugraph); n != INVALID; ++n) {
2285 if (!processed[n] && n != anode && n != bnode) {
2287 processed[n] = true;
2289 while (m != INVALID && !processed[m]) {
2291 processed[m] = true;
2294 while (!st.empty()) {
2295 corder.push_back(st.back());
2302 typename AuxUGraph::template NodeMap<int> atree(ugraph, 0);
2303 for (int i = aorder.size() - 1; i >= 0; --i) {
2306 for (OutEdgeIt e(ugraph, n); e != INVALID; ++e) {
2307 if (apred[ugraph.target(e)] == n) {
2308 atree[n] += atree[ugraph.target(e)];
2313 typename AuxUGraph::template NodeMap<int> btree(ugraph, 0);
2314 for (int i = border.size() - 1; i >= 0; --i) {
2317 for (OutEdgeIt e(ugraph, n); e != INVALID; ++e) {
2318 if (bpred[ugraph.target(e)] == n) {
2319 btree[n] += btree[ugraph.target(e)];
2324 typename AuxUGraph::template NodeMap<int> apath(ugraph, 0);
2325 apath[bnode] = apath[cnode] = 1;
2326 typename AuxUGraph::template NodeMap<int> apath_btree(ugraph, 0);
2327 apath_btree[bnode] = btree[bnode];
2328 for (int i = 1; i < int(aorder.size()); ++i) {
2330 apath[n] = apath[apred[n]] + 1;
2331 apath_btree[n] = btree[n] + apath_btree[apred[n]];
2334 typename AuxUGraph::template NodeMap<int> bpath_atree(ugraph, 0);
2335 bpath_atree[anode] = atree[anode];
2336 for (int i = 1; i < int(border.size()); ++i) {
2338 bpath_atree[n] = atree[n] + bpath_atree[bpred[n]];
2341 typename AuxUGraph::template NodeMap<int> cpath(ugraph, 0);
2342 cpath[anode] = cpath[bnode] = 1;
2343 typename AuxUGraph::template NodeMap<int> cpath_atree(ugraph, 0);
2344 cpath_atree[anode] = atree[anode];
2345 typename AuxUGraph::template NodeMap<int> cpath_btree(ugraph, 0);
2346 cpath_btree[bnode] = btree[bnode];
2347 for (int i = 1; i < int(corder.size()); ++i) {
2349 cpath[n] = cpath[cpred[n]] + 1;
2350 cpath_atree[n] = atree[n] + cpath_atree[cpred[n]];
2351 cpath_btree[n] = btree[n] + cpath_btree[cpred[n]];
2354 typename AuxUGraph::template NodeMap<int> third(ugraph);
2355 for (NodeIt n(ugraph); n != INVALID; ++n) {
2357 bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1;
2359 cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1;
2366 /// \brief Calculates the node locations
2368 /// This function calculates the node locations.
2370 PlanarEmbedding<UGraph> pe(_ugraph);
2371 if (!pe.run()) return false;
2377 /// \brief Calculates the node locations according to a
2378 /// combinatorical embedding
2380 /// This function calculates the node locations. The \c embedding
2381 /// parameter should contain a valid combinatorical embedding, ie.
2382 /// a valid cyclic order of the edges.
2383 template <typename EmbeddingMap>
2384 void run(const EmbeddingMap& embedding) {
2385 typedef SmartUEdgeSet<UGraph> AuxUGraph;
2387 if (3 * countNodes(_ugraph) - 6 == countUEdges(_ugraph)) {
2388 drawing(_ugraph, embedding, _point_map);
2392 AuxUGraph aux_ugraph(_ugraph);
2393 typename AuxUGraph::template EdgeMap<typename AuxUGraph::Edge>
2394 aux_embedding(aux_ugraph);
2398 typename UGraph::template UEdgeMap<typename AuxUGraph::UEdge>
2401 for (UEdgeIt e(_ugraph); e != INVALID; ++e) {
2402 ref[e] = aux_ugraph.addEdge(_ugraph.source(e), _ugraph.target(e));
2405 for (UEdgeIt e(_ugraph); e != INVALID; ++e) {
2406 Edge ee = embedding[_ugraph.direct(e, true)];
2407 aux_embedding[aux_ugraph.direct(ref[e], true)] =
2408 aux_ugraph.direct(ref[ee], _ugraph.direction(ee));
2409 ee = embedding[_ugraph.direct(e, false)];
2410 aux_embedding[aux_ugraph.direct(ref[e], false)] =
2411 aux_ugraph.direct(ref[ee], _ugraph.direction(ee));
2414 _planarity_bits::makeConnected(aux_ugraph, aux_embedding);
2415 _planarity_bits::makeBiNodeConnected(aux_ugraph, aux_embedding);
2416 _planarity_bits::makeMaxPlanar(aux_ugraph, aux_embedding);
2417 drawing(aux_ugraph, aux_embedding, _point_map);
2420 /// \brief The coordinate of the given node
2422 /// The coordinate of the given node.
2423 Point operator[](const Node& node) {
2424 return _point_map[node];
2427 /// \brief Returns the grid embedding in a \e NodeMap.
2429 /// Returns the grid embedding in a \e NodeMap of \c dim2::Point<int> .
2430 const PointMap& coords() const {
2436 const UGraph& _ugraph;
2437 PointMap _point_map;