From b1121beb26d3f99094bc4fe9a783f38812e56779 Mon Sep 17 00:00:00 2001 From: Markus Blatt <mblatt@dune-project.org> Date: Wed, 19 Jan 2005 16:09:04 +0000 Subject: [PATCH] Added access to the matrix values (now recognized as weights). Through template parameters arbituary properties can be attached to the vertices and edges, respectively. [[Imported from SVN: r1379]] --- istl/paamg/graph.hh | 868 ++++++++++++++++++++++++++++++++------------ 1 file changed, 636 insertions(+), 232 deletions(-) diff --git a/istl/paamg/graph.hh b/istl/paamg/graph.hh index 7fb1b6445..f6764951e 100644 --- a/istl/paamg/graph.hh +++ b/istl/paamg/graph.hh @@ -4,9 +4,8 @@ #ifndef DUNE_AMG_GRAPH_HH #define DUNE_AMG_GRAPH_HH -#include "link.hh" -#include "node.hh" #include <iostream> + namespace Dune { namespace amg @@ -14,183 +13,415 @@ namespace Dune /** * @defgroup ISTL_PAAMG Parallel Algebraic Multigrid * @ingroup ISTL - * @brief A Parallel Algebraic Multigrid based on Agglomeration - * + * @brief A Parallel Algebraic Multigrid based on Agglomeration. + */ + /** * @addtogroup ISTL_PAAMG * * @{ - * @file + */ + /** @file * @author Markus Blatt * @brief Provides classes for building the matrix graph. * * During the coarsening process in AMG the matrix graph together * with the dependencies, what connections in the graph are considered - * strong or weak, what nodes are isolated, etc., have to build. + * strong or weak, what vertices are isolated, etc., have to build. * This information will be contained in the MatrixGraph class. */ /** - * @brief The matrix graph. + * @brief The weighted matrix graph with properties attached to the vertices + * and edges. * * This class contains information about the graph of a matrix. - * It holds information about the nodes and links in the graph. + * It holds information about the vertices and edges in the graph. + * At each vertex and edge the values of the matrix are represented as + * weights. */ - template<class M> + template<class M, class VP, class EP> class Graph { + private: + /** + * @brief All the edges of a matrix graph. + */ + class Edges + { + public: + typedef const EP* const_iterator; + typedef EP* iterator; + + /** + * @brief Iterator for allocating space for the edge properties. + */ + class BuildIterator + { + public: + /** @brief Constructor. */ + BuildIterator(Edges& edges) + : edges_(edges), currentVertex_(0), noEdges_(0) + { + + if(edges_.vertices_>=0) + edges_.start_[currentVertex_]=noEdges_; + } + /** + * @brief Save Edge information for the current vertex and inkrement iterator. + */ + BuildIterator& operator++() + { + ++currentVertex_; + + if(currentVertex_<edges_.vertices_) + edges_.start_[currentVertex_]=noEdges_; + else{ + edges_.start_[currentVertex_]=noEdges_; + edges_.edges_ = new EP[noEdges_]; + edges_.edgesBuilt_ = true; + } + return *this; + } + + /** + * @brief Set the number of edges for the current vertex. + * @param edges The number of edges. + */ + void setNoEdges(int edges) + { + noEdges_+=edges; + } + + private: + /** @brief The edges we build. */ + Edges& edges_; + /** @brief The current vertex. */ + int currentVertex_; + /** @brief The total number of edges. */ + int noEdges_; + }; + + /** + * @brief Free allocated memory. + */ + void free(); + /** + * @brief Reserve space for edges. + * @param vertices The number of vertices the graph contains. + */ + void reserveVertices(int vertices); + + /** + * @brief Get an iterator for building the edge structure. + * @return An Iterator for building then edge structure. + */ + BuildIterator begin(); + + iterator operator[](int i); + + const_iterator operator[](int i) const; + /** + * @brief Constructor. + */ + Edges(); + + /** + * @brief Destructor. + */ + ~Edges(); + + private: + /** @brief The indices of the first edge for each vertex.*/ + int* start_; + /** @brief All edge properties ordered by source vertices. */ + EP* edges_; + /** @brief True if the edges array is allocated. */ + bool edgesBuilt_; + /** @brief True if the start array is allocated. */ + bool startBuilt_; + /** @brief The number of vertices of the graph. */ + int vertices_; + + }; + public: /** * @brief The type of the matrix we are a graph for. */ typedef M Matrix; - class LinkIterator; + /** + * @brief The type of the weights + */ + typedef typename M::block_type Weight; + + /** + * @brief The type of the properties of the vertices. + */ + typedef VP VertexProperties; + + /** + * @brief The type of the vertex descriptor. + */ + typedef int VertexDescriptor; + + /** + * @brief The type of the properties of the edges. + */ + typedef EP EdgeProperties; + + class EdgeIterator; /** - * @brief Const iterator over the links starting at specific node of the graph. + * @brief Const iterator over the edges starting at specific vertex of the graph. */ - class ConstLinkIterator + class ConstEdgeIterator { - typedef typename Matrix::row_type::ConstIterator RowIterator; - friend class LinkIterator; + typedef typename Matrix::row_type::ConstIterator ColIterator; + friend class EdgeIterator; public: /** - * @brief Constructor an iterator over all links starting from a specific source node. + * @brief Constructor an iterator over all edges starting from a specific source vertex. * - * @param source The index of the source node. - * @param link The link the iterator should point to. + * @param source The index of the source vertex. + * @param edge The edge the iterator should point to. * @param block The corresponding matrix row block. * @param blockEnd Pointer to the end of the matrix row. */ - ConstLinkIterator(int source, const typename Links::const_iterator link, - const RowIterator& block, const RowIterator& blockEnd); + ConstEdgeIterator(VertexDescriptor source, const typename Edges::const_iterator edge, + const ColIterator& block, const ColIterator& blockEnd); - const Link& operator*() const; + ConstEdgeIterator(const EdgeIterator& other); - const Link* operator->() const; + /** + * @brief Access the edge properties + */ + const EdgeProperties& properties() const; + + /** + * @brief Access the edge weight + */ + const Weight& weight() const; /** @brief preincrement operator. */ - ConstLinkIterator& operator++(); + ConstEdgeIterator& operator++(); /** @brief Inequality operator. */ - bool operator!=(const LinkIterator& other) const; + bool operator!=(const EdgeIterator& other) const; /** @brief Inequality operator. */ - bool operator!=(const ConstLinkIterator& other) const; + bool operator!=(const ConstEdgeIterator& other) const; - /** @brief The index of the destination node of the current link. */ - int destination() const; + /** @brief The index of the target vertex of the current edge. */ + VertexDescriptor target() const; private: - /** The current link. */ - typename Links::const_iterator link_; + /** The current edge. */ + typename Edges::const_iterator edge_; /** The matrix row iterator. */ - RowIterator block_; + ColIterator block_; /** End of the matrix row. */ - RowIterator blockEnd_; - /** @brief The source index of the links. */ - int source_; + ColIterator blockEnd_; + /** @brief The source index of the edges. */ + VertexDescriptor source_; }; /** - * @brief Iterator over the links starting at specific node of the graph. + * @brief Iterator over the edges starting at specific vertex of the graph. */ - class LinkIterator + class EdgeIterator { - typedef typename Matrix::row_type::Iterator RowIterator; - friend class ConstLinkIterator; + typedef typename Matrix::row_type::Iterator ColIterator; + friend class ConstEdgeIterator; public: /** - * @brief Constructor an iterator over all links starting from a specific source node. + * @brief Constructor an iterator over all edges starting from a specific source vertex. * - * @param source The index of the source node. - * @param link The link the iterator should point to. + * @param source The index of the source vertex. + * @param edge The edge the iterator should point to. * @param block The corresponding matrix row block. * @param blockEnd Pointer to the end of the matrix row. */ - LinkIterator(int source, const typename Links::iterator link, const RowIterator& block, - const RowIterator& blockEnd); + EdgeIterator(VertexDescriptor source, const typename Edges::iterator edge, const ColIterator& block, + const ColIterator& blockEnd); - Link& operator*() const; + /** + * @brief Access the edge properties. + */ + EdgeProperties& properties() const; - Link* operator->() const; + /** + * @brief Access the edge weight. + */ + Weight& weight() const; /** @brief preincrement operator. */ - LinkIterator& operator++(); + EdgeIterator& operator++(); /** @brief Inequality operator. */ - bool operator!=(const LinkIterator& other) const; + bool operator!=(const EdgeIterator& other) const; /** @brief Inequality operator. */ - bool operator!=(const ConstLinkIterator& other) const; + bool operator!=(const ConstEdgeIterator& other) const; - /** @brief The index of the destination node of the current link. */ - int destination() const; + /** @brief The index of the target vertex of the current edge. */ + VertexDescriptor target() const; private: - /** The current link. */ - typename Links::iterator link_; + /** The current edge. */ + typename Edges::iterator edge_; /** The matrix row iterator. */ - RowIterator block_; + ColIterator block_; /** End of the matrix row. */ - RowIterator blockEnd_; - /** @brief The source index of the links. */ - int source_; + ColIterator blockEnd_; + /** @brief The source of the edges. */ + VertexDescriptor source_; + }; + + class ConstVertexIterator; + + /** + * @brief Iterator over the matrix graph vertices. + * + * Provides access to the vertex indices and iterators + * over the edges starting at each vertex. + */ + class VertexIterator + { + friend class ConstVertexIterator; + + public: + /** + * @brief Constructor. + * + * @param graph Reference to surrounding graph. + * @param currentVertex The current vertex index. + */ + VertexIterator(Graph<M,VP,EP>* graph, VertexDescriptor currentVertex); + + /** @brief Preincrement operator. */ + VertexIterator& operator++(); + + /** @brief Inequality operator. */ + bool operator!=(const VertexIterator& other) const; + + /** @brief Equality operator. */ + bool operator==(const VertexIterator& other) const; + + /** @brief Inequality operator. */ + bool operator!=(const ConstVertexIterator& other) const; + + /** @brief Equality operator. */ + bool operator==(const ConstVertexIterator& other) const; + + /** @brief Access the properties attached to the vertex. */ + VertexProperties& properties() const; + + /** @brief Access the weight of the vertex. */ + Weight& weight() const; + + /** + * @brief Get the descriptor of the current vertex. + * @return The index of the currently referenced vertex. + */ + VertexDescriptor index() const; + + /** + * @brief Get an iterator over all edges starting at the + * current vertex. + * @return Iterator position on the first edge to another vertex. + */ + ConstEdgeIterator begin() const; + + /** + * @brief Get an iterator over all edges starting at the + * current vertex. + * @return Iterator position on the first edge to another vertex. + */ + ConstEdgeIterator end() const; + + private: + /** @brief Reference to the outer graph. */ + Graph<M,VP,EP>* graph_; + /** @brief Current vertex index. */ + VertexDescriptor current_; + }; /** - * @brief Iterator over the matrix graph nodes. + * @brief Const iterator over the matrix graph vertices. * - * Provides access to the node indices and iterators - * over the links starting at each node. + * Provides access to the vertex indices and iterators + * over the edges starting at each vertex. */ - class NodeIterator + class ConstVertexIterator { + friend class VertexIterator; + public: /** * @brief Constructor. * * @param graph Reference to surrounding graph. - * @param currentNode The current node index. + * @param currentVertex The current vertex index. + */ + ConstVertexIterator(const Graph<M,VP,EP>* graph, VertexDescriptor currentVertex); + + /** + * @brief Copy Constructor. + * + * @param other The iterator to copy */ - NodeIterator(const Graph<M>& graph, int currentNode); + ConstVertexIterator(const VertexIterator& other); /** @brief Preincrement operator. */ - NodeIterator& operator++(); + ConstVertexIterator& operator++(); + + /** @brief Inequality operator. */ + bool operator!=(const VertexIterator& other) const; /** @brief Inequality operator. */ - bool operator!=(const NodeIterator& other) const; + bool operator!=(const ConstVertexIterator& other) const; /** @brief Equality operator. */ - bool operator==(const NodeIterator& other) const; + bool operator==(const VertexIterator& other) const; + + /** @brief Equality operator. */ + bool operator==(const ConstVertexIterator& other) const; + + /** @brief Access the properties attached to the vertex. */ + const VertexProperties& properties() const; + + /** @brief Access the weight of the vertex. */ + const Weight& weight() const; /** - * @brief Get the index of the current node. - * @return The index of the currently referenced node. + * @brief Get the descriptor of the current vertex. + * @return The index of the currently referenced vertex. */ - int index() const; + VertexDescriptor index() const; /** - * @brief Get an iterator over all links starting at the - * current node. - * @return Iterator position on the first link to another node. + * @brief Get an iterator over all edges starting at the + * current vertex. + * @return Iterator position on the first edge to another vertex. */ - ConstLinkIterator begin() const; + ConstEdgeIterator begin() const; /** - * @brief Get an iterator over all links starting at the - * current node. - * @return Iterator position on the first link to another node. + * @brief Get an iterator over all edges starting at the + * current vertex. + * @return Iterator position on the first edge to another vertex. */ - ConstLinkIterator end() const; + ConstEdgeIterator end() const; private: /** @brief Reference to the outer graph. */ - const Graph<M>& graph_; - /** @brief Current node index. */ - int current_; + const Graph<M,VP,EP>* graph_; + /** @brief Current vertex index. */ + VertexDescriptor current_; }; /** @@ -223,71 +454,85 @@ namespace Dune const Matrix& matrix() const; /** - * @brief Get an iterator over the links of the node positioned at the first link. - * @param row The index of the matrix row whose links we want. + * @brief Get an iterator over the edges of the vertex positioned at the first edge. + * @param vertex The descriptor of the vertex whose edges we want. */ - ConstLinkIterator beginLinks(int row) const; + ConstEdgeIterator beginEdges(VertexDescriptor vertex) const; /** - * @brief Get an iterator over the links of the node positioned at the first link. - * @param row The index of the matrix row whose links we want. + * @brief Get an iterator over the edges of the vertex positioned at the first edge. + * @param vertex The descriptor of vertex whose edges we want. */ - LinkIterator beginLinks(int row); + EdgeIterator beginEdges(VertexDescriptor vertex); /** - * @brief Get an end iterator over the links of the node. - * @param row The index of the matrix row whose links we want. + * @brief Get an end iterator over the edges of the vertex. + * @param vertex The descriptor of the vertex whose edges we want. */ - ConstLinkIterator endLinks(int row) const; + ConstEdgeIterator endEdges(VertexDescriptor vertex) const; /** - * @brief Get an end iterator over the links of the node. - * @param row The index of the matrix row whose links we want. + * @brief Get an end iterator over the edges of the vertex. + * @param vertex The descriptor of the vertex whose edges we want. */ - LinkIterator endLinks(int row); + EdgeIterator endEdges(VertexDescriptor vertex); /** - * @brief Random access to links in the graph. - * @param source The index of the source node. - * @param destination The index of the destination node. - * @return The link pointing from source to destination. + * @brief Random access to edges in the graph. + * @param source The index of the source vertex. + * @param target The index of the target vertex. + * @return The edge pointing from source to target. */ - Link& operator()(int source, int destination); + EdgeProperties& operator()(VertexDescriptor source, VertexDescriptor target); /** - * @brief Random access to links in the graph. - * @param source The index of the source node. - * @param destination The index of the destination node. - * @return The link pointing from source to destination. + * @brief Random access to edges in the graph. + * @param source The index of the source vertex. + * @param target The index of the target vertex. + * @return The edge pointing from source to target. */ - const Link& operator()(int source, int destination) const; + const EdgeProperties& operator()(VertexDescriptor source, VertexDescriptor target) const; /** - * @brief Random access to the nodes of the graph. - * @param index The index of the node. - * @return The node corresponding to that index. + * @brief Random access to the vertex properties of the graph. + * @param index The index of the vertex. + * @return The properties corresponding to that vertex. */ - Node& operator()(int index); + VertexProperties& operator()(VertexDescriptor index); /** - * @brief Random access to the nodes of the graph. - * @param index The index of the node. - * @return The node corresponding to that index. + * @brief Random access to the vertex properties of the graph. + * @param index The index of the vertex. + * @return The properties corresponding to that vertex. + */ + const VertexProperties& operator()(VertexDescriptor index) const; + /** + * @brief Get iterator over the vertices. + * @retune An iterator over the vertices positioned at the + * first vertex. */ - const Node& operator()(int index) const; + ConstVertexIterator begin() const; + /** - * @brief Get end iterator over the nodes. - * @param A iterator over the nodes positioned at the - * first node. + * @brief Get end iterator over the vertices. + * @return An iterator over the vertices positioned behind the + * last vertex. */ - NodeIterator begin() const; + ConstVertexIterator end() const; /** - * @brief Get end iterator over the nodes. - * @param A iterator over the nodes positioned behind the - * last node. + * @brief Get an iterator over the vertices. + * @return An iterator over the vertices positioned at the + * first vertex. */ - NodeIterator end() const; + VertexIterator begin(); + + /** + * @brief Get end iterator over the vertices. + * @return An iterator over the vertices positioned behind the + * last vertex. + */ + VertexIterator end(); /** * @brief Print the matrix graph. @@ -298,279 +543,438 @@ namespace Dune private: /** @brief the matrix we are a graph for. */ const Matrix* matrix_; - /** @brief The nodes of the graph. */ - Node* nodes_; - /** @brief The number of nodes of the graph. */ - int noNodes_; - /** @brief The links of the graph. */ - Links links_; + /** @brief The vertices of the graph. */ + VertexProperties* vertexProperties_; + /** @brief The number of vertices of the graph. */ + int noVertices_; + /** @brief The edges of the graph. */ + Edges edges_; /** @brief True if the graph is built. */ bool built_; }; - template<class M> - Graph<M>::Graph() - : matrix_(0), nodes_(0), noNodes_(0), built_(false) + template<class M, class VP, class EP> + Graph<M,VP,EP>::Graph() + : matrix_(0), vertexProperties_(0), noVertices_(0), built_(false) {} - template<class M> - inline void Graph<M>::build(const Matrix& matrix) + template<class M, class VP, class EP> + inline void Graph<M,VP,EP>::build(const Matrix& matrix) { - // Setup the links for each node. + // Setup the edges for each vertex. typedef typename Matrix::ConstRowIterator RowIterator; - noNodes_ = matrix.N(); - nodes_ = new Node[matrix.N()]; - links_.reserveNodes(matrix.N()); + noVertices_ = matrix.N(); + vertexProperties_ = new VertexProperties[matrix.N()]; + edges_.reserveVertices(matrix.N()); const RowIterator end = matrix.end(); - typename Links::BuildIterator linkBuilder = links_.begin(); + typename Edges::BuildIterator edgeBuilder = edges_.begin(); - for(RowIterator row = matrix.begin(); row != end; ++row,++linkBuilder) { - linkBuilder.setNoLinks(row->size()-1); + for(RowIterator row = matrix.begin(); row != end; ++row,++edgeBuilder) { + edgeBuilder.setNoEdges(row->size()); } matrix_ = &matrix; } - template<class M> - inline void Graph<M>::free() + template<class M, class VP, class EP> + inline void Graph<M,VP,EP>::free() { - delete[] nodes_; - links_.free(); + delete[] vertexProperties_; + edges_.free(); matrix_ = 0; - noNodes_ = 0; + noVertices_ = 0; built_=false; } - template<class M> - Graph<M>::~Graph() + template<class M, class VP, class EP> + Graph<M,VP,EP>::~Graph() { if(built_) free(); } - template<class M> - inline const M& Graph<M>::matrix() const + template<class M, class VP, class EP> + inline const M& Graph<M,VP,EP>::matrix() const { return *matrix_; } - template<class M> - inline typename Graph<M>::ConstLinkIterator Graph<M>::beginLinks(int row) const + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::ConstEdgeIterator Graph<M,VP,EP>::beginEdges(VertexDescriptor row) const { - return ConstLinkIterator(row, links_[row], matrix_[row].begin(), matrix_[row].end()); + return ConstEdgeIterator(row, edges_[row], matrix_[row].begin(), matrix_[row].end()); } - template<class M> - inline typename Graph<M>::ConstLinkIterator Graph<M>::endLinks(int row) const + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::ConstEdgeIterator Graph<M,VP,EP>::endEdges(VertexDescriptor row) const { - return ConstLinkIterator(row, links_[row+1], matrix_[row].end(), matrix_[row].end()); + return ConstEdgeIterator(row, edges_[row+1], matrix_[row].end(), matrix_[row].end()); } - template<class M> - inline typename Graph<M>::LinkIterator Graph<M>::beginLinks(int row) + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::EdgeIterator Graph<M,VP,EP>::beginEdges(VertexDescriptor row) { - return LinkIterator(row, links_[row], matrix_[row].begin(), matrix_[row].end()); + return EdgeIterator(row, edges_[row], matrix_[row].begin(), matrix_[row].end()); } - template<class M> - inline typename Graph<M>::LinkIterator Graph<M>::endLinks(int row) + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::EdgeIterator Graph<M,VP,EP>::endEdges(VertexDescriptor row) { - return LinkIterator(row, links_[row+1], matrix_[row].end(), matrix_[row].end()); + return EdgeIterator(row, edges_[row+1], matrix_[row].end(), matrix_[row].end()); } - template<class M> - inline Link& Graph<M>::operator()(int source, int destination) + template<class M, class VP, class EP> + inline EP& Graph<M,VP,EP>::operator()(VertexDescriptor source, VertexDescriptor target) { - return links_[source] + matrix[source].find(destination)-matrix[source].begin(); + return edges_[source] + matrix[source].find(target).offset(); } - template<class M> - inline const Link& Graph<M>::operator()(int source, int destination) const + template<class M, class VP, class EP> + inline const EP& Graph<M,VP,EP>::operator()(VertexDescriptor source, VertexDescriptor target) const { - return links_[source] + matrix[source].find(destination)-matrix[source].begin(); + return edges_[source] + matrix[source].find(target).offset(); } - template<class M> - inline Graph<M>::ConstLinkIterator::ConstLinkIterator(int source, const typename Links::const_iterator link, - const RowIterator& block, const RowIterator& blockEnd) : - link_(link), block_(block), blockEnd_(blockEnd), source_(source) + template<class M, class VP, class EP> + inline Graph<M,VP,EP>::ConstEdgeIterator::ConstEdgeIterator(VertexDescriptor source, const typename Edges::const_iterator edge, + const ColIterator& block, const ColIterator& blockEnd) : + edge_(edge), block_(block), blockEnd_(blockEnd), source_(source) { if(block_!=blockEnd_ && block.index() == source_) { + // This is the diagonal and not a edge. Skip it. ++block_; - }else{ - int i=source_; - i+=5; + ++edge_; } } - template<class M> - inline const Link& Graph<M>::ConstLinkIterator::operator*() const + template<class M, class VP, class EP> + inline Graph<M,VP,EP>::ConstEdgeIterator::ConstEdgeIterator(const EdgeIterator& other) + : edge_(other.edge_), block_(other.block_), source_(other.source_) + {} + + template<class M, class VP, class EP> + inline const EP & Graph<M,VP,EP>::ConstEdgeIterator::properties() const { - return *link_; + return *edge_; } - template<class M> - inline const Link* Graph<M>::ConstLinkIterator::operator->() const + template<class M, class VP, class EP> + inline const typename M::block_type& Graph<M,VP,EP>::ConstEdgeIterator::weight() const { - return link_; + return *block_; } - template<class M> - inline typename Graph<M>::ConstLinkIterator& Graph<M>::ConstLinkIterator::operator++() + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::ConstEdgeIterator& Graph<M,VP,EP>::ConstEdgeIterator::operator++() { ++block_; - ++link_; + ++edge_; if(block_!=blockEnd_ && block_.index() == source_) { + // This is the edge from the diagonal to the diagonal. Skip it. ++block_; + ++edge_; } return *this; } - template<class M> - inline bool Graph<M>::ConstLinkIterator::operator!=(const Graph<M>::LinkIterator& other) const + template<class M, class VP, class EP> + inline bool Graph<M,VP,EP>::ConstEdgeIterator::operator!=(const Graph<M,VP,EP>::EdgeIterator& other) const { return block_!=other.block_; } - template<class M> - inline bool Graph<M>::ConstLinkIterator::operator!=(const Graph<M>::ConstLinkIterator& other) const + template<class M, class VP, class EP> + inline bool Graph<M,VP,EP>::ConstEdgeIterator::operator!=(const Graph<M,VP,EP>::ConstEdgeIterator& other) const { return block_!=other.block_; } - template<class M> - inline int Graph<M>::ConstLinkIterator::destination() const + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::VertexDescriptor Graph<M,VP,EP>::ConstEdgeIterator::target() const { return block_.index(); } - template<class M> - inline Graph<M>::LinkIterator::LinkIterator(int source, const typename Links::iterator link, - const RowIterator& block, const RowIterator& blockEnd) : - link_(link), block_(block), blockEnd_(blockEnd), source_(source) + template<class M, class VP, class EP> + inline Graph<M,VP,EP>::EdgeIterator::EdgeIterator(VertexDescriptor source, const typename Edges::iterator edge, + const ColIterator& block, const ColIterator& blockEnd) : + edge_(edge), block_(block), blockEnd_(blockEnd), source_(source) { if(block_!=blockEnd_ && block->index() == source_) { + // This is the edge from the diagonal to the diagonal. Skip it. ++block_; + ++edge_; } } - template<class M> - inline Link& Graph<M>::LinkIterator::operator*() const + template<class M, class VP, class EP> + inline EP & Graph<M,VP,EP>::EdgeIterator::properties() const { - return *link_; + return *edge_; } - template<class M> - inline Link* Graph<M>::LinkIterator::operator->() const + template<class M, class VP, class EP> + inline typename M::block_type& Graph<M,VP,EP>::EdgeIterator::weight() const { - return link_; + return *block_; } - template<class M> - inline typename Graph<M>::LinkIterator& Graph<M>::LinkIterator::operator++() + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::EdgeIterator& Graph<M,VP,EP>::EdgeIterator::operator++() { ++block_; - ++link_; + ++edge_; if(block_!=blockEnd_ && block_->index() == source_) { + // This is the edge from the diagonal to the diagonal. Skip it. ++block_; } return *this; } - template<class M> - inline bool Graph<M>::LinkIterator::operator!=(const Graph<M>::ConstLinkIterator& other) const + template<class M, class VP, class EP> + inline bool Graph<M,VP,EP>::EdgeIterator::operator!=(const Graph<M,VP,EP>::ConstEdgeIterator& other) const { return block_!=other.block_; } - template<class M> - inline bool Graph<M>::LinkIterator::operator!=(const Graph<M>::LinkIterator& other) const + template<class M, class VP, class EP> + inline bool Graph<M,VP,EP>::EdgeIterator::operator!=(const Graph<M,VP,EP>::EdgeIterator& other) const { return block_!=other.block_; } - template<class M> - inline int Graph<M>::LinkIterator::destination() const + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::VertexDescriptor Graph<M,VP,EP>::EdgeIterator::target() const { return block_->index(); } - template<class M> - inline void Graph<M>::print(std::ostream& os) const + template<class M, class VP, class EP> + inline void Graph<M,VP,EP>::print(std::ostream& os) const { - for(NodeIterator node = begin(); node!=end(); ++node) { - const ConstLinkIterator endLink = node.end(); - os<<"Links starting from Node "<<node.index()<<" to nodes "; + for(ConstVertexIterator vertex = begin(); vertex!=end(); ++vertex) { + const ConstEdgeIterator endEdge = vertex.end(); + os<<"Edges starting from Vertex "<<vertex.index()<<" (weight="<<vertex.weight()<<", properties="<<vertex.properties()<<") to vertices "; - for(ConstLinkIterator link = node.begin(); link != endLink; ++link) - os<<link.destination()<<" "; + for(ConstEdgeIterator edge = vertex.begin(); edge != endEdge; ++edge) + os<<edge.target()<<" (weight="<<edge.weight()<<", properties="<<edge.properties()<<"), "; os<<std::endl; } } - template<class M> - inline typename Graph<M>::NodeIterator Graph<M>::begin() const + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::ConstVertexIterator Graph<M,VP,EP>::begin() const + { + return ConstVertexIterator(this, 0); + } + + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::ConstVertexIterator Graph<M,VP,EP>::end() const + { + return ConstVertexIterator(this, noVertices_); + } + + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::VertexIterator Graph<M,VP,EP>::begin() + { + return VertexIterator(this, 0); + } + + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::VertexIterator Graph<M,VP,EP>::end() + { + return VertexIterator(this, noVertices_); + } + + template<class M, class VP, class EP> + inline Graph<M,VP,EP>::VertexIterator::VertexIterator(Graph<M,VP,EP>* graph, VertexDescriptor current) + : graph_(graph), current_(current) + {} + + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::VertexIterator& Graph<M,VP,EP>::VertexIterator::operator++() + { + ++current_; + return *this; + } + + template<class M, class VP, class EP> + inline VP & Graph<M,VP,EP>::VertexIterator::properties() const + { + return graph_->vertexProperties_[current_]; + } + + template<class M, class VP, class EP> + inline typename M::block_type& Graph<M,VP,EP>::VertexIterator::weight() const + { + return graph_->matrix()[current_][current_]; + } + + template<class M, class VP, class EP> + inline bool Graph<M,VP,EP>::VertexIterator::operator!=(const VertexIterator& other) const + { + return current_!=other.current_; + } + + template<class M, class VP, class EP> + inline bool Graph<M,VP,EP>::VertexIterator::operator==(const VertexIterator& other) const + { + return current_==other.current_; + } + + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::VertexDescriptor Graph<M,VP,EP>::VertexIterator::index() const { - return NodeIterator(*this, 0); + return current_; } - template<class M> - inline typename Graph<M>::NodeIterator Graph<M>::end() const + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::ConstEdgeIterator Graph<M,VP,EP>::VertexIterator::begin() const { - return NodeIterator(*this, noNodes_); + return ConstEdgeIterator(current_, graph_->edges_[current_], + graph_->matrix()[current_].begin(), graph_->matrix()[current_].end()); } - template<class M> - inline Graph<M>::NodeIterator::NodeIterator(const Graph<M>& graph, int current) + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::ConstEdgeIterator Graph<M,VP,EP>::VertexIterator::end() const + { + return ConstEdgeIterator(current_, graph_->edges_[current_+1], + graph_->matrix()[current_].end(), graph_->matrix()[current_].end()); + } + + template<class M, class VP, class EP> + inline Graph<M,VP,EP>::ConstVertexIterator::ConstVertexIterator(const Graph<M,VP,EP>* graph, VertexDescriptor current) : graph_(graph), current_(current) {} - template<class M> - inline typename Graph<M>::NodeIterator& Graph<M>::NodeIterator::operator++() + template<class M, class VP, class EP> + inline Graph<M,VP,EP>::ConstVertexIterator::ConstVertexIterator(const VertexIterator& other) + : graph_(other.graph_), current_(other.current_) + {} + + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::ConstVertexIterator& Graph<M,VP,EP>::ConstVertexIterator::operator++() { ++current_; return *this; } - template<class M> - inline bool Graph<M>::NodeIterator::operator!=(const NodeIterator& other) const + template<class M, class VP, class EP> + inline const VP & Graph<M,VP,EP>::ConstVertexIterator::properties() const + { + return graph_->vertexProperties_[current_]; + } + + template<class M, class VP, class EP> + inline const typename M::block_type& Graph<M,VP,EP>::ConstVertexIterator::weight() const + { + return graph_->matrix()[current_][current_]; + } + + template<class M, class VP, class EP> + inline bool Graph<M,VP,EP>::ConstVertexIterator::operator!=(const VertexIterator& other) const + { + assert(graph_==other.graph_); + return current_!=other.current_; + } + + template<class M, class VP, class EP> + inline bool Graph<M,VP,EP>::ConstVertexIterator::operator!=(const ConstVertexIterator& other) const { + assert(graph_==other.graph_); return current_!=other.current_; } + template<class M, class VP, class EP> + inline bool Graph<M,VP,EP>::ConstVertexIterator::operator==(const VertexIterator& other) const + { + assert(graph_==other.graph_); + return current_==other.current_; + } - template<class M> - inline bool Graph<M>::NodeIterator::operator==(const NodeIterator& other) const + template<class M, class VP, class EP> + inline bool Graph<M,VP,EP>::ConstVertexIterator::operator==(const ConstVertexIterator& other) const { + assert(graph_==other.graph_); return current_==other.current_; } - template<class M> - inline int Graph<M>::NodeIterator::index() const + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::VertexDescriptor Graph<M,VP,EP>::ConstVertexIterator::index() const { return current_; } - template<class M> - inline typename Graph<M>::ConstLinkIterator Graph<M>::NodeIterator::begin() const + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::ConstEdgeIterator Graph<M,VP,EP>::ConstVertexIterator::begin() const + { + return ConstEdgeIterator(current_, graph_->edges_[current_], + graph_->matrix()[current_].begin(), graph_->matrix()[current_].end()); + } + + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::ConstEdgeIterator Graph<M,VP,EP>::ConstVertexIterator::end() const { - return ConstLinkIterator(current_, graph_.links_[current_], - graph_.matrix()[current_].begin(), graph_.matrix()[current_].end()); + return ConstEdgeIterator(current_, graph_->edges_[current_+1], + graph_->matrix()[current_].end(), graph_->matrix()[current_].end()); } - template<class M> - inline typename Graph<M>::ConstLinkIterator Graph<M>::NodeIterator::end() const + template<class M, class VP, class EP> + inline Graph<M,VP,EP>::Edges::Edges() + : start_(), edges_(), edgesBuilt_(false), startBuilt_(false), vertices_(-1) + {} + + template<class M, class VP, class EP> + inline void Graph<M,VP,EP>::Edges::free() { - return ConstLinkIterator(current_, graph_.links_[current_+1], - graph_.matrix()[current_].end(), graph_.matrix()[current_].end()); + if(edgesBuilt_) + delete[] edges_; + if(startBuilt_) + delete[] start_; + edgesBuilt_ = false; + startBuilt_ = false; + vertices_=-1; } + template<class M, class VP, class EP> + inline void Graph<M,VP,EP>::Edges::reserveVertices(int vertices) + { + vertices_=vertices; + start_ = new int[vertices_+1]; + startBuilt_ = true; + } + template<class M, class VP, class EP> + inline typename Graph<M,VP,EP>::Edges::BuildIterator Graph<M,VP,EP>::Edges::begin() + { + return BuildIterator(*this); + } + + template<class M, class VP, class EP> + inline EP* Graph<M,VP,EP>::Edges::operator[](int i) + { + return edges_+start_[i]; + } + + template<class M, class VP, class EP> + inline const EP* Graph<M,VP,EP>::Edges::operator[](int i) const + { + return edges_+start_[i]; + } + + template<class M, class VP, class EP> + inline Graph<M,VP,EP>::Edges::~Edges() + { + if(startBuilt_) + delete[] start_; + if(edgesBuilt_) + delete[] edges_; + } /** @} */ } } -- GitLab