[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