[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