[Lemon-commits] Balazs Dezso: Planarity checking function instea...

Lemon HG hg at lemon.cs.elte.hu
Wed Dec 9 11:30:51 CET 2009


details:   http://lemon.cs.elte.hu/hg/lemon/rev/58c330ad0b5c
changeset: 862:58c330ad0b5c
user:      Balazs Dezso <deba [at] inf.elte.hu>
date:      Sun Oct 04 10:15:32 2009 +0200
description:
	Planarity checking function instead of class (#62)

diffstat:

 lemon/planarity.h      |  764 +++++++++++++++++++++++++-------------------------
 test/planarity_test.cc |    9 +-
 2 files changed, 388 insertions(+), 385 deletions(-)

diffs (truncated from 814 to 300 lines):

diff --git a/lemon/planarity.h b/lemon/planarity.h
--- a/lemon/planarity.h
+++ b/lemon/planarity.h
@@ -137,395 +137,395 @@
       typename Graph::Arc prev, next;
     };
 
+    template <typename Graph>
+    class PlanarityChecking {
+    private:
+      
+      TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+      const Graph& _graph;
+
+    private:
+      
+      typedef typename Graph::template NodeMap<Arc> PredMap;
+      
+      typedef typename Graph::template EdgeMap<bool> TreeMap;
+      
+      typedef typename Graph::template NodeMap<int> OrderMap;
+      typedef std::vector<Node> OrderList;
+
+      typedef typename Graph::template NodeMap<int> LowMap;
+      typedef typename Graph::template NodeMap<int> AncestorMap;
+
+      typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
+      typedef std::vector<NodeDataNode> NodeData;
+
+      typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
+      typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
+
+      typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
+
+      typedef typename Graph::template NodeMap<bool> EmbedArc;
+
+    public:
+
+      PlanarityChecking(const Graph& graph) : _graph(graph) {}
+
+      bool run() {
+        typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
+
+        PredMap pred_map(_graph, INVALID);
+        TreeMap tree_map(_graph, false);
+
+        OrderMap order_map(_graph, -1);
+        OrderList order_list;
+
+        AncestorMap ancestor_map(_graph, -1);
+        LowMap low_map(_graph, -1);
+
+        Visitor visitor(_graph, pred_map, tree_map,
+                        order_map, order_list, ancestor_map, low_map);
+        DfsVisit<Graph, Visitor> visit(_graph, visitor);
+        visit.run();
+
+        ChildLists child_lists(_graph);
+        createChildLists(tree_map, order_map, low_map, child_lists);
+
+        NodeData node_data(2 * order_list.size());
+
+        EmbedArc embed_arc(_graph, false);
+
+        MergeRoots merge_roots(_graph);
+
+        for (int i = order_list.size() - 1; i >= 0; --i) {
+
+          Node node = order_list[i];
+
+          Node source = node;
+          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && tree_map[e]) {
+              initFace(target, node_data, order_map, order_list);
+            }
+          }
+
+          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && !tree_map[e]) {
+              embed_arc[target] = true;
+              walkUp(target, source, i, pred_map, low_map,
+                     order_map, order_list, node_data, merge_roots);
+            }
+          }
+
+          for (typename MergeRoots::Value::iterator it =
+                 merge_roots[node].begin(); 
+               it != merge_roots[node].end(); ++it) {
+            int rn = *it;
+            walkDown(rn, i, node_data, order_list, child_lists,
+                     ancestor_map, low_map, embed_arc, merge_roots);
+          }
+          merge_roots[node].clear();
+
+          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && !tree_map[e]) {
+              if (embed_arc[target]) {
+                return false;
+              }
+            }
+          }
+        }
+
+        return true;
+      }
+
+    private:
+
+      void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
+                            const LowMap& low_map, ChildLists& child_lists) {
+
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          Node source = n;
+
+          std::vector<Node> targets;
+          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && tree_map[e]) {
+              targets.push_back(target);
+            }
+          }
+
+          if (targets.size() == 0) {
+            child_lists[source].first = INVALID;
+          } else if (targets.size() == 1) {
+            child_lists[source].first = targets[0];
+            child_lists[targets[0]].prev = INVALID;
+            child_lists[targets[0]].next = INVALID;
+          } else {
+            radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
+            for (int i = 1; i < int(targets.size()); ++i) {
+              child_lists[targets[i]].prev = targets[i - 1];
+              child_lists[targets[i - 1]].next = targets[i];
+            }
+            child_lists[targets.back()].next = INVALID;
+            child_lists[targets.front()].prev = INVALID;
+            child_lists[source].first = targets.front();
+          }
+        }
+      }
+
+      void walkUp(const Node& node, Node root, int rorder,
+                  const PredMap& pred_map, const LowMap& low_map,
+                  const OrderMap& order_map, const OrderList& order_list,
+                  NodeData& node_data, MergeRoots& merge_roots) {
+
+        int na, nb;
+        bool da, db;
+
+        na = nb = order_map[node];
+        da = true; db = false;
+
+        while (true) {
+
+          if (node_data[na].visited == rorder) break;
+          if (node_data[nb].visited == rorder) break;
+
+          node_data[na].visited = rorder;
+          node_data[nb].visited = rorder;
+
+          int rn = -1;
+
+          if (na >= int(order_list.size())) {
+            rn = na;
+          } else if (nb >= int(order_list.size())) {
+            rn = nb;
+          }
+
+          if (rn == -1) {
+            int nn;
+
+            nn = da ? node_data[na].prev : node_data[na].next;
+            da = node_data[nn].prev != na;
+            na = nn;
+
+            nn = db ? node_data[nb].prev : node_data[nb].next;
+            db = node_data[nn].prev != nb;
+            nb = nn;
+
+          } else {
+
+            Node rep = order_list[rn - order_list.size()];
+            Node parent = _graph.source(pred_map[rep]);
+
+            if (low_map[rep] < rorder) {
+              merge_roots[parent].push_back(rn);
+            } else {
+              merge_roots[parent].push_front(rn);
+            }
+
+            if (parent != root) {
+              na = nb = order_map[parent];
+              da = true; db = false;
+            } else {
+              break;
+            }
+          }
+        }
+      }
+
+      void walkDown(int rn, int rorder, NodeData& node_data,
+                    OrderList& order_list, ChildLists& child_lists,
+                    AncestorMap& ancestor_map, LowMap& low_map,
+                    EmbedArc& embed_arc, MergeRoots& merge_roots) {
+
+        std::vector<std::pair<int, bool> > merge_stack;
+
+        for (int di = 0; di < 2; ++di) {
+          bool rd = di == 0;
+          int pn = rn;
+          int n = rd ? node_data[rn].next : node_data[rn].prev;
+
+          while (n != rn) {
+
+            Node node = order_list[n];
+
+            if (embed_arc[node]) {
+
+              // Merging components on the critical path
+              while (!merge_stack.empty()) {
+
+                // Component root
+                int cn = merge_stack.back().first;
+                bool cd = merge_stack.back().second;
+                merge_stack.pop_back();
+
+                // Parent of component
+                int dn = merge_stack.back().first;
+                bool dd = merge_stack.back().second;
+                merge_stack.pop_back();
+
+                Node parent = order_list[dn];
+
+                // Erasing from merge_roots
+                merge_roots[parent].pop_front();
+
+                Node child = order_list[cn - order_list.size()];
+
+                // Erasing from child_lists
+                if (child_lists[child].prev != INVALID) {
+                  child_lists[child_lists[child].prev].next =
+                    child_lists[child].next;
+                } else {
+                  child_lists[parent].first = child_lists[child].next;
+                }
+
+                if (child_lists[child].next != INVALID) {
+                  child_lists[child_lists[child].next].prev =
+                    child_lists[child].prev;
+                }
+
+                // Merging external faces
+                {
+                  int en = cn;
+                  cn = cd ? node_data[cn].prev : node_data[cn].next;
+                  cd = node_data[cn].next == en;
+
+                }
+
+                if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
+                if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
+
+              }
+
+              bool d = pn == node_data[n].prev;
+
+              if (node_data[n].prev == node_data[n].next &&
+                  node_data[n].inverted) {
+                d = !d;
+              }
+
+              // Embedding arc into external face
+              if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
+              if (d) node_data[n].prev = rn; else node_data[n].next = rn;
+              pn = rn;
+
+              embed_arc[order_list[n]] = false;
+            }
+
+            if (!merge_roots[node].empty()) {
+
+              bool d = pn == node_data[n].prev;
+
+              merge_stack.push_back(std::make_pair(n, d));
+
+              int rn = merge_roots[node].front();
+
+              int xn = node_data[rn].next;
+              Node xnode = order_list[xn];
+
+              int yn = node_data[rn].prev;
+              Node ynode = order_list[yn];



More information about the Lemon-commits mailing list