[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

merge_graph_adaptor.hxx VIGRA

1 
2 /************************************************************************/
3 /* */
4 /* Copyright 2014 by Thorsten Beier and Ullrich Koethe */
5 /* */
6 /* This file is part of the VIGRA computer vision library. */
7 /* The VIGRA Website is */
8 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
9 /* Please direct questions, bug reports, and contributions to */
10 /* ullrich.koethe@iwr.uni-heidelberg.de or */
11 /* vigra@informatik.uni-hamburg.de */
12 /* */
13 /* Permission is hereby granted, free of charge, to any person */
14 /* obtaining a copy of this software and associated documentation */
15 /* files (the "Software"), to deal in the Software without */
16 /* restriction, including without limitation the rights to use, */
17 /* copy, modify, merge, publish, distribute, sublicense, and/or */
18 /* sell copies of the Software, and to permit persons to whom the */
19 /* Software is furnished to do so, subject to the following */
20 /* conditions: */
21 /* */
22 /* The above copyright notice and this permission notice shall be */
23 /* included in all copies or substantial portions of the */
24 /* Software. */
25 /* */
26 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
27 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
28 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
29 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
30 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
31 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
32 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
33 /* OTHER DEALINGS IN THE SOFTWARE. */
34 /* */
35 /************************************************************************/
36 
37 
38 #ifndef VIGRA_NEW_MERGE_GRAPH_HXX
39 #define VIGRA_NEW_MERGE_GRAPH_HXX
40 
41 
42 /* delegates / callbacks */
43 #include "delegate/delegate.hxx"
44 
45 /* std library */
46 #include <vector>
47 #include <algorithm>
48 #include <cmath>
49 #include <stdexcept>
50 #include <map>
51 
52 /* vigra */
53 #include "multi_array.hxx"
54 #include "tinyvector.hxx"
55 #include "multi_array.hxx"
56 #include "graphs.hxx"
57 #include "graph_maps.hxx"
58 #include "graph_item_impl.hxx"
59 #include "random_access_set.hxx"
60 #include "iteratorfacade.hxx"
61 
62 
63 namespace vigra {
64 
65 namespace merge_graph_detail {
66 
67 // ufd data structure structure for merge graph
68 // only useful for merge graphs internal usage
69 template<class T>
71 
72 // representative element iterator
73 // for IterablePartition
74 // only useful for merge graphs internal usage
75 template<class T>
76 struct ConstRepIter
77 : public ForwardIteratorFacade<
78  ConstRepIter<T>,T,true
79  >
80 
81 {
82  typedef IterablePartition<T> IterablePartitionType;
83  ConstRepIter(const IterablePartitionType & p,const T cr)
84  : partition_(&p),
85  currentRep_(cr){
86  }
87 
88 
89  ConstRepIter()
90  : partition_(NULL),
91  currentRep_()
92  {
93  }
94 
95 private:
96  friend class vigra::IteratorFacadeCoreAccess;
97 
98 
99  bool isBegin()const{
100  return partition_!=NULL && currentRep_==partition_->firstRep();
101  }
102  bool isEnd()const{
103  return partition_==NULL || currentRep_>partition_->lastRep();
104  }
105 
106  bool equal(const ConstRepIter & other)const{
107  return (this->isEnd() && other.isEnd() ) || ((this->isEnd()==other.isEnd() ) && this->currentRep_==other.currentRep_);
108  }
109 
110  void increment(){
111  if(partition_->jumpVec_[currentRep_].second==0){
112  currentRep_+=1;
113  }
114  else{
115  currentRep_+=partition_->jumpVec_[currentRep_].second;
116  }
117  }
118 
119  void decrement(){
120  if(partition_->jumpVec_[currentRep_].first==0){
121  //VIGRA_ASSERT_OP(currentRep_,==,partition_->firstRep());
122  //currentRep_+=1;
123  }
124  else{
125  currentRep_-=partition_->jumpVec_[currentRep_].first;
126  }
127  }
128 
129  const T & dereference()const{
130  return currentRep_;
131  }
132 
133 
134 
135  const IterablePartitionType * partition_;
136  T currentRep_;
137 
138 };
139 
140 
141 
142 // ufd data structure structure for merge graph
143 // only useful for merge graphs internal usage
144 /// Disjoint set data structure with path compression.
145 /// \ingroup datastructures
146 template<class T>
147 class IterablePartition {
148 public:
149  friend struct ConstRepIter<T>;
150  typedef T value_type;
151  typedef std::size_t SizeTType;
153  IterablePartition(const value_type&);
154 
155  // query
156  value_type find(const value_type&) const; // without path compression
157  value_type find(value_type); // with path compression
158  value_type numberOfElements() const;
159  value_type numberOfSets() const;
160  template<class Iterator> void elementLabeling(Iterator) const;
161  template<class Iterator> void representatives(Iterator) const;
162  void representativeLabeling(std::map<value_type, value_type>&) const;
163 
164  // manipulation
165  void reset(const value_type&);
166  void merge(value_type, value_type);
167 
168  value_type firstRep()const{
169  return firstRep_;
170  }
171  value_type lastRep()const{
172  return lastRep_;
173  }
174  typedef ConstRepIter<T> const_iterator;
175 
176  const_iterator begin()const{
177  if(numberOfSets_!=0)
178  return ConstRepIter<T>(*this,firstRep_);
179  else
180  return ConstRepIter<T>(*this,lastRep_+1);
181  }
182  const_iterator end()const{
183  return ConstRepIter<T>(*this,lastRep_+1);
184  }
185 
186 
187  const_iterator iteratorAt(const value_type & rep)const{
188  if(numberOfSets_!=0)
189  return ConstRepIter<T>(*this,rep);
190  else
191  return ConstRepIter<T>(*this,lastRep_+1);
192  }
193 
194  bool isErased(const value_type & value)const{
195  return jumpVec_[value].first == -1 && jumpVec_[value].second == -1;
196  }
197 
198  void eraseElement(const value_type & value,const bool reduceSize=true){
199  const T notRep=value;
200  const T jumpMinus = jumpVec_[notRep].first;
201  const T jumpPlus = jumpVec_[notRep].second;
202 
203  if(jumpMinus==0){
204  const T nextRep = notRep+jumpPlus;
205  firstRep_=nextRep;
206  jumpVec_[nextRep].first=0;
207  }
208  else if(jumpPlus==0){
209  //VIGRA_ASSERT_OP(lastRep_,==,notRep);
210  const T prevRep = notRep-jumpMinus;
211  lastRep_=prevRep;
212  jumpVec_[prevRep].second=0;
213 
214  }
215  else{
216  const T nextRep = notRep+jumpPlus;
217  const T prevRep = notRep-jumpMinus;
218  jumpVec_[nextRep].first+=jumpVec_[notRep].first;
219  jumpVec_[prevRep].second+=jumpVec_[notRep].second;
220  }
221  if(reduceSize){
222  --numberOfSets_;
223  }
224  jumpVec_[notRep].first =-1;
225  jumpVec_[notRep].second =-1;
226  }
227 
228 private:
229  std::vector<value_type> parents_;
230  std::vector<value_type> ranks_;
231  std::vector< std::pair< vigra::Int64, vigra::Int64> > jumpVec_;
232  value_type firstRep_;
233  value_type lastRep_;
234  value_type numberOfElements_;
235  value_type numberOfSets_;
236 };
237 
238 
239 } // end namespa merge graph detail
240 
241 
242 
243 // helper classes to generalize
244 // some functionality for
245 // nodes,edges and arcs
246 template<class GRAPH,class ITEM>
247 struct MergeGraphItemHelper;
248 
249 template<class MG>
250 struct MergeGraphItemHelper<MG,typename MG::Edge>{
251  typedef typename MG::Graph Graph;
252  typedef typename MG::index_type index_type ;
253  typedef typename MG::Edge Item;
254  typedef typename Graph::Edge GraphItem;
255  typedef typename MG::EdgeIt ItemIt;
256 
257 
258  static index_type maxItemId(const MG & g){
259  return g.maxEdgeId();
260  }
261  static index_type itemNum(const MG & g){
262  return g.edgeNum();
263  }
264 
265  static GraphItem itemToGraphItem(const MG & g,const Item & item){
266  const index_type id = g.id(item);
267  return g.graph().edgeFromId(id);
268  }
269 };
270 
271 template<class MG>
272 struct MergeGraphItemHelper<MG,typename MG::Node>{
273  typedef typename MG::Graph Graph;
274  typedef typename MG::index_type index_type ;
275  typedef typename MG::Node Item;
276  typedef typename Graph::Node GraphItem;
277  typedef typename MG::NodeIt ItemIt;
278 
279 
280  static index_type maxItemId(const MG & g){
281  return g.maxNodeId();
282  }
283  static index_type itemNum(const MG & g){
284  return g.nodeNum();
285  }
286  static GraphItem itemToGraphItem(const MG & g,const Item & item){
287  const index_type id = g.id(item);
288  return g.graph().nodeFromId(id);
289  }
290 };
291 
292 // merge graphs LEMON compatible iterator
293 template<class MERGE_GRAPH>
294 class MergeGraphNodeIt
295 : public ForwardIteratorFacade<MergeGraphNodeIt<MERGE_GRAPH>,typename MERGE_GRAPH::Node,true>{
296 public:
297  typedef MERGE_GRAPH Graph;
298  typedef typename Graph::Node Node;
299  // Invalid constructor & conversion.
300  MergeGraphNodeIt(const lemon::Invalid & /*invalid*/ = lemon::INVALID)
301  : graph_(NULL),
302  nodeIdIt_(),
303  node_(){
304 
305  }
306  MergeGraphNodeIt(const Graph & g)
307  : graph_(&g),
308  nodeIdIt_(g.nodeUfd_.begin()),
309  node_(){
310  }
311  MergeGraphNodeIt(const Graph & g,const Node & node)
312  : graph_(&g),
313  nodeIdIt_(g.nodeUfd_.iteratorAt(g.id(node))),
314  node_(){
315 
316  }
317  bool isEnd()const{
318  return graph_==NULL || nodeIdIt_==graph_->nodeUfd_.end();
319  }
320  bool isBegin()const{
321  return graph_!=NULL && nodeIdIt_==graph_->nodeUfd_.begin();
322  }
323 private:
324  friend class vigra::IteratorFacadeCoreAccess;
325 
326 
327  bool equal(const MergeGraphNodeIt<MERGE_GRAPH> & other)const{
328  return (isEnd()&&other.isEnd()) || nodeIdIt_==other.nodeIdIt_;
329  }
330  void increment(){++nodeIdIt_;}
331  const Node & dereference()const{
332  node_=Node(*nodeIdIt_);
333  return node_;
334  }
335  // members
336  const Graph * graph_;
337  typename Graph::NodeIdIt nodeIdIt_;
338  mutable Node node_;
339 };
340 
341 // merge graphs LEMON compatible iterator
342 template<class MERGE_GRAPH>
343 class MergeGraphEdgeIt
344 : public ForwardIteratorFacade<MergeGraphEdgeIt<MERGE_GRAPH>,typename MERGE_GRAPH::Edge,true>{
345 public:
346  typedef MERGE_GRAPH Graph;
347  typedef typename Graph::Edge Edge;
348  // Invalid constructor & conversion.
349  MergeGraphEdgeIt(const lemon::Invalid & /*invalid*/ = lemon::INVALID)
350  : graph_(NULL),
351  edgeIdIt_(),
352  edge_(){
353  }
354  MergeGraphEdgeIt(const Graph & g)
355  : graph_(&g),
356  edgeIdIt_(g.edgeUfd_.begin()),
357  edge_(){
358 
359  }
360  MergeGraphEdgeIt(const Graph & g,const Edge & node)
361  : graph_(&g),
362  edgeIdIt_(g.edgeUfd_.iteratorAt(g.id(node))),
363  edge_(){
364  }
365  bool isEnd()const{
366  return graph_==NULL || edgeIdIt_==graph_->edgeUfd_.end();
367  }
368  bool isBegin()const{
369  return graph_!=NULL && edgeIdIt_==graph_->edgeUfd_.begin();
370  }
371 private:
372  friend class vigra::IteratorFacadeCoreAccess;
373 
374 
375  bool equal(const MergeGraphEdgeIt<MERGE_GRAPH> & other)const{
376  return (isEnd()&&other.isEnd()) || edgeIdIt_==other.edgeIdIt_;
377  }
378  void increment(){
379  ++edgeIdIt_;
380  }
381  const Edge & dereference()const{
382  edge_=Edge(*edgeIdIt_);
383  return edge_;
384  }
385  // members
386  const Graph * graph_;
387  typename Graph::EdgeIdIt edgeIdIt_;
388  mutable Edge edge_;
389 };
390 
391 // merge graphs LEMON compatible iterator
392 template<class GRAPH>
393 class MergeGraphArcIt
394 : public ForwardIteratorFacade<
395  MergeGraphArcIt<GRAPH>,typename GRAPH::Arc,true
396 >
397 {
398 public:
399  typedef GRAPH Graph;
400  typedef typename Graph::Arc Arc;
401  typedef typename Graph::Edge Edge;
402  typedef typename Graph::EdgeIt EdgeIt;
403  MergeGraphArcIt(const lemon::Invalid /*invalid*/ = lemon::INVALID )
404  : graph_(NULL),
405  pos_(),
406  inFirstHalf_(false),
407  veryEnd_(true),
408  arc_(){
409  }
410  MergeGraphArcIt(const GRAPH & g )
411  : graph_(&g),
412  pos_(g),
413  inFirstHalf_(true),
414  veryEnd_( g.edgeNum()==0 ? true : false),
415  arc_(){
416  }
417 
418  MergeGraphArcIt(const GRAPH & g , const Arc & arc )
419  : graph_(&g),
420  pos_(g,arc.edgeId()),
421  inFirstHalf_(g.id(arc)<=g.maxEdgeId()),
422  veryEnd_(false),
423  arc_(){
424  }
425 private:
426  friend class vigra::IteratorFacadeCoreAccess;
427  bool isEnd()const{
428  return veryEnd_ || graph_==NULL;
429  }
430 
431  bool isBegin()const{
432  return graph_!=NULL && veryEnd_==false && pos_ == EdgeIt(*graph_);
433  }
434 
435  void increment() {
436  if(inFirstHalf_){
437  ++pos_;
438  if(pos_ == lemon::INVALID ) {
439  pos_ = EdgeIt(*graph_);
440  inFirstHalf_=false;
441  }
442  return;
443  }
444  else{
445  ++pos_;
446  if(pos_ == lemon::INVALID){
447  veryEnd_=true;
448  }
449  return;
450  }
451 
452 
453  }
454  bool equal(MergeGraphArcIt const& other) const{
455  return (
456  (
457  isEnd()==other.isEnd() &&
458  inFirstHalf_==other.inFirstHalf_
459  ) &&
460  (isEnd() || graph_==NULL || pos_==other.pos_ )
461  );
462 
463  }
464 
465  const Arc & dereference() const {
466  //std::cout<<graph_->id(*pos_)<<"\n";
467  arc_ = graph_->direct(*pos_,inFirstHalf_);
468  return arc_;
469  }
470 
471 
472  const GRAPH * graph_;
473  EdgeIt pos_;
474  bool inFirstHalf_;
475  bool veryEnd_;
476  mutable Arc arc_;
477 };
478 
479 
480 // callbacks of merge graph
481 // to update node and edge maps w.r.t. edge contractions
482 template<class NODE,class EDGE>
483 class MergeGraphCallbacks{
484  public:
485 
486  typedef delegate2<void ,const NODE & ,const NODE &> MergeNodeCallBackType;
487  typedef delegate2<void ,const EDGE & ,const EDGE &> MergeEdgeCallBackType;
488  typedef delegate1<void ,const EDGE &> EraseEdgeCallBackType;
489 
490  MergeGraphCallbacks(){}
491 
492  void registerMergeNodeCallBack(MergeNodeCallBackType f){
493  mergeNodeCallbacks_.push_back(f);
494  }
495  void registerMergeEdgeCallBack(MergeEdgeCallBackType f){
496  mergeEdgeCallbacks_.push_back(f);
497  }
498  void registerEraseEdgeCallBack(EraseEdgeCallBackType f){
499  eraseEdgeCallbacks_.push_back(f);
500  }
501 
502  protected:
503  void callMergeNodeCallbacks(const NODE & a,const NODE & b){
504  for(size_t i=0;i<mergeNodeCallbacks_.size();++i)
505  mergeNodeCallbacks_[i](a,b);
506  }
507  void callMergeEdgeCallbacks(const EDGE & a,const EDGE & b){
508  for(size_t i=0;i<mergeEdgeCallbacks_.size();++i)
509  mergeEdgeCallbacks_[i](a,b);
510  }
511  void callEraseEdgeCallbacks(const EDGE & a){
512  for(size_t i=0;i<eraseEdgeCallbacks_.size();++i)
513  eraseEdgeCallbacks_[i](a);
514  }
515  void clearCallbacks(){
516  mergeNodeCallbacks_.clear();
517  mergeEdgeCallbacks_.clear();
518  eraseEdgeCallbacks_.clear();
519  }
520  private:
521  std::vector<MergeNodeCallBackType> mergeNodeCallbacks_;
522  std::vector<MergeEdgeCallBackType> mergeEdgeCallbacks_;
523  std::vector<EraseEdgeCallBackType> eraseEdgeCallbacks_;
524 };
525 
526 
527 
528 /** \brief undirected graph adaptor
529  for edge contraction and feature merging
530  */
531 template<class GRAPH>
533 : public MergeGraphCallbacks<
534  detail::GenericNode<vigra::Int64> ,
535  detail::GenericEdge<vigra::Int64>
536  >
537 
538 {
539 
540  public:
541  typedef vigra::Int64 IdType;
542  typedef IdType index_type;
544 
545 
546  typedef detail::GenericNode<index_type> Node;
547  typedef detail::GenericEdge<index_type> Edge;
548  typedef detail::GenericArc<index_type> Arc;
549 
550  typedef GRAPH Graph;
551  typedef typename Graph::Node GraphNode;
552  typedef typename Graph::Edge GraphEdge;
553  typedef typename Graph::Node GraphArc;
554 
555 
556 
557 
558 
559  //typedef std::set<index_type> NodeStorageEdgeSet;
560  typedef detail::GenericNodeImpl<index_type,false > NodeStorage;
561  typedef detail::GenericEdgeImpl<index_type > EdgeStorage;
562 
563 
564 
565  private:
566 
567  typedef std::map<vigra::UInt64 , std::vector<IdType> > DoubleMap;
569  typedef typename UfdType::const_iterator ConstUdfIter;
570  typedef ConstUdfIter EdgeIdIt;
571  typedef ConstUdfIter NodeIdIt;
572  typedef detail::NeighborNodeFilter<MergeGraphType> NnFilter;
573  typedef detail::IncEdgeFilter<MergeGraphType> IncFilter;
574  typedef detail::IsInFilter<MergeGraphType> InFlter;
575  typedef detail::IsOutFilter<MergeGraphType> OutFilter;
576  public:
577  typedef MergeGraphNodeIt<MergeGraphType> NodeIt;
578  typedef MergeGraphEdgeIt<MergeGraphType> EdgeIt;
579  typedef MergeGraphArcIt<MergeGraphType> ArcIt;
580  typedef detail::GenericIncEdgeIt<MergeGraphType,NodeStorage,NnFilter > NeighborNodeIt;
581  typedef detail::GenericIncEdgeIt<MergeGraphType,NodeStorage,IncFilter > IncEdgeIt;
582  typedef detail::GenericIncEdgeIt<MergeGraphType,NodeStorage,InFlter > InArcIt;
583  typedef detail::GenericIncEdgeIt<MergeGraphType,NodeStorage,OutFilter > OutArcIt;
584 
585 
586 
587  template<class T>
588  struct EdgeMap : DenseEdgeReferenceMap<MergeGraphType,T> {
589  EdgeMap(): DenseEdgeReferenceMap<MergeGraphType,T>(){
590  }
591  EdgeMap(const MergeGraphType & g)
592  : DenseEdgeReferenceMap<MergeGraphType,T>(g){
593  }
594  EdgeMap(const MergeGraphType & g,const T & val)
595  : DenseEdgeReferenceMap<MergeGraphType,T>(g,val){
596  }
597  };
598 
599  template<class T>
600  struct NodeMap : DenseNodeReferenceMap<MergeGraphType,T> {
601  NodeMap(): DenseNodeReferenceMap<MergeGraphType,T>(){
602  }
603  NodeMap(const MergeGraphType & g)
604  : DenseNodeReferenceMap<MergeGraphType,T>(g){
605  }
606  NodeMap(const MergeGraphType & g,const T & val)
607  : DenseNodeReferenceMap<MergeGraphType,T>(g,val){
608  }
609  };
610 
611  template<class T>
612  struct ArcMap : DenseArcReferenceMap<MergeGraphType,T> {
613  ArcMap(): DenseArcReferenceMap<MergeGraphType,T>(){
614  }
615  ArcMap(const MergeGraphType & g)
616  : DenseArcReferenceMap<MergeGraphType,T>(g){
617  }
618  ArcMap(const MergeGraphType & g,const T & val)
619  : DenseArcReferenceMap<MergeGraphType,T>(g,val){
620  }
621  };
622 
623 
624 
625  private:
626  MergeGraphAdaptor(); // non empty-construction
627  MergeGraphAdaptor( const MergeGraphAdaptor& other ); // non construction-copyable
628  MergeGraphAdaptor& operator=( const MergeGraphAdaptor& ); // non copyable
629  public:
630  MergeGraphAdaptor(const Graph & graph);
631  //void setInitalEdge(const size_t initEdge,const size_t initNode0,const size_t initNode1);
632 
633  // query (sizes)
634  size_t edgeNum()const;
635  size_t nodeNum()const;
636  size_t arcNum()const;
637 
638  IdType maxEdgeId()const;
639  IdType maxNodeId()const;
640  IdType maxArcId()const;
641 
642 
643  // query (iterators )
644  EdgeIdIt edgeIdsBegin()const;
645  EdgeIdIt edgeIdsEnd()const;
646  NodeIdIt nodeIdsBegin()const;
647  NodeIdIt nodeIdsEnd()const;
648 
649 
650 
651 
652  // query (get edge / nodes from id)
653  Edge edgeFromId(const IdType index)const;
654  Node nodeFromId(const IdType index)const;
655  Arc arcFromId( const IdType index)const;
656 
657 
658 
659 
660 
661  // query ( has edge )
662  bool hasEdgeId(const IdType edgeIndex)const;
663  bool hasNodeId(const IdType nodeIndex)const;
664  bool hasArcId(const IdType arcId)const{
665  return hasEdgeId(arcFromId(arcId).edgeId());
666  }
667 
668 
669  Edge findEdge(const Node & a,const Node & b)const;
670  Arc findArc(const Node & u,const Node & v)const;
671 
672 
673  IdType id(const Edge & edge)const;
674  IdType id(const Node & node)const;
675  IdType id(const Arc & arc)const;
676 
677 
678  size_t degree(const Node & node)const;
679 
680 
681 
682  Node u(const Edge & edge)const;
683  Node v(const Edge & edge)const;
684 
685  Node source(const Arc & arc)const{
686  if(arc!=lemon::INVALID)
687  return direction(arc) ? u(Edge(arc)) : v(Edge(arc));
688  else
689  return Node(lemon::INVALID);
690  }
691  Node target(const Arc & arc)const{
692  if(arc!=lemon::INVALID)
693  return direction(arc) ? v(Edge(arc)) : u(Edge(arc));
694  else
695  return Node(lemon::INVALID);
696  }
697 
698 
699  // query (w.r.t. inital nodesIds/edgesIds)
700  IdType reprEdgeId(const IdType edgeIndex)const;
701  IdType reprNodeId(const IdType nodeIndex)const;
702  bool stateOfInitalEdge(const IdType initalEdge)const;
703  // modification
704  void contractEdge(const Edge & edge);
705 
706 
707  Node oppositeNode(Node const &n, const Edge &e) const {
708  const Node uNode = u(e);
709  const Node vNode = v(e);
710  if(id(uNode)==id(n)){
711  return vNode;
712  }
713  else if(id(vNode)==id(n)){
714  return uNode;
715  }
716  else{
717  return Node(lemon::INVALID);
718  }
719  }
720 
721 
722  Arc direct(const Edge & edge,const bool forward)const{
723  if(edge!=lemon::INVALID){
724  if(forward)
725  return Arc(id(edge),id(edge));
726  else
727  return Arc(id(edge)+(maxEdgeId()+1),id(edge));
728  }
729  else{
730  return Arc(lemon::INVALID);
731  }
732  }
733  Arc direct(const Edge & edge,const Node & node)const{
734  if(u(edge)==node)
735  return direct(edge,true);
736  else if(v(edge)==node)
737  return direct(edge,false);
738  else
739  return Arc(lemon::INVALID);
740  }
741 
742  bool direction(const Arc & arc)const{
743  return arc.id()==arc.edgeId();
744  }
745 
746 
747  // special merge graph members
748  GraphEdge reprGraphEdge(const GraphEdge & edge)const{
749  return graph_.edgeFromId(reprEdgeId(graph_.id(edge)));
750  }
751  GraphNode reprGraphNode(const GraphNode & node)const{
752  return graph_.nodeFromId(reprNodeId(graph_.id(node)));
753  }
754 
755 
756  Edge reprEdge(const GraphEdge & edge)const{
757  return edgeFromId(reprEdgeId(graph_.id(edge)));
758  }
759  Node reprNode(const GraphNode & node)const{
760  return nodeFromId(reprNodeId(graph_.id(node)));
761  }
762 
763  const Graph & graph()const{
764  return graph_;
765  }
766  const Graph & graph(){
767  return graph_;
768  }
769 
770  // in which node is a "merged inactive" edge
771  Node inactiveEdgesNode(const Edge edge)const{
772  return reprNodeId(graphUId(id(edge)));
773  }
774  size_t maxDegree()const{
775  size_t md=0;
776  for(NodeIt it(*this);it!=lemon::INVALID;++it){
777  std::max(md, size_t( degree(*it) ) );
778  }
779  return md;
780  }
781 
782  void reset();
783 
784  private:
785  // needs acces to const nodeImpl
786  template<class G,class NIMPL,class FILT>
787  friend class detail::GenericIncEdgeIt;
788 
789  template<class G>
790  friend struct detail::NeighborNodeFilter;
791  template<class G>
792  friend struct detail::IncEdgeFilter;
793  template<class G>
794  friend struct detail::BackEdgeFilter;
795  template<class G>
796  friend struct detail::IsOutFilter;
797  template<class G>
798  friend struct detail::IsInFilter;
799  friend class MergeGraphNodeIt<MergeGraphType>;
800  friend class MergeGraphArcIt<MergeGraphType>;
801  friend class MergeGraphEdgeIt<MergeGraphType>;
802 
803  Edge edgeFromIdUnsave(const IdType index)const;
804 
805  index_type uId(const index_type edgeId)const;
806  index_type vId(const index_type edgeId)const;
807  index_type graphUId(const index_type edgeId)const;
808  index_type graphVId(const index_type edgeId)const;
809  //index_type uId(const Edge & edge)const{return uId(id(edge));}
810  //index_type vId(const Edge & edge)const{return vId(id(edge));}
811  const NodeStorage & nodeImpl(const Node & node)const{
812  return nodeVector_[id(node)];
813  }
814  NodeStorage & nodeImpl(const Node & node){
815  return nodeVector_[id(node)];
816  }
817 
818 
819  const GRAPH & graph_;
820  UfdType nodeUfd_;
821  UfdType edgeUfd_;
822 
823  std::vector< NodeStorage > nodeVector_;
824 
825  size_t nDoubleEdges_;
826  std::vector<std::pair<index_type,index_type> > doubleEdges_;
827 };
828 
829 
830 template<class GRAPH>
832 : MergeGraphCallbacks<Node,Edge >(),
833  graph_(graph),
834  nodeUfd_(graph.maxNodeId()+1),
835  edgeUfd_(graph.maxEdgeId()+1),
836  nodeVector_(graph.maxNodeId()+1),
837  nDoubleEdges_(0),
838  doubleEdges_(graph_.edgeNum()/2 +1)
839 {
840  for(index_type possibleNodeId = 0 ; possibleNodeId <= graph_.maxNodeId(); ++possibleNodeId){
841  if(graph_.nodeFromId(possibleNodeId)==lemon::INVALID){
842  nodeUfd_.eraseElement(possibleNodeId);
843  }
844  else{
845  nodeVector_[possibleNodeId].id_ = possibleNodeId;
846  }
847  }
848  for(index_type possibleEdgeId = 0 ; possibleEdgeId <= graph_.maxEdgeId(); ++possibleEdgeId){
849  const GraphEdge possibleEdge(graph_.edgeFromId(possibleEdgeId));
850  if(possibleEdge==lemon::INVALID){
851  edgeUfd_.eraseElement(possibleEdgeId);
852  }
853  else{
854  const index_type guid = graphUId(possibleEdgeId);
855  const index_type gvid = graphVId(possibleEdgeId);
856  nodeVector_[ guid ].insert(gvid,possibleEdgeId);
857  nodeVector_[ gvid ].insert(guid,possibleEdgeId);
858  }
859  }
860 
861 }
862 
863 
864 template<class GRAPH>
865 void MergeGraphAdaptor<GRAPH>::reset (){
866 
867  nodeUfd_.reset(graph_.maxNodeId()+1),
868  edgeUfd_.reset(graph_.maxEdgeId()+1),
869 
870  this->clearCallbacks();
871 
872  // clean nodes_
873  for(index_type possibleNodeId = 0 ; possibleNodeId <= graph_.maxNodeId(); ++possibleNodeId){
874 
875  nodeVector_[possibleNodeId].clear();
876  if(graph_.nodeFromId(possibleNodeId)==lemon::INVALID){
877  nodeUfd_.eraseElement(possibleNodeId);
878  }
879  else{
880  nodeVector_[possibleNodeId].id_ = possibleNodeId;
881  }
882  }
883 
884  for(index_type possibleEdgeId = 0 ; possibleEdgeId <= graph_.maxEdgeId(); ++possibleEdgeId){
885  const GraphEdge possibleEdge(graph_.edgeFromId(possibleEdgeId));
886  if(possibleEdge==lemon::INVALID){
887  edgeUfd_.eraseElement(possibleEdgeId);
888  }
889  else{
890  const index_type guid = graphUId(possibleEdgeId);
891  const index_type gvid = graphVId(possibleEdgeId);
892  nodeVector_[ guid ].insert(gvid,possibleEdgeId);
893  nodeVector_[ gvid ].insert(guid,possibleEdgeId);
894  }
895  }
896 }
897 
898 
899 template<class GRAPH>
900 inline typename MergeGraphAdaptor<GRAPH>::Edge
901 MergeGraphAdaptor<GRAPH>::findEdge (
902  const typename MergeGraphAdaptor<GRAPH>::Node & a,
903  const typename MergeGraphAdaptor<GRAPH>::Node & b
904 )const{
905 
906  if(a!=b){
907  std::pair<index_type,bool> res = nodeVector_[id(a)].findEdge(id(b));
908  if(res.second){
909  return Edge(res.first);
910  }
911  }
912  return Edge(lemon::INVALID);
913 }
914 
915 template<class GRAPH>
916 inline typename MergeGraphAdaptor<GRAPH>::Arc
917 MergeGraphAdaptor<GRAPH>::findArc (
918  const typename MergeGraphAdaptor<GRAPH>::Node & uNode,
919  const typename MergeGraphAdaptor<GRAPH>::Node & vNode
920 )const{
921  const Edge edge = findEdge(uNode,vNode);
922  if(edge==lemon::INVALID)
923  return Arc(lemon::INVALID);
924  else
925  return direct(edge,u(edge)==uNode);
926 }
927 
928 
929 template<class GRAPH>
930 inline typename MergeGraphAdaptor<GRAPH>::Node
931 MergeGraphAdaptor<GRAPH>::u(const Edge & edge)const{
932  return nodeFromId(uId(id(edge)));
933 }
934 
935 template<class GRAPH>
936 inline typename MergeGraphAdaptor<GRAPH>::Node
937 MergeGraphAdaptor<GRAPH>::v(const Edge & edge)const{
938  return nodeFromId(vId(id(edge)));
939 }
940 
941 template<class GRAPH>
942 inline typename MergeGraphAdaptor<GRAPH>::index_type
943 MergeGraphAdaptor<GRAPH>::uId(const index_type edgeId)const{
944  return reprNodeId(graphUId(edgeId));
945 }
946 
947 template<class GRAPH>
948 inline typename MergeGraphAdaptor<GRAPH>::index_type
949 MergeGraphAdaptor<GRAPH>::vId(const index_type edgeId)const{
950  return reprNodeId(graphVId(edgeId));
951 }
952 
953 
954 
955 template<class GRAPH>
956 inline typename MergeGraphAdaptor<GRAPH>::index_type
957 MergeGraphAdaptor<GRAPH>::graphUId(const index_type edgeId)const{
958  return graph_.id(graph_.u(graph_.edgeFromId(edgeId)));
959 }
960 
961 template<class GRAPH>
962 inline typename MergeGraphAdaptor<GRAPH>::index_type
963 MergeGraphAdaptor<GRAPH>::graphVId(const index_type edgeId)const{
964  return graph_.id(graph_.v(graph_.edgeFromId(edgeId)));
965 }
966 
967 
968 template<class GRAPH>
969 inline typename MergeGraphAdaptor<GRAPH>::IdType
970 MergeGraphAdaptor<GRAPH>::maxEdgeId()const {
971  return static_cast<index_type>(edgeUfd_.lastRep());
972 }
973 template<class GRAPH>
974 inline typename MergeGraphAdaptor<GRAPH>::IdType
975 MergeGraphAdaptor<GRAPH>::maxNodeId()const {
976  return static_cast<index_type>(nodeUfd_.lastRep());
977 }
978 
979 template<class GRAPH>
980 inline typename MergeGraphAdaptor<GRAPH>::IdType
981 MergeGraphAdaptor<GRAPH>::maxArcId()const {
982  return maxEdgeId()*2 +1 ;
983 }
984 
985 
986 #ifndef DOXYGEN // doxygen doesn't understand this
987 
988 template<class GRAPH>
989 inline typename MergeGraphAdaptor<GRAPH>::IdType
990 MergeGraphAdaptor<GRAPH>::id(
991  const typename MergeGraphAdaptor<GRAPH>::Edge & edge
992 )const{
993  return edge.id();
994 }
995 
996 template<class GRAPH>
997 inline typename MergeGraphAdaptor<GRAPH>::IdType
998 MergeGraphAdaptor<GRAPH>::id(
999  const typename MergeGraphAdaptor<GRAPH>::Node & node
1000 )const{
1001  return node.id();
1002 }
1003 
1004 template<class GRAPH>
1005 inline typename MergeGraphAdaptor<GRAPH>::IdType
1006 MergeGraphAdaptor<GRAPH>::id(
1007  const typename MergeGraphAdaptor<GRAPH>::Arc & arc
1008 )const{
1009  return arc.id();
1010 }
1011 
1012 #endif //DOXYGEN
1013 
1014 
1015 template<class GRAPH>
1016 inline size_t
1018  typename MergeGraphAdaptor<GRAPH>::Node const & node
1019 )const{
1020  return static_cast<size_t>( nodeVector_[id(node)].edgeNum() );
1021 }
1022 
1023 
1024 
1025 template<class GRAPH>
1026 inline typename MergeGraphAdaptor<GRAPH>::EdgeIdIt
1027 MergeGraphAdaptor<GRAPH>::edgeIdsBegin()const{
1028  return edgeUfd_.begin();
1029 }
1030 
1031 template<class GRAPH>
1032 inline typename MergeGraphAdaptor<GRAPH>::EdgeIdIt
1033 MergeGraphAdaptor<GRAPH>::edgeIdsEnd()const{
1034  return edgeUfd_.end();
1035 }
1036 
1037 
1038 template<class GRAPH>
1039 inline typename MergeGraphAdaptor<GRAPH>::NodeIdIt
1040 MergeGraphAdaptor<GRAPH>::nodeIdsBegin()const{
1041  return nodeUfd_.begin();
1042 }
1043 
1044 template<class GRAPH>
1045 inline typename MergeGraphAdaptor<GRAPH>::NodeIdIt
1046 MergeGraphAdaptor<GRAPH>::nodeIdsEnd()const{
1047  return nodeUfd_.end();
1048 }
1049 
1050 
1051 template<class GRAPH>
1052 inline typename MergeGraphAdaptor<GRAPH>::Edge
1053 MergeGraphAdaptor<GRAPH>::edgeFromIdUnsave(
1054  const typename MergeGraphAdaptor<GRAPH>::IdType index
1055 )const{
1056  return Edge(index);
1057 }
1058 
1059 template<class GRAPH>
1060 inline typename MergeGraphAdaptor<GRAPH>::Edge
1061 MergeGraphAdaptor<GRAPH>::edgeFromId(
1062  const typename MergeGraphAdaptor<GRAPH>::IdType index
1063 )const{
1064  if (hasEdgeId(index))
1065  return Edge(index);
1066  else
1067  return Edge(lemon::INVALID);
1068 }
1069 
1070 template<class GRAPH>
1071 inline typename MergeGraphAdaptor<GRAPH>::Node
1072 MergeGraphAdaptor<GRAPH>::nodeFromId(
1073  const typename MergeGraphAdaptor<GRAPH>::IdType index
1074 )const{
1075  if(hasNodeId(index))
1076  return Node(index);
1077  else
1078  return Node(lemon::INVALID);
1079 }
1080 
1081 template<class GRAPH>
1082 inline typename MergeGraphAdaptor<GRAPH>::Arc
1083 MergeGraphAdaptor<GRAPH>::arcFromId(
1084  const typename MergeGraphAdaptor<GRAPH>::IdType index
1085 )const{
1086  if(index<=maxEdgeId( ))
1087  return Arc(index,index);
1088  else
1089  return Arc(index, index-maxEdgeId() -1);
1090 }
1091 
1092 template<class GRAPH>
1093 inline bool
1094 MergeGraphAdaptor<GRAPH>::hasEdgeId(
1095  const typename MergeGraphAdaptor<GRAPH>::IdType edgeIndex
1096 )const{
1097  if(edgeIndex<=maxEdgeId() && !edgeUfd_.isErased(edgeIndex)){
1098  const IdType reprEdgeIndex = reprEdgeId(edgeIndex);
1099  if(reprEdgeIndex!=edgeIndex){
1100  return false;
1101  }
1102  else{
1103  const index_type rnid0= uId(reprEdgeIndex);
1104  const index_type rnid1= vId(reprEdgeIndex);
1105  return rnid0!=rnid1;
1106  }
1107  }
1108  else{
1109  return false;
1110  }
1111 }
1112 
1113 template<class GRAPH>
1114 inline bool
1115 MergeGraphAdaptor<GRAPH>::hasNodeId(
1116  const typename MergeGraphAdaptor<GRAPH>::IdType nodeIndex
1117 )const{
1118 
1119  return nodeIndex<=maxNodeId() && !nodeUfd_.isErased(nodeIndex) && nodeUfd_.find(nodeIndex)==nodeIndex;
1120 }
1121 
1122 template<class GRAPH>
1123 inline typename MergeGraphAdaptor<GRAPH>::IdType
1124 MergeGraphAdaptor<GRAPH>::reprEdgeId(
1125  const typename MergeGraphAdaptor<GRAPH>::IdType edgeIndex
1126 )const{
1127  return edgeUfd_.find(edgeIndex);
1128 }
1129 
1130 template<class GRAPH>
1131 inline typename MergeGraphAdaptor<GRAPH>::IdType
1132 MergeGraphAdaptor<GRAPH>::reprNodeId(
1133  const typename MergeGraphAdaptor<GRAPH>::IdType nodeIndex
1134 )const{
1135  return nodeUfd_.find(nodeIndex);
1136 }
1137 
1138 template<class GRAPH>
1139 inline bool MergeGraphAdaptor<GRAPH>::stateOfInitalEdge(
1140  const typename MergeGraphAdaptor<GRAPH>::IdType initalEdge
1141 )const{
1142 
1143  const index_type rnid0= reprNodeId( graphUId(initalEdge) );
1144  const index_type rnid1= reprNodeId( graphVId(initalEdge) );
1145  return rnid0!=rnid1;
1146 }
1147 
1148 template<class GRAPH>
1149 inline size_t MergeGraphAdaptor<GRAPH>::nodeNum()const{
1150  return nodeUfd_.numberOfSets();
1151 }
1152 
1153 template<class GRAPH>
1154 inline size_t MergeGraphAdaptor<GRAPH>::arcNum()const{
1155  return edgeNum()*2;
1156 }
1157 
1158 template<class GRAPH>
1159 inline size_t MergeGraphAdaptor<GRAPH>::edgeNum()const{
1160  return edgeUfd_.numberOfSets();
1161 }
1162 
1163 template<class GRAPH>
1164 void MergeGraphAdaptor<GRAPH>::contractEdge(
1165  const typename MergeGraphAdaptor<GRAPH>::Edge & toDeleteEdge
1166 ){
1167  //std::cout<<"node num "<<nodeNum()<<"\n";
1168  const index_type toDeleteEdgeIndex = id(toDeleteEdge);
1169  const index_type nodesIds[2]={id(u(toDeleteEdge)),id(v(toDeleteEdge))};
1170 
1171  // merge the two nodes
1172  nodeUfd_.merge(nodesIds[0],nodesIds[1]);
1173  const IdType newNodeRep = reprNodeId(nodesIds[0]);
1174  const IdType notNewNodeRep = (newNodeRep == nodesIds[0] ? nodesIds[1] : nodesIds[0] );
1175 
1176  typename NodeStorage::AdjIt iter=nodeVector_[notNewNodeRep].adjacencyBegin();
1177  typename NodeStorage::AdjIt end =nodeVector_[notNewNodeRep].adjacencyEnd();
1178 
1179  nDoubleEdges_=0;
1180  for(;iter!=end;++iter){
1181  const size_t adjToDeadNodeId = iter->nodeId();
1182  if(newNodeRep < 0 || adjToDeadNodeId!=static_cast<unsigned long long>(newNodeRep)){
1183 
1184  // REFACTOR ME, we can make that faster if
1185  // we do that in set intersect style
1186  std::pair<index_type,bool> found=nodeVector_[adjToDeadNodeId].findEdge(newNodeRep);
1187 
1188 
1189  if(found.second){
1190  edgeUfd_.merge(iter->edgeId(),found.first);
1191 
1192  const index_type edgeA = iter->edgeId();
1193  const index_type edgeB = found.first;
1194  const index_type edgeR = edgeUfd_.find(edgeA);
1195  const index_type edgeNR = edgeR==edgeA ? edgeB : edgeA;
1196 
1197  nodeVector_[adjToDeadNodeId].eraseFromAdjacency(notNewNodeRep);
1198 
1199  // refactor me ... this DOES NOT change the key
1200  nodeVector_[adjToDeadNodeId].eraseFromAdjacency(newNodeRep);
1201  nodeVector_[adjToDeadNodeId].insert(newNodeRep,edgeR);
1202 
1203  // refactor me .. this DOES NOT change the key
1204  nodeVector_[newNodeRep].eraseFromAdjacency(adjToDeadNodeId);
1205  nodeVector_[newNodeRep].insert(adjToDeadNodeId,edgeR);
1206 
1207  doubleEdges_[nDoubleEdges_]=std::pair<index_type,index_type>(edgeR,edgeNR );
1208  ++nDoubleEdges_;
1209  }
1210  else{
1211  nodeVector_[adjToDeadNodeId].eraseFromAdjacency(notNewNodeRep);
1212  //nodeVector_[adjToDeadNodeId].eraseFromAdjacency(newNodeRep);
1213  nodeVector_[adjToDeadNodeId].insert(newNodeRep,iter->edgeId());
1214 
1215  // symetric
1216  //nodeVector_[newNodeRep].eraseFromAdjacency(adjToDeadNodeId);
1217  nodeVector_[newNodeRep].insert(adjToDeadNodeId,iter->edgeId());
1218 
1219  }
1220  }
1221  }
1222 
1223  //nodeVector_[newNodeRep].merge(nodeVector_[notNewNodeRep]);
1224  nodeVector_[newNodeRep].eraseFromAdjacency(notNewNodeRep);
1225  //nodeVector_[newNodeRep].eraseFromAdjacency(newNodeRep); // no self adjacecy
1226  nodeVector_[notNewNodeRep].clear();
1227 
1228  edgeUfd_.eraseElement(toDeleteEdgeIndex);
1229 
1230  //std::cout<<"merge nodes callbacks\n";
1231 
1232  this->callMergeNodeCallbacks(Node(newNodeRep),Node(notNewNodeRep));
1233 
1234  //std::cout<<"merge double edge callbacks\n";
1235  for(size_t de=0;de<nDoubleEdges_;++de){
1236  this->callMergeEdgeCallbacks(Edge(doubleEdges_[de].first),Edge(doubleEdges_[de].second));
1237  }
1238  //std::cout<<"erase edge callbacks\n";
1239  this->callEraseEdgeCallbacks(Edge(toDeleteEdgeIndex));
1240 
1241  //std::cout<<"and done\n";
1242 }
1243 
1244 
1245 
1246 namespace merge_graph_detail {
1247 /// Construct a partition.
1248 template<class T>
1250 : parents_(),
1251  ranks_(),
1252  jumpVec_(),
1253  firstRep_(0),
1254  lastRep_(0),
1255  numberOfElements_(0),
1256  numberOfSets_(0)
1257 {}
1258 
1259 /// Construct a partition.
1260 ///
1261 /// \param size Number of distinct sets.
1262 ///
1263 template<class T>
1264 inline
1267  const value_type& size
1268 )
1269 : parents_(static_cast<SizeTType>(size)),
1270  ranks_(static_cast<SizeTType>(size)),
1271  jumpVec_(static_cast<SizeTType>(size)),
1272  firstRep_(0),
1273  lastRep_(static_cast<SizeTType>(size)-1),
1274  numberOfElements_(size),
1275  numberOfSets_(size)
1276 {
1277  for(T j=0; j<size; ++j) {
1278  parents_[static_cast<SizeTType>(j)] = j;
1279  }
1280 
1281  jumpVec_.front().first=0;
1282  jumpVec_.front().second=1;
1283  for(T j=1; j<size-1;++j){
1284  jumpVec_[j].first =1;
1285  jumpVec_[j].second=1;
1286  }
1287  jumpVec_.back().first=1;
1288  jumpVec_.back().second=0;
1289 }
1290 
1291 /// Reset a partition such that each set contains precisely one element
1292 ///
1293 /// \param size Number of distinct sets.
1294 ///
1295 template<class T>
1296 inline void
1299  const value_type& size
1300 )
1301 {
1302  numberOfElements_ = size;
1303  numberOfSets_ = size;
1304  ranks_.resize(static_cast<SizeTType>(size));
1305  parents_.resize(static_cast<SizeTType>(size));
1306  jumpVec_.resize(static_cast<SizeTType>(size));
1307  firstRep_=0;
1308  lastRep_=static_cast<SizeTType>(size)-1;
1309  for(T j=0; j<size; ++j) {
1310  ranks_[static_cast<SizeTType>(j)] = 0;
1311  parents_[static_cast<SizeTType>(j)] = j;
1312  }
1313 
1314  jumpVec_.front().first=0;
1315  jumpVec_.front().second=1;
1316  for(T j=1; j<size-1;++j){
1317  jumpVec_[j].first =1;
1318  jumpVec_[j].second=1;
1319  }
1320  jumpVec_.back().first=1;
1321  jumpVec_.back().second=0;
1322 }
1323 
1324 /// Find the representative element of the set that contains the given element.
1325 ///
1326 /// This constant function does not compress the search path.
1327 ///
1328 /// \param element Element.
1329 ///
1330 template<class T>
1331 inline typename IterablePartition<T>::value_type
1334  const value_type& element
1335 ) const
1336 {
1337  // find the root
1338  value_type root = element;
1339  while(parents_[static_cast<SizeTType>(root)] != root) {
1340  root = parents_[static_cast<SizeTType>(root)];
1341  }
1342  return root;
1343 }
1344 
1345 /// Find the representative element of the set that contains the given element.
1346 ///
1347 /// This mutable function compresses the search path.
1348 ///
1349 /// \param element Element.
1350 ///
1351 template<class T>
1352 inline typename IterablePartition<T>::value_type
1355  value_type element // copy to work with
1356 )
1357 {
1358  // find the root
1359  value_type root = element;
1360  while(parents_[static_cast<SizeTType>(root)] != root) {
1361  root = parents_[static_cast<SizeTType>(root)];
1362  }
1363  // path compression
1364  while(element != root) {
1365  value_type tmp = parents_[static_cast<SizeTType>(element)];
1366  parents_[static_cast<SizeTType>(element)] = root;
1367  element = tmp;
1368  }
1369  return root;
1370 }
1371 
1372 /// Merge two sets.
1373 ///
1374 /// \param element1 Element in the first set.
1375 /// \param element2 Element in the second set.
1376 ///
1377 template<class T>
1378 inline void
1381  value_type element1,
1382  value_type element2
1383 )
1384 {
1385  // merge by rank
1386  element1 = find(element1);
1387  element2 = find(element2);
1388  if(element1!=element2){
1389  T notRep;
1390  if(ranks_[static_cast<SizeTType>(element1)] < ranks_[static_cast<SizeTType>(element2)]) {
1391  parents_[static_cast<SizeTType>(element1)] = element2;
1392  --numberOfSets_;
1393  //rep=element2;
1394  notRep=element1;
1395  }
1396  else if(ranks_[static_cast<SizeTType>(element1)] > ranks_[static_cast<SizeTType>(element2)]) {
1397  parents_[static_cast<SizeTType>(element2)] = element1;
1398  --numberOfSets_;
1399  //rep=element1;
1400  notRep=element2;
1401  }
1402  else if(element1 != element2) {
1403  parents_[static_cast<SizeTType>(element2)] = element1;
1404  ++ranks_[static_cast<SizeTType>(element1)];
1405  --numberOfSets_;
1406  //rep=element1;
1407  notRep=element2;
1408  }
1409  this->eraseElement(notRep,false);
1410  }
1411 }
1412 
1413 template<class T>
1414 inline typename IterablePartition<T>::value_type
1416 {
1417  return numberOfElements_;
1418 }
1419 
1420 template<class T>
1421 inline typename IterablePartition<T>::value_type
1422 IterablePartition<T>::numberOfSets() const
1423 {
1424  return numberOfSets_;
1425 }
1426 
1427 template<class T>
1428 inline bool operator == (const ConstRepIter<T> & iter,const lemon::Invalid & /*iv*/){
1429  return iter.isEnd();
1430 }
1431 template<class T>
1432 inline bool operator == (const lemon::Invalid & /*iv*/ , const ConstRepIter<T> & iter){
1433  return iter.isEnd();
1434 }
1435 
1436 template<class T>
1437 inline bool operator != (const ConstRepIter<T> & iter,const lemon::Invalid & /*iv*/){
1438  return !iter.isEnd();
1439 }
1440 template<class T>
1441 inline bool operator != (const lemon::Invalid & /*iv*/ , const ConstRepIter<T> & iter){
1442  return !iter.isEnd();
1443 }
1444 
1445 
1446 } // end namespace merge_graph_detail
1447 
1448 
1449 } // end namespace vigra
1450 
1451 
1452 
1453 #endif //VIGRA_NEW_MERGE_GRAPH_HXX
void merge(value_type, value_type)
Definition: merge_graph_adaptor.hxx:1380
vigra::GridGraph< N, DirectedTag >::degree_size_type degree(typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &v, vigra::GridGraph< N, DirectedTag > const &g)
Return total number of edges (incoming and outgoing) of vertex v (API: boost).
Definition: multi_gridgraph.hxx:2828
Definition: merge_graph_adaptor.hxx:70
value_type find(const value_type &) const
Definition: merge_graph_adaptor.hxx:1333
undirected graph adaptor for edge contraction and feature merging
Definition: merge_graph_adaptor.hxx:532
IterablePartition()
Construct a partition.
Definition: merge_graph_adaptor.hxx:1249
void reset(const value_type &)
Definition: merge_graph_adaptor.hxx:1298
detail::SelectIntegerType< 64, detail::SignedIntTypes >::type Int64
64-bit signed int
Definition: sized_int.hxx:177
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825
std::pair< typename vigra::GridGraph< N, DirectedTag >::edge_descriptor, bool > edge(typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &u, typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &v, vigra::GridGraph< N, DirectedTag > const &g)
Return the pair (edge_descriptor, true) when an edge between vertices u and v exists, or (lemon::INVALID, false) otherwise (API: boost).
Definition: multi_gridgraph.hxx:2990

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)