[Lemon-commits] [lemon_svn] deba: r2822 - in hugo/trunk: demo doc lemon lemon/bits test
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 21:50:37 CET 2006
Author: deba
Date: Fri Jun 30 14:15:45 2006
New Revision: 2822
Removed:
hugo/trunk/lemon/bits/bpugraph_extender.h
hugo/trunk/lemon/bits/ugraph_extender.h
hugo/trunk/lemon/full_bpugraph.h
hugo/trunk/lemon/full_ugraph.h
hugo/trunk/lemon/list_bpugraph.h
hugo/trunk/lemon/list_ugraph.h
hugo/trunk/lemon/smart_bpugraph.h
hugo/trunk/lemon/smart_ugraph.h
Modified:
hugo/trunk/demo/coloring.cc
hugo/trunk/demo/strongly_connected_orientation.cc
hugo/trunk/demo/topology_demo.cc
hugo/trunk/doc/graphs.dox
hugo/trunk/lemon/Makefile.am
hugo/trunk/lemon/bits/graph_extender.h
hugo/trunk/lemon/edge_set.h
hugo/trunk/lemon/full_graph.h
hugo/trunk/lemon/grid_ugraph.h
hugo/trunk/lemon/list_graph.h
hugo/trunk/lemon/min_cut.h
hugo/trunk/lemon/smart_graph.h
hugo/trunk/test/bipartite_matching_test.cc
hugo/trunk/test/max_matching_test.cc
hugo/trunk/test/ugraph_test.cc
Log:
Revert splitted files
Modified: hugo/trunk/demo/coloring.cc
==============================================================================
--- hugo/trunk/demo/coloring.cc (original)
+++ hugo/trunk/demo/coloring.cc Fri Jun 30 14:15:45 2006
@@ -29,7 +29,7 @@
#include <iostream>
-#include <lemon/smart_ugraph.h>
+#include <lemon/smart_graph.h>
#include <lemon/bucket_heap.h>
#include <lemon/graph_reader.h>
#include <lemon/graph_to_eps.h>
Modified: hugo/trunk/demo/strongly_connected_orientation.cc
==============================================================================
--- hugo/trunk/demo/strongly_connected_orientation.cc (original)
+++ hugo/trunk/demo/strongly_connected_orientation.cc Fri Jun 30 14:15:45 2006
@@ -18,7 +18,7 @@
#include <iostream>
-#include <lemon/smart_ugraph.h>
+#include <lemon/smart_graph.h>
#include <lemon/graph_reader.h>
#include <lemon/ugraph_adaptor.h>
#include <lemon/graph_to_eps.h>
Modified: hugo/trunk/demo/topology_demo.cc
==============================================================================
--- hugo/trunk/demo/topology_demo.cc (original)
+++ hugo/trunk/demo/topology_demo.cc Fri Jun 30 14:15:45 2006
@@ -17,7 +17,6 @@
*/
#include <lemon/list_graph.h>
-#include <lemon/list_ugraph.h>
#include <lemon/topology.h>
#include <lemon/graph_to_eps.h>
#include <lemon/graph_reader.h>
Modified: hugo/trunk/doc/graphs.dox
==============================================================================
--- hugo/trunk/doc/graphs.dox (original)
+++ hugo/trunk/doc/graphs.dox Fri Jun 30 14:15:45 2006
@@ -9,20 +9,20 @@
The primary data structures of LEMON are the graph classes. They all
provide a node list - edge list interface, i.e. they have
functionalities to list the nodes and the edges of the graph as well
-as incoming and outgoing edges of a given node. This functionalities
-are defined in the \ref lemon::concept::Graph "Graph" concept.
+as incoming and outgoing edges of a given node.
-The next important graph type concept is the undirected graph concept
-what is defined in the \ref lemon::concept::UGraph "UGraph" concept class.
-Each undirected graphs provide node - undirected edge list interfaces.
-In addition the undirected graphs can be used as directed graphs so
-they are also conform to the \ref lemon::concept::Graph "Graph" concept.
-
-Usually the graphs can be sorted to two group, the first is the
-general topology graph types which can store any graph and the second
-are the special topology graphs like the \ref FullUGraph or the \ref
-GridUGraph.
+Each graph should meet the \ref lemon::concept::Graph "Graph" concept.
+This concept does not make it possible to change the graph (i.e. it is
+not possible to add or delete edges or nodes). Most of the graph
+algorithms will run on these graphs.
+
+In case of graphs meeting the full feature
+\ref lemon::concept::ErasableGraph "ErasableGraph"
+concept
+you can also erase individual edges and nodes in arbitrary order.
+
+The implemented graph structures are the following.
\li \ref lemon::ListGraph "ListGraph" is the most versatile graph class. It meets
the \ref lemon::concept::ErasableGraph "ErasableGraph" concept
and it also has some convenient extra features.
Modified: hugo/trunk/lemon/Makefile.am
==============================================================================
--- hugo/trunk/lemon/Makefile.am (original)
+++ hugo/trunk/lemon/Makefile.am Fri Jun 30 14:15:45 2006
@@ -43,9 +43,7 @@
lemon/fib_heap.h \
lemon/floyd_warshall.h \
lemon/fredman_tarjan.h \
- lemon/full_bpugraph.h \
lemon/full_graph.h \
- lemon/full_ugraph.h \
lemon/graph_adaptor.h \
lemon/graph_reader.h \
lemon/graph_to_eps.h \
@@ -58,9 +56,7 @@
lemon/kruskal.h \
lemon/lemon_reader.h \
lemon/lemon_writer.h \
- lemon/list_bpugraph.h \
lemon/list_graph.h \
- lemon/list_ugraph.h \
lemon/lp.h \
lemon/lp_base.h \
lemon/lp_cplex.h \
@@ -81,9 +77,7 @@
lemon/radix_sort.h \
lemon/refptr.h \
lemon/simann.h \
- lemon/smart_bpugraph.h \
lemon/smart_graph.h \
- lemon/smart_ugraph.h \
lemon/sub_graph.h \
lemon/suurballe.h \
lemon/tabu_search.h \
@@ -98,7 +92,6 @@
lemon/bits/alteration_notifier.h \
lemon/bits/array_map.h \
lemon/bits/base_extender.h \
- lemon/bits/bpugraph_extender.h \
lemon/bits/default_map.h \
lemon/bits/edge_set_extender.h \
lemon/bits/graph_adaptor_extender.h \
@@ -110,7 +103,6 @@
lemon/bits/mingw32_rand.h \
lemon/bits/mingw32_time.h \
lemon/bits/traits.h \
- lemon/bits/ugraph_extender.h \
lemon/bits/utility.h \
lemon/bits/vector_map.h
Modified: hugo/trunk/lemon/bits/graph_extender.h
==============================================================================
--- hugo/trunk/lemon/bits/graph_extender.h (original)
+++ hugo/trunk/lemon/bits/graph_extender.h Fri Jun 30 14:15:45 2006
@@ -20,10 +20,14 @@
#define LEMON_BITS_GRAPH_EXTENDER_H
#include <lemon/bits/invalid.h>
+#include <lemon/error.h>
#include <lemon/bits/map_extender.h>
#include <lemon/bits/default_map.h>
+#include <lemon/concept_check.h>
+#include <lemon/concept/maps.h>
+
///\ingroup graphbits
///\file
///\brief Extenders for the graph types
@@ -314,6 +318,1212 @@
}
};
+ /// \ingroup graphbits
+ ///
+ /// \brief Extender for the UGraphs
+ template <typename Base>
+ class UGraphExtender : public Base {
+ public:
+
+ typedef Base Parent;
+ typedef UGraphExtender Graph;
+
+ typedef typename Parent::Node Node;
+ typedef typename Parent::Edge Edge;
+ typedef typename Parent::UEdge UEdge;
+
+ // UGraph extension
+
+ int maxId(Node) const {
+ return Parent::maxNodeId();
+ }
+
+ int maxId(Edge) const {
+ return Parent::maxEdgeId();
+ }
+
+ int maxId(UEdge) const {
+ return Parent::maxUEdgeId();
+ }
+
+ Node fromId(int id, Node) const {
+ return Parent::nodeFromId(id);
+ }
+
+ Edge fromId(int id, Edge) const {
+ return Parent::edgeFromId(id);
+ }
+
+ UEdge fromId(int id, UEdge) const {
+ return Parent::uEdgeFromId(id);
+ }
+
+ Node oppositeNode(const Node &n, const UEdge &e) const {
+ if( n == Parent::source(e))
+ return Parent::target(e);
+ else if( n == Parent::target(e))
+ return Parent::source(e);
+ else
+ return INVALID;
+ }
+
+ Edge oppositeEdge(const Edge &e) const {
+ return Parent::direct(e, !Parent::direction(e));
+ }
+
+ using Parent::direct;
+ Edge direct(const UEdge &ue, const Node &s) const {
+ return Parent::direct(ue, Parent::source(ue) == s);
+ }
+
+ // Alterable extension
+
+ typedef AlterationNotifier<UGraphExtender, Node> NodeNotifier;
+ typedef AlterationNotifier<UGraphExtender, Edge> EdgeNotifier;
+ typedef AlterationNotifier<UGraphExtender, UEdge> UEdgeNotifier;
+
+
+ protected:
+
+ mutable NodeNotifier node_notifier;
+ mutable EdgeNotifier edge_notifier;
+ mutable UEdgeNotifier uedge_notifier;
+
+ public:
+
+ NodeNotifier& getNotifier(Node) const {
+ return node_notifier;
+ }
+
+ EdgeNotifier& getNotifier(Edge) const {
+ return edge_notifier;
+ }
+
+ UEdgeNotifier& getNotifier(UEdge) const {
+ return uedge_notifier;
+ }
+
+
+
+ class NodeIt : public Node {
+ const Graph* graph;
+ public:
+
+ NodeIt() {}
+
+ NodeIt(Invalid i) : Node(i) { }
+
+ explicit NodeIt(const Graph& _graph) : graph(&_graph) {
+ _graph.first(static_cast<Node&>(*this));
+ }
+
+ NodeIt(const Graph& _graph, const Node& node)
+ : Node(node), graph(&_graph) {}
+
+ NodeIt& operator++() {
+ graph->next(*this);
+ return *this;
+ }
+
+ };
+
+
+ class EdgeIt : public Edge {
+ const Graph* graph;
+ public:
+
+ EdgeIt() { }
+
+ EdgeIt(Invalid i) : Edge(i) { }
+
+ explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
+ _graph.first(static_cast<Edge&>(*this));
+ }
+
+ EdgeIt(const Graph& _graph, const Edge& e) :
+ Edge(e), graph(&_graph) { }
+
+ EdgeIt& operator++() {
+ graph->next(*this);
+ return *this;
+ }
+
+ };
+
+
+ class OutEdgeIt : public Edge {
+ const Graph* graph;
+ public:
+
+ OutEdgeIt() { }
+
+ OutEdgeIt(Invalid i) : Edge(i) { }
+
+ OutEdgeIt(const Graph& _graph, const Node& node)
+ : graph(&_graph) {
+ _graph.firstOut(*this, node);
+ }
+
+ OutEdgeIt(const Graph& _graph, const Edge& edge)
+ : Edge(edge), graph(&_graph) {}
+
+ OutEdgeIt& operator++() {
+ graph->nextOut(*this);
+ return *this;
+ }
+
+ };
+
+
+ class InEdgeIt : public Edge {
+ const Graph* graph;
+ public:
+
+ InEdgeIt() { }
+
+ InEdgeIt(Invalid i) : Edge(i) { }
+
+ InEdgeIt(const Graph& _graph, const Node& node)
+ : graph(&_graph) {
+ _graph.firstIn(*this, node);
+ }
+
+ InEdgeIt(const Graph& _graph, const Edge& edge) :
+ Edge(edge), graph(&_graph) {}
+
+ InEdgeIt& operator++() {
+ graph->nextIn(*this);
+ return *this;
+ }
+
+ };
+
+
+ class UEdgeIt : public Parent::UEdge {
+ const Graph* graph;
+ public:
+
+ UEdgeIt() { }
+
+ UEdgeIt(Invalid i) : UEdge(i) { }
+
+ explicit UEdgeIt(const Graph& _graph) : graph(&_graph) {
+ _graph.first(static_cast<UEdge&>(*this));
+ }
+
+ UEdgeIt(const Graph& _graph, const UEdge& e) :
+ UEdge(e), graph(&_graph) { }
+
+ UEdgeIt& operator++() {
+ graph->next(*this);
+ return *this;
+ }
+
+ };
+
+ class IncEdgeIt : public Parent::UEdge {
+ friend class UGraphExtender;
+ const Graph* graph;
+ bool direction;
+ public:
+
+ IncEdgeIt() { }
+
+ IncEdgeIt(Invalid i) : UEdge(i), direction(false) { }
+
+ IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
+ _graph.firstInc(*this, direction, n);
+ }
+
+ IncEdgeIt(const Graph& _graph, const UEdge &ue, const Node &n)
+ : graph(&_graph), UEdge(ue) {
+ direction = (_graph.source(ue) == n);
+ }
+
+ IncEdgeIt& operator++() {
+ graph->nextInc(*this, direction);
+ return *this;
+ }
+ };
+
+ /// \brief Base node of the iterator
+ ///
+ /// Returns the base node (ie. the source in this case) of the iterator
+ Node baseNode(const OutEdgeIt &e) const {
+ return Parent::source((Edge)e);
+ }
+ /// \brief Running node of the iterator
+ ///
+ /// Returns the running node (ie. the target in this case) of the
+ /// iterator
+ Node runningNode(const OutEdgeIt &e) const {
+ return Parent::target((Edge)e);
+ }
+
+ /// \brief Base node of the iterator
+ ///
+ /// Returns the base node (ie. the target in this case) of the iterator
+ Node baseNode(const InEdgeIt &e) const {
+ return Parent::target((Edge)e);
+ }
+ /// \brief Running node of the iterator
+ ///
+ /// Returns the running node (ie. the source in this case) of the
+ /// iterator
+ Node runningNode(const InEdgeIt &e) const {
+ return Parent::source((Edge)e);
+ }
+
+ /// Base node of the iterator
+ ///
+ /// Returns the base node of the iterator
+ Node baseNode(const IncEdgeIt &e) const {
+ return e.direction ? source(e) : target(e);
+ }
+ /// Running node of the iterator
+ ///
+ /// Returns the running node of the iterator
+ Node runningNode(const IncEdgeIt &e) const {
+ return e.direction ? target(e) : source(e);
+ }
+
+ // Mappable extension
+
+ template <typename _Value>
+ class NodeMap
+ : public MapExtender<DefaultMap<Graph, Node, _Value> > {
+ public:
+ typedef UGraphExtender Graph;
+ typedef MapExtender<DefaultMap<Graph, Node, _Value> > Parent;
+
+ NodeMap(const Graph& graph)
+ : Parent(graph) {}
+ NodeMap(const Graph& graph, const _Value& value)
+ : Parent(graph, value) {}
+
+ NodeMap& operator=(const NodeMap& cmap) {
+ return operator=<NodeMap>(cmap);
+ }
+
+ template <typename CMap>
+ NodeMap& operator=(const CMap& cmap) {
+ Parent::operator=(cmap);
+ return *this;
+ }
+
+ };
+
+ template <typename _Value>
+ class EdgeMap
+ : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
+ public:
+ typedef UGraphExtender Graph;
+ typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
+
+ EdgeMap(const Graph& graph)
+ : Parent(graph) {}
+ EdgeMap(const Graph& graph, const _Value& value)
+ : Parent(graph, value) {}
+
+ EdgeMap& operator=(const EdgeMap& cmap) {
+ return operator=<EdgeMap>(cmap);
+ }
+
+ template <typename CMap>
+ EdgeMap& operator=(const CMap& cmap) {
+ Parent::operator=(cmap);
+ return *this;
+ }
+ };
+
+
+ template <typename _Value>
+ class UEdgeMap
+ : public MapExtender<DefaultMap<Graph, UEdge, _Value> > {
+ public:
+ typedef UGraphExtender Graph;
+ typedef MapExtender<DefaultMap<Graph, UEdge, _Value> > Parent;
+
+ UEdgeMap(const Graph& graph)
+ : Parent(graph) {}
+
+ UEdgeMap(const Graph& graph, const _Value& value)
+ : Parent(graph, value) {}
+
+ UEdgeMap& operator=(const UEdgeMap& cmap) {
+ return operator=<UEdgeMap>(cmap);
+ }
+
+ template <typename CMap>
+ UEdgeMap& operator=(const CMap& cmap) {
+ Parent::operator=(cmap);
+ return *this;
+ }
+
+ };
+
+ // Alteration extension
+
+ Node addNode() {
+ Node node = Parent::addNode();
+ getNotifier(Node()).add(node);
+ return node;
+ }
+
+ UEdge addEdge(const Node& from, const Node& to) {
+ UEdge uedge = Parent::addEdge(from, to);
+ getNotifier(UEdge()).add(uedge);
+ getNotifier(Edge()).add(Parent::direct(uedge, true));
+ getNotifier(Edge()).add(Parent::direct(uedge, false));
+ return uedge;
+ }
+
+ void clear() {
+ getNotifier(Edge()).clear();
+ getNotifier(UEdge()).clear();
+ getNotifier(Node()).clear();
+ Parent::clear();
+ }
+
+ void erase(const Node& node) {
+ Edge edge;
+ Parent::firstOut(edge, node);
+ while (edge != INVALID ) {
+ erase(edge);
+ Parent::firstOut(edge, node);
+ }
+
+ Parent::firstIn(edge, node);
+ while (edge != INVALID ) {
+ erase(edge);
+ Parent::firstIn(edge, node);
+ }
+
+ getNotifier(Node()).erase(node);
+ Parent::erase(node);
+ }
+
+ void erase(const UEdge& uedge) {
+ getNotifier(Edge()).erase(Parent::direct(uedge, true));
+ getNotifier(Edge()).erase(Parent::direct(uedge, false));
+ getNotifier(UEdge()).erase(uedge);
+ Parent::erase(uedge);
+ }
+
+ UGraphExtender() {
+ node_notifier.setContainer(*this);
+ edge_notifier.setContainer(*this);
+ uedge_notifier.setContainer(*this);
+ }
+
+ ~UGraphExtender() {
+ uedge_notifier.clear();
+ edge_notifier.clear();
+ node_notifier.clear();
+ }
+
+ };
+
+ /// \ingroup graphbits
+ ///
+ /// \brief Extender for the BpUGraphs
+ template <typename Base>
+ class BpUGraphExtender : public Base {
+ public:
+ typedef Base Parent;
+ typedef BpUGraphExtender Graph;
+
+ typedef typename Parent::Node Node;
+ typedef typename Parent::UEdge UEdge;
+
+
+ using Parent::first;
+ using Parent::next;
+
+ using Parent::id;
+
+ class ANode : public Node {
+ friend class BpUGraphExtender;
+ public:
+ ANode() {}
+ ANode(const Node& node) : Node(node) {
+ LEMON_ASSERT(Parent::aNode(node) || node == INVALID,
+ typename Parent::NodeSetError());
+ }
+ ANode(Invalid) : Node(INVALID) {}
+ };
+
+ void first(ANode& node) const {
+ Parent::firstANode(static_cast<Node&>(node));
+ }
+ void next(ANode& node) const {
+ Parent::nextANode(static_cast<Node&>(node));
+ }
+
+ int id(const ANode& node) const {
+ return Parent::aNodeId(node);
+ }
+
+ class BNode : public Node {
+ friend class BpUGraphExtender;
+ public:
+ BNode() {}
+ BNode(const Node& node) : Node(node) {
+ LEMON_ASSERT(Parent::bNode(node) || node == INVALID,
+ typename Parent::NodeSetError());
+ }
+ BNode(Invalid) : Node(INVALID) {}
+ };
+
+ void first(BNode& node) const {
+ Parent::firstBNode(static_cast<Node&>(node));
+ }
+ void next(BNode& node) const {
+ Parent::nextBNode(static_cast<Node&>(node));
+ }
+
+ int id(const BNode& node) const {
+ return Parent::aNodeId(node);
+ }
+
+ Node source(const UEdge& edge) const {
+ return aNode(edge);
+ }
+ Node target(const UEdge& edge) const {
+ return bNode(edge);
+ }
+
+ void firstInc(UEdge& edge, bool& direction, const Node& node) const {
+ if (Parent::aNode(node)) {
+ Parent::firstFromANode(edge, node);
+ direction = true;
+ } else {
+ Parent::firstFromBNode(edge, node);
+ direction = static_cast<UEdge&>(edge) == INVALID;
+ }
+ }
+ void nextInc(UEdge& edge, bool& direction) const {
+ if (direction) {
+ Parent::nextFromANode(edge);
+ } else {
+ Parent::nextFromBNode(edge);
+ if (edge == INVALID) direction = true;
+ }
+ }
+
+ class Edge : public UEdge {
+ friend class BpUGraphExtender;
+ protected:
+ bool forward;
+
+ Edge(const UEdge& edge, bool _forward)
+ : UEdge(edge), forward(_forward) {}
+
+ public:
+ Edge() {}
+ Edge (Invalid) : UEdge(INVALID), forward(true) {}
+ bool operator==(const Edge& i) const {
+ return UEdge::operator==(i) && forward == i.forward;
+ }
+ bool operator!=(const Edge& i) const {
+ return UEdge::operator!=(i) || forward != i.forward;
+ }
+ bool operator<(const Edge& i) const {
+ return UEdge::operator<(i) ||
+ (!(i.forward<forward) && UEdge(*this)<UEdge(i));
+ }
+ };
+
+ void first(Edge& edge) const {
+ Parent::first(static_cast<UEdge&>(edge));
+ edge.forward = true;
+ }
+
+ void next(Edge& edge) const {
+ if (!edge.forward) {
+ Parent::next(static_cast<UEdge&>(edge));
+ }
+ edge.forward = !edge.forward;
+ }
+
+ void firstOut(Edge& edge, const Node& node) const {
+ if (Parent::aNode(node)) {
+ Parent::firstFromANode(edge, node);
+ edge.forward = true;
+ } else {
+ Parent::firstFromBNode(edge, node);
+ edge.forward = static_cast<UEdge&>(edge) == INVALID;
+ }
+ }
+ void nextOut(Edge& edge) const {
+ if (edge.forward) {
+ Parent::nextFromANode(edge);
+ } else {
+ Parent::nextFromBNode(edge);
+ edge.forward = static_cast<UEdge&>(edge) == INVALID;
+ }
+ }
+
+ void firstIn(Edge& edge, const Node& node) const {
+ if (Parent::bNode(node)) {
+ Parent::firstFromBNode(edge, node);
+ edge.forward = true;
+ } else {
+ Parent::firstFromANode(edge, node);
+ edge.forward = static_cast<UEdge&>(edge) == INVALID;
+ }
+ }
+ void nextIn(Edge& edge) const {
+ if (edge.forward) {
+ Parent::nextFromBNode(edge);
+ } else {
+ Parent::nextFromANode(edge);
+ edge.forward = static_cast<UEdge&>(edge) == INVALID;
+ }
+ }
+
+ Node source(const Edge& edge) const {
+ return edge.forward ? Parent::aNode(edge) : Parent::bNode(edge);
+ }
+ Node target(const Edge& edge) const {
+ return edge.forward ? Parent::bNode(edge) : Parent::aNode(edge);
+ }
+
+ int id(const Edge& edge) const {
+ return (Parent::id(static_cast<const UEdge&>(edge)) << 1) +
+ (edge.forward ? 0 : 1);
+ }
+ Edge edgeFromId(int id) const {
+ return Edge(Parent::fromUEdgeId(id >> 1), (id & 1) == 0);
+ }
+ int maxEdgeId() const {
+ return (Parent::maxUEdgeId(UEdge()) << 1) + 1;
+ }
+
+ bool direction(const Edge& edge) const {
+ return edge.forward;
+ }
+
+ Edge direct(const UEdge& edge, bool direction) const {
+ return Edge(edge, direction);
+ }
+
+ int edgeNum() const {
+ return 2 * Parent::uEdgeNum();
+ }
+
+ int uEdgeNum() const {
+ return Parent::uEdgeNum();
+ }
+
+ Node oppositeNode(const UEdge& edge, const Node& node) const {
+ return source(edge) == node ?
+ target(edge) : source(edge);
+ }
+
+ Edge direct(const UEdge& edge, const Node& node) const {
+ return Edge(edge, node == Parent::source(edge));
+ }
+
+ Edge oppositeEdge(const Edge& edge) const {
+ return Parent::direct(edge, !Parent::direction(edge));
+ }
+
+
+ int maxId(Node) const {
+ return Parent::maxNodeId();
+ }
+ int maxId(BNode) const {
+ return Parent::maxBNodeId();
+ }
+ int maxId(ANode) const {
+ return Parent::maxANodeId();
+ }
+ int maxId(Edge) const {
+ return maxEdgeId();
+ }
+ int maxId(UEdge) const {
+ return Parent::maxUEdgeId();
+ }
+
+
+ Node fromId(int id, Node) const {
+ return Parent::nodeFromId(id);
+ }
+ ANode fromId(int id, ANode) const {
+ return Parent::fromANodeId(id);
+ }
+ BNode fromId(int id, BNode) const {
+ return Parent::fromBNodeId(id);
+ }
+ Edge fromId(int id, Edge) const {
+ return Parent::edgeFromId(id);
+ }
+ UEdge fromId(int id, UEdge) const {
+ return Parent::uEdgeFromId(id);
+ }
+
+ typedef AlterationNotifier<BpUGraphExtender, ANode> ANodeNotifier;
+ typedef AlterationNotifier<BpUGraphExtender, BNode> BNodeNotifier;
+ typedef AlterationNotifier<BpUGraphExtender, Node> NodeNotifier;
+ typedef AlterationNotifier<BpUGraphExtender, Edge> EdgeNotifier;
+ typedef AlterationNotifier<BpUGraphExtender, UEdge> UEdgeNotifier;
+
+ protected:
+
+ mutable ANodeNotifier anode_notifier;
+ mutable BNodeNotifier bnode_notifier;
+ mutable NodeNotifier node_notifier;
+ mutable EdgeNotifier edge_notifier;
+ mutable UEdgeNotifier uedge_notifier;
+
+ public:
+
+ NodeNotifier& getNotifier(Node) const {
+ return node_notifier;
+ }
+
+ ANodeNotifier& getNotifier(ANode) const {
+ return anode_notifier;
+ }
+
+ BNodeNotifier& getNotifier(BNode) const {
+ return bnode_notifier;
+ }
+
+ EdgeNotifier& getNotifier(Edge) const {
+ return edge_notifier;
+ }
+
+ UEdgeNotifier& getNotifier(UEdge) const {
+ return uedge_notifier;
+ }
+
+ class NodeIt : public Node {
+ const Graph* graph;
+ public:
+
+ NodeIt() { }
+
+ NodeIt(Invalid i) : Node(INVALID) { }
+
+ explicit NodeIt(const Graph& _graph) : graph(&_graph) {
+ graph->first(static_cast<Node&>(*this));
+ }
+
+ NodeIt(const Graph& _graph, const Node& node)
+ : Node(node), graph(&_graph) { }
+
+ NodeIt& operator++() {
+ graph->next(*this);
+ return *this;
+ }
+
+ };
+
+ class ANodeIt : public Node {
+ friend class BpUGraphExtender;
+ const Graph* graph;
+ public:
+
+ ANodeIt() { }
+
+ ANodeIt(Invalid i) : Node(INVALID) { }
+
+ explicit ANodeIt(const Graph& _graph) : graph(&_graph) {
+ graph->firstANode(static_cast<Node&>(*this));
+ }
+
+ ANodeIt(const Graph& _graph, const Node& node)
+ : Node(node), graph(&_graph) {}
+
+ ANodeIt& operator++() {
+ graph->nextANode(*this);
+ return *this;
+ }
+ };
+
+ class BNodeIt : public Node {
+ friend class BpUGraphExtender;
+ const Graph* graph;
+ public:
+
+ BNodeIt() { }
+
+ BNodeIt(Invalid i) : Node(INVALID) { }
+
+ explicit BNodeIt(const Graph& _graph) : graph(&_graph) {
+ graph->firstBNode(static_cast<Node&>(*this));
+ }
+
+ BNodeIt(const Graph& _graph, const Node& node)
+ : Node(node), graph(&_graph) {}
+
+ BNodeIt& operator++() {
+ graph->nextBNode(*this);
+ return *this;
+ }
+ };
+
+ class EdgeIt : public Edge {
+ friend class BpUGraphExtender;
+ const Graph* graph;
+ public:
+
+ EdgeIt() { }
+
+ EdgeIt(Invalid i) : Edge(INVALID) { }
+
+ explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
+ graph->first(static_cast<Edge&>(*this));
+ }
+
+ EdgeIt(const Graph& _graph, const Edge& edge)
+ : Edge(edge), graph(&_graph) { }
+
+ EdgeIt& operator++() {
+ graph->next(*this);
+ return *this;
+ }
+
+ };
+
+ class UEdgeIt : public UEdge {
+ friend class BpUGraphExtender;
+ const Graph* graph;
+ public:
+
+ UEdgeIt() { }
+
+ UEdgeIt(Invalid i) : UEdge(INVALID) { }
+
+ explicit UEdgeIt(const Graph& _graph) : graph(&_graph) {
+ graph->first(static_cast<UEdge&>(*this));
+ }
+
+ UEdgeIt(const Graph& _graph, const UEdge& edge)
+ : UEdge(edge), graph(&_graph) { }
+
+ UEdgeIt& operator++() {
+ graph->next(*this);
+ return *this;
+ }
+ };
+
+ class OutEdgeIt : public Edge {
+ friend class BpUGraphExtender;
+ const Graph* graph;
+ public:
+
+ OutEdgeIt() { }
+
+ OutEdgeIt(Invalid i) : Edge(i) { }
+
+ OutEdgeIt(const Graph& _graph, const Node& node)
+ : graph(&_graph) {
+ graph->firstOut(*this, node);
+ }
+
+ OutEdgeIt(const Graph& _graph, const Edge& edge)
+ : Edge(edge), graph(&_graph) {}
+
+ OutEdgeIt& operator++() {
+ graph->nextOut(*this);
+ return *this;
+ }
+
+ };
+
+
+ class InEdgeIt : public Edge {
+ friend class BpUGraphExtender;
+ const Graph* graph;
+ public:
+
+ InEdgeIt() { }
+
+ InEdgeIt(Invalid i) : Edge(i) { }
+
+ InEdgeIt(const Graph& _graph, const Node& node)
+ : graph(&_graph) {
+ graph->firstIn(*this, node);
+ }
+
+ InEdgeIt(const Graph& _graph, const Edge& edge) :
+ Edge(edge), graph(&_graph) {}
+
+ InEdgeIt& operator++() {
+ graph->nextIn(*this);
+ return *this;
+ }
+
+ };
+
+ /// \brief Base node of the iterator
+ ///
+ /// Returns the base node (ie. the source in this case) of the iterator
+ Node baseNode(const OutEdgeIt &e) const {
+ return Parent::source((Edge&)e);
+ }
+ /// \brief Running node of the iterator
+ ///
+ /// Returns the running node (ie. the target in this case) of the
+ /// iterator
+ Node runningNode(const OutEdgeIt &e) const {
+ return Parent::target((Edge&)e);
+ }
+
+ /// \brief Base node of the iterator
+ ///
+ /// Returns the base node (ie. the target in this case) of the iterator
+ Node baseNode(const InEdgeIt &e) const {
+ return Parent::target((Edge&)e);
+ }
+ /// \brief Running node of the iterator
+ ///
+ /// Returns the running node (ie. the source in this case) of the
+ /// iterator
+ Node runningNode(const InEdgeIt &e) const {
+ return Parent::source((Edge&)e);
+ }
+
+ class IncEdgeIt : public Parent::UEdge {
+ friend class BpUGraphExtender;
+ const Graph* graph;
+ bool direction;
+ public:
+
+ IncEdgeIt() { }
+
+ IncEdgeIt(Invalid i) : UEdge(i), direction(true) { }
+
+ IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
+ graph->firstInc(*this, direction, n);
+ }
+
+ IncEdgeIt(const Graph& _graph, const UEdge &ue, const Node &n)
+ : graph(&_graph), UEdge(ue) {
+ direction = (graph->source(ue) == n);
+ }
+
+ IncEdgeIt& operator++() {
+ graph->nextInc(*this, direction);
+ return *this;
+ }
+ };
+
+
+ /// Base node of the iterator
+ ///
+ /// Returns the base node of the iterator
+ Node baseNode(const IncEdgeIt &e) const {
+ return e.direction ? source(e) : target(e);
+ }
+
+ /// Running node of the iterator
+ ///
+ /// Returns the running node of the iterator
+ Node runningNode(const IncEdgeIt &e) const {
+ return e.direction ? target(e) : source(e);
+ }
+
+ template <typename _Value>
+ class ANodeMap
+ : public MapExtender<DefaultMap<Graph, ANode, _Value> > {
+ public:
+ typedef BpUGraphExtender Graph;
+ typedef MapExtender<DefaultMap<Graph, ANode, _Value> > Parent;
+
+ ANodeMap(const Graph& graph)
+ : Parent(graph) {}
+ ANodeMap(const Graph& graph, const _Value& value)
+ : Parent(graph, value) {}
+
+ ANodeMap& operator=(const ANodeMap& cmap) {
+ return operator=<ANodeMap>(cmap);
+ }
+
+ template <typename CMap>
+ ANodeMap& operator=(const CMap& cmap) {
+ Parent::operator=(cmap);
+ return *this;
+ }
+
+ };
+
+ template <typename _Value>
+ class BNodeMap
+ : public MapExtender<DefaultMap<Graph, BNode, _Value> > {
+ public:
+ typedef BpUGraphExtender Graph;
+ typedef MapExtender<DefaultMap<Graph, BNode, _Value> > Parent;
+
+ BNodeMap(const Graph& graph)
+ : Parent(graph) {}
+ BNodeMap(const Graph& graph, const _Value& value)
+ : Parent(graph, value) {}
+
+ BNodeMap& operator=(const BNodeMap& cmap) {
+ return operator=<BNodeMap>(cmap);
+ }
+
+ template <typename CMap>
+ BNodeMap& operator=(const CMap& cmap) {
+ Parent::operator=(cmap);
+ return *this;
+ }
+
+ };
+
+ public:
+
+ template <typename _Value>
+ class NodeMap {
+ public:
+ typedef BpUGraphExtender Graph;
+
+ typedef Node Key;
+ typedef _Value Value;
+
+ /// The reference type of the map;
+ typedef typename ANodeMap<_Value>::Reference Reference;
+ /// The const reference type of the map;
+ typedef typename ANodeMap<_Value>::ConstReference ConstReference;
+
+ typedef True ReferenceMapTag;
+
+ NodeMap(const Graph& _graph)
+ : graph(_graph), aNodeMap(_graph), bNodeMap(_graph) {}
+ NodeMap(const Graph& _graph, const _Value& _value)
+ : graph(_graph), aNodeMap(_graph, _value), bNodeMap(_graph, _value) {}
+
+ NodeMap& operator=(const NodeMap& cmap) {
+ return operator=<NodeMap>(cmap);
+ }
+
+ template <typename CMap>
+ NodeMap& operator=(const CMap& cmap) {
+ checkConcept<concept::ReadMap<Node, _Value>, CMap>();
+ const typename Parent::Notifier* notifier = Parent::getNotifier();
+ Edge it;
+ for (graph.first(it); it != INVALID; graph.next(it)) {
+ Parent::set(it, cmap[it]);
+ }
+ return *this;
+ }
+
+ ConstReference operator[](const Key& node) const {
+ if (Parent::aNode(node)) {
+ return aNodeMap[node];
+ } else {
+ return bNodeMap[node];
+ }
+ }
+
+ Reference operator[](const Key& node) {
+ if (Parent::aNode(node)) {
+ return aNodeMap[node];
+ } else {
+ return bNodeMap[node];
+ }
+ }
+
+ void set(const Key& node, const Value& value) {
+ if (Parent::aNode(node)) {
+ aNodeMap.set(node, value);
+ } else {
+ bNodeMap.set(node, value);
+ }
+ }
+
+ class MapIt : public NodeIt {
+ public:
+
+ typedef NodeIt Parent;
+
+ explicit MapIt(NodeMap& _map)
+ : Parent(_map.graph), map(_map) {}
+
+ typename MapTraits<NodeMap>::ConstReturnValue operator*() const {
+ return map[*this];
+ }
+
+ typename MapTraits<NodeMap>::ReturnValue operator*() {
+ return map[*this];
+ }
+
+ void set(const Value& value) {
+ map.set(*this, value);
+ }
+
+ private:
+ NodeMap& map;
+ };
+
+ class ConstMapIt : public NodeIt {
+ public:
+
+ typedef NodeIt Parent;
+
+ explicit ConstMapIt(const NodeMap& _map)
+ : Parent(_map.graph), map(_map) {}
+
+ typename MapTraits<NodeMap>::ConstReturnValue operator*() const {
+ return map[*this];
+ }
+
+ private:
+ const NodeMap& map;
+ };
+
+ class ItemIt : public NodeIt {
+ public:
+
+ typedef NodeIt Parent;
+
+ explicit ItemIt(const NodeMap& _map)
+ : Parent(_map.graph) {}
+
+ };
+
+ private:
+ const Graph& graph;
+ ANodeMap<_Value> aNodeMap;
+ BNodeMap<_Value> bNodeMap;
+ };
+
+
+ template <typename _Value>
+ class EdgeMap
+ : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
+ public:
+ typedef BpUGraphExtender Graph;
+ typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
+
+ EdgeMap(const Graph& graph)
+ : Parent(graph) {}
+ EdgeMap(const Graph& graph, const _Value& value)
+ : Parent(graph, value) {}
+
+ EdgeMap& operator=(const EdgeMap& cmap) {
+ return operator=<EdgeMap>(cmap);
+ }
+
+ template <typename CMap>
+ EdgeMap& operator=(const CMap& cmap) {
+ Parent::operator=(cmap);
+ return *this;
+ }
+ };
+
+ template <typename _Value>
+ class UEdgeMap
+ : public MapExtender<DefaultMap<Graph, UEdge, _Value> > {
+ public:
+ typedef BpUGraphExtender Graph;
+ typedef MapExtender<DefaultMap<Graph, UEdge, _Value> > Parent;
+
+ UEdgeMap(const Graph& graph)
+ : Parent(graph) {}
+ UEdgeMap(const Graph& graph, const _Value& value)
+ : Parent(graph, value) {}
+
+ UEdgeMap& operator=(const UEdgeMap& cmap) {
+ return operator=<UEdgeMap>(cmap);
+ }
+
+ template <typename CMap>
+ UEdgeMap& operator=(const CMap& cmap) {
+ Parent::operator=(cmap);
+ return *this;
+ }
+ };
+
+
+ Node addANode() {
+ Node node = Parent::addANode();
+ getNotifier(ANode()).add(node);
+ getNotifier(Node()).add(node);
+ return node;
+ }
+
+ Node addBNode() {
+ Node node = Parent::addBNode();
+ getNotifier(BNode()).add(node);
+ getNotifier(Node()).add(node);
+ return node;
+ }
+
+ UEdge addEdge(const Node& source, const Node& target) {
+ UEdge uedge = Parent::addEdge(source, target);
+ getNotifier(UEdge()).add(uedge);
+
+ std::vector<Edge> edges;
+ edges.push_back(direct(uedge, true));
+ edges.push_back(direct(uedge, false));
+ getNotifier(Edge()).add(edges);
+
+ return uedge;
+ }
+
+ void clear() {
+ getNotifier(Edge()).clear();
+ getNotifier(UEdge()).clear();
+ getNotifier(Node()).clear();
+ getNotifier(BNode()).clear();
+ getNotifier(ANode()).clear();
+ Parent::clear();
+ }
+
+ void erase(const Node& node) {
+ UEdge uedge;
+ if (Parent::aNode(node)) {
+ Parent::firstFromANode(uedge, node);
+ while (uedge != INVALID) {
+ erase(uedge);
+ Parent::firstFromANode(uedge, node);
+ }
+ } else {
+ Parent::firstFromBNode(uedge, node);
+ while (uedge != INVALID) {
+ erase(uedge);
+ Parent::firstFromBNode(uedge, node);
+ }
+ }
+
+ getNotifier(Node()).erase(node);
+ Parent::erase(node);
+ }
+
+ void erase(const UEdge& uedge) {
+ std::vector<Edge> edges;
+ edges.push_back(direct(uedge, true));
+ edges.push_back(direct(uedge, false));
+ getNotifier(Edge()).erase(edges);
+ getNotifier(UEdge()).erase(uedge);
+ Parent::erase(uedge);
+ }
+
+
+ BpUGraphExtender() {
+ anode_notifier.setContainer(*this);
+ bnode_notifier.setContainer(*this);
+ node_notifier.setContainer(*this);
+ edge_notifier.setContainer(*this);
+ uedge_notifier.setContainer(*this);
+ }
+
+ ~BpUGraphExtender() {
+ uedge_notifier.clear();
+ edge_notifier.clear();
+ node_notifier.clear();
+ anode_notifier.clear();
+ bnode_notifier.clear();
+ }
+
+
+ };
+
}
#endif
Modified: hugo/trunk/lemon/edge_set.h
==============================================================================
--- hugo/trunk/lemon/edge_set.h (original)
+++ hugo/trunk/lemon/edge_set.h Fri Jun 30 14:15:45 2006
@@ -22,7 +22,6 @@
#include <lemon/bits/default_map.h>
#include <lemon/bits/edge_set_extender.h>
-#include <lemon/bits/base_extender.h>
/// \ingroup graphs
/// \file
Modified: hugo/trunk/lemon/full_graph.h
==============================================================================
--- hugo/trunk/lemon/full_graph.h (original)
+++ hugo/trunk/lemon/full_graph.h Fri Jun 30 14:15:45 2006
@@ -21,6 +21,7 @@
#include <cmath>
+#include <lemon/bits/base_extender.h>
#include <lemon/bits/graph_extender.h>
#include <lemon/bits/invalid.h>
@@ -29,7 +30,7 @@
///\ingroup graphs
///\file
-///\brief FullGraph class.
+///\brief FullGraph and FullUGraph classes.
namespace lemon {
@@ -246,6 +247,473 @@
}
};
+
+ /// \brief Base of the FullUGrpah.
+ ///
+ /// Base of the FullUGrpah.
+ class FullUGraphBase {
+ int _nodeNum;
+ int _edgeNum;
+ public:
+
+ typedef FullUGraphBase Graph;
+
+ class Node;
+ class Edge;
+
+ public:
+
+ FullUGraphBase() {}
+
+
+ ///Creates a full graph with \c n nodes.
+ void construct(int n) { _nodeNum = n; _edgeNum = n * (n - 1) / 2; }
+
+ /// \brief Returns the node with the given index.
+ ///
+ /// Returns the node with the given index. Because it is a
+ /// static size graph the node's of the graph can be indiced
+ /// by the range from 0 to \e nodeNum()-1 and the index of
+ /// the node can accessed by the \e index() member.
+ Node operator()(int index) const { return Node(index); }
+
+ /// \brief Returns the index of the node.
+ ///
+ /// Returns the index of the node. Because it is a
+ /// static size graph the node's of the graph can be indiced
+ /// by the range from 0 to \e nodeNum()-1 and the index of
+ /// the node can accessed by the \e index() member.
+ int index(const Node& node) const { return node.id; }
+
+ typedef True NodeNumTag;
+ typedef True EdgeNumTag;
+
+ ///Number of nodes.
+ int nodeNum() const { return _nodeNum; }
+ ///Number of edges.
+ int edgeNum() const { return _edgeNum; }
+
+ /// Maximum node ID.
+
+ /// Maximum node ID.
+ ///\sa id(Node)
+ int maxNodeId() const { return _nodeNum-1; }
+ /// Maximum edge ID.
+
+ /// Maximum edge ID.
+ ///\sa id(Edge)
+ int maxEdgeId() const { return _edgeNum-1; }
+
+ /// \brief Returns the node from its \c id.
+ ///
+ /// Returns the node from its \c id. If there is not node
+ /// with the given id the effect of the function is undefinied.
+ static Node nodeFromId(int id) { return Node(id);}
+
+ /// \brief Returns the edge from its \c id.
+ ///
+ /// Returns the edge from its \c id. If there is not edge
+ /// with the given id the effect of the function is undefinied.
+ static Edge edgeFromId(int id) { return Edge(id);}
+
+ Node source(Edge e) const {
+ /// \todo we may do it faster
+ return Node(((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2);
+ }
+
+ Node target(Edge e) const {
+ int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
+ return Node(e.id - (source) * (source - 1) / 2);
+ }
+
+
+ /// \brief Node ID.
+ ///
+ /// The ID of a valid Node is a nonnegative integer not greater than
+ /// \ref maxNodeId(). The range of the ID's is not surely continuous
+ /// and the greatest node ID can be actually less then \ref maxNodeId().
+ ///
+ /// The ID of the \ref INVALID node is -1.
+ /// \return The ID of the node \c v.
+
+ static int id(Node v) { return v.id; }
+
+ /// \brief Edge ID.
+ ///
+ /// The ID of a valid Edge is a nonnegative integer not greater than
+ /// \ref maxEdgeId(). The range of the ID's is not surely continuous
+ /// and the greatest edge ID can be actually less then \ref maxEdgeId().
+ ///
+ /// The ID of the \ref INVALID edge is -1.
+ ///\return The ID of the edge \c e.
+ static int id(Edge e) { return e.id; }
+
+ /// \brief Finds an edge between two nodes.
+ ///
+ /// Finds an edge from node \c u to node \c v.
+ ///
+ /// If \c prev is \ref INVALID (this is the default value), then
+ /// It finds the first edge from \c u to \c v. Otherwise it looks for
+ /// the next edge from \c u to \c v after \c prev.
+ /// \return The found edge or INVALID if there is no such an edge.
+ Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
+ if (prev.id != -1 || u.id <= v.id) return Edge(-1);
+ return Edge(u.id * (u.id - 1) / 2 + v.id);
+ }
+
+ typedef True FindEdgeTag;
+
+
+ class Node {
+ friend class FullUGraphBase;
+
+ protected:
+ 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;}
+ };
+
+
+
+ class Edge {
+ friend class FullUGraphBase;
+
+ protected:
+ int id; // _nodeNum * target + source;
+
+ 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;}
+ };
+
+ void first(Node& node) const {
+ node.id = _nodeNum - 1;
+ }
+
+ static void next(Node& node) {
+ --node.id;
+ }
+
+ void first(Edge& edge) const {
+ edge.id = _edgeNum - 1;
+ }
+
+ static void next(Edge& edge) {
+ --edge.id;
+ }
+
+ void firstOut(Edge& edge, const Node& node) const {
+ int src = node.id;
+ int trg = 0;
+ edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
+ }
+
+ /// \todo with specialized iterators we can make faster iterating
+ void nextOut(Edge& edge) const {
+ int src = source(edge).id;
+ int trg = target(edge).id;
+ ++trg;
+ edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
+ }
+
+ void firstIn(Edge& edge, const Node& node) const {
+ int src = node.id + 1;
+ int trg = node.id;
+ edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
+ }
+
+ void nextIn(Edge& edge) const {
+ int src = source(edge).id;
+ int trg = target(edge).id;
+ ++src;
+ edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
+ }
+
+ };
+
+ typedef UGraphExtender<UndirGraphExtender<FullUGraphBase> >
+ ExtendedFullUGraphBase;
+
+ /// \ingroup graphs
+ ///
+ /// \brief An undirected full graph class.
+ ///
+ /// This is a simple and fast undirected full graph implementation.
+ /// It is completely static, so you can neither add nor delete either
+ /// edges or nodes.
+ ///
+ /// The main difference beetween the \e FullGraph and \e FullUGraph class
+ /// is that this class conforms to the undirected graph concept and
+ /// it does not contain the loop edges.
+ ///
+ /// \sa FullUGraphBase
+ /// \sa FullGraph
+ ///
+ /// \author Balazs Dezso
+ class FullUGraph : public ExtendedFullUGraphBase {
+ public:
+
+ typedef ExtendedFullUGraphBase Parent;
+
+ /// \brief Constructor
+ FullUGraph() { construct(0); }
+
+ /// \brief Constructor
+ FullUGraph(int n) { construct(n); }
+
+ /// \brief Resize the graph
+ ///
+ /// Resize the graph. The function will fully destroy and build the graph.
+ /// This cause that the maps of the graph will reallocated
+ /// automatically and the previous values will be lost.
+ void resize(int n) {
+ Parent::getNotifier(Edge()).clear();
+ Parent::getNotifier(UEdge()).clear();
+ Parent::getNotifier(Node()).clear();
+ construct(n);
+ Parent::getNotifier(Node()).build();
+ Parent::getNotifier(UEdge()).build();
+ Parent::getNotifier(Edge()).build();
+ }
+ };
+
+
+ class FullBpUGraphBase {
+ protected:
+
+ int _aNodeNum;
+ int _bNodeNum;
+
+ int _edgeNum;
+
+ public:
+
+ class NodeSetError : public LogicError {
+ virtual const char* exceptionName() const {
+ return "lemon::FullBpUGraph::NodeSetError";
+ }
+ };
+
+ class Node {
+ friend class FullBpUGraphBase;
+ protected:
+ int id;
+
+ Node(int _id) : id(_id) {}
+ public:
+ Node() {}
+ Node(Invalid) { id = -1; }
+ bool operator==(const Node i) const {return id==i.id;}
+ bool operator!=(const Node i) const {return id!=i.id;}
+ bool operator<(const Node i) const {return id<i.id;}
+ };
+
+ class UEdge {
+ friend class FullBpUGraphBase;
+ protected:
+ int id;
+
+ UEdge(int _id) { id = _id;}
+ public:
+ UEdge() {}
+ UEdge (Invalid) { id = -1; }
+ bool operator==(const UEdge i) const {return id==i.id;}
+ bool operator!=(const UEdge i) const {return id!=i.id;}
+ bool operator<(const UEdge i) const {return id<i.id;}
+ };
+
+ void construct(int aNodeNum, int bNodeNum) {
+ _aNodeNum = aNodeNum;
+ _bNodeNum = bNodeNum;
+ _edgeNum = aNodeNum * bNodeNum;
+ }
+
+ void firstANode(Node& node) const {
+ node.id = 2 * _aNodeNum - 2;
+ if (node.id < 0) node.id = -1;
+ }
+ void nextANode(Node& node) const {
+ node.id -= 2;
+ if (node.id < 0) node.id = -1;
+ }
+
+ void firstBNode(Node& node) const {
+ node.id = 2 * _bNodeNum - 1;
+ }
+ void nextBNode(Node& node) const {
+ node.id -= 2;
+ }
+
+ void first(Node& node) const {
+ if (_aNodeNum > 0) {
+ node.id = 2 * _aNodeNum - 2;
+ } else {
+ node.id = 2 * _bNodeNum - 1;
+ }
+ }
+ void next(Node& node) const {
+ node.id -= 2;
+ if (node.id == -2) {
+ node.id = 2 * _bNodeNum - 1;
+ }
+ }
+
+ void first(UEdge& edge) const {
+ edge.id = _edgeNum - 1;
+ }
+ void next(UEdge& edge) const {
+ --edge.id;
+ }
+
+ void firstFromANode(UEdge& edge, const Node& node) const {
+ LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
+ edge.id = (node.id >> 1) * _bNodeNum;
+ }
+ void nextFromANode(UEdge& edge) const {
+ ++(edge.id);
+ if (edge.id % _bNodeNum == 0) edge.id = -1;
+ }
+
+ void firstFromBNode(UEdge& edge, const Node& node) const {
+ LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
+ edge.id = (node.id >> 1);
+ }
+ void nextFromBNode(UEdge& edge) const {
+ edge.id += _bNodeNum;
+ if (edge.id >= _edgeNum) edge.id = -1;
+ }
+
+ static int id(const Node& node) {
+ return node.id;
+ }
+ static Node nodeFromId(int id) {
+ return Node(id);
+ }
+ int maxNodeId() const {
+ return _aNodeNum > _bNodeNum ?
+ _aNodeNum * 2 - 2 : _bNodeNum * 2 - 1;
+ }
+
+ static int id(const UEdge& edge) {
+ return edge.id;
+ }
+ static UEdge uEdgeFromId(int id) {
+ return UEdge(id);
+ }
+ int maxUEdgeId() const {
+ return _edgeNum - 1;
+ }
+
+ static int aNodeId(const Node& node) {
+ return node.id >> 1;
+ }
+ static Node fromANodeId(int id) {
+ return Node(id << 1);
+ }
+ int maxANodeId() const {
+ return _aNodeNum;
+ }
+
+ static int bNodeId(const Node& node) {
+ return node.id >> 1;
+ }
+ static Node fromBNodeId(int id) {
+ return Node((id << 1) + 1);
+ }
+ int maxBNodeId() const {
+ return _bNodeNum;
+ }
+
+ Node aNode(const UEdge& edge) const {
+ return Node((edge.id / _bNodeNum) << 1);
+ }
+ Node bNode(const UEdge& edge) const {
+ return Node(((edge.id % _bNodeNum) << 1) + 1);
+ }
+
+ static bool aNode(const Node& node) {
+ return (node.id & 1) == 0;
+ }
+
+ static bool bNode(const Node& node) {
+ return (node.id & 1) == 1;
+ }
+
+ static Node aNode(int index) {
+ return Node(index << 1);
+ }
+
+ static Node bNode(int index) {
+ return Node((index << 1) + 1);
+ }
+
+ typedef True NodeNumTag;
+ int nodeNum() const { return _aNodeNum + _bNodeNum; }
+ int aNodeNum() const { return _aNodeNum; }
+ int bNodeNum() const { return _bNodeNum; }
+
+ typedef True EdgeNumTag;
+ int uEdgeNum() const { return _edgeNum; }
+
+ };
+
+
+ typedef BpUGraphExtender<FullBpUGraphBase> ExtendedFullBpUGraphBase;
+
+
+ /// \ingroup graphs
+ ///
+ /// \brief An undirected full bipartite graph class.
+ ///
+ /// This is a simple and fast bipartite undirected full graph implementation.
+ /// It is completely static, so you can neither add nor delete either
+ /// edges or nodes.
+ ///
+ /// \sa FullUGraphBase
+ /// \sa FullGraph
+ ///
+ /// \author Balazs Dezso
+ class FullBpUGraph :
+ public ExtendedFullBpUGraphBase {
+ public:
+
+ typedef ExtendedFullBpUGraphBase Parent;
+
+ FullBpUGraph() {
+ Parent::construct(0, 0);
+ }
+
+ FullBpUGraph(int aNodeNum, int bNodeNum) {
+ Parent::construct(aNodeNum, bNodeNum);
+ }
+
+ /// \brief Resize the graph
+ ///
+ void resize(int n, int m) {
+ Parent::getNotifier(Edge()).clear();
+ Parent::getNotifier(UEdge()).clear();
+ Parent::getNotifier(Node()).clear();
+ Parent::getNotifier(ANode()).clear();
+ Parent::getNotifier(BNode()).clear();
+ construct(n, m);
+ Parent::getNotifier(ANode()).build();
+ Parent::getNotifier(BNode()).build();
+ Parent::getNotifier(Node()).build();
+ Parent::getNotifier(UEdge()).build();
+ Parent::getNotifier(Edge()).build();
+ }
+ };
+
} //namespace lemon
Modified: hugo/trunk/lemon/grid_ugraph.h
==============================================================================
--- hugo/trunk/lemon/grid_ugraph.h (original)
+++ hugo/trunk/lemon/grid_ugraph.h Fri Jun 30 14:15:45 2006
@@ -24,7 +24,7 @@
#include <lemon/bits/utility.h>
#include <lemon/bits/base_extender.h>
-#include <lemon/bits/ugraph_extender.h>
+#include <lemon/bits/graph_extender.h>
#include <lemon/xy.h>
Modified: hugo/trunk/lemon/list_graph.h
==============================================================================
--- hugo/trunk/lemon/list_graph.h (original)
+++ hugo/trunk/lemon/list_graph.h Fri Jun 30 14:15:45 2006
@@ -21,10 +21,13 @@
///\ingroup graphs
///\file
-///\brief ListGraph class.
+///\brief ListGraph, ListUGraph classes.
+#include <lemon/bits/base_extender.h>
#include <lemon/bits/graph_extender.h>
+#include <lemon/error.h>
+
#include <vector>
#include <list>
@@ -306,7 +309,8 @@
typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
- /// \ingroup graphs
+ /// \addtogroup graphs
+ /// @{
///A list graph class.
@@ -701,6 +705,454 @@
};
+ ///@}
+
+ /**************** Undirected List Graph ****************/
+
+ typedef UGraphExtender<UndirGraphExtender<ListGraphBase> >
+ ExtendedListUGraphBase;
+
+ /// \addtogroup graphs
+ /// @{
+
+ ///An undirected list graph class.
+
+ ///This is a simple and fast erasable undirected graph implementation.
+ ///
+ ///It conforms to the
+ ///\ref concept::UGraph "UGraph" concept.
+ ///
+ ///\sa concept::UGraph.
+ ///
+ ///\todo Snapshot, reverseEdge(), changeTarget(), changeSource(), contract()
+ ///haven't been implemented yet.
+ ///
+ class ListUGraph : public ExtendedListUGraphBase {
+ public:
+ typedef ExtendedListUGraphBase Parent;
+ /// \brief Add a new node to the graph.
+ ///
+ /// \return the new node.
+ ///
+ Node addNode() { return Parent::addNode(); }
+
+ /// \brief Add a new edge to the graph.
+ ///
+ /// Add a new edge to the graph with source node \c s
+ /// and target node \c t.
+ /// \return the new undirected edge.
+ UEdge addEdge(const Node& s, const Node& t) {
+ return Parent::addEdge(s, t);
+ }
+ /// \brief Changes the target of \c e to \c n
+ ///
+ /// Changes the target of \c e to \c n
+ ///
+ /// \note The <tt>Edge</tt>'s and <tt>OutEdge</tt>'s
+ /// referencing the changed edge remain
+ /// valid. However <tt>InEdge</tt>'s are invalidated.
+ void changeTarget(UEdge e, Node n) {
+ Parent::changeTarget(e,n);
+ }
+ /// Changes the source of \c e to \c n
+ ///
+ /// Changes the source of \c e to \c n
+ ///
+ ///\note The <tt>Edge</tt>'s and <tt>InEdge</tt>'s
+ ///referencing the changed edge remain
+ ///valid. However <tt>OutEdge</tt>'s are invalidated.
+ void changeSource(UEdge e, Node n) {
+ Parent::changeSource(e,n);
+ }
+ /// \brief Contract two nodes.
+ ///
+ /// This function contracts two nodes.
+ ///
+ /// Node \p b will be removed but instead of deleting
+ /// its neighboring edges, they will be joined to \p a.
+ /// The last parameter \p r controls whether to remove loops. \c true
+ /// means that loops will be removed.
+ ///
+ /// \note The <tt>Edge</tt>s
+ /// referencing a moved edge remain
+ /// valid.
+ void contract(Node a, Node b, bool r = true) {
+ for(IncEdgeIt e(*this, b); e!=INVALID;) {
+ IncEdgeIt f = e; ++f;
+ if (r && runningNode(e) == a) {
+ erase(e);
+ } else if (source(e) == b) {
+ changeSource(e, a);
+ } else {
+ changeTarget(e, a);
+ }
+ e = f;
+ }
+ erase(b);
+ }
+ };
+
+
+ class ListBpUGraphBase {
+ public:
+
+ class NodeSetError : public LogicError {
+ virtual const char* exceptionName() const {
+ return "lemon::ListBpUGraph::NodeSetError";
+ }
+ };
+
+ protected:
+
+ struct NodeT {
+ int first_edge, prev, next;
+ };
+
+ struct UEdgeT {
+ int aNode, prev_out, next_out;
+ int bNode, prev_in, next_in;
+ };
+
+ std::vector<NodeT> aNodes;
+ std::vector<NodeT> bNodes;
+
+ std::vector<UEdgeT> edges;
+
+ int first_anode;
+ int first_free_anode;
+
+ int first_bnode;
+ int first_free_bnode;
+
+ int first_free_edge;
+
+ public:
+
+ class Node {
+ friend class ListBpUGraphBase;
+ protected:
+ int id;
+
+ explicit Node(int _id) : id(_id) {}
+ public:
+ Node() {}
+ Node(Invalid) { id = -1; }
+ bool operator==(const Node i) const {return id==i.id;}
+ bool operator!=(const Node i) const {return id!=i.id;}
+ bool operator<(const Node i) const {return id<i.id;}
+ };
+
+ class UEdge {
+ friend class ListBpUGraphBase;
+ protected:
+ int id;
+
+ explicit UEdge(int _id) { id = _id;}
+ public:
+ UEdge() {}
+ UEdge (Invalid) { id = -1; }
+ bool operator==(const UEdge i) const {return id==i.id;}
+ bool operator!=(const UEdge i) const {return id!=i.id;}
+ bool operator<(const UEdge i) const {return id<i.id;}
+ };
+
+ ListBpUGraphBase()
+ : first_anode(-1), first_free_anode(-1),
+ first_bnode(-1), first_free_bnode(-1),
+ first_free_edge(-1) {}
+
+ void firstANode(Node& node) const {
+ node.id = first_anode != -1 ? (first_anode << 1) : -1;
+ }
+ void nextANode(Node& node) const {
+ node.id = aNodes[node.id >> 1].next;
+ }
+
+ void firstBNode(Node& node) const {
+ node.id = first_bnode != -1 ? (first_bnode << 1) + 1 : -1;
+ }
+ void nextBNode(Node& node) const {
+ node.id = bNodes[node.id >> 1].next;
+ }
+
+ void first(Node& node) const {
+ if (first_anode != -1) {
+ node.id = (first_anode << 1);
+ } else if (first_bnode != -1) {
+ node.id = (first_bnode << 1) + 1;
+ } else {
+ node.id = -1;
+ }
+ }
+ void next(Node& node) const {
+ if (aNode(node)) {
+ node.id = aNodes[node.id >> 1].next;
+ if (node.id == -1) {
+ if (first_bnode != -1) {
+ node.id = (first_bnode << 1) + 1;
+ }
+ }
+ } else {
+ node.id = bNodes[node.id >> 1].next;
+ }
+ }
+
+ void first(UEdge& edge) const {
+ int aNodeId = first_anode;
+ while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
+ aNodeId = aNodes[aNodeId].next != -1 ?
+ aNodes[aNodeId].next >> 1 : -1;
+ }
+ if (aNodeId != -1) {
+ edge.id = aNodes[aNodeId].first_edge;
+ } else {
+ edge.id = -1;
+ }
+ }
+ void next(UEdge& edge) const {
+ int aNodeId = edges[edge.id].aNode >> 1;
+ edge.id = edges[edge.id].next_out;
+ if (edge.id == -1) {
+ aNodeId = aNodes[aNodeId].next != -1 ?
+ aNodes[aNodeId].next >> 1 : -1;
+ while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
+ aNodeId = aNodes[aNodeId].next != -1 ?
+ aNodes[aNodeId].next >> 1 : -1;
+ }
+ if (aNodeId != -1) {
+ edge.id = aNodes[aNodeId].first_edge;
+ } else {
+ edge.id = -1;
+ }
+ }
+ }
+
+ void firstFromANode(UEdge& edge, const Node& node) const {
+ LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
+ edge.id = aNodes[node.id >> 1].first_edge;
+ }
+ void nextFromANode(UEdge& edge) const {
+ edge.id = edges[edge.id].next_out;
+ }
+
+ void firstFromBNode(UEdge& edge, const Node& node) const {
+ LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
+ edge.id = bNodes[node.id >> 1].first_edge;
+ }
+ void nextFromBNode(UEdge& edge) const {
+ edge.id = edges[edge.id].next_in;
+ }
+
+ static int id(const Node& node) {
+ return node.id;
+ }
+ static Node nodeFromId(int id) {
+ return Node(id);
+ }
+ int maxNodeId() const {
+ return aNodes.size() > bNodes.size() ?
+ aNodes.size() * 2 - 2 : bNodes.size() * 2 - 1;
+ }
+
+ static int id(const UEdge& edge) {
+ return edge.id;
+ }
+ static UEdge uEdgeFromId(int id) {
+ return UEdge(id);
+ }
+ int maxUEdgeId() const {
+ return edges.size();
+ }
+
+ static int aNodeId(const Node& node) {
+ return node.id >> 1;
+ }
+ static Node fromANodeId(int id) {
+ return Node(id << 1);
+ }
+ int maxANodeId() const {
+ return aNodes.size();
+ }
+
+ static int bNodeId(const Node& node) {
+ return node.id >> 1;
+ }
+ static Node fromBNodeId(int id) {
+ return Node((id << 1) + 1);
+ }
+ int maxBNodeId() const {
+ return bNodes.size();
+ }
+
+ Node aNode(const UEdge& edge) const {
+ return Node(edges[edge.id].aNode);
+ }
+ Node bNode(const UEdge& edge) const {
+ return Node(edges[edge.id].bNode);
+ }
+
+ static bool aNode(const Node& node) {
+ return (node.id & 1) == 0;
+ }
+
+ static bool bNode(const Node& node) {
+ return (node.id & 1) == 1;
+ }
+
+ Node addANode() {
+ int aNodeId;
+ if (first_free_anode == -1) {
+ aNodeId = aNodes.size();
+ aNodes.push_back(NodeT());
+ } else {
+ aNodeId = first_free_anode;
+ first_free_anode = aNodes[first_free_anode].next;
+ }
+ if (first_anode != -1) {
+ aNodes[aNodeId].next = first_anode << 1;
+ aNodes[first_anode].prev = aNodeId << 1;
+ } else {
+ aNodes[aNodeId].next = -1;
+ }
+ aNodes[aNodeId].prev = -1;
+ first_anode = aNodeId;
+ aNodes[aNodeId].first_edge = -1;
+ return Node(aNodeId << 1);
+ }
+
+ Node addBNode() {
+ int bNodeId;
+ if (first_free_bnode == -1) {
+ bNodeId = bNodes.size();
+ bNodes.push_back(NodeT());
+ } else {
+ bNodeId = first_free_bnode;
+ first_free_bnode = bNodes[first_free_bnode].next;
+ }
+ if (first_bnode != -1) {
+ bNodes[bNodeId].next = (first_bnode << 1) + 1;
+ bNodes[first_bnode].prev = (bNodeId << 1) + 1;
+ } else {
+ bNodes[bNodeId].next = -1;
+ }
+ first_bnode = bNodeId;
+ bNodes[bNodeId].first_edge = -1;
+ return Node((bNodeId << 1) + 1);
+ }
+
+ UEdge addEdge(const Node& source, const Node& target) {
+ LEMON_ASSERT(((source.id ^ target.id) & 1) == 1, NodeSetError());
+ int edgeId;
+ if (first_free_edge != -1) {
+ edgeId = first_free_edge;
+ first_free_edge = edges[edgeId].next_out;
+ } else {
+ edgeId = edges.size();
+ edges.push_back(UEdgeT());
+ }
+ if ((source.id & 1) == 0) {
+ edges[edgeId].aNode = source.id;
+ edges[edgeId].bNode = target.id;
+ } else {
+ edges[edgeId].aNode = target.id;
+ edges[edgeId].bNode = source.id;
+ }
+ edges[edgeId].next_out = aNodes[edges[edgeId].aNode >> 1].first_edge;
+ edges[edgeId].prev_out = -1;
+ if (aNodes[edges[edgeId].aNode >> 1].first_edge != -1) {
+ edges[aNodes[edges[edgeId].aNode >> 1].first_edge].prev_out = edgeId;
+ }
+ aNodes[edges[edgeId].aNode >> 1].first_edge = edgeId;
+ edges[edgeId].next_in = bNodes[edges[edgeId].bNode >> 1].first_edge;
+ edges[edgeId].prev_in = -1;
+ if (bNodes[edges[edgeId].bNode >> 1].first_edge != -1) {
+ edges[bNodes[edges[edgeId].bNode >> 1].first_edge].prev_in = edgeId;
+ }
+ bNodes[edges[edgeId].bNode >> 1].first_edge = edgeId;
+ return UEdge(edgeId);
+ }
+
+ void erase(const Node& node) {
+ if (aNode(node)) {
+ int aNodeId = node.id >> 1;
+ if (aNodes[aNodeId].prev != -1) {
+ aNodes[aNodes[aNodeId].prev >> 1].next = aNodes[aNodeId].next;
+ } else {
+ first_anode = aNodes[aNodeId].next >> 1;
+ }
+ if (aNodes[aNodeId].next != -1) {
+ aNodes[aNodes[aNodeId].next >> 1].prev = aNodes[aNodeId].prev;
+ }
+ aNodes[aNodeId].next = first_free_anode;
+ first_free_anode = aNodeId;
+ } else {
+ int bNodeId = node.id >> 1;
+ if (bNodes[bNodeId].prev != -1) {
+ bNodes[bNodes[bNodeId].prev >> 1].next = bNodes[bNodeId].next;
+ } else {
+ first_bnode = bNodes[bNodeId].next >> 1;
+ }
+ if (bNodes[bNodeId].next != -1) {
+ bNodes[bNodes[bNodeId].next >> 1].prev = bNodes[bNodeId].prev;
+ }
+ bNodes[bNodeId].next = first_free_bnode;
+ first_free_bnode = bNodeId;
+ }
+ }
+
+ void erase(const UEdge& edge) {
+
+ if (edges[edge.id].prev_out != -1) {
+ edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
+ } else {
+ aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
+ }
+ if (edges[edge.id].next_out != -1) {
+ edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;
+ }
+
+ if (edges[edge.id].prev_in != -1) {
+ edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
+ } else {
+ bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
+ }
+ if (edges[edge.id].next_in != -1) {
+ edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;
+ }
+
+ edges[edge.id].next_out = first_free_edge;
+ first_free_edge = edge.id;
+ }
+
+ void clear() {
+ aNodes.clear();
+ bNodes.clear();
+ edges.clear();
+ first_anode = -1;
+ first_free_anode = -1;
+ first_bnode = -1;
+ first_free_bnode = -1;
+ first_free_edge = -1;
+ }
+
+ };
+
+
+ typedef BpUGraphExtender< ListBpUGraphBase > ExtendedListBpUGraphBase;
+
+ /// \ingroup graphs
+ ///
+ /// \brief A smart bipartite undirected graph class.
+ ///
+ /// This is a bipartite undirected graph implementation.
+ /// It is conforms to the \ref concept::ErasableBpUGraph "ErasableBpUGraph"
+ /// concept.
+ /// \sa concept::BpUGraph.
+ ///
+ class ListBpUGraph : public ExtendedListBpUGraphBase {};
+
+
+ /// @}
} //namespace lemon
Modified: hugo/trunk/lemon/min_cut.h
==============================================================================
--- hugo/trunk/lemon/min_cut.h (original)
+++ hugo/trunk/lemon/min_cut.h Fri Jun 30 14:15:45 2006
@@ -23,7 +23,6 @@
/// \brief Maximum cardinality search and min cut in undirected graphs.
#include <lemon/list_graph.h>
-#include <lemon/list_ugraph.h>
#include <lemon/bin_heap.h>
#include <lemon/bucket_heap.h>
@@ -195,7 +194,7 @@
#ifdef DOXYGEN
template <typename _Graph, typename _CapacityMap, typename _Traits>
#else
- template <typename _Graph = ListGraph,
+ template <typename _Graph = ListUGraph,
typename _CapacityMap = typename _Graph::template EdgeMap<int>,
typename _Traits =
MaxCardinalitySearchDefaultTraits<_Graph, _CapacityMap> >
Modified: hugo/trunk/lemon/smart_graph.h
==============================================================================
--- hugo/trunk/lemon/smart_graph.h (original)
+++ hugo/trunk/lemon/smart_graph.h Fri Jun 30 14:15:45 2006
@@ -21,15 +21,17 @@
///\ingroup graphs
///\file
-///\brief SmartGraph class.
+///\brief SmartGraph and SmartUGraph classes.
#include <vector>
#include <lemon/bits/invalid.h>
+#include <lemon/bits/base_extender.h>
#include <lemon/bits/graph_extender.h>
#include <lemon/bits/utility.h>
+#include <lemon/error.h>
#include <lemon/bits/graph_extender.h>
@@ -354,6 +356,261 @@
};
+ /**************** Undirected List Graph ****************/
+
+ typedef UGraphExtender<UndirGraphExtender<SmartGraphBase> >
+ ExtendedSmartUGraphBase;
+
+ /// \ingroup graphs
+ ///
+ /// \brief A smart undirected graph class.
+ ///
+ /// This is a simple and fast undirected graph implementation.
+ /// It is also quite memory efficient, but at the price
+ /// that <b> it does support only limited (only stack-like)
+ /// node and edge deletions</b>.
+ /// Except from this it conforms to
+ /// the \ref concept::UGraph "UGraph" concept.
+ /// \sa concept::UGraph.
+ ///
+ /// \todo Snapshot hasn't been implemented yet.
+ ///
+ class SmartUGraph : public ExtendedSmartUGraphBase {
+ };
+
+
+ class SmartBpUGraphBase {
+ public:
+
+ class NodeSetError : public LogicError {
+ virtual const char* exceptionName() const {
+ return "lemon::SmartBpUGraph::NodeSetError";
+ }
+ };
+
+ protected:
+
+ struct NodeT {
+ int first;
+ NodeT() {}
+ NodeT(int _first) : first(_first) {}
+ };
+
+ struct UEdgeT {
+ int aNode, next_out;
+ int bNode, next_in;
+ };
+
+ std::vector<NodeT> aNodes;
+ std::vector<NodeT> bNodes;
+
+ std::vector<UEdgeT> edges;
+
+ public:
+
+ class Node {
+ friend class SmartBpUGraphBase;
+ protected:
+ int id;
+
+ Node(int _id) : id(_id) {}
+ public:
+ Node() {}
+ Node(Invalid) { id = -1; }
+ bool operator==(const Node i) const {return id==i.id;}
+ bool operator!=(const Node i) const {return id!=i.id;}
+ bool operator<(const Node i) const {return id<i.id;}
+ };
+
+ class UEdge {
+ friend class SmartBpUGraphBase;
+ protected:
+ int id;
+
+ UEdge(int _id) { id = _id;}
+ public:
+ UEdge() {}
+ UEdge (Invalid) { id = -1; }
+ bool operator==(const UEdge i) const {return id==i.id;}
+ bool operator!=(const UEdge i) const {return id!=i.id;}
+ bool operator<(const UEdge i) const {return id<i.id;}
+ };
+
+ void firstANode(Node& node) const {
+ node.id = 2 * aNodes.size() - 2;
+ if (node.id < 0) node.id = -1;
+ }
+ void nextANode(Node& node) const {
+ node.id -= 2;
+ if (node.id < 0) node.id = -1;
+ }
+
+ void firstBNode(Node& node) const {
+ node.id = 2 * bNodes.size() - 1;
+ }
+ void nextBNode(Node& node) const {
+ node.id -= 2;
+ }
+
+ void first(Node& node) const {
+ if (aNodes.size() > 0) {
+ node.id = 2 * aNodes.size() - 2;
+ } else {
+ node.id = 2 * bNodes.size() - 1;
+ }
+ }
+ void next(Node& node) const {
+ node.id -= 2;
+ if (node.id == -2) {
+ node.id = 2 * bNodes.size() - 1;
+ }
+ }
+
+ void first(UEdge& edge) const {
+ edge.id = edges.size() - 1;
+ }
+ void next(UEdge& edge) const {
+ --edge.id;
+ }
+
+ void firstFromANode(UEdge& edge, const Node& node) const {
+ LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
+ edge.id = aNodes[node.id >> 1].first;
+ }
+ void nextFromANode(UEdge& edge) const {
+ edge.id = edges[edge.id].next_out;
+ }
+
+ void firstFromBNode(UEdge& edge, const Node& node) const {
+ LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
+ edge.id = bNodes[node.id >> 1].first;
+ }
+ void nextFromBNode(UEdge& edge) const {
+ edge.id = edges[edge.id].next_in;
+ }
+
+ static int id(const Node& node) {
+ return node.id;
+ }
+ static Node nodeFromId(int id) {
+ return Node(id);
+ }
+ int maxNodeId() const {
+ return aNodes.size() > bNodes.size() ?
+ aNodes.size() * 2 - 2 : bNodes.size() * 2 - 1;
+ }
+
+ static int id(const UEdge& edge) {
+ return edge.id;
+ }
+ static UEdge uEdgeFromId(int id) {
+ return UEdge(id);
+ }
+ int maxUEdgeId() const {
+ return edges.size();
+ }
+
+ static int aNodeId(const Node& node) {
+ return node.id >> 1;
+ }
+ static Node fromANodeId(int id) {
+ return Node(id << 1);
+ }
+ int maxANodeId() const {
+ return aNodes.size();
+ }
+
+ static int bNodeId(const Node& node) {
+ return node.id >> 1;
+ }
+ static Node fromBNodeId(int id) {
+ return Node((id << 1) + 1);
+ }
+ int maxBNodeId() const {
+ return bNodes.size();
+ }
+
+ Node aNode(const UEdge& edge) const {
+ return Node(edges[edge.id].aNode);
+ }
+ Node bNode(const UEdge& edge) const {
+ return Node(edges[edge.id].bNode);
+ }
+
+ static bool aNode(const Node& node) {
+ return (node.id & 1) == 0;
+ }
+
+ static bool bNode(const Node& node) {
+ return (node.id & 1) == 1;
+ }
+
+ Node addANode() {
+ NodeT nodeT;
+ nodeT.first = -1;
+ aNodes.push_back(nodeT);
+ return Node(aNodes.size() * 2 - 2);
+ }
+
+ Node addBNode() {
+ NodeT nodeT;
+ nodeT.first = -1;
+ bNodes.push_back(nodeT);
+ return Node(bNodes.size() * 2 - 1);
+ }
+
+ UEdge addEdge(const Node& source, const Node& target) {
+ LEMON_ASSERT(((source.id ^ target.id) & 1) == 1, NodeSetError());
+ UEdgeT edgeT;
+ if ((source.id & 1) == 0) {
+ edgeT.aNode = source.id;
+ edgeT.bNode = target.id;
+ } else {
+ edgeT.aNode = target.id;
+ edgeT.bNode = source.id;
+ }
+ edgeT.next_out = aNodes[edgeT.aNode >> 1].first;
+ aNodes[edgeT.aNode >> 1].first = edges.size();
+ edgeT.next_in = bNodes[edgeT.bNode >> 1].first;
+ bNodes[edgeT.bNode >> 1].first = edges.size();
+ edges.push_back(edgeT);
+ return UEdge(edges.size() - 1);
+ }
+
+ void clear() {
+ aNodes.clear();
+ bNodes.clear();
+ edges.clear();
+ }
+
+ typedef True NodeNumTag;
+ int nodeNum() const { return aNodes.size() + bNodes.size(); }
+ int aNodeNum() const { return aNodes.size(); }
+ int bNodeNum() const { return bNodes.size(); }
+
+ typedef True EdgeNumTag;
+ int uEdgeNum() const { return edges.size(); }
+
+ };
+
+
+ typedef BpUGraphExtender<SmartBpUGraphBase> ExtendedSmartBpUGraphBase;
+
+ /// \ingroup graphs
+ ///
+ /// \brief A smart bipartite undirected graph class.
+ ///
+ /// This is a simple and fast bipartite undirected graph implementation.
+ /// It is also quite memory efficient, but at the price
+ /// that <b> it does not support node and edge deletions</b>.
+ /// Except from this it conforms to
+ /// the \ref concept::BpUGraph "BpUGraph" concept.
+ /// \sa concept::BpUGraph.
+ ///
+ class SmartBpUGraph : public ExtendedSmartBpUGraphBase {};
+
+
+ /// @}
} //namespace lemon
Modified: hugo/trunk/test/bipartite_matching_test.cc
==============================================================================
--- hugo/trunk/test/bipartite_matching_test.cc (original)
+++ hugo/trunk/test/bipartite_matching_test.cc Fri Jun 30 14:15:45 2006
@@ -2,7 +2,7 @@
#include <iostream>
#include <sstream>
-#include <lemon/list_bpugraph.h>
+#include <lemon/list_graph.h>
#include <lemon/bpugraph_adaptor.h>
#include <lemon/bipartite_matching.h>
Modified: hugo/trunk/test/max_matching_test.cc
==============================================================================
--- hugo/trunk/test/max_matching_test.cc (original)
+++ hugo/trunk/test/max_matching_test.cc Fri Jun 30 14:15:45 2006
@@ -23,7 +23,7 @@
#include <cstdlib>
#include "test_tools.h"
-#include <lemon/list_ugraph.h>
+#include <lemon/list_graph.h>
#include <lemon/max_matching.h>
using namespace std;
Modified: hugo/trunk/test/ugraph_test.cc
==============================================================================
--- hugo/trunk/test/ugraph_test.cc (original)
+++ hugo/trunk/test/ugraph_test.cc Fri Jun 30 14:15:45 2006
@@ -18,9 +18,9 @@
#include <lemon/bits/graph_extender.h>
#include <lemon/concept/ugraph.h>
-#include <lemon/list_ugraph.h>
-#include <lemon/smart_ugraph.h>
-#include <lemon/full_ugraph.h>
+#include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/full_graph.h>
#include <lemon/grid_ugraph.h>
#include <lemon/graph_utils.h>
More information about the Lemon-commits
mailing list