[Lemon-commits] Peter Kovacs: Rework hypercube graph implementat...

Lemon HG hg at lemon.cs.elte.hu
Thu Nov 6 15:49:43 CET 2008


details:   http://lemon.cs.elte.hu/hg/lemon/rev/a12eef1f82b2
changeset: 377:a12eef1f82b2
user:      Peter Kovacs <kpeter [at] inf.elte.hu>
date:      Thu Nov 06 15:16:37 2008 +0100
description:
	Rework hypercube graph implementation to be undirected (#57)

diffstat:

4 files changed, 293 insertions(+), 151 deletions(-)
lemon/hypercube_graph.h   |  335 ++++++++++++++++++++++++++++++---------------
test/digraph_test.cc      |   40 -----
test/graph_test.cc        |   68 ++++++++-
tools/lemon-0.x-to-1.x.sh |    1 

diffs (truncated from 719 to 300 lines):

diff -r b4a01426c0d9 -r a12eef1f82b2 lemon/hypercube_graph.h
--- a/lemon/hypercube_graph.h	Wed Nov 05 21:36:28 2008 +0100
+++ b/lemon/hypercube_graph.h	Thu Nov 06 15:16:37 2008 +0100
@@ -19,128 +19,230 @@
 #ifndef HYPERCUBE_GRAPH_H
 #define HYPERCUBE_GRAPH_H
 
-#include <iostream>
 #include <vector>
 #include <lemon/core.h>
-#include <lemon/error.h>
-
-#include <lemon/bits/base_extender.h>
+#include <lemon/assert.h>
 #include <lemon/bits/graph_extender.h>
 
 ///\ingroup graphs
 ///\file
-///\brief HypercubeDigraph class.
+///\brief HypercubeGraph class.
 
 namespace lemon {
 
-  class HypercubeDigraphBase {
+  class HypercubeGraphBase {
 
   public:
 
-    typedef HypercubeDigraphBase Digraph;
+    typedef HypercubeGraphBase Graph;
 
     class Node;
+    class Edge;
     class Arc;
 
   public:
 
-    HypercubeDigraphBase() {}
+    HypercubeGraphBase() {}
 
   protected:
 
     void construct(int dim) {
+      LEMON_ASSERT(dim >= 1, "The number of dimensions must be at least 1.");
       _dim = dim;
-      _nodeNum = 1 << dim;
+      _node_num = 1 << dim;
+      _edge_num = dim * (1 << dim-1);
     }
 
   public:
 
     typedef True NodeNumTag;
+    typedef True EdgeNumTag;
     typedef True ArcNumTag;
 
-    int nodeNum() const { return _nodeNum; }
-    int arcNum() const { return _nodeNum * _dim; }
+    int nodeNum() const { return _node_num; }
+    int edgeNum() const { return _edge_num; }
+    int arcNum() const { return 2 * _edge_num; }
 
-    int maxNodeId() const { return nodeNum() - 1; }
-    int maxArcId() const { return arcNum() - 1; }
+    int maxNodeId() const { return _node_num - 1; }
+    int maxEdgeId() const { return _edge_num - 1; }
+    int maxArcId() const { return 2 * _edge_num - 1; }
 
-    Node source(Arc e) const {
-      return e.id / _dim;
+    static Node nodeFromId(int id) { return Node(id); }
+    static Edge edgeFromId(int id) { return Edge(id); }
+    static Arc arcFromId(int id) { return Arc(id); }
+
+    static int id(Node node) { return node._id; }
+    static int id(Edge edge) { return edge._id; }
+    static int id(Arc arc) { return arc._id; }
+
+    Node u(Edge edge) const {
+      int base = edge._id & ((1 << _dim-1) - 1);
+      int k = edge._id >> _dim-1;
+      return ((base >> k) << k+1) | (base & ((1 << k) - 1));
     }
 
-    Node target(Arc e) const {
-      return (e.id / _dim) ^ (1 << (e.id % _dim));
+    Node v(Edge edge) const {
+      int base = edge._id & ((1 << _dim-1) - 1);
+      int k = edge._id >> _dim-1;
+      return ((base >> k) << k+1) | (base & ((1 << k) - 1)) | (1 << k);
     }
 
-    static int id(Node v) { return v.id; }
-    static int id(Arc e) { return e.id; }
+    Node source(Arc arc) const {
+      return (arc._id & 1) == 1 ? u(arc) : v(arc);
+    }
 
-    static Node nodeFromId(int id) { return Node(id); }
+    Node target(Arc arc) const {
+      return (arc._id & 1) == 1 ? v(arc) : u(arc);
+    }
 
-    static Arc arcFromId(int id) { return Arc(id); }
+    typedef True FindEdgeTag;
+    typedef True FindArcTag;
+
+    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
+      if (prev != INVALID) return INVALID;
+      int d = u._id ^ v._id;
+      int k = 0;
+      if (d == 0) return INVALID;
+      for ( ; (d & 1) == 0; d >>= 1) ++k;
+      if (d >> 1 != 0) return INVALID;
+      return (k << _dim-1) | ((u._id >> k+1) << k) | (u._id & ((1 << k) - 1));
+    }
+
+    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
+      Edge edge = findEdge(u, v, prev);
+      if (edge == INVALID) return INVALID;
+      int k = edge._id >> _dim-1;
+      return ((u._id >> k) & 1) == 1 ? edge._id << 1 : (edge._id << 1) | 1;
+    }
 
     class Node {
-      friend class HypercubeDigraphBase;
+      friend class HypercubeGraphBase;
+
     protected:
-      int id;
-      Node(int _id) { id = _id;}
+      int _id;
+      Node(int id) : _id(id) {}
     public:
       Node() {}
-      Node (Invalid) { id = -1; }
-      bool operator==(const Node node) const { return id == node.id; }
-      bool operator!=(const Node node) const { return id != node.id; }
-      bool operator<(const Node node) const { return id < node.id; }
+      Node (Invalid) : _id(-1) {}
+      bool operator==(const Node node) const {return _id == node._id;}
+      bool operator!=(const Node node) const {return _id != node._id;}
+      bool operator<(const Node node) const {return _id < node._id;}
+    };
+
+    class Edge {
+      friend class HypercubeGraphBase;
+      friend class Arc;
+
+    protected:
+      int _id;
+
+      Edge(int id) : _id(id) {}
+
+    public:
+      Edge() {}
+      Edge (Invalid) : _id(-1) {}
+      bool operator==(const Edge edge) const {return _id == edge._id;}
+      bool operator!=(const Edge edge) const {return _id != edge._id;}
+      bool operator<(const Edge edge) const {return _id < edge._id;}
     };
 
     class Arc {
-      friend class HypercubeDigraphBase;
+      friend class HypercubeGraphBase;
+
     protected:
-      int id;
-      Arc(int _id) : id(_id) {}
+      int _id;
+
+      Arc(int id) : _id(id) {}
+
     public:
-      Arc() { }
-      Arc (Invalid) { id = -1; }
-      bool operator==(const Arc arc) const { return id == arc.id; }
-      bool operator!=(const Arc arc) const { return id != arc.id; }
-      bool operator<(const Arc arc) const { return id < arc.id; }
+      Arc() {}
+      Arc (Invalid) : _id(-1) {}
+      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
+      bool operator==(const Arc arc) const {return _id == arc._id;}
+      bool operator!=(const Arc arc) const {return _id != arc._id;}
+      bool operator<(const Arc arc) const {return _id < arc._id;}
     };
 
     void first(Node& node) const {
-      node.id = nodeNum() - 1;
+      node._id = _node_num - 1;
     }
 
     static void next(Node& node) {
-      --node.id;
+      --node._id;
+    }
+
+    void first(Edge& edge) const {
+      edge._id = _edge_num - 1;
+    }
+
+    static void next(Edge& edge) {
+      --edge._id;
     }
 
     void first(Arc& arc) const {
-      arc.id = arcNum() - 1;
+      arc._id = 2 * _edge_num - 1;
     }
 
     static void next(Arc& arc) {
-      --arc.id;
+      --arc._id;
+    }
+
+    void firstInc(Edge& edge, bool& dir, const Node& node) const {
+      edge._id = node._id >> 1;
+      dir = (node._id & 1) == 0;
+    }
+
+    void nextInc(Edge& edge, bool& dir) const {
+      Node n = dir ? u(edge) : v(edge);
+      int k = (edge._id >> _dim-1) + 1;
+      if (k < _dim) {
+        edge._id = (k << _dim-1) |
+                   ((n._id >> k+1) << k) | (n._id & ((1 << k) - 1));
+        dir = ((n._id >> k) & 1) == 0;
+      } else {
+        edge._id = -1;
+        dir = true;
+      }
     }
 
     void firstOut(Arc& arc, const Node& node) const {
-      arc.id = node.id * _dim;
+      arc._id = ((node._id >> 1) << 1) | (~node._id & 1);
     }
 
     void nextOut(Arc& arc) const {
-      ++arc.id;
-      if (arc.id % _dim == 0) arc.id = -1;
+      Node n = (arc._id & 1) == 1 ? u(arc) : v(arc);
+      int k = (arc._id >> _dim) + 1;
+      if (k < _dim) {
+        arc._id = (k << _dim-1) |
+                  ((n._id >> k+1) << k) | (n._id & ((1 << k) - 1));
+        arc._id = (arc._id << 1) | (~(n._id >> k) & 1);
+      } else {
+        arc._id = -1;
+      }
     }
 
     void firstIn(Arc& arc, const Node& node) const {
-      arc.id = (node.id ^ 1) * _dim;
+      arc._id = ((node._id >> 1) << 1) | (node._id & 1);
     }
 
     void nextIn(Arc& arc) const {
-      int cnt = arc.id % _dim;
-      if ((cnt + 1) % _dim == 0) {
-        arc.id = -1;
+      Node n = (arc._id & 1) == 1 ? v(arc) : u(arc);
+      int k = (arc._id >> _dim) + 1;
+      if (k < _dim) {
+        arc._id = (k << _dim-1) |
+                  ((n._id >> k+1) << k) | (n._id & ((1 << k) - 1));
+        arc._id = (arc._id << 1) | ((n._id >> k) & 1);
       } else {
-        arc.id = ((arc.id / _dim) ^ ((1 << cnt) * 3)) * _dim + cnt + 1;
+        arc._id = -1;
       }
+    }
+
+    static bool direction(Arc arc) {
+      return (arc._id & 1) == 1;
+    }
+
+    static Arc direct(Edge edge, bool dir) {
+      return Arc((edge._id << 1) | (dir ? 1 : 0));
     }
 
     int dimension() const {
@@ -148,15 +250,19 @@
     }
 
     bool projection(Node node, int n) const {
-      return static_cast<bool>(node.id & (1 << n));
+      return static_cast<bool>(node._id & (1 << n));
+    }
+
+    int dimension(Edge edge) const {
+      return edge._id >> _dim-1;
     }
 
     int dimension(Arc arc) const {
-      return arc.id % _dim;
+      return arc._id >> _dim;
     }
 
     int index(Node node) const {



More information about the Lemon-commits mailing list