2885: Introduce a dual graph class.

* mln/core/concept/graph.hh: does not force add_* methods. * mln/util/dual_graph.hh: new class. * mln/util/graph.hh: cleanup comments * mln/util/internal/graph_edge.hh: add missing operator<<. * mln/util/internal/graph_nbh_iter_base.hh, * mln/util/internal/graph_iter_base.hh: add operator unsigned(). * tests/util/Makefile.am, * tests/util/dual_graph.cc: Add a new test. --- milena/ChangeLog | 18 ++ milena/mln/core/concept/graph.hh | 2 - milena/mln/util/{graph.hh => dual_graph.hh} | 243 +++++++++++------------ milena/mln/util/graph.hh | 14 +- milena/mln/util/internal/graph_edge.hh | 19 ++- milena/mln/util/internal/graph_iter_base.hh | 11 + milena/mln/util/internal/graph_nbh_iter_base.hh | 10 + milena/tests/util/Makefile.am | 2 + milena/tests/util/dual_graph.cc | 164 +++++++++++++++ 9 files changed, 338 insertions(+), 145 deletions(-) copy milena/mln/util/{graph.hh => dual_graph.hh} (58%) create mode 100644 milena/tests/util/dual_graph.cc diff --git a/milena/ChangeLog b/milena/ChangeLog index c947990..809f727 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,21 @@ +2008-11-17 Guillaume Lazzara <guillaume.lazzara@lrde.epita.fr> + + Introduce a dual graph class. + + * mln/core/concept/graph.hh: does not force add_* methods. + + * mln/util/dual_graph.hh: new class. + + * mln/util/graph.hh: cleanup comments + + * mln/util/internal/graph_edge.hh: add missing operator<<. + + * mln/util/internal/graph_nbh_iter_base.hh, + * mln/util/internal/graph_iter_base.hh: add operator unsigned(). + + * tests/util/Makefile.am, + * tests/util/dual_graph.cc: Add a new test. + 2008-11-14 Thierry Geraud <thierry.geraud@lrde.epita.fr> Factor code for erosion on lines. diff --git a/milena/mln/core/concept/graph.hh b/milena/mln/core/concept/graph.hh index c98d9e5..e89acc2 100644 --- a/milena/mln/core/concept/graph.hh +++ b/milena/mln/core/concept/graph.hh @@ -113,8 +113,6 @@ namespace mln m1 = 0; unsigned (E::*m2)(unsigned id_e, unsigned id_v) const = & E::v_other; m2 = 0; - unsigned (E::*m3)() = & E::add_vertex; - m3 = 0; size_t (E::*m4)() const = & E::v_nmax; m4 = 0; bool (E::*m5)(unsigned id_v) const = & E::has_v; diff --git a/milena/mln/util/graph.hh b/milena/mln/util/dual_graph.hh similarity index 58% copy from milena/mln/util/graph.hh copy to milena/mln/util/dual_graph.hh index dfcbc23..3533e7c 100644 --- a/milena/mln/util/graph.hh +++ b/milena/mln/util/dual_graph.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// Copyright (C) 2008 EPITA Research and Development Laboratory // (LRDE) // // This file is part of the Olena Library. This library is free @@ -26,10 +26,10 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_UTIL_GRAPH_HH -# define MLN_UTIL_GRAPH_HH +#ifndef MLN_UTIL_DUAL_GRAPH_HH +# define MLN_UTIL_DUAL_GRAPH_HH -/// \file mln/util/graph.hh +/// \file mln/util/dual_graph.hh /// Definitions of undirected graphs. # include <mln/util/internal/graph_base.hh> @@ -43,7 +43,8 @@ namespace mln namespace util { /// Fwd declaration. - class graph; + template <typename G> + class dual_graph; } @@ -51,23 +52,22 @@ namespace mln { /// Data structure for \c mln::image2d<T>. - template <> - struct data<util::graph> + template <typename G> + struct data< util::dual_graph<G> > { - typedef util::graph G; + typedef std::vector<std::vector<unsigned> > vertices_t; typedef std::vector<util::ord_pair<unsigned> > edges_t; - typedef std::set<util::ord_pair<unsigned> > edges_set_t; data(); + data(const G& g); ~data(); + G g_; /// The vertices. vertices_t vertices_; /// The edges. edges_t edges_; - /// An index of the set of edges, for fast-access purpose. - edges_set_t edges_set_; }; } // end of namespace mln::internal @@ -76,14 +76,18 @@ namespace mln namespace util { - /// \brief Undirected graph. - class graph : public internal::graph_base<graph> + /// Undirected dual graph of a graph of type \tparam G. + template <typename G> + class dual_graph : public internal::graph_base< dual_graph<G> > { /// The super class. - typedef internal::graph_base<graph> super; + typedef internal::graph_base< dual_graph<G> > super; - using super::vertex_data_t; - using super::edge_data_t; + typedef typename super::vertex_t vertex_t; + typedef typename super::edge_t edge_t; + + typedef typename super::vertex_data_t vertex_data_t; + typedef typename super::edge_data_t edge_data_t; public: /// The type of the set of vertices. @@ -91,71 +95,46 @@ namespace mln /// The type of the set of edges. typedef std::vector<edge_data_t> edges_t; - /// A set to test the presence of a given edge. - typedef std::set<edge_data_t> edges_set_t; /// Iterator types /// \{ /// Vertex iterators /// \{ - typedef mln::internal::vertex_fwd_iterator<graph> vertex_fwd_iter; - typedef mln::internal::vertex_bkd_iterator<graph> vertex_bkd_iter; + typedef mln::internal::vertex_fwd_iterator< dual_graph<G> > + vertex_fwd_iter; + typedef mln::internal::vertex_bkd_iterator< dual_graph<G> > + vertex_bkd_iter; typedef vertex_fwd_iter vertex_iter; - /// \} - /// Vertex centered edge iterators - /// \{ - typedef mln::internal::vertex_nbh_edge_fwd_iterator<graph> vertex_nbh_edge_fwd_iter; - typedef mln::internal::vertex_nbh_edge_bkd_iterator<graph> vertex_nbh_edge_bkd_iter; - typedef vertex_nbh_edge_fwd_iter vertex_nbh_edge_iter; - /// \} - - /// Vertex centered vertex iterators - /// \{ - typedef mln::internal::vertex_nbh_vertex_fwd_iterator<graph> vertex_nbh_vertex_fwd_iter; - typedef mln::internal::vertex_nbh_vertex_bkd_iterator<graph> vertex_nbh_vertex_bkd_iter; - typedef vertex_nbh_vertex_fwd_iter vertex_nbh_vertex_iter; - /// \} - - /// Edge iterators - /// \{ - typedef mln::internal::edge_fwd_iterator<graph> edge_fwd_iter; - typedef mln::internal::edge_bkd_iterator<graph> edge_bkd_iter; + typedef mln::internal::edge_fwd_iterator< dual_graph<G> > + edge_fwd_iter; + typedef mln::internal::edge_bkd_iterator< dual_graph<G> > + edge_bkd_iter; typedef edge_fwd_iter edge_iter; - /// \} - /// Edge centered edge iterators. - /// \{ - typedef mln::internal::edge_nbh_edge_fwd_iterator<graph> edge_nbh_edge_fwd_iter; - typedef mln::internal::edge_nbh_edge_bkd_iterator<graph> edge_nbh_edge_bkd_iter; - typedef edge_nbh_edge_fwd_iter edge_nbh_edge_iter; /// \} /// \} - graph(); + dual_graph(); + dual_graph(const G& g); /// Vertex oriented. /// \{ /// Shortcuts factoring the insertion of vertices and edges. /// \{ - /// \brief Add a vertex. - /// - /// \return The id of the new vertex. - unsigned add_vertex(); - /// Return the vertex whose id is \a v. /// \{ vertex_t vertex(unsigned id_v) const; /// \} - /// \brief Return the number of vertices in the graph. + /// Return the number of vertices in the graph. size_t v_nmax() const; /// Check whether a vertex id \p id_v exists in the graph. bool has_v(unsigned id_v) const; /// Check whether an edge \p v exists in the graph. - template <typename G> - bool has_v(const util::vertex<G>& v) const; + template <typename G2> + bool has_v(const util::vertex<G2>& v) const; /// Return the number of adjacent edges of vertex \p id_v. @@ -176,23 +155,17 @@ namespace mln /// Edge oriented. /// \{ - /// \brief Add an edge. - /// - /// \return The id of the new edge if it does not exist yet; - /// otherwise, return <tt>mln_max(unsigned)</tt>. - unsigned add_edge(unsigned id_v1, unsigned id_v2); - /// Return the edge whose id is \a e. edge_t edge(unsigned e) const; - /// \brief Return the number of edges in the graph. + /// Return the number of edges in the graph. size_t e_nmax() const; /// Return whether \p id_e is in the graph. bool has_e(unsigned id_e) const; /// Return whether \p e is in the graph. - template <typename G> - bool has_e(const util::edge<G>& e) const; + template <typename G2> + bool has_e(const util::edge<G2>& e) const; /// Return the first vertex associated to the edge \p id_e. @@ -213,6 +186,8 @@ namespace mln bool is_subgraph_of(const G2& g) const; /// \} + protected: + using super::data_; }; } // end of namespace mln::util @@ -227,13 +202,32 @@ namespace mln namespace internal { + template <typename G> inline - data<util::graph>::data() + data< util::dual_graph<G> >::data() { } + template <typename G> inline - data<util::graph>::~data() + data< util::dual_graph<G> >::data(const G& g) + { + g_ = g; + vertices_.resize(g.e_nmax()); + mln_edge_iter(G) e(g); + mln_edge_nbh_edge_iter(G) ne(e); + + for_all(e) + for_all(ne) + { + vertices_[e].push_back(edges_.size()); + edges_.push_back(util::ord_pair<unsigned>(e, ne)); + } + } + + template <typename G> + inline + data< util::dual_graph<G> >::~data() { } @@ -242,69 +236,73 @@ namespace mln namespace util { + template <typename G> inline - graph::graph() + dual_graph<G>::dual_graph() { - this->data_ = new mln::internal::data<util::graph>(); + this->data_ = new mln::internal::data< util::dual_graph<G> >(); } - /*---------------. - | Vertex related | - `---------------*/ - + template <typename G> inline - unsigned - graph::add_vertex() + dual_graph<G>::dual_graph(const G& g) { - /* FIXME: This is not thread-proof (these two lines should - form an atomic section). */ - data_->vertices_.resize(data_->vertices_.size() + 1); - - return v_nmax() - 1; + this->data_ = new mln::internal::data< util::dual_graph<G> >(g); } + /*---------------. + | Vertex related | + `---------------*/ + + template <typename G> inline - graph::vertex_t - graph::vertex(unsigned id_v) const + typename dual_graph<G>::vertex_t + dual_graph<G>::vertex(unsigned id_v) const { mln_assertion(has_v(id_v)); return vertex_t(*this, id_v); } + template <typename G> inline size_t - graph::v_nmax() const + dual_graph<G>::v_nmax() const { - return data_->vertices_.size(); + return data_->g_.e_nmax(); } + template <typename G> inline bool - graph::has_v(unsigned id_v) const + dual_graph<G>::has_v(unsigned id_v) const { - return id_v < data_->vertices_.size(); + return data_->g_.has_e(id_v); } template <typename G> + template <typename G2> inline bool - graph::has_v(const util::vertex<G>& v) const + dual_graph<G>::has_v(const util::vertex<G2>& v) const { + //FIXME: not sure... return v.graph().is_subgraph_of(*this) && has_v(v.id()); } + template <typename G> inline size_t - graph::v_nmax_nbh_edges(unsigned id_v) const + dual_graph<G>::v_nmax_nbh_edges(unsigned id_v) const { mln_precondition(has_v(id_v)); - return data_->vertices_[id_v].size(); + return data_->g_.e_nmax_nbh_edges(id_v); } + template <typename G> inline unsigned - graph::v_ith_nbh_edge(unsigned id_v, unsigned i) const + dual_graph<G>::v_ith_nbh_edge(unsigned id_v, unsigned i) const { mln_precondition(has_v(id_v)); if (i >= v_nmax_nbh_edges(id_v)) @@ -312,22 +310,24 @@ namespace mln return data_->vertices_[id_v][i]; } + template <typename G> inline size_t - graph::v_nmax_nbh_vertices(unsigned id_v) const + dual_graph<G>::v_nmax_nbh_vertices(unsigned id_v) const { mln_precondition(has_v(id_v)); return v_nmax_nbh_edges(id_v); } + template <typename G> inline unsigned - graph::v_ith_nbh_vertex(unsigned id_v, unsigned i) const + dual_graph<G>::v_ith_nbh_vertex(unsigned id_v, unsigned i) const { mln_precondition(has_v(id_v)); - unsigned id_e = v_ith_nbh_edge(id_v, i); - return v_other(id_e, id_v); + unsigned id_e = this->v_ith_nbh_edge(id_v, i); + return this->v_other(id_e, id_v); } @@ -335,91 +335,71 @@ namespace mln | Edges related | `---------------*/ + template <typename G> inline - unsigned - graph::add_edge(unsigned id_v1, unsigned id_v2) - { - // Does this edge already exist in the graph? - edge_data_t edge(id_v1, id_v2); - if (data_->edges_set_.find(edge) != data_->edges_set_.end ()) - { - // Return the erroneous value. - return mln_max(unsigned); - } - else - { - // Otherwise insert it into the graph. - /* FIXME: This is not thread-proof (these two lines should - form an atomic section). */ - data_->edges_.push_back(edge); - unsigned id = data_->edges_.size() - 1; - - // Update the set of edges. - data_->edges_set_.insert(edge); - data_->vertices_[edge.first()].push_back(id); - data_->vertices_[edge.second()].push_back(id); - - return id; - } - } - - inline - graph::edge_t - graph::edge(unsigned e) const + typename dual_graph<G>::edge_t + dual_graph<G>::edge(unsigned e) const { mln_assertion(e < e_nmax()); return edge_t(*this, e); } + template <typename G> inline size_t - graph::e_nmax() const + dual_graph<G>::e_nmax() const { return data_->edges_.size(); } + template <typename G> inline bool - graph::has_e(unsigned id_e) const + dual_graph<G>::has_e(unsigned id_e) const { return id_e < data_->edges_.size(); } template <typename G> + template <typename G2> inline bool - graph::has_e(const util::edge<G>& e) const + dual_graph<G>::has_e(const util::edge<G2>& e) const { return e.graph().is_subgraph_of(*this) && has_e(e.id()); } + template <typename G> inline unsigned - graph::v1(unsigned id_e) const + dual_graph<G>::v1(unsigned id_e) const { mln_precondition(has_e(id_e)); return data_->edges_[id_e].first(); } + template <typename G> inline unsigned - graph::v2(unsigned id_e) const + dual_graph<G>::v2(unsigned id_e) const { mln_precondition(has_e(id_e)); return data_->edges_[id_e].second(); } + template <typename G> inline size_t - graph::e_nmax_nbh_edges(unsigned id_e) const + dual_graph<G>::e_nmax_nbh_edges(unsigned id_e) const { mln_precondition(has_e(id_e)); return v_nmax_nbh_edges(v1(id_e)) + v_nmax_nbh_edges(v2(id_e)); } + template <typename G> inline unsigned - graph::e_ith_nbh_edge(unsigned id_e, unsigned i) const + dual_graph<G>::e_ith_nbh_edge(unsigned id_e, unsigned i) const { mln_precondition(has_e(id_e)); if (i >= e_nmax_nbh_edges(id_e)) @@ -432,10 +412,11 @@ namespace mln } + template <typename G> template <typename G2> inline bool - graph::is_subgraph_of(const G2& g) const + dual_graph<G>::is_subgraph_of(const G2& g) const { return g.graph_id() == this->graph_id(); } @@ -447,4 +428,4 @@ namespace mln # endif // ! MLN_INCLUDE_ONLY -#endif // ! MLN_UTIL_GRAPH_HH +#endif // ! MLN_UTIL_DUAL_GRAPH_HH diff --git a/milena/mln/util/graph.hh b/milena/mln/util/graph.hh index dfcbc23..30b19bd 100644 --- a/milena/mln/util/graph.hh +++ b/milena/mln/util/graph.hh @@ -76,14 +76,14 @@ namespace mln namespace util { - /// \brief Undirected graph. + /// Undirected graph. class graph : public internal::graph_base<graph> { /// The super class. typedef internal::graph_base<graph> super; - using super::vertex_data_t; - using super::edge_data_t; + typedef super::vertex_data_t vertex_data_t; + typedef super::edge_data_t edge_data_t; public: /// The type of the set of vertices. @@ -138,7 +138,7 @@ namespace mln /// \{ /// Shortcuts factoring the insertion of vertices and edges. /// \{ - /// \brief Add a vertex. + /// Add a vertex. /// /// \return The id of the new vertex. unsigned add_vertex(); @@ -148,7 +148,7 @@ namespace mln vertex_t vertex(unsigned id_v) const; /// \} - /// \brief Return the number of vertices in the graph. + /// Return the number of vertices in the graph. size_t v_nmax() const; /// Check whether a vertex id \p id_v exists in the graph. @@ -176,7 +176,7 @@ namespace mln /// Edge oriented. /// \{ - /// \brief Add an edge. + /// Add an edge. /// /// \return The id of the new edge if it does not exist yet; /// otherwise, return <tt>mln_max(unsigned)</tt>. @@ -185,7 +185,7 @@ namespace mln /// Return the edge whose id is \a e. edge_t edge(unsigned e) const; - /// \brief Return the number of edges in the graph. + /// Return the number of edges in the graph. size_t e_nmax() const; /// Return whether \p id_e is in the graph. diff --git a/milena/mln/util/internal/graph_edge.hh b/milena/mln/util/internal/graph_edge.hh index 06e39d4..bab22d8 100644 --- a/milena/mln/util/internal/graph_edge.hh +++ b/milena/mln/util/internal/graph_edge.hh @@ -110,12 +110,16 @@ namespace mln }; template <typename G> + std::ostream& + operator<<(std::ostream& ostr, edge<G>& p); + + template <typename G> bool - operator==(const util::edge<G>& lhs, const util::edge<G>& rhs); + operator==(const edge<G>& lhs, const edge<G>& rhs); template <typename G> bool - operator< (const util::edge<G>& lhs, const util::edge<G>& rhs); + operator< (const edge<G>& lhs, const edge<G>& rhs); } // End of namespace mln::util @@ -283,12 +287,17 @@ namespace mln return g_.e_ith_nbh_edge(id_, i); } - + template <typename G> + std::ostream& + operator<<(std::ostream& ostr, edge<G>& p) + { + return ostr << p.id(); + } template <typename G> inline bool - operator==(const util::edge<G>& lhs, const util::edge<G>& rhs) + operator==(const edge<G>& lhs, const edge<G>& rhs) { return lhs.pair_vertex_ == rhs.pair_vertex_; } @@ -296,7 +305,7 @@ namespace mln template <typename G> inline bool - operator< (const util::edge<G>& lhs, const util::edge<G>& rhs) + operator< (const edge<G>& lhs, const edge<G>& rhs) { return lhs.pair_vertex_ < rhs.pair_vertex_; } diff --git a/milena/mln/util/internal/graph_iter_base.hh b/milena/mln/util/internal/graph_iter_base.hh index a901192..96777af 100644 --- a/milena/mln/util/internal/graph_iter_base.hh +++ b/milena/mln/util/internal/graph_iter_base.hh @@ -62,6 +62,9 @@ namespace mln /// Return current index unsigned index() const; + + /// Conversion operator. Returns the element id. + operator unsigned() const; /// \} /// Proxy. @@ -76,6 +79,7 @@ namespace mln P p_; }; + # ifndef MLN_INCLUDE_ONLY template <typename G, typename P, typename E> @@ -128,6 +132,13 @@ namespace mln template <typename G, typename P, typename E> inline + graph_iter_base<G, P, E>::operator unsigned() const + { + return p_.id(); + } + + template <typename G, typename P, typename E> + inline const P& graph_iter_base<G, P, E>::subj_() { diff --git a/milena/mln/util/internal/graph_nbh_iter_base.hh b/milena/mln/util/internal/graph_nbh_iter_base.hh index 14950a1..f6f02ea 100644 --- a/milena/mln/util/internal/graph_nbh_iter_base.hh +++ b/milena/mln/util/internal/graph_nbh_iter_base.hh @@ -61,6 +61,9 @@ namespace mln /// Return current index unsigned index() const; + + /// Conversion operator. Returns the element ID. + operator unsigned() const; /// \} /// Proxy. @@ -145,6 +148,13 @@ namespace mln template <typename G, typename C, typename P, typename E> inline + nbh_iterator_base<G, C, P, E>::operator unsigned() const + { + return p_.id(); + } + + template <typename G, typename C, typename P, typename E> + inline const P& nbh_iterator_base<G, C, P, E>::subj_() { diff --git a/milena/tests/util/Makefile.am b/milena/tests/util/Makefile.am index d0fe4be..fcfb902 100644 --- a/milena/tests/util/Makefile.am +++ b/milena/tests/util/Makefile.am @@ -6,6 +6,7 @@ include $(top_srcdir)/milena/tests/tests.mk check_PROGRAMS = \ branch_iter \ branch_iter_ind \ + dual_graph \ eat \ graph \ lazy_set \ @@ -19,6 +20,7 @@ check_PROGRAMS = \ branch_iter_SOURCES = branch_iter.cc branch_iter_ind_SOURCES = branch_iter_ind.cc +dual_graph_SOURCES = dual_graph.cc eat_SOURCES = eat.cc graph_SOURCES = graph.cc lazy_set_SOURCES = lazy_set.cc diff --git a/milena/tests/util/dual_graph.cc b/milena/tests/util/dual_graph.cc new file mode 100644 index 0000000..ff8c8ad --- /dev/null +++ b/milena/tests/util/dual_graph.cc @@ -0,0 +1,164 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/// \file tests/util/dual_graph.cc +/// test of mln::util::dual_graph + +#include <mln/util/graph.hh> +#include <mln/util/dual_graph.hh> +#include <iostream> + +int main () +{ + using namespace mln; + + util::graph g; + + g.add_vertex (); // 0 + g.add_vertex (); // 1 + g.add_vertex (); // 2 + g.add_vertex (); // 3 + g.add_vertex (); // 4 + g.add_vertex (); // 5 + g.add_edge (0, 1); + g.add_edge (1, 0); // Not inserted twice + g.add_edge (0, 2); + g.add_edge (3, 4); + g.add_edge (4, 5); + g.add_edge (5, 4); // Not inserted twice + g.add_edge (5, 3); + g.add_edge (2, 1); + + typedef util::dual_graph<util::graph> DG; + DG dg(g); + + // Vertex iter and edge iter + { + unsigned i = 0; + mln_vertex_fwd_iter_(DG) v(dg); + for_all(v) + std::cout << v.index() << std::endl; +// mln_assertion(i++ == v.index()); + //mln_assertion(i != 0); + + i = 0; + mln_edge_fwd_iter_(util::graph) e(g); + for_all(e) + std::cout << e << std::endl; +// mln_assertion(i++ == e.index()); +// mln_assertion(i != 0);*/ + } +/* { + unsigned i = g.v_nmax() - 1; + mln_vertex_bkd_iter_(util::graph) v(g); + for_all(v) + mln_assertion(i-- == v.index()); + mln_assertion(i != g.v_nmax() - 1); + + i = g.e_nmax() - 1; + mln_edge_bkd_iter_(util::graph) e(g); + for_all(e) + mln_assertion(i-- == e.index()); + mln_assertion(i != g.e_nmax() - 1); + } + + // vertex iter + Edge nbh iter + { + mln_vertex_fwd_iter_(util::graph) v(g); + mln_vertex_nbh_edge_fwd_iter_(util::graph) n(v); + for_all(v) + { + unsigned i = 0; + for_all(n) + mln_assertion(i++ == n.index()); + mln_assertion(i != 0); + } + } + { + mln_vertex_bkd_iter_(util::graph) v(g); + mln_vertex_nbh_edge_bkd_iter_(util::graph) e(v); + for_all(v) + { + unsigned i = v.nmax_nbh_edges(); + for_all(e) + mln_assertion(--i == e.index()); + mln_assertion((v.nmax_nbh_edges() == 0 && i == 0) || i != v.nmax_nbh_edges()); + } + } + + { + mln_edge_fwd_iter_(util::graph) e(g); + mln_edge_nbh_edge_fwd_iter_(util::graph) n(e); + for_all(e) + { + unsigned i = 0; + for_all(n) + ++i; + // we check i == e.nmax_nbh_edges() - 2 since e is it's own neighboor and the + // iterator skip it. + mln_assertion((i == 0 && e.nmax_nbh_edges() < 2) || i == e.nmax_nbh_edges() - 2); + } + } + { + mln_edge_bkd_iter_(util::graph) e(g); + mln_edge_nbh_edge_bkd_iter_(util::graph) n(e); + for_all(e) + { + //std::cout << "== e.id() = " << e.id() << std::endl; + unsigned i = e.nmax_nbh_edges(); + for_all(n) + --i; + // we check i == e.nmax_nbh_edges() - 2 since e is it's own neighboor and the + // iterator skip it. + mln_assertion((i == e.nmax_nbh_edges() && e.nmax_nbh_edges() < 2) || i == 2); + + } + } + + { + mln_vertex_fwd_iter_(util::graph) v(g); + mln_vertex_nbh_vertex_fwd_iter_(util::graph) n(v); + for_all(v) + { + unsigned i = 0; + for_all(n) + ++i; + mln_assertion(i == v.nmax_nbh_vertices()); + } + } + { + mln_vertex_bkd_iter_(util::graph) v(g); + mln_vertex_nbh_vertex_bkd_iter_(util::graph) n(v); + for_all(v) + { + unsigned i = v.nmax_nbh_vertices(); + for_all(n) + --i; + mln_assertion(i == 0); + } + }*/ +} -- 1.5.6.5
participants (1)
-
Guillaume Lazzara