3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_PLANARITY_H
20 #define LEMON_PLANARITY_H
24 /// \brief Planarity checking, embedding, drawing and coloring
29 #include <lemon/dfs.h>
30 #include <lemon/bfs.h>
31 #include <lemon/radix_sort.h>
32 #include <lemon/maps.h>
33 #include <lemon/path.h>
34 #include <lemon/iterable_maps.h>
35 #include <lemon/edge_set.h>
36 #include <lemon/bucket_heap.h>
37 #include <lemon/ugraph_adaptor.h>
38 #include <lemon/color.h>
43 namespace _planarity_bits {
45 template <typename UGraph>
46 struct PlanarityVisitor : DfsVisitor<UGraph> {
48 typedef typename UGraph::Node Node;
49 typedef typename UGraph::Edge Edge;
51 typedef typename UGraph::template NodeMap<Edge> PredMap;
53 typedef typename UGraph::template UEdgeMap<bool> TreeMap;
55 typedef typename UGraph::template NodeMap<int> OrderMap;
56 typedef std::vector<Node> OrderList;
58 typedef typename UGraph::template NodeMap<int> LowMap;
59 typedef typename UGraph::template NodeMap<int> AncestorMap;
61 PlanarityVisitor(const UGraph& ugraph,
62 PredMap& pred_map, TreeMap& tree_map,
63 OrderMap& order_map, OrderList& order_list,
64 AncestorMap& ancestor_map, LowMap& low_map)
65 : _ugraph(ugraph), _pred_map(pred_map), _tree_map(tree_map),
66 _order_map(order_map), _order_list(order_list),
67 _ancestor_map(ancestor_map), _low_map(low_map) {}
69 void reach(const Node& node) {
70 _order_map[node] = _order_list.size();
71 _low_map[node] = _order_list.size();
72 _ancestor_map[node] = _order_list.size();
73 _order_list.push_back(node);
76 void discover(const Edge& edge) {
77 Node source = _ugraph.source(edge);
78 Node target = _ugraph.target(edge);
80 _tree_map[edge] = true;
81 _pred_map[target] = edge;
84 void examine(const Edge& edge) {
85 Node source = _ugraph.source(edge);
86 Node target = _ugraph.target(edge);
88 if (_order_map[target] < _order_map[source] && !_tree_map[edge]) {
89 if (_low_map[source] > _order_map[target]) {
90 _low_map[source] = _order_map[target];
92 if (_ancestor_map[source] > _order_map[target]) {
93 _ancestor_map[source] = _order_map[target];
98 void backtrack(const Edge& edge) {
99 Node source = _ugraph.source(edge);
100 Node target = _ugraph.target(edge);
102 if (_low_map[source] > _low_map[target]) {
103 _low_map[source] = _low_map[target];
107 const UGraph& _ugraph;
110 OrderMap& _order_map;
111 OrderList& _order_list;
112 AncestorMap& _ancestor_map;
116 template <typename UGraph, bool embedding = true>
117 struct NodeDataNode {
120 typename UGraph::Edge first;
124 template <typename UGraph>
125 struct NodeDataNode<UGraph, false> {
130 template <typename UGraph>
131 struct ChildListNode {
132 typedef typename UGraph::Node Node;
137 template <typename UGraph>
138 struct EdgeListNode {
139 typename UGraph::Edge prev, next;
146 /// \brief Planarity checking of an undirected simple graph
148 /// This class implements the Boyer-Myrvold algorithm for planarity
149 /// checking of an undirected graph. This class is a simplified
150 /// version of the PlanarEmbedding algorithm class, and it does
151 /// provide neither embedding nor kuratowski subdivisons.
152 template <typename UGraph>
153 class PlanarityChecking {
156 UGRAPH_TYPEDEFS(typename UGraph);
158 const UGraph& _ugraph;
162 typedef typename UGraph::template NodeMap<Edge> PredMap;
164 typedef typename UGraph::template UEdgeMap<bool> TreeMap;
166 typedef typename UGraph::template NodeMap<int> OrderMap;
167 typedef std::vector<Node> OrderList;
169 typedef typename UGraph::template NodeMap<int> LowMap;
170 typedef typename UGraph::template NodeMap<int> AncestorMap;
172 typedef _planarity_bits::NodeDataNode<UGraph> NodeDataNode;
173 typedef std::vector<NodeDataNode> NodeData;
175 typedef _planarity_bits::ChildListNode<UGraph> ChildListNode;
176 typedef typename UGraph::template NodeMap<ChildListNode> ChildLists;
178 typedef typename UGraph::template NodeMap<std::list<int> > MergeRoots;
180 typedef typename UGraph::template NodeMap<bool> EmbedEdge;
184 /// \brief Constructor
186 /// \warining The graph should be simple, i.e. parallel and loop edge
188 PlanarityChecking(const UGraph& ugraph) : _ugraph(ugraph) {}
190 /// \brief Runs the algorithm.
192 /// Runs the algorithm.
193 /// \return %True when the graph is planar.
195 typedef _planarity_bits::PlanarityVisitor<UGraph> Visitor;
197 PredMap pred_map(_ugraph, INVALID);
198 TreeMap tree_map(_ugraph, false);
200 OrderMap order_map(_ugraph, -1);
201 OrderList order_list;
203 AncestorMap ancestor_map(_ugraph, -1);
204 LowMap low_map(_ugraph, -1);
206 Visitor visitor(_ugraph, pred_map, tree_map,
207 order_map, order_list, ancestor_map, low_map);
208 DfsVisit<UGraph, Visitor> visit(_ugraph, visitor);
211 ChildLists child_lists(_ugraph);
212 createChildLists(tree_map, order_map, low_map, child_lists);
214 NodeData node_data(2 * order_list.size());
216 EmbedEdge embed_edge(_ugraph, false);
218 MergeRoots merge_roots(_ugraph);
220 for (int i = order_list.size() - 1; i >= 0; --i) {
222 Node node = order_list[i];
225 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
226 Node target = _ugraph.target(e);
228 if (order_map[source] < order_map[target] && tree_map[e]) {
229 initFace(target, node_data, order_map, order_list);
233 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
234 Node target = _ugraph.target(e);
236 if (order_map[source] < order_map[target] && !tree_map[e]) {
237 embed_edge[target] = true;
238 walkUp(target, source, i, pred_map, low_map,
239 order_map, order_list, node_data, merge_roots);
243 for (typename MergeRoots::Value::iterator it =
244 merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
246 walkDown(rn, i, node_data, order_list, child_lists,
247 ancestor_map, low_map, embed_edge, merge_roots);
249 merge_roots[node].clear();
251 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
252 Node target = _ugraph.target(e);
254 if (order_map[source] < order_map[target] && !tree_map[e]) {
255 if (embed_edge[target]) {
267 void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
268 const LowMap& low_map, ChildLists& child_lists) {
270 for (NodeIt n(_ugraph); n != INVALID; ++n) {
273 std::vector<Node> targets;
274 for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
275 Node target = _ugraph.target(e);
277 if (order_map[source] < order_map[target] && tree_map[e]) {
278 targets.push_back(target);
282 if (targets.size() == 0) {
283 child_lists[source].first = INVALID;
284 } else if (targets.size() == 1) {
285 child_lists[source].first = targets[0];
286 child_lists[targets[0]].prev = INVALID;
287 child_lists[targets[0]].next = INVALID;
289 radixSort(targets.begin(), targets.end(), mapFunctor(low_map));
290 for (int i = 1; i < int(targets.size()); ++i) {
291 child_lists[targets[i]].prev = targets[i - 1];
292 child_lists[targets[i - 1]].next = targets[i];
294 child_lists[targets.back()].next = INVALID;
295 child_lists[targets.front()].prev = INVALID;
296 child_lists[source].first = targets.front();
301 void walkUp(const Node& node, Node root, int rorder,
302 const PredMap& pred_map, const LowMap& low_map,
303 const OrderMap& order_map, const OrderList& order_list,
304 NodeData& node_data, MergeRoots& merge_roots) {
309 na = nb = order_map[node];
310 da = true; db = false;
314 if (node_data[na].visited == rorder) break;
315 if (node_data[nb].visited == rorder) break;
317 node_data[na].visited = rorder;
318 node_data[nb].visited = rorder;
322 if (na >= int(order_list.size())) {
324 } else if (nb >= int(order_list.size())) {
331 nn = da ? node_data[na].prev : node_data[na].next;
332 da = node_data[nn].prev != na;
335 nn = db ? node_data[nb].prev : node_data[nb].next;
336 db = node_data[nn].prev != nb;
341 Node rep = order_list[rn - order_list.size()];
342 Node parent = _ugraph.source(pred_map[rep]);
344 if (low_map[rep] < rorder) {
345 merge_roots[parent].push_back(rn);
347 merge_roots[parent].push_front(rn);
350 if (parent != root) {
351 na = nb = order_map[parent];
352 da = true; db = false;
360 void walkDown(int rn, int rorder, NodeData& node_data,
361 OrderList& order_list, ChildLists& child_lists,
362 AncestorMap& ancestor_map, LowMap& low_map,
363 EmbedEdge& embed_edge, MergeRoots& merge_roots) {
365 std::vector<std::pair<int, bool> > merge_stack;
367 for (int di = 0; di < 2; ++di) {
370 int n = rd ? node_data[rn].next : node_data[rn].prev;
374 Node node = order_list[n];
376 if (embed_edge[node]) {
378 // Merging components on the critical path
379 while (!merge_stack.empty()) {
382 int cn = merge_stack.back().first;
383 bool cd = merge_stack.back().second;
384 merge_stack.pop_back();
386 // Parent of component
387 int dn = merge_stack.back().first;
388 bool dd = merge_stack.back().second;
389 merge_stack.pop_back();
391 Node parent = order_list[dn];
393 // Erasing from merge_roots
394 merge_roots[parent].pop_front();
396 Node child = order_list[cn - order_list.size()];
398 // Erasing from child_lists
399 if (child_lists[child].prev != INVALID) {
400 child_lists[child_lists[child].prev].next =
401 child_lists[child].next;
403 child_lists[parent].first = child_lists[child].next;
406 if (child_lists[child].next != INVALID) {
407 child_lists[child_lists[child].next].prev =
408 child_lists[child].prev;
411 // Merging external faces
414 cn = cd ? node_data[cn].prev : node_data[cn].next;
415 cd = node_data[cn].next == en;
419 if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
420 if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
424 bool d = pn == node_data[n].prev;
426 if (node_data[n].prev == node_data[n].next &&
427 node_data[n].inverted) {
431 // Embedding edge into external face
432 if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
433 if (d) node_data[n].prev = rn; else node_data[n].next = rn;
436 embed_edge[order_list[n]] = false;
439 if (!merge_roots[node].empty()) {
441 bool d = pn == node_data[n].prev;
443 merge_stack.push_back(std::make_pair(n, d));
445 int rn = merge_roots[node].front();
447 int xn = node_data[rn].next;
448 Node xnode = order_list[xn];
450 int yn = node_data[rn].prev;
451 Node ynode = order_list[yn];
454 if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
456 } else if (!external(ynode, rorder, child_lists,
457 ancestor_map, low_map)) {
459 } else if (pertinent(xnode, embed_edge, merge_roots)) {
465 merge_stack.push_back(std::make_pair(rn, rd));
470 } else if (!external(node, rorder, child_lists,
471 ancestor_map, low_map)) {
472 int nn = (node_data[n].next != pn ?
473 node_data[n].next : node_data[n].prev);
475 bool nd = n == node_data[nn].prev;
477 if (nd) node_data[nn].prev = pn;
478 else node_data[nn].next = pn;
480 if (n == node_data[pn].prev) node_data[pn].prev = nn;
481 else node_data[pn].next = nn;
483 node_data[nn].inverted =
484 (node_data[nn].prev == node_data[nn].next && nd != rd);
492 if (!merge_stack.empty() || n == rn) {
498 void initFace(const Node& node, NodeData& node_data,
499 const OrderMap& order_map, const OrderList& order_list) {
500 int n = order_map[node];
501 int rn = n + order_list.size();
503 node_data[n].next = node_data[n].prev = rn;
504 node_data[rn].next = node_data[rn].prev = n;
506 node_data[n].visited = order_list.size();
507 node_data[rn].visited = order_list.size();
511 bool external(const Node& node, int rorder,
512 ChildLists& child_lists, AncestorMap& ancestor_map,
514 Node child = child_lists[node].first;
516 if (child != INVALID) {
517 if (low_map[child] < rorder) return true;
520 if (ancestor_map[node] < rorder) return true;
525 bool pertinent(const Node& node, const EmbedEdge& embed_edge,
526 const MergeRoots& merge_roots) {
527 return !merge_roots[node].empty() || embed_edge[node];
534 /// \brief Planar embedding of an undirected simple graph
536 /// This class implements the Boyer-Myrvold algorithm for planar
537 /// embedding of an undirected graph. The planar embeding is an
538 /// ordering of the outgoing edges in each node, which is a possible
539 /// configuration to draw the graph in the plane. If there is not
540 /// such ordering then the graph contains a \f$ K_5 \f$ (full graph
541 /// with 5 nodes) or an \f$ K_{3,3} \f$ (complete bipartite graph on
542 /// 3 ANode and 3 BNode) subdivision.
544 /// The current implementation calculates an embedding or an
545 /// Kuratowski subdivision if the graph is not planar. The running
546 /// time of the algorithm is \f$ O(n) \f$.
547 template <typename UGraph>
548 class PlanarEmbedding {
551 UGRAPH_TYPEDEFS(typename UGraph);
553 const UGraph& _ugraph;
554 typename UGraph::template EdgeMap<Edge> _embedding;
556 typename UGraph::template UEdgeMap<bool> _kuratowski;
560 typedef typename UGraph::template NodeMap<Edge> PredMap;
562 typedef typename UGraph::template UEdgeMap<bool> TreeMap;
564 typedef typename UGraph::template NodeMap<int> OrderMap;
565 typedef std::vector<Node> OrderList;
567 typedef typename UGraph::template NodeMap<int> LowMap;
568 typedef typename UGraph::template NodeMap<int> AncestorMap;
570 typedef _planarity_bits::NodeDataNode<UGraph> NodeDataNode;
571 typedef std::vector<NodeDataNode> NodeData;
573 typedef _planarity_bits::ChildListNode<UGraph> ChildListNode;
574 typedef typename UGraph::template NodeMap<ChildListNode> ChildLists;
576 typedef typename UGraph::template NodeMap<std::list<int> > MergeRoots;
578 typedef typename UGraph::template NodeMap<Edge> EmbedEdge;
580 typedef _planarity_bits::EdgeListNode<UGraph> EdgeListNode;
581 typedef typename UGraph::template EdgeMap<EdgeListNode> EdgeLists;
583 typedef typename UGraph::template NodeMap<bool> FlipMap;
585 typedef typename UGraph::template NodeMap<int> TypeMap;
587 enum IsolatorNodeType {
590 ROOT = 10, PERTINENT = 11,
596 /// \brief The map for store of embedding
597 typedef typename UGraph::template EdgeMap<Edge> EmbeddingMap;
599 /// \brief Constructor
601 /// \warining The graph should be simple, i.e. parallel and loop edge
603 PlanarEmbedding(const UGraph& ugraph)
604 : _ugraph(ugraph), _embedding(_ugraph), _kuratowski(ugraph, false) {}
606 /// \brief Runs the algorithm.
608 /// Runs the algorithm.
609 /// \param kuratowski If the parameter is false, then the
610 /// algorithm does not calculate the isolate Kuratowski
612 ///\return %True when the graph is planar.
613 bool run(bool kuratowski = true) {
614 typedef _planarity_bits::PlanarityVisitor<UGraph> Visitor;
616 PredMap pred_map(_ugraph, INVALID);
617 TreeMap tree_map(_ugraph, false);
619 OrderMap order_map(_ugraph, -1);
620 OrderList order_list;
622 AncestorMap ancestor_map(_ugraph, -1);
623 LowMap low_map(_ugraph, -1);
625 Visitor visitor(_ugraph, pred_map, tree_map,
626 order_map, order_list, ancestor_map, low_map);
627 DfsVisit<UGraph, Visitor> visit(_ugraph, visitor);
630 ChildLists child_lists(_ugraph);
631 createChildLists(tree_map, order_map, low_map, child_lists);
633 NodeData node_data(2 * order_list.size());
635 EmbedEdge embed_edge(_ugraph, INVALID);
637 MergeRoots merge_roots(_ugraph);
639 EdgeLists edge_lists(_ugraph);
641 FlipMap flip_map(_ugraph, false);
643 for (int i = order_list.size() - 1; i >= 0; --i) {
645 Node node = order_list[i];
647 node_data[i].first = INVALID;
650 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
651 Node target = _ugraph.target(e);
653 if (order_map[source] < order_map[target] && tree_map[e]) {
654 initFace(target, edge_lists, node_data,
655 pred_map, order_map, order_list);
659 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
660 Node target = _ugraph.target(e);
662 if (order_map[source] < order_map[target] && !tree_map[e]) {
663 embed_edge[target] = e;
664 walkUp(target, source, i, pred_map, low_map,
665 order_map, order_list, node_data, merge_roots);
669 for (typename MergeRoots::Value::iterator it =
670 merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
672 walkDown(rn, i, node_data, edge_lists, flip_map, order_list,
673 child_lists, ancestor_map, low_map, embed_edge, merge_roots);
675 merge_roots[node].clear();
677 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
678 Node target = _ugraph.target(e);
680 if (order_map[source] < order_map[target] && !tree_map[e]) {
681 if (embed_edge[target] != INVALID) {
683 isolateKuratowski(e, node_data, edge_lists, flip_map,
684 order_map, order_list, pred_map, child_lists,
685 ancestor_map, low_map,
686 embed_edge, merge_roots);
694 for (int i = 0; i < int(order_list.size()); ++i) {
696 mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
697 child_lists, edge_lists);
698 storeEmbedding(order_list[i], node_data, order_map, pred_map,
699 edge_lists, flip_map);
705 /// \brief Gives back the successor of an edge
707 /// Gives back the successor of an edge. This function makes
708 /// possible to query the cyclic order of the outgoing edges from
710 Edge next(const Edge& edge) const {
711 return _embedding[edge];
714 /// \brief Gives back the calculated embedding map
716 /// The returned map contains the successor of each edge in the
718 const EmbeddingMap& embedding() const {
722 /// \brief Gives back true when the undirected edge is in the
723 /// kuratowski subdivision
725 /// Gives back true when the undirected edge is in the kuratowski
727 bool kuratowski(const UEdge& uedge) {
728 return _kuratowski[uedge];
733 void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
734 const LowMap& low_map, ChildLists& child_lists) {
736 for (NodeIt n(_ugraph); n != INVALID; ++n) {
739 std::vector<Node> targets;
740 for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
741 Node target = _ugraph.target(e);
743 if (order_map[source] < order_map[target] && tree_map[e]) {
744 targets.push_back(target);
748 if (targets.size() == 0) {
749 child_lists[source].first = INVALID;
750 } else if (targets.size() == 1) {
751 child_lists[source].first = targets[0];
752 child_lists[targets[0]].prev = INVALID;
753 child_lists[targets[0]].next = INVALID;
755 radixSort(targets.begin(), targets.end(), mapFunctor(low_map));
756 for (int i = 1; i < int(targets.size()); ++i) {
757 child_lists[targets[i]].prev = targets[i - 1];
758 child_lists[targets[i - 1]].next = targets[i];
760 child_lists[targets.back()].next = INVALID;
761 child_lists[targets.front()].prev = INVALID;
762 child_lists[source].first = targets.front();
767 void walkUp(const Node& node, Node root, int rorder,
768 const PredMap& pred_map, const LowMap& low_map,
769 const OrderMap& order_map, const OrderList& order_list,
770 NodeData& node_data, MergeRoots& merge_roots) {
775 na = nb = order_map[node];
776 da = true; db = false;
780 if (node_data[na].visited == rorder) break;
781 if (node_data[nb].visited == rorder) break;
783 node_data[na].visited = rorder;
784 node_data[nb].visited = rorder;
788 if (na >= int(order_list.size())) {
790 } else if (nb >= int(order_list.size())) {
797 nn = da ? node_data[na].prev : node_data[na].next;
798 da = node_data[nn].prev != na;
801 nn = db ? node_data[nb].prev : node_data[nb].next;
802 db = node_data[nn].prev != nb;
807 Node rep = order_list[rn - order_list.size()];
808 Node parent = _ugraph.source(pred_map[rep]);
810 if (low_map[rep] < rorder) {
811 merge_roots[parent].push_back(rn);
813 merge_roots[parent].push_front(rn);
816 if (parent != root) {
817 na = nb = order_map[parent];
818 da = true; db = false;
826 void walkDown(int rn, int rorder, NodeData& node_data,
827 EdgeLists& edge_lists, FlipMap& flip_map,
828 OrderList& order_list, ChildLists& child_lists,
829 AncestorMap& ancestor_map, LowMap& low_map,
830 EmbedEdge& embed_edge, MergeRoots& merge_roots) {
832 std::vector<std::pair<int, bool> > merge_stack;
834 for (int di = 0; di < 2; ++di) {
837 int n = rd ? node_data[rn].next : node_data[rn].prev;
841 Node node = order_list[n];
843 if (embed_edge[node] != INVALID) {
845 // Merging components on the critical path
846 while (!merge_stack.empty()) {
849 int cn = merge_stack.back().first;
850 bool cd = merge_stack.back().second;
851 merge_stack.pop_back();
853 // Parent of component
854 int dn = merge_stack.back().first;
855 bool dd = merge_stack.back().second;
856 merge_stack.pop_back();
858 Node parent = order_list[dn];
860 // Erasing from merge_roots
861 merge_roots[parent].pop_front();
863 Node child = order_list[cn - order_list.size()];
865 // Erasing from child_lists
866 if (child_lists[child].prev != INVALID) {
867 child_lists[child_lists[child].prev].next =
868 child_lists[child].next;
870 child_lists[parent].first = child_lists[child].next;
873 if (child_lists[child].next != INVALID) {
874 child_lists[child_lists[child].next].prev =
875 child_lists[child].prev;
878 // Merging edges + flipping
879 Edge de = node_data[dn].first;
880 Edge ce = node_data[cn].first;
882 flip_map[order_list[cn - order_list.size()]] = cd != dd;
884 std::swap(edge_lists[ce].prev, edge_lists[ce].next);
885 ce = edge_lists[ce].prev;
886 std::swap(edge_lists[ce].prev, edge_lists[ce].next);
890 Edge dne = edge_lists[de].next;
891 Edge cne = edge_lists[ce].next;
893 edge_lists[de].next = cne;
894 edge_lists[ce].next = dne;
896 edge_lists[dne].prev = ce;
897 edge_lists[cne].prev = de;
901 node_data[dn].first = ce;
904 // Merging external faces
907 cn = cd ? node_data[cn].prev : node_data[cn].next;
908 cd = node_data[cn].next == en;
910 if (node_data[cn].prev == node_data[cn].next &&
911 node_data[cn].inverted) {
916 if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
917 if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
921 bool d = pn == node_data[n].prev;
923 if (node_data[n].prev == node_data[n].next &&
924 node_data[n].inverted) {
930 Edge edge = embed_edge[node];
931 Edge re = node_data[rn].first;
933 edge_lists[edge_lists[re].next].prev = edge;
934 edge_lists[edge].next = edge_lists[re].next;
935 edge_lists[edge].prev = re;
936 edge_lists[re].next = edge;
939 node_data[rn].first = edge;
942 Edge rev = _ugraph.oppositeEdge(edge);
943 Edge e = node_data[n].first;
945 edge_lists[edge_lists[e].next].prev = rev;
946 edge_lists[rev].next = edge_lists[e].next;
947 edge_lists[rev].prev = e;
948 edge_lists[e].next = rev;
951 node_data[n].first = rev;
956 // Embedding edge into external face
957 if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
958 if (d) node_data[n].prev = rn; else node_data[n].next = rn;
961 embed_edge[order_list[n]] = INVALID;
964 if (!merge_roots[node].empty()) {
966 bool d = pn == node_data[n].prev;
967 if (node_data[n].prev == node_data[n].next &&
968 node_data[n].inverted) {
972 merge_stack.push_back(std::make_pair(n, d));
974 int rn = merge_roots[node].front();
976 int xn = node_data[rn].next;
977 Node xnode = order_list[xn];
979 int yn = node_data[rn].prev;
980 Node ynode = order_list[yn];
983 if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
985 } else if (!external(ynode, rorder, child_lists,
986 ancestor_map, low_map)) {
988 } else if (pertinent(xnode, embed_edge, merge_roots)) {
994 merge_stack.push_back(std::make_pair(rn, rd));
999 } else if (!external(node, rorder, child_lists,
1000 ancestor_map, low_map)) {
1001 int nn = (node_data[n].next != pn ?
1002 node_data[n].next : node_data[n].prev);
1004 bool nd = n == node_data[nn].prev;
1006 if (nd) node_data[nn].prev = pn;
1007 else node_data[nn].next = pn;
1009 if (n == node_data[pn].prev) node_data[pn].prev = nn;
1010 else node_data[pn].next = nn;
1012 node_data[nn].inverted =
1013 (node_data[nn].prev == node_data[nn].next && nd != rd);
1021 if (!merge_stack.empty() || n == rn) {
1027 void initFace(const Node& node, EdgeLists& edge_lists,
1028 NodeData& node_data, const PredMap& pred_map,
1029 const OrderMap& order_map, const OrderList& order_list) {
1030 int n = order_map[node];
1031 int rn = n + order_list.size();
1033 node_data[n].next = node_data[n].prev = rn;
1034 node_data[rn].next = node_data[rn].prev = n;
1036 node_data[n].visited = order_list.size();
1037 node_data[rn].visited = order_list.size();
1039 node_data[n].inverted = false;
1040 node_data[rn].inverted = false;
1042 Edge edge = pred_map[node];
1043 Edge rev = _ugraph.oppositeEdge(edge);
1045 node_data[rn].first = edge;
1046 node_data[n].first = rev;
1048 edge_lists[edge].prev = edge;
1049 edge_lists[edge].next = edge;
1051 edge_lists[rev].prev = rev;
1052 edge_lists[rev].next = rev;
1056 void mergeRemainingFaces(const Node& node, NodeData& node_data,
1057 OrderList& order_list, OrderMap& order_map,
1058 ChildLists& child_lists, EdgeLists& edge_lists) {
1059 while (child_lists[node].first != INVALID) {
1060 int dd = order_map[node];
1061 Node child = child_lists[node].first;
1062 int cd = order_map[child] + order_list.size();
1063 child_lists[node].first = child_lists[child].next;
1065 Edge de = node_data[dd].first;
1066 Edge ce = node_data[cd].first;
1068 if (de != INVALID) {
1069 Edge dne = edge_lists[de].next;
1070 Edge cne = edge_lists[ce].next;
1072 edge_lists[de].next = cne;
1073 edge_lists[ce].next = dne;
1075 edge_lists[dne].prev = ce;
1076 edge_lists[cne].prev = de;
1079 node_data[dd].first = ce;
1084 void storeEmbedding(const Node& node, NodeData& node_data,
1085 OrderMap& order_map, PredMap& pred_map,
1086 EdgeLists& edge_lists, FlipMap& flip_map) {
1088 if (node_data[order_map[node]].first == INVALID) return;
1090 if (pred_map[node] != INVALID) {
1091 Node source = _ugraph.source(pred_map[node]);
1092 flip_map[node] = flip_map[node] != flip_map[source];
1095 Edge first = node_data[order_map[node]].first;
1098 Edge edge = flip_map[node] ?
1099 edge_lists[prev].prev : edge_lists[prev].next;
1101 _embedding[prev] = edge;
1103 while (edge != first) {
1104 Edge next = edge_lists[edge].prev == prev ?
1105 edge_lists[edge].next : edge_lists[edge].prev;
1106 prev = edge; edge = next;
1107 _embedding[prev] = edge;
1112 bool external(const Node& node, int rorder,
1113 ChildLists& child_lists, AncestorMap& ancestor_map,
1115 Node child = child_lists[node].first;
1117 if (child != INVALID) {
1118 if (low_map[child] < rorder) return true;
1121 if (ancestor_map[node] < rorder) return true;
1126 bool pertinent(const Node& node, const EmbedEdge& embed_edge,
1127 const MergeRoots& merge_roots) {
1128 return !merge_roots[node].empty() || embed_edge[node] != INVALID;
1131 int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
1132 AncestorMap& ancestor_map, LowMap& low_map) {
1135 Node child = child_lists[node].first;
1137 if (child != INVALID) {
1138 low_point = low_map[child];
1140 low_point = order_map[node];
1143 if (low_point > ancestor_map[node]) {
1144 low_point = ancestor_map[node];
1150 int findComponentRoot(Node root, Node node, ChildLists& child_lists,
1151 OrderMap& order_map, OrderList& order_list) {
1153 int order = order_map[root];
1154 int norder = order_map[node];
1156 Node child = child_lists[root].first;
1157 while (child != INVALID) {
1158 int corder = order_map[child];
1159 if (corder > order && corder < norder) {
1162 child = child_lists[child].next;
1164 return order + order_list.size();
1167 Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
1168 EmbedEdge& embed_edge, MergeRoots& merge_roots) {
1169 Node wnode =_ugraph.target(node_data[order_map[node]].first);
1170 while (!pertinent(wnode, embed_edge, merge_roots)) {
1171 wnode = _ugraph.target(node_data[order_map[wnode]].first);
1177 Node findExternal(Node node, int rorder, OrderMap& order_map,
1178 ChildLists& child_lists, AncestorMap& ancestor_map,
1179 LowMap& low_map, NodeData& node_data) {
1180 Node wnode =_ugraph.target(node_data[order_map[node]].first);
1181 while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
1182 wnode = _ugraph.target(node_data[order_map[wnode]].first);
1187 void markCommonPath(Node node, int rorder, Node& wnode, Node& znode,
1188 OrderList& order_list, OrderMap& order_map,
1189 NodeData& node_data, EdgeLists& edge_lists,
1190 EmbedEdge& embed_edge, MergeRoots& merge_roots,
1191 ChildLists& child_lists, AncestorMap& ancestor_map,
1195 Node pred = INVALID;
1199 bool pert = pertinent(cnode, embed_edge, merge_roots);
1200 bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
1203 if (!merge_roots[cnode].empty()) {
1204 int cn = merge_roots[cnode].back();
1206 if (low_map[order_list[cn - order_list.size()]] < rorder) {
1207 Edge edge = node_data[cn].first;
1208 _kuratowski.set(edge, true);
1211 cnode = _ugraph.target(edge);
1216 wnode = znode = cnode;
1222 while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
1223 Edge edge = node_data[order_map[cnode]].first;
1225 if (_ugraph.target(edge) == pred) {
1226 edge = edge_lists[edge].next;
1228 _kuratowski.set(edge, true);
1230 Node next = _ugraph.target(edge);
1231 pred = cnode; cnode = next;
1240 while (!pertinent(cnode, embed_edge, merge_roots)) {
1241 Edge edge = node_data[order_map[cnode]].first;
1243 if (_ugraph.target(edge) == pred) {
1244 edge = edge_lists[edge].next;
1246 _kuratowski.set(edge, true);
1248 Node next = _ugraph.target(edge);
1249 pred = cnode; cnode = next;
1256 Edge edge = node_data[order_map[cnode]].first;
1258 if (_ugraph.target(edge) == pred) {
1259 edge = edge_lists[edge].next;
1261 _kuratowski.set(edge, true);
1263 Node next = _ugraph.target(edge);
1264 pred = cnode; cnode = next;
1271 void orientComponent(Node root, int rn, OrderMap& order_map,
1272 PredMap& pred_map, NodeData& node_data,
1273 EdgeLists& edge_lists, FlipMap& flip_map,
1274 TypeMap& type_map) {
1275 node_data[order_map[root]].first = node_data[rn].first;
1278 std::vector<Node> st, qu;
1281 while (!st.empty()) {
1282 Node node = st.back();
1286 Edge edge = node_data[order_map[node]].first;
1288 if (type_map[_ugraph.target(edge)] == 0) {
1289 st.push_back(_ugraph.target(edge));
1290 type_map[_ugraph.target(edge)] = 1;
1293 Edge last = edge, pred = edge;
1294 edge = edge_lists[edge].next;
1295 while (edge != last) {
1297 if (type_map[_ugraph.target(edge)] == 0) {
1298 st.push_back(_ugraph.target(edge));
1299 type_map[_ugraph.target(edge)] = 1;
1302 Edge next = edge_lists[edge].next != pred ?
1303 edge_lists[edge].next : edge_lists[edge].prev;
1304 pred = edge; edge = next;
1310 flip_map[root] = false;
1312 for (int i = 1; i < int(qu.size()); ++i) {
1316 while (type_map[node] != 2) {
1319 node = _ugraph.source(pred_map[node]);
1322 bool flip = flip_map[node];
1324 while (!st.empty()) {
1328 flip_map[node] = flip != flip_map[node];
1329 flip = flip_map[node];
1332 Edge edge = node_data[order_map[node]].first;
1333 std::swap(edge_lists[edge].prev, edge_lists[edge].next);
1334 edge = edge_lists[edge].prev;
1335 std::swap(edge_lists[edge].prev, edge_lists[edge].next);
1336 node_data[order_map[node]].first = edge;
1341 for (int i = 0; i < int(qu.size()); ++i) {
1343 Edge edge = node_data[order_map[qu[i]]].first;
1344 Edge last = edge, pred = edge;
1346 edge = edge_lists[edge].next;
1347 while (edge != last) {
1349 if (edge_lists[edge].next == pred) {
1350 std::swap(edge_lists[edge].next, edge_lists[edge].prev);
1352 pred = edge; edge = edge_lists[edge].next;
1358 void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
1359 OrderMap& order_map, NodeData& node_data,
1360 TypeMap& type_map) {
1361 Node node = _ugraph.target(node_data[order_map[root]].first);
1363 while (node != ynode) {
1364 type_map[node] = HIGHY;
1365 node = _ugraph.target(node_data[order_map[node]].first);
1368 while (node != wnode) {
1369 type_map[node] = LOWY;
1370 node = _ugraph.target(node_data[order_map[node]].first);
1373 node = _ugraph.target(node_data[order_map[wnode]].first);
1375 while (node != xnode) {
1376 type_map[node] = LOWX;
1377 node = _ugraph.target(node_data[order_map[node]].first);
1379 type_map[node] = LOWX;
1381 node = _ugraph.target(node_data[order_map[xnode]].first);
1382 while (node != root) {
1383 type_map[node] = HIGHX;
1384 node = _ugraph.target(node_data[order_map[node]].first);
1387 type_map[wnode] = PERTINENT;
1388 type_map[root] = ROOT;
1391 void findInternalPath(std::vector<Edge>& ipath,
1392 Node wnode, Node root, TypeMap& type_map,
1393 OrderMap& order_map, NodeData& node_data,
1394 EdgeLists& edge_lists) {
1395 std::vector<Edge> st;
1399 while (node != root) {
1400 Edge edge = edge_lists[node_data[order_map[node]].first].next;
1402 node = _ugraph.target(edge);
1406 Edge edge = st.back();
1407 if (type_map[_ugraph.target(edge)] == LOWX ||
1408 type_map[_ugraph.target(edge)] == HIGHX) {
1411 if (type_map[_ugraph.target(edge)] == 2) {
1412 type_map[_ugraph.target(edge)] = 3;
1414 edge = edge_lists[_ugraph.oppositeEdge(edge)].next;
1418 edge = edge_lists[edge].next;
1420 while (_ugraph.oppositeEdge(edge) == st.back()) {
1423 edge = edge_lists[edge].next;
1429 for (int i = 0; i < int(st.size()); ++i) {
1430 if (type_map[_ugraph.target(st[i])] != LOWY &&
1431 type_map[_ugraph.target(st[i])] != HIGHY) {
1432 for (; i < int(st.size()); ++i) {
1433 ipath.push_back(st[i]);
1439 void setInternalFlags(std::vector<Edge>& ipath, TypeMap& type_map) {
1440 for (int i = 1; i < int(ipath.size()); ++i) {
1441 type_map[_ugraph.source(ipath[i])] = INTERNAL;
1445 void findPilePath(std::vector<Edge>& ppath,
1446 Node root, TypeMap& type_map, OrderMap& order_map,
1447 NodeData& node_data, EdgeLists& edge_lists) {
1448 std::vector<Edge> st;
1450 st.push_back(_ugraph.oppositeEdge(node_data[order_map[root]].first));
1451 st.push_back(node_data[order_map[root]].first);
1453 while (st.size() > 1) {
1454 Edge edge = st.back();
1455 if (type_map[_ugraph.target(edge)] == INTERNAL) {
1458 if (type_map[_ugraph.target(edge)] == 3) {
1459 type_map[_ugraph.target(edge)] = 4;
1461 edge = edge_lists[_ugraph.oppositeEdge(edge)].next;
1465 edge = edge_lists[edge].next;
1467 while (!st.empty() && _ugraph.oppositeEdge(edge) == st.back()) {
1470 edge = edge_lists[edge].next;
1476 for (int i = 1; i < int(st.size()); ++i) {
1477 ppath.push_back(st[i]);
1482 int markExternalPath(Node node, OrderMap& order_map,
1483 ChildLists& child_lists, PredMap& pred_map,
1484 AncestorMap& ancestor_map, LowMap& low_map) {
1485 int lp = lowPoint(node, order_map, child_lists,
1486 ancestor_map, low_map);
1488 if (ancestor_map[node] != lp) {
1489 node = child_lists[node].first;
1490 _kuratowski[pred_map[node]] = true;
1492 while (ancestor_map[node] != lp) {
1493 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
1494 Node tnode = _ugraph.target(e);
1495 if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
1497 _kuratowski[e] = true;
1504 for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
1505 if (order_map[_ugraph.target(e)] == lp) {
1506 _kuratowski[e] = true;
1514 void markPertinentPath(Node node, OrderMap& order_map,
1515 NodeData& node_data, EdgeLists& edge_lists,
1516 EmbedEdge& embed_edge, MergeRoots& merge_roots) {
1517 while (embed_edge[node] == INVALID) {
1518 int n = merge_roots[node].front();
1519 Edge edge = node_data[n].first;
1521 _kuratowski.set(edge, true);
1524 node = _ugraph.target(edge);
1525 while (!pertinent(node, embed_edge, merge_roots)) {
1526 edge = node_data[order_map[node]].first;
1527 if (_ugraph.target(edge) == pred) {
1528 edge = edge_lists[edge].next;
1530 _kuratowski.set(edge, true);
1532 node = _ugraph.target(edge);
1535 _kuratowski.set(embed_edge[node], true);
1538 void markPredPath(Node node, Node snode, PredMap& pred_map) {
1539 while (node != snode) {
1540 _kuratowski.set(pred_map[node], true);
1541 node = _ugraph.source(pred_map[node]);
1545 void markFacePath(Node ynode, Node xnode,
1546 OrderMap& order_map, NodeData& node_data) {
1547 Edge edge = node_data[order_map[ynode]].first;
1548 Node node = _ugraph.target(edge);
1549 _kuratowski.set(edge, true);
1551 while (node != xnode) {
1552 edge = node_data[order_map[node]].first;
1553 _kuratowski.set(edge, true);
1554 node = _ugraph.target(edge);
1558 void markInternalPath(std::vector<Edge>& path) {
1559 for (int i = 0; i < int(path.size()); ++i) {
1560 _kuratowski.set(path[i], true);
1564 void markPilePath(std::vector<Edge>& path) {
1565 for (int i = 0; i < int(path.size()); ++i) {
1566 _kuratowski.set(path[i], true);
1570 void isolateKuratowski(Edge edge, NodeData& node_data,
1571 EdgeLists& edge_lists, FlipMap& flip_map,
1572 OrderMap& order_map, OrderList& order_list,
1573 PredMap& pred_map, ChildLists& child_lists,
1574 AncestorMap& ancestor_map, LowMap& low_map,
1575 EmbedEdge& embed_edge, MergeRoots& merge_roots) {
1577 Node root = _ugraph.source(edge);
1578 Node enode = _ugraph.target(edge);
1580 int rorder = order_map[root];
1582 TypeMap type_map(_ugraph, 0);
1584 int rn = findComponentRoot(root, enode, child_lists,
1585 order_map, order_list);
1587 Node xnode = order_list[node_data[rn].next];
1588 Node ynode = order_list[node_data[rn].prev];
1592 while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
1594 if (!merge_roots[xnode].empty()) {
1596 rn = merge_roots[xnode].front();
1599 rn = merge_roots[ynode].front();
1602 xnode = order_list[node_data[rn].next];
1603 ynode = order_list[node_data[rn].prev];
1606 if (root != _ugraph.source(edge)) {
1607 orientComponent(root, rn, order_map, pred_map,
1608 node_data, edge_lists, flip_map, type_map);
1609 markFacePath(root, root, order_map, node_data);
1610 int xlp = markExternalPath(xnode, order_map, child_lists,
1611 pred_map, ancestor_map, low_map);
1612 int ylp = markExternalPath(ynode, order_map, child_lists,
1613 pred_map, ancestor_map, low_map);
1614 markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1615 Node lwnode = findPertinent(ynode, order_map, node_data,
1616 embed_edge, merge_roots);
1618 markPertinentPath(lwnode, order_map, node_data, edge_lists,
1619 embed_edge, merge_roots);
1625 orientComponent(root, rn, order_map, pred_map,
1626 node_data, edge_lists, flip_map, type_map);
1628 Node wnode = findPertinent(ynode, order_map, node_data,
1629 embed_edge, merge_roots);
1630 setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
1634 if (!merge_roots[wnode].empty()) {
1635 int cn = merge_roots[wnode].back();
1636 Node rep = order_list[cn - order_list.size()];
1637 if (low_map[rep] < rorder) {
1638 markFacePath(root, root, order_map, node_data);
1639 int xlp = markExternalPath(xnode, order_map, child_lists,
1640 pred_map, ancestor_map, low_map);
1641 int ylp = markExternalPath(ynode, order_map, child_lists,
1642 pred_map, ancestor_map, low_map);
1644 Node lwnode, lznode;
1645 markCommonPath(wnode, rorder, lwnode, lznode, order_list,
1646 order_map, node_data, edge_lists, embed_edge,
1647 merge_roots, child_lists, ancestor_map, low_map);
1649 markPertinentPath(lwnode, order_map, node_data, edge_lists,
1650 embed_edge, merge_roots);
1651 int zlp = markExternalPath(lznode, order_map, child_lists,
1652 pred_map, ancestor_map, low_map);
1654 int minlp = xlp < ylp ? xlp : ylp;
1655 if (zlp < minlp) minlp = zlp;
1657 int maxlp = xlp > ylp ? xlp : ylp;
1658 if (zlp > maxlp) maxlp = zlp;
1660 markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1666 Node pxnode, pynode;
1667 std::vector<Edge> ipath;
1668 findInternalPath(ipath, wnode, root, type_map, order_map,
1669 node_data, edge_lists);
1670 setInternalFlags(ipath, type_map);
1671 pynode = _ugraph.source(ipath.front());
1672 pxnode = _ugraph.target(ipath.back());
1674 wnode = findPertinent(pynode, order_map, node_data,
1675 embed_edge, merge_roots);
1679 if (type_map[_ugraph.source(ipath.front())] == HIGHY) {
1680 if (type_map[_ugraph.target(ipath.back())] == HIGHX) {
1681 markFacePath(xnode, pxnode, order_map, node_data);
1683 markFacePath(root, xnode, order_map, node_data);
1684 markPertinentPath(wnode, order_map, node_data, edge_lists,
1685 embed_edge, merge_roots);
1686 markInternalPath(ipath);
1687 int xlp = markExternalPath(xnode, order_map, child_lists,
1688 pred_map, ancestor_map, low_map);
1689 int ylp = markExternalPath(ynode, order_map, child_lists,
1690 pred_map, ancestor_map, low_map);
1691 markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1695 if (type_map[_ugraph.target(ipath.back())] == HIGHX) {
1696 markFacePath(ynode, root, order_map, node_data);
1697 markPertinentPath(wnode, order_map, node_data, edge_lists,
1698 embed_edge, merge_roots);
1699 markInternalPath(ipath);
1700 int xlp = markExternalPath(xnode, order_map, child_lists,
1701 pred_map, ancestor_map, low_map);
1702 int ylp = markExternalPath(ynode, order_map, child_lists,
1703 pred_map, ancestor_map, low_map);
1704 markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1709 std::vector<Edge> ppath;
1710 findPilePath(ppath, root, type_map, order_map, node_data, edge_lists);
1713 if (!ppath.empty()) {
1714 markFacePath(ynode, xnode, order_map, node_data);
1715 markPertinentPath(wnode, order_map, node_data, edge_lists,
1716 embed_edge, merge_roots);
1717 markPilePath(ppath);
1718 markInternalPath(ipath);
1719 int xlp = markExternalPath(xnode, order_map, child_lists,
1720 pred_map, ancestor_map, low_map);
1721 int ylp = markExternalPath(ynode, order_map, child_lists,
1722 pred_map, ancestor_map, low_map);
1723 markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1730 if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
1731 Node znode = findExternal(pynode, rorder, order_map,
1732 child_lists, ancestor_map,
1733 low_map, node_data);
1735 if (type_map[znode] == LOWY) {
1736 markFacePath(root, xnode, order_map, node_data);
1737 markPertinentPath(wnode, order_map, node_data, edge_lists,
1738 embed_edge, merge_roots);
1739 markInternalPath(ipath);
1740 int xlp = markExternalPath(xnode, order_map, child_lists,
1741 pred_map, ancestor_map, low_map);
1742 int zlp = markExternalPath(znode, order_map, child_lists,
1743 pred_map, ancestor_map, low_map);
1744 markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
1746 markFacePath(ynode, root, order_map, node_data);
1747 markPertinentPath(wnode, order_map, node_data, edge_lists,
1748 embed_edge, merge_roots);
1749 markInternalPath(ipath);
1750 int ylp = markExternalPath(ynode, order_map, child_lists,
1751 pred_map, ancestor_map, low_map);
1752 int zlp = markExternalPath(znode, order_map, child_lists,
1753 pred_map, ancestor_map, low_map);
1754 markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
1759 int xlp = markExternalPath(xnode, order_map, child_lists,
1760 pred_map, ancestor_map, low_map);
1761 int ylp = markExternalPath(ynode, order_map, child_lists,
1762 pred_map, ancestor_map, low_map);
1763 int wlp = markExternalPath(wnode, order_map, child_lists,
1764 pred_map, ancestor_map, low_map);
1766 if (wlp > xlp && wlp > ylp) {
1767 markFacePath(root, root, order_map, node_data);
1768 markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1772 markInternalPath(ipath);
1773 markPertinentPath(wnode, order_map, node_data, edge_lists,
1774 embed_edge, merge_roots);
1776 if (xlp > ylp && xlp > wlp) {
1777 markFacePath(root, pynode, order_map, node_data);
1778 markFacePath(wnode, xnode, order_map, node_data);
1779 markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
1783 if (ylp > xlp && ylp > wlp) {
1784 markFacePath(pxnode, root, order_map, node_data);
1785 markFacePath(ynode, wnode, order_map, node_data);
1786 markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
1790 if (pynode != ynode) {
1791 markFacePath(pxnode, wnode, order_map, node_data);
1793 int minlp = xlp < ylp ? xlp : ylp;
1794 if (wlp < minlp) minlp = wlp;
1796 int maxlp = xlp > ylp ? xlp : ylp;
1797 if (wlp > maxlp) maxlp = wlp;
1799 markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1803 if (pxnode != xnode) {
1804 markFacePath(wnode, pynode, order_map, node_data);
1806 int minlp = xlp < ylp ? xlp : ylp;
1807 if (wlp < minlp) minlp = wlp;
1809 int maxlp = xlp > ylp ? xlp : ylp;
1810 if (wlp > maxlp) maxlp = wlp;
1812 markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1816 markFacePath(root, root, order_map, node_data);
1817 int minlp = xlp < ylp ? xlp : ylp;
1818 if (wlp < minlp) minlp = wlp;
1819 markPredPath(root, order_list[minlp], pred_map);
1827 namespace _planarity_bits {
1829 template <typename UGraph, typename EmbeddingMap>
1830 void makeConnected(UGraph& ugraph, EmbeddingMap& embedding) {
1831 DfsVisitor<UGraph> null_visitor;
1832 DfsVisit<UGraph, DfsVisitor<UGraph> > dfs(ugraph, null_visitor);
1835 typename UGraph::Node u = INVALID;
1836 for (typename UGraph::NodeIt n(ugraph); n != INVALID; ++n) {
1837 if (!dfs.reached(n)) {
1843 typename UGraph::Node v = n;
1845 typename UGraph::Edge ue = typename UGraph::OutEdgeIt(ugraph, u);
1846 typename UGraph::Edge ve = typename UGraph::OutEdgeIt(ugraph, v);
1848 typename UGraph::Edge e = ugraph.direct(ugraph.addEdge(u, v), true);
1850 if (ue != INVALID) {
1851 embedding[e] = embedding[ue];
1857 if (ve != INVALID) {
1858 embedding[ugraph.oppositeEdge(e)] = embedding[ve];
1859 embedding[ve] = ugraph.oppositeEdge(e);
1861 embedding[ugraph.oppositeEdge(e)] = ugraph.oppositeEdge(e);
1868 template <typename UGraph, typename EmbeddingMap>
1869 void makeBiNodeConnected(UGraph& ugraph, EmbeddingMap& embedding) {
1870 typename UGraph::template EdgeMap<bool> processed(ugraph);
1872 std::vector<typename UGraph::Edge> edges;
1873 for (typename UGraph::EdgeIt e(ugraph); e != INVALID; ++e) {
1877 IterableBoolMap<UGraph, typename UGraph::Node> visited(ugraph, false);
1879 for (int i = 0; i < int(edges.size()); ++i) {
1880 typename UGraph::Edge pp = edges[i];
1881 if (processed[pp]) continue;
1883 typename UGraph::Edge e = embedding[ugraph.oppositeEdge(pp)];
1884 processed[e] = true;
1885 visited.set(ugraph.source(e), true);
1887 typename UGraph::Edge p = e, l = e;
1888 e = embedding[ugraph.oppositeEdge(e)];
1891 processed[e] = true;
1893 if (visited[ugraph.source(e)]) {
1895 typename UGraph::Edge n =
1896 ugraph.direct(ugraph.addEdge(ugraph.source(p),
1897 ugraph.target(e)), true);
1899 embedding[ugraph.oppositeEdge(pp)] = n;
1901 embedding[ugraph.oppositeEdge(n)] =
1902 embedding[ugraph.oppositeEdge(e)];
1903 embedding[ugraph.oppositeEdge(e)] =
1904 ugraph.oppositeEdge(n);
1907 e = embedding[ugraph.oppositeEdge(n)];
1909 visited.set(ugraph.source(e), true);
1912 e = embedding[ugraph.oppositeEdge(e)];
1915 visited.setAll(false);
1920 template <typename UGraph, typename EmbeddingMap>
1921 void makeMaxPlanar(UGraph& ugraph, EmbeddingMap& embedding) {
1923 typename UGraph::template NodeMap<int> degree(ugraph);
1925 for (typename UGraph::NodeIt n(ugraph); n != INVALID; ++n) {
1926 degree[n] = countIncEdges(ugraph, n);
1929 typename UGraph::template EdgeMap<bool> processed(ugraph);
1930 IterableBoolMap<UGraph, typename UGraph::Node> visited(ugraph, false);
1932 std::vector<typename UGraph::Edge> edges;
1933 for (typename UGraph::EdgeIt e(ugraph); e != INVALID; ++e) {
1937 for (int i = 0; i < int(edges.size()); ++i) {
1938 typename UGraph::Edge e = edges[i];
1940 if (processed[e]) continue;
1941 processed[e] = true;
1943 typename UGraph::Edge mine = e;
1944 int mind = degree[ugraph.source(e)];
1948 typename UGraph::Edge l = e;
1949 e = embedding[ugraph.oppositeEdge(e)];
1951 processed[e] = true;
1955 if (degree[ugraph.source(e)] < mind) {
1957 mind = degree[ugraph.source(e)];
1960 e = embedding[ugraph.oppositeEdge(e)];
1963 if (face_size < 4) {
1967 typename UGraph::Node s = ugraph.source(mine);
1968 for (typename UGraph::OutEdgeIt e(ugraph, s); e != INVALID; ++e) {
1969 visited.set(ugraph.target(e), true);
1972 typename UGraph::Edge oppe = INVALID;
1974 e = embedding[ugraph.oppositeEdge(mine)];
1975 e = embedding[ugraph.oppositeEdge(e)];
1976 while (ugraph.target(e) != s) {
1977 if (visited[ugraph.source(e)]) {
1981 e = embedding[ugraph.oppositeEdge(e)];
1983 visited.setAll(false);
1985 if (oppe == INVALID) {
1987 e = embedding[ugraph.oppositeEdge(mine)];
1988 typename UGraph::Edge pn = mine, p = e;
1990 e = embedding[ugraph.oppositeEdge(e)];
1991 while (ugraph.target(e) != s) {
1992 typename UGraph::Edge n =
1993 ugraph.direct(ugraph.addEdge(s, ugraph.source(e)), true);
1996 embedding[ugraph.oppositeEdge(n)] = e;
1997 embedding[ugraph.oppositeEdge(p)] = ugraph.oppositeEdge(n);
2002 e = embedding[ugraph.oppositeEdge(e)];
2005 embedding[ugraph.oppositeEdge(e)] = pn;
2009 mine = embedding[ugraph.oppositeEdge(mine)];
2010 s = ugraph.source(mine);
2011 oppe = embedding[ugraph.oppositeEdge(oppe)];
2012 typename UGraph::Node t = ugraph.source(oppe);
2014 typename UGraph::Edge ce = ugraph.direct(ugraph.addEdge(s, t), true);
2015 embedding[ce] = mine;
2016 embedding[ugraph.oppositeEdge(ce)] = oppe;
2018 typename UGraph::Edge pn = ce, p = oppe;
2019 e = embedding[ugraph.oppositeEdge(oppe)];
2020 while (ugraph.target(e) != s) {
2021 typename UGraph::Edge n =
2022 ugraph.direct(ugraph.addEdge(s, ugraph.source(e)), true);
2025 embedding[ugraph.oppositeEdge(n)] = e;
2026 embedding[ugraph.oppositeEdge(p)] = ugraph.oppositeEdge(n);
2031 e = embedding[ugraph.oppositeEdge(e)];
2034 embedding[ugraph.oppositeEdge(e)] = pn;
2036 pn = ugraph.oppositeEdge(ce), p = mine;
2037 e = embedding[ugraph.oppositeEdge(mine)];
2038 while (ugraph.target(e) != t) {
2039 typename UGraph::Edge n =
2040 ugraph.direct(ugraph.addEdge(t, ugraph.source(e)), true);
2043 embedding[ugraph.oppositeEdge(n)] = e;
2044 embedding[ugraph.oppositeEdge(p)] = ugraph.oppositeEdge(n);
2049 e = embedding[ugraph.oppositeEdge(e)];
2052 embedding[ugraph.oppositeEdge(e)] = pn;
2061 /// \brief Schnyder's planar drawing algorithms
2063 /// The planar drawing algorithm calculates location for each node
2064 /// in the plane, which coordinates satisfies that if each edge is
2065 /// represented with a straight line then the edges will not
2066 /// intersect each other.
2068 /// Scnyder's algorithm embeds the graph on \c (n-2,n-2) size grid,
2069 /// ie. each node will be located in the \c [0,n-2]x[0,n-2] square.
2070 /// The time complexity of the algorithm is O(n).
2071 template <typename UGraph>
2072 class PlanarDrawing {
2075 UGRAPH_TYPEDEFS(typename UGraph);
2077 /// \brief The point type for store coordinates
2078 typedef dim2::Point<int> Point;
2079 /// \brief The map type for store coordinates
2080 typedef typename UGraph::template NodeMap<Point> PointMap;
2083 /// \brief Constructor
2086 /// \pre The ugraph should be simple, ie. loop and parallel edge free.
2087 PlanarDrawing(const UGraph& ugraph)
2088 : _ugraph(ugraph), _point_map(ugraph) {}
2092 template <typename AuxUGraph, typename AuxEmbeddingMap>
2093 void drawing(const AuxUGraph& ugraph,
2094 const AuxEmbeddingMap& next,
2095 PointMap& point_map) {
2096 UGRAPH_TYPEDEFS(typename AuxUGraph);
2098 typename AuxUGraph::template EdgeMap<Edge> prev(ugraph);
2100 for (NodeIt n(ugraph); n != INVALID; ++n) {
2101 Edge e = OutEdgeIt(ugraph, n);
2114 Node anode, bnode, cnode;
2117 Edge e = EdgeIt(ugraph);
2118 anode = ugraph.source(e);
2119 bnode = ugraph.target(e);
2120 cnode = ugraph.target(next[ugraph.oppositeEdge(e)]);
2123 IterableBoolMap<AuxUGraph, Node> proper(ugraph, false);
2124 typename AuxUGraph::template NodeMap<int> conn(ugraph, -1);
2126 conn[anode] = conn[bnode] = -2;
2128 for (OutEdgeIt e(ugraph, anode); e != INVALID; ++e) {
2129 Node m = ugraph.target(e);
2130 if (conn[m] == -1) {
2136 for (OutEdgeIt e(ugraph, bnode); e != INVALID; ++e) {
2137 Node m = ugraph.target(e);
2138 if (conn[m] == -1) {
2140 } else if (conn[m] != -2) {
2142 Edge pe = ugraph.oppositeEdge(e);
2143 if (conn[ugraph.target(next[pe])] == -2) {
2146 if (conn[ugraph.target(prev[pe])] == -2) {
2150 proper.set(m, conn[m] == 1);
2156 typename AuxUGraph::template EdgeMap<int> angle(ugraph, -1);
2158 while (proper.trueNum() != 0) {
2159 Node n = typename IterableBoolMap<AuxUGraph, Node>::TrueIt(proper);
2160 proper.set(n, false);
2163 for (OutEdgeIt e(ugraph, n); e != INVALID; ++e) {
2164 Node m = ugraph.target(e);
2165 if (conn[m] == -1) {
2167 } else if (conn[m] != -2) {
2169 Edge pe = ugraph.oppositeEdge(e);
2170 if (conn[ugraph.target(next[pe])] == -2) {
2173 if (conn[ugraph.target(prev[pe])] == -2) {
2177 proper.set(m, conn[m] == 1);
2182 Edge e = OutEdgeIt(ugraph, n);
2188 if (conn[ugraph.target(e)] == -2 && conn[ugraph.target(p)] == -2) {
2191 f = next[ugraph.oppositeEdge(f)];
2193 f = next[ugraph.oppositeEdge(f)];
2201 if (conn[ugraph.target(e)] == -2 && conn[ugraph.target(p)] == -2) {
2204 f = next[ugraph.oppositeEdge(f)];
2206 f = next[ugraph.oppositeEdge(f)];
2212 typename AuxUGraph::template NodeMap<Node> apred(ugraph, INVALID);
2213 typename AuxUGraph::template NodeMap<Node> bpred(ugraph, INVALID);
2214 typename AuxUGraph::template NodeMap<Node> cpred(ugraph, INVALID);
2216 typename AuxUGraph::template NodeMap<int> apredid(ugraph, -1);
2217 typename AuxUGraph::template NodeMap<int> bpredid(ugraph, -1);
2218 typename AuxUGraph::template NodeMap<int> cpredid(ugraph, -1);
2220 for (EdgeIt e(ugraph); e != INVALID; ++e) {
2221 if (angle[e] == angle[next[e]]) {
2224 apred[ugraph.target(e)] = ugraph.source(e);
2225 apredid[ugraph.target(e)] = ugraph.id(ugraph.source(e));
2228 bpred[ugraph.target(e)] = ugraph.source(e);
2229 bpredid[ugraph.target(e)] = ugraph.id(ugraph.source(e));
2232 cpred[ugraph.target(e)] = ugraph.source(e);
2233 cpredid[ugraph.target(e)] = ugraph.id(ugraph.source(e));
2239 cpred[anode] = INVALID;
2240 cpred[bnode] = INVALID;
2242 std::vector<Node> aorder, border, corder;
2245 typename AuxUGraph::template NodeMap<bool> processed(ugraph, false);
2246 std::vector<Node> st;
2247 for (NodeIt n(ugraph); n != INVALID; ++n) {
2248 if (!processed[n] && n != bnode && n != cnode) {
2250 processed[n] = true;
2252 while (m != INVALID && !processed[m]) {
2254 processed[m] = true;
2257 while (!st.empty()) {
2258 aorder.push_back(st.back());
2266 typename AuxUGraph::template NodeMap<bool> processed(ugraph, false);
2267 std::vector<Node> st;
2268 for (NodeIt n(ugraph); n != INVALID; ++n) {
2269 if (!processed[n] && n != cnode && n != anode) {
2271 processed[n] = true;
2273 while (m != INVALID && !processed[m]) {
2275 processed[m] = true;
2278 while (!st.empty()) {
2279 border.push_back(st.back());
2287 typename AuxUGraph::template NodeMap<bool> processed(ugraph, false);
2288 std::vector<Node> st;
2289 for (NodeIt n(ugraph); n != INVALID; ++n) {
2290 if (!processed[n] && n != anode && n != bnode) {
2292 processed[n] = true;
2294 while (m != INVALID && !processed[m]) {
2296 processed[m] = true;
2299 while (!st.empty()) {
2300 corder.push_back(st.back());
2307 typename AuxUGraph::template NodeMap<int> atree(ugraph, 0);
2308 for (int i = aorder.size() - 1; i >= 0; --i) {
2311 for (OutEdgeIt e(ugraph, n); e != INVALID; ++e) {
2312 if (apred[ugraph.target(e)] == n) {
2313 atree[n] += atree[ugraph.target(e)];
2318 typename AuxUGraph::template NodeMap<int> btree(ugraph, 0);
2319 for (int i = border.size() - 1; i >= 0; --i) {
2322 for (OutEdgeIt e(ugraph, n); e != INVALID; ++e) {
2323 if (bpred[ugraph.target(e)] == n) {
2324 btree[n] += btree[ugraph.target(e)];
2329 typename AuxUGraph::template NodeMap<int> apath(ugraph, 0);
2330 apath[bnode] = apath[cnode] = 1;
2331 typename AuxUGraph::template NodeMap<int> apath_btree(ugraph, 0);
2332 apath_btree[bnode] = btree[bnode];
2333 for (int i = 1; i < int(aorder.size()); ++i) {
2335 apath[n] = apath[apred[n]] + 1;
2336 apath_btree[n] = btree[n] + apath_btree[apred[n]];
2339 typename AuxUGraph::template NodeMap<int> bpath_atree(ugraph, 0);
2340 bpath_atree[anode] = atree[anode];
2341 for (int i = 1; i < int(border.size()); ++i) {
2343 bpath_atree[n] = atree[n] + bpath_atree[bpred[n]];
2346 typename AuxUGraph::template NodeMap<int> cpath(ugraph, 0);
2347 cpath[anode] = cpath[bnode] = 1;
2348 typename AuxUGraph::template NodeMap<int> cpath_atree(ugraph, 0);
2349 cpath_atree[anode] = atree[anode];
2350 typename AuxUGraph::template NodeMap<int> cpath_btree(ugraph, 0);
2351 cpath_btree[bnode] = btree[bnode];
2352 for (int i = 1; i < int(corder.size()); ++i) {
2354 cpath[n] = cpath[cpred[n]] + 1;
2355 cpath_atree[n] = atree[n] + cpath_atree[cpred[n]];
2356 cpath_btree[n] = btree[n] + cpath_btree[cpred[n]];
2359 typename AuxUGraph::template NodeMap<int> third(ugraph);
2360 for (NodeIt n(ugraph); n != INVALID; ++n) {
2362 bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1;
2364 cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1;
2371 /// \brief Calculates the node locations
2373 /// This function calculates the node locations.
2375 PlanarEmbedding<UGraph> pe(_ugraph);
2376 if (!pe.run()) return false;
2382 /// \brief Calculates the node locations according to a
2383 /// combinatorical embedding
2385 /// This function calculates the node locations. The \c embedding
2386 /// parameter should contain a valid combinatorical embedding, ie.
2387 /// a valid cyclic order of the edges.
2388 template <typename EmbeddingMap>
2389 void run(const EmbeddingMap& embedding) {
2390 typedef SmartUEdgeSet<UGraph> AuxUGraph;
2392 if (3 * countNodes(_ugraph) - 6 == countUEdges(_ugraph)) {
2393 drawing(_ugraph, embedding, _point_map);
2397 AuxUGraph aux_ugraph(_ugraph);
2398 typename AuxUGraph::template EdgeMap<typename AuxUGraph::Edge>
2399 aux_embedding(aux_ugraph);
2403 typename UGraph::template UEdgeMap<typename AuxUGraph::UEdge>
2406 for (UEdgeIt e(_ugraph); e != INVALID; ++e) {
2407 ref[e] = aux_ugraph.addEdge(_ugraph.source(e), _ugraph.target(e));
2410 for (UEdgeIt e(_ugraph); e != INVALID; ++e) {
2411 Edge ee = embedding[_ugraph.direct(e, true)];
2412 aux_embedding[aux_ugraph.direct(ref[e], true)] =
2413 aux_ugraph.direct(ref[ee], _ugraph.direction(ee));
2414 ee = embedding[_ugraph.direct(e, false)];
2415 aux_embedding[aux_ugraph.direct(ref[e], false)] =
2416 aux_ugraph.direct(ref[ee], _ugraph.direction(ee));
2419 _planarity_bits::makeConnected(aux_ugraph, aux_embedding);
2420 _planarity_bits::makeBiNodeConnected(aux_ugraph, aux_embedding);
2421 _planarity_bits::makeMaxPlanar(aux_ugraph, aux_embedding);
2422 drawing(aux_ugraph, aux_embedding, _point_map);
2425 /// \brief The coordinate of the given node
2427 /// The coordinate of the given node.
2428 Point operator[](const Node& node) {
2429 return _point_map[node];
2432 /// \brief Returns the grid embedding in a \e NodeMap.
2434 /// Returns the grid embedding in a \e NodeMap of \c dim2::Point<int> .
2435 const PointMap& coords() const {
2441 const UGraph& _ugraph;
2442 PointMap _point_map;
2446 namespace _planarity_bits {
2448 template <typename ColorMap>
2451 typedef typename ColorMap::Key Key;
2454 KempeFilter(const ColorMap& color_map,
2455 const typename ColorMap::Value& first,
2456 const typename ColorMap::Value& second)
2457 : _color_map(color_map), _first(first), _second(second) {}
2459 Value operator[](const Key& key) const {
2460 return _color_map[key] == _first || _color_map[key] == _second;
2464 const ColorMap& _color_map;
2465 typename ColorMap::Value _first, _second;
2471 /// \brief Coloring planar graphs
2473 /// The graph coloring problem is the coloring of the graph nodes
2474 /// such way that there are not adjacent nodes with the same
2475 /// color. The planar graphs can be always colored with four colors,
2476 /// it is proved by Appel and Haken and their proofs provide a
2477 /// quadratic time algorithm for four coloring, but it could not be
2478 /// used to implement efficient algorithm. The five and six coloring
2479 /// can be made in linear time, but in this class the five coloring
2480 /// has quadratic worst case time complexity. The two coloring (if
2481 /// possible) is solvable with a graph search algorithm and it is
2482 /// implemented in \ref bipartitePartitions() function in Lemon. To
2483 /// decide whether the planar graph is three colorable is
2486 /// This class contains member functions for calculate colorings
2487 /// with five and six colors. The six coloring algorithm is a simple
2488 /// greedy coloring on the backward minimum outgoing order of nodes.
2489 /// This order can be computed such way, that in each phase the node
2490 /// with least outgoing edges to unprocessed nodes is choosen. This
2491 /// order guarantees that at the time of coloring of a node it has
2492 /// at most five already colored adjacents. The five coloring
2493 /// algorithm works in the same way, but if the greedy approach
2494 /// fails to color with five color, ie. the node has five already
2495 /// different colored neighbours, it swaps the colors in one
2496 /// connected two colored set with the Kempe recoloring method.
2497 template <typename UGraph>
2498 class PlanarColoring {
2501 UGRAPH_TYPEDEFS(typename UGraph);
2503 /// \brief The map type for store color indexes
2504 typedef typename UGraph::template NodeMap<int> IndexMap;
2505 /// \brief The map type for store colors
2506 typedef ComposeMap<Palette, IndexMap> ColorMap;
2508 /// \brief Constructor
2511 /// \pre The ugraph should be simple, ie. loop and parallel edge free.
2512 PlanarColoring(const UGraph& ugraph)
2513 : _ugraph(ugraph), _color_map(ugraph), _palette(0) {
2514 _palette.add(Color(1,0,0));
2515 _palette.add(Color(0,1,0));
2516 _palette.add(Color(0,0,1));
2517 _palette.add(Color(1,1,0));
2518 _palette.add(Color(1,0,1));
2519 _palette.add(Color(0,1,1));
2522 /// \brief Returns the \e NodeMap of color indexes
2524 /// Returns the \e NodeMap of color indexes. The values are in the
2525 /// range \c [0..4] or \c [0..5] according to the five coloring or
2527 IndexMap colorIndexMap() const {
2531 /// \brief Returns the \e NodeMap of colors
2533 /// Returns the \e NodeMap of colors. The values are five or six
2534 /// distinct \ref lemon::Color "colors".
2535 ColorMap colorMap() const {
2536 return composeMap(_palette, _color_map);
2539 /// \brief Returns the color index of the node
2541 /// Returns the color index of the node. The values are in the
2542 /// range \c [0..4] or \c [0..5] according to the five coloring or
2544 int colorIndex(const Node& node) const {
2545 return _color_map[node];
2548 /// \brief Returns the color of the node
2550 /// Returns the color of the node. The values are five or six
2551 /// distinct \ref lemon::Color "colors".
2552 Color color(const Node& node) const {
2553 return _palette[_color_map[node]];
2557 /// \brief Calculates a coloring with at most six colors
2559 /// This function calculates a coloring with at most six colors. The time
2560 /// complexity of this variant is linear in the size of the graph.
2561 /// \return %True when the algorithm could color the graph with six color.
2562 /// If the algorithm fails, then the graph could not be planar.
2563 bool runSixColoring() {
2565 typename UGraph::template NodeMap<int> heap_index(_ugraph, -1);
2566 BucketHeap<typename UGraph::template NodeMap<int> > heap(heap_index);
2568 for (NodeIt n(_ugraph); n != INVALID; ++n) {
2570 heap.push(n, countOutEdges(_ugraph, n));
2573 std::vector<Node> order;
2575 while (!heap.empty()) {
2576 Node n = heap.top();
2580 for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
2581 Node t = _ugraph.runningNode(e);
2582 if (_color_map[t] == -2) {
2583 heap.decrease(t, heap[t] - 1);
2588 for (int i = order.size() - 1; i >= 0; --i) {
2589 std::vector<bool> forbidden(6, false);
2590 for (OutEdgeIt e(_ugraph, order[i]); e != INVALID; ++e) {
2591 Node t = _ugraph.runningNode(e);
2592 if (_color_map[t] != -1) {
2593 forbidden[_color_map[t]] = true;
2596 for (int k = 0; k < 6; ++k) {
2597 if (!forbidden[k]) {
2598 _color_map[order[i]] = k;
2602 if (_color_map[order[i]] == -1) {
2611 bool recolor(const Node& u, const Node& v) {
2612 int ucolor = _color_map[u];
2613 int vcolor = _color_map[v];
2614 typedef _planarity_bits::KempeFilter<IndexMap> KempeFilter;
2615 KempeFilter filter(_color_map, ucolor, vcolor);
2617 typedef NodeSubUGraphAdaptor<const UGraph, const KempeFilter> KempeUGraph;
2618 KempeUGraph kempe_ugraph(_ugraph, filter);
2620 std::vector<Node> comp;
2621 Bfs<KempeUGraph> bfs(kempe_ugraph);
2624 while (!bfs.emptyQueue()) {
2625 Node n = bfs.nextNode();
2626 if (n == v) return false;
2628 bfs.processNextNode();
2631 int scolor = ucolor + vcolor;
2632 for (int i = 0; i < static_cast<int>(comp.size()); ++i) {
2633 _color_map[comp[i]] = scolor - _color_map[comp[i]];
2639 template <typename EmbeddingMap>
2640 void kempeRecoloring(const Node& node, const EmbeddingMap& embedding) {
2641 std::vector<Node> nodes;
2644 for (Edge e = OutEdgeIt(_ugraph, node); e != INVALID; e = embedding[e]) {
2645 Node t = _ugraph.target(e);
2646 if (_color_map[t] != -1) {
2648 if (nodes.size() == 4) break;
2652 int color = _color_map[nodes[0]];
2653 if (recolor(nodes[0], nodes[2])) {
2654 _color_map[node] = color;
2656 color = _color_map[nodes[1]];
2657 recolor(nodes[1], nodes[3]);
2658 _color_map[node] = color;
2664 /// \brief Calculates a coloring with at most five colors
2666 /// This function calculates a coloring with at most five
2667 /// colors. The worst case time complexity of this variant is
2668 /// quadratic in the size of the graph.
2669 template <typename EmbeddingMap>
2670 void runFiveColoring(const EmbeddingMap& embedding) {
2672 typename UGraph::template NodeMap<int> heap_index(_ugraph, -1);
2673 BucketHeap<typename UGraph::template NodeMap<int> > heap(heap_index);
2675 for (NodeIt n(_ugraph); n != INVALID; ++n) {
2677 heap.push(n, countOutEdges(_ugraph, n));
2680 std::vector<Node> order;
2682 while (!heap.empty()) {
2683 Node n = heap.top();
2687 for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
2688 Node t = _ugraph.runningNode(e);
2689 if (_color_map[t] == -2) {
2690 heap.decrease(t, heap[t] - 1);
2695 for (int i = order.size() - 1; i >= 0; --i) {
2696 std::vector<bool> forbidden(5, false);
2697 for (OutEdgeIt e(_ugraph, order[i]); e != INVALID; ++e) {
2698 Node t = _ugraph.runningNode(e);
2699 if (_color_map[t] != -1) {
2700 forbidden[_color_map[t]] = true;
2703 for (int k = 0; k < 5; ++k) {
2704 if (!forbidden[k]) {
2705 _color_map[order[i]] = k;
2709 if (_color_map[order[i]] == -1) {
2710 kempeRecoloring(order[i], embedding);
2715 /// \brief Calculates a coloring with at most five colors
2717 /// This function calculates a coloring with at most five
2718 /// colors. The worst case time complexity of this variant is
2719 /// quadratic in the size of the graph, but it most cases it does
2720 /// not have to use Kempe recoloring method, in this case it is
2721 /// equivalent with the runSixColoring() algorithm.
2722 /// \return %True when the graph is planar.
2723 bool runFiveColoring() {
2724 PlanarEmbedding<UGraph> pe(_ugraph);
2725 if (!pe.run()) return false;
2727 runFiveColoring(pe.embeddingMap());
2733 const UGraph& _ugraph;
2734 IndexMap _color_map;