[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