[Lemon-commits] Balazs Dezso: ListBpGraph implementation (#69)
Lemon HG
hg at lemon.cs.elte.hu
Fri Mar 1 17:49:46 CET 2013
details: http://lemon.cs.elte.hu/hg/lemon/rev/a12cca3ad15a
changeset: 1189:a12cca3ad15a
user: Balazs Dezso <deba [at] inf.elte.hu>
date: Mon Nov 15 09:46:08 2010 +0100
description:
ListBpGraph implementation (#69)
diffstat:
lemon/list_graph.h | 879 +++++++++++++++++++++++++++++++++++++++++++++++++++
lemon/smart_graph.h | 2 +-
test/bpgraph_test.cc | 120 ++++++-
3 files changed, 992 insertions(+), 9 deletions(-)
diffs (truncated from 1062 to 300 lines):
diff --git a/lemon/list_graph.h b/lemon/list_graph.h
--- a/lemon/list_graph.h
+++ b/lemon/list_graph.h
@@ -1599,6 +1599,885 @@
};
/// @}
+
+ class ListBpGraphBase {
+
+ protected:
+
+ struct NodeT {
+ int first_out;
+ int prev, next;
+ int partition_prev, partition_next;
+ int partition_index;
+ bool red;
+ };
+
+ struct ArcT {
+ int target;
+ int prev_out, next_out;
+ };
+
+ std::vector<NodeT> nodes;
+
+ int first_node, first_red, first_blue;
+ int max_red, max_blue;
+
+ int first_free_red, first_free_blue;
+
+ std::vector<ArcT> arcs;
+
+ int first_free_arc;
+
+ public:
+
+ typedef ListBpGraphBase BpGraph;
+
+ class Node {
+ friend class ListBpGraphBase;
+ protected:
+
+ int id;
+ explicit Node(int pid) { id = pid;}
+
+ 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;}
+ };
+
+ class Edge {
+ friend class ListBpGraphBase;
+ protected:
+
+ int id;
+ explicit Edge(int pid) { id = pid;}
+
+ 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 ListBpGraphBase;
+ protected:
+
+ int id;
+ explicit Arc(int pid) { id = pid;}
+
+ public:
+ operator Edge() const {
+ return id != -1 ? edgeFromId(id / 2) : INVALID;
+ }
+
+ 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;}
+ };
+
+ ListBpGraphBase()
+ : nodes(), first_node(-1),
+ first_red(-1), first_blue(-1),
+ max_red(-1), max_blue(-1),
+ first_free_red(-1), first_free_blue(-1),
+ arcs(), first_free_arc(-1) {}
+
+
+ bool red(Node n) const { return nodes[n.id].red; }
+ bool blue(Node n) const { return !nodes[n.id].red; }
+
+ int maxNodeId() const { return nodes.size()-1; }
+ int maxRedId() const { return max_red; }
+ int maxBlueId() const { return max_blue; }
+ int maxEdgeId() const { return arcs.size() / 2 - 1; }
+ int maxArcId() const { return arcs.size()-1; }
+
+ Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
+ Node target(Arc e) const { return Node(arcs[e.id].target); }
+
+ Node redNode(Edge e) const { return Node(arcs[2 * e.id].target); }
+ Node blueNode(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
+
+ static bool direction(Arc e) {
+ return (e.id & 1) == 1;
+ }
+
+ static Arc direct(Edge e, bool d) {
+ return Arc(e.id * 2 + (d ? 1 : 0));
+ }
+
+ void first(Node& node) const {
+ node.id = first_node;
+ }
+
+ void next(Node& node) const {
+ node.id = nodes[node.id].next;
+ }
+
+ void firstRed(Node& node) const {
+ node.id = first_red;
+ }
+
+ void nextRed(Node& node) const {
+ node.id = nodes[node.id].partition_next;
+ }
+
+ void firstBlue(Node& node) const {
+ node.id = first_blue;
+ }
+
+ void nextBlue(Node& node) const {
+ node.id = nodes[node.id].partition_next;
+ }
+
+ void first(Arc& e) const {
+ int n = first_node;
+ while (n != -1 && nodes[n].first_out == -1) {
+ n = nodes[n].next;
+ }
+ e.id = (n == -1) ? -1 : nodes[n].first_out;
+ }
+
+ void next(Arc& e) const {
+ if (arcs[e.id].next_out != -1) {
+ e.id = arcs[e.id].next_out;
+ } else {
+ int n = nodes[arcs[e.id ^ 1].target].next;
+ while(n != -1 && nodes[n].first_out == -1) {
+ n = nodes[n].next;
+ }
+ e.id = (n == -1) ? -1 : nodes[n].first_out;
+ }
+ }
+
+ void first(Edge& e) const {
+ int n = first_node;
+ while (n != -1) {
+ e.id = nodes[n].first_out;
+ while ((e.id & 1) != 1) {
+ e.id = arcs[e.id].next_out;
+ }
+ if (e.id != -1) {
+ e.id /= 2;
+ return;
+ }
+ n = nodes[n].next;
+ }
+ e.id = -1;
+ }
+
+ void next(Edge& e) const {
+ int n = arcs[e.id * 2].target;
+ e.id = arcs[(e.id * 2) | 1].next_out;
+ while ((e.id & 1) != 1) {
+ e.id = arcs[e.id].next_out;
+ }
+ if (e.id != -1) {
+ e.id /= 2;
+ return;
+ }
+ n = nodes[n].next;
+ while (n != -1) {
+ e.id = nodes[n].first_out;
+ while ((e.id & 1) != 1) {
+ e.id = arcs[e.id].next_out;
+ }
+ if (e.id != -1) {
+ e.id /= 2;
+ return;
+ }
+ n = nodes[n].next;
+ }
+ e.id = -1;
+ }
+
+ void firstOut(Arc &e, const Node& v) const {
+ e.id = nodes[v.id].first_out;
+ }
+ void nextOut(Arc &e) const {
+ e.id = arcs[e.id].next_out;
+ }
+
+ void firstIn(Arc &e, const Node& v) const {
+ e.id = ((nodes[v.id].first_out) ^ 1);
+ if (e.id == -2) e.id = -1;
+ }
+ void nextIn(Arc &e) const {
+ e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
+ if (e.id == -2) e.id = -1;
+ }
+
+ void firstInc(Edge &e, bool& d, const Node& v) const {
+ int a = nodes[v.id].first_out;
+ if (a != -1 ) {
+ e.id = a / 2;
+ d = ((a & 1) == 1);
+ } else {
+ e.id = -1;
+ d = true;
+ }
+ }
+ void nextInc(Edge &e, bool& d) const {
+ int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
+ if (a != -1 ) {
+ e.id = a / 2;
+ d = ((a & 1) == 1);
+ } else {
+ e.id = -1;
+ d = true;
+ }
+ }
+
+ static int id(Node v) { return v.id; }
+ int redId(Node v) const {
+ LEMON_DEBUG(nodes[v.id].red, "Node has to be red");
+ return nodes[v.id].partition_index;
+ }
+ int blueId(Node v) const {
+ LEMON_DEBUG(!nodes[v.id].red, "Node has to be blue");
+ return nodes[v.id].partition_index;
+ }
+ static int id(Arc e) { return e.id; }
+ static int id(Edge e) { return e.id; }
+
+ static Node nodeFromId(int id) { return Node(id);}
+ static Arc arcFromId(int id) { return Arc(id);}
+ static Edge edgeFromId(int id) { return Edge(id);}
+
+ bool valid(Node n) const {
+ return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
+ nodes[n.id].prev != -2;
+ }
+
+ bool valid(Arc a) const {
+ return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
+ arcs[a.id].prev_out != -2;
+ }
+
+ bool valid(Edge e) const {
+ return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
+ arcs[2 * e.id].prev_out != -2;
+ }
+
+ Node addRedNode() {
+ int n;
+
+ if(first_free_red==-1) {
+ n = nodes.size();
+ nodes.push_back(NodeT());
+ nodes[n].partition_index = ++max_red;
+ nodes[n].red = true;
+ } else {
+ n = first_free_red;
+ first_free_red = nodes[n].next;
+ }
+
+ nodes[n].next = first_node;
+ if (first_node != -1) nodes[first_node].prev = n;
+ first_node = n;
+ nodes[n].prev = -1;
+
+ nodes[n].partition_next = first_red;
+ if (first_red != -1) nodes[first_red].partition_prev = n;
+ first_red = n;
+ nodes[n].partition_prev = -1;
+
+ nodes[n].first_out = -1;
+
+ return Node(n);
+ }
More information about the Lemon-commits
mailing list