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