00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_UTIL_GRAPH_HH
00027 # define MLN_UTIL_GRAPH_HH
00028
00032
00033 # include <mln/util/internal/graph_base.hh>
00034 # include <mln/util/internal/graph_iter.hh>
00035 # include <mln/util/internal/graph_nbh_iter.hh>
00036 # include <mln/util/vertex.hh>
00037 # include <mln/util/edge.hh>
00038 # include <mln/util/ord_pair.hh>
00039
00040 namespace mln
00041 {
00042
00044 namespace util { class graph; }
00045
00046
00047 namespace internal
00048 {
00049
00051 template <>
00052 struct data<util::graph>
00053 {
00054 typedef util::graph G;
00055 typedef std::vector<std::vector<util::edge_id_t> > vertices_t;
00056 typedef std::vector<util::ord_pair<util::vertex_id_t> > edges_t;
00057 typedef std::set<util::ord_pair<util::vertex_id_t> > edges_set_t;
00058
00059 data();
00062 data(unsigned nvertices);
00063 ~data();
00064
00066 vertices_t vertices_;
00068 edges_t edges_;
00069
00070 # ifndef NDEBUG
00071
00072 edges_set_t edges_set_;
00073 # endif // ! NDEBUG
00074 };
00075
00076 }
00077
00078
00079 namespace util
00080 {
00081
00085
00086 class graph : public internal::graph_base<graph>
00087 {
00089 typedef internal::graph_base<graph> super;
00090
00091 typedef super::vertex_data_t vertex_data_t;
00092 typedef super::edge_data_t edge_data_t;
00093
00094 public:
00096 typedef std::vector<vertex_data_t> vertices_t;
00097
00099 typedef std::vector<edge_data_t> edges_t;
00101 typedef std::set<edge_data_t> edges_set_t;
00102
00107 typedef mln::internal::vertex_fwd_iterator<graph> vertex_fwd_iter;
00108 typedef mln::internal::vertex_bkd_iterator<graph> vertex_bkd_iter;
00109 typedef vertex_fwd_iter vertex_iter;
00111
00114 typedef mln::internal::vertex_nbh_edge_fwd_iterator<graph> vertex_nbh_edge_fwd_iter;
00115 typedef mln::internal::vertex_nbh_edge_bkd_iterator<graph> vertex_nbh_edge_bkd_iter;
00116 typedef vertex_nbh_edge_fwd_iter vertex_nbh_edge_iter;
00118
00121 typedef mln::internal::vertex_nbh_vertex_fwd_iterator<graph> vertex_nbh_vertex_fwd_iter;
00122 typedef mln::internal::vertex_nbh_vertex_bkd_iterator<graph> vertex_nbh_vertex_bkd_iter;
00123 typedef vertex_nbh_vertex_fwd_iter vertex_nbh_vertex_iter;
00125
00128 typedef mln::internal::edge_fwd_iterator<graph> edge_fwd_iter;
00129 typedef mln::internal::edge_bkd_iterator<graph> edge_bkd_iter;
00130 typedef edge_fwd_iter edge_iter;
00132
00135 typedef mln::internal::edge_nbh_edge_fwd_iterator<graph> edge_nbh_edge_fwd_iter;
00136 typedef mln::internal::edge_nbh_edge_bkd_iterator<graph> edge_nbh_edge_bkd_iter;
00137 typedef edge_nbh_edge_fwd_iter edge_nbh_edge_iter;
00140
00142 graph();
00144 graph(unsigned nvertices);
00145
00148
00151
00155 unsigned add_vertex();
00156
00160 std::pair<vertex_id_t, vertex_id_t> add_vertices(unsigned n);
00161
00164 vertex_t vertex(vertex_id_t id_v) const;
00166
00168 size_t v_nmax() const;
00169
00171 bool has_v(const vertex_id_t& id_v) const;
00172
00173
00175 size_t v_nmax_nbh_edges(const vertex_id_t& id_v) const;
00176
00178 edge_id_t
00179 v_ith_nbh_edge(const vertex_id_t& id_v,
00180 unsigned i) const;
00181
00183 size_t v_nmax_nbh_vertices(const vertex_id_t& id_v) const;
00184
00186 vertex_id_t v_ith_nbh_vertex(const vertex_id_t& id_v,
00187 unsigned i) const;
00189
00190
00191
00198 edge_id_t add_edge(const vertex_id_t& id_v1, const vertex_id_t& id_v2);
00199
00201 edge_t edge(const edge_id_t& e) const;
00202
00203
00205 const std::vector<util::ord_pair<vertex_id_t> >& edges() const;
00206
00208 size_t e_nmax() const;
00209
00212 bool has_e(const edge_id_t& id_e) const;
00214
00217 edge_t edge(const vertex_t& v1, const vertex_t& v2) const;
00218
00220 vertex_id_t v1(const edge_id_t& id_e) const;
00221
00223 vertex_id_t v2(const edge_id_t& id_e) const;
00224
00226 size_t e_nmax_nbh_edges(const edge_id_t& id_e) const;
00227
00229 edge_id_t e_ith_nbh_edge(const edge_id_t& id_e, unsigned i) const;
00230
00233 template <typename G2>
00234 bool is_subgraph_of(const G2& g) const;
00236
00237 };
00238
00239 std::ostream&
00240 operator<<(std::ostream& ostr, const graph& g);
00241
00242 }
00243
00244 }
00245
00246
00247
00248
00249 # ifndef MLN_INCLUDE_ONLY
00250
00251 namespace mln
00252 {
00253
00254 namespace internal
00255 {
00256
00257 inline
00258 data<util::graph>::data()
00259 {
00260 }
00261
00262 inline
00263 data<util::graph>::data(unsigned nvertices)
00264 {
00265 vertices_.resize(nvertices);
00266 }
00267
00268 inline
00269 data<util::graph>::~data()
00270 {
00271 }
00272
00273 }
00274
00275 namespace util
00276 {
00277
00278 inline
00279 graph::graph()
00280 {
00281 this->data_ = new mln::internal::data<util::graph>();
00282 }
00283
00284 inline
00285 graph::graph(unsigned nvertices)
00286 {
00287 this->data_ = new mln::internal::data<util::graph>(nvertices);
00288 }
00289
00290
00291
00292
00293
00294 inline
00295 unsigned
00296 graph::add_vertex()
00297 {
00298
00299
00300 data_->vertices_.resize(data_->vertices_.size() + 1);
00301
00302 return v_nmax() - 1;
00303 }
00304
00305 inline
00306 std::pair<vertex_id_t, vertex_id_t>
00307 graph::add_vertices(unsigned n)
00308 {
00309
00310
00311 data_->vertices_.resize(data_->vertices_.size() + n);
00312
00313 return std::make_pair(v_nmax() - n,
00314 v_nmax() - 1);
00315 }
00316
00317 inline
00318 graph::vertex_t
00319 graph::vertex(vertex_id_t id_v) const
00320 {
00321 mln_assertion(has_v(id_v));
00322 return vertex_t(*this, id_v);
00323 }
00324
00325
00326 inline
00327 size_t
00328 graph::v_nmax() const
00329 {
00330 return data_->vertices_.size();
00331 }
00332
00333 inline
00334 bool
00335 graph::has_v(const vertex_id_t& id_v) const
00336 {
00337 return id_v < data_->vertices_.size();
00338 }
00339
00340 inline
00341 size_t
00342 graph::v_nmax_nbh_edges(const vertex_id_t& id_v) const
00343 {
00344 mln_precondition(has_v(id_v));
00345 return data_->vertices_[id_v].size();
00346 }
00347
00348 inline
00349 edge_id_t
00350 graph::v_ith_nbh_edge(const vertex_id_t& id_v, unsigned i) const
00351 {
00352 mln_precondition(has_v(id_v));
00353 if (i >= v_nmax_nbh_edges(id_v))
00354 return edge_id_t();
00355 return data_->vertices_[id_v][i];
00356 }
00357
00358 inline
00359 size_t
00360 graph::v_nmax_nbh_vertices(const vertex_id_t& id_v) const
00361 {
00362 mln_precondition(has_v(id_v));
00363 return v_nmax_nbh_edges(id_v);
00364 }
00365
00366 inline
00367 vertex_id_t
00368 graph::v_ith_nbh_vertex(const vertex_id_t& id_v, unsigned i) const
00369 {
00370 mln_precondition(has_v(id_v));
00371
00372 edge_id_t id_e = v_ith_nbh_edge(id_v, i);
00373 return v_other(id_e, id_v);
00374 }
00375
00376
00377
00378
00379
00380
00381 inline
00382 edge_id_t
00383 graph::add_edge(const vertex_id_t& id_v1, const vertex_id_t& id_v2)
00384 {
00385 mln_precondition(id_v1 != id_v2);
00386 mln_precondition(has_v(id_v1));
00387 mln_precondition(has_v(id_v2));
00388
00389
00390 edge_data_t edge(id_v1, id_v2);
00391 # ifndef NDEBUG
00392 if (data_->edges_set_.find(edge) != data_->edges_set_.end ())
00393 {
00394
00395 return edge_id_t();
00396 }
00397 else
00398 {
00399 # endif // ! NDEBUG
00400
00401
00402
00403 data_->edges_.push_back(edge);
00404 edge_id_t id = data_->edges_.size() - 1;
00405
00406
00407 # ifndef NDEBUG
00408 data_->edges_set_.insert(edge);
00409 # endif // ! NDEBUG
00410 data_->vertices_[edge.first()].push_back(id);
00411 data_->vertices_[edge.second()].push_back(id);
00412
00413 return id;
00414
00415 # ifndef NDEBUG
00416 }
00417 # endif // ! NDEBUG
00418
00419 }
00420
00421 inline
00422 const std::vector<util::ord_pair<vertex_id_t> >&
00423 graph::edges() const
00424 {
00425 return this->data_->edges_;
00426 }
00427
00428 inline
00429 graph::edge_t
00430 graph::edge(const edge_id_t& e) const
00431 {
00432 mln_assertion(e < e_nmax());
00433 return edge_t(*this, e);
00434 }
00435
00436 inline
00437 size_t
00438 graph::e_nmax() const
00439 {
00440 return data_->edges_.size();
00441 }
00442
00443 inline
00444 bool
00445 graph::has_e(const edge_id_t& id_e) const
00446 {
00447 return id_e < data_->edges_.size();
00448 }
00449
00450 inline
00451 graph::edge_t
00452 graph::edge(const vertex_t& v1, const vertex_t& v2) const
00453 {
00454 mln_precondition(has_v(v1));
00455 mln_precondition(has_v(v2));
00456
00457 vertex_id_t
00458 id_v1 = v1.id(),
00459 id_v2 = v2.id();
00460
00461 if (id_v1 > id_v2)
00462 std::swap(id_v1, id_v2);
00463
00464 for (unsigned i = 0; i < data_->vertices_[id_v1].size(); ++i)
00465 if (data_->edges_[data_->vertices_[id_v1][i]].second() == id_v2)
00466 return edge_t(*this, data_->vertices_[id_v1][i]);
00467
00468
00469 return edge_t();
00470 }
00471
00472 inline
00473 vertex_id_t
00474 graph::v1(const edge_id_t& id_e) const
00475 {
00476 mln_precondition(has_e(id_e));
00477 return data_->edges_[id_e].first();
00478 }
00479
00480 inline
00481 vertex_id_t
00482 graph::v2(const edge_id_t& id_e) const
00483 {
00484 mln_precondition(has_e(id_e));
00485 return data_->edges_[id_e].second();
00486 }
00487
00488 inline
00489 size_t
00490 graph::e_nmax_nbh_edges(const edge_id_t& id_e) const
00491 {
00492 mln_precondition(has_e(id_e));
00493 return v_nmax_nbh_edges(v1(id_e)) + v_nmax_nbh_edges(v2(id_e));
00494 }
00495
00496 inline
00497 edge_id_t
00498 graph::e_ith_nbh_edge(const edge_id_t& id_e, unsigned i) const
00499 {
00500 mln_precondition(has_e(id_e));
00501 if (i >= e_nmax_nbh_edges(id_e))
00502 return e_nmax();
00503
00504 unsigned v1_nmax = v_nmax_nbh_edges(v1(id_e));
00505 if (i < v1_nmax)
00506 return v_ith_nbh_edge(v1(id_e), i);
00507 return v_ith_nbh_edge(v2(id_e), i - v1_nmax);
00508 }
00509
00510
00511 template <typename G2>
00512 inline
00513 bool
00514 graph::is_subgraph_of(const G2& g) const
00515 {
00516 return g.id() == this->id();
00517 }
00518
00519
00520 inline
00521 std::ostream&
00522 operator<<(std::ostream& ostr, const graph& g)
00523 {
00524 mln_vertex_iter_(graph) v(g);
00525 mln_vertex_nbh_edge_iter_(graph) e(v);
00526 for_all(v)
00527 {
00528 ostr << "v(" << v << ") : ";
00529 for_all(e)
00530 ostr << e << " ";
00531 ostr << std::endl;
00532 }
00533
00534 return ostr;
00535 }
00536
00537 }
00538
00539 }
00540
00541 # endif // ! MLN_INCLUDE_ONLY
00542
00543
00544 #endif // ! MLN_UTIL_GRAPH_HH