unionfind.h
Go to the documentation of this file.
1 /* Copyright (C) 2013-2016, The Regents of The University of Michigan.
2 All rights reserved.
3 
4 This software was developed in the APRIL Robotics Lab under the
5 direction of Edwin Olson, ebolson@umich.edu. This software may be
6 available under alternative licensing terms; contact the address above.
7 
8  Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10 
11 1. Redistributions of source code must retain the above copyright notice, this
12  list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 The views and conclusions contained in the software and documentation are those
29 of the authors and should not be interpreted as representing official policies,
30 either expressed or implied, of the Regents of The University of Michigan.
31 */
32 
33 #ifndef _UNIONFIND_H
34 #define _UNIONFIND_H
35 
36 #include <stdint.h>
37 #include <stdlib.h>
38 
39 typedef struct unionfind unionfind_t;
40 
41 struct unionfind
42 {
43  uint32_t maxid;
44  struct ufrec *data;
45 };
46 
47 struct ufrec
48 {
49  // the parent of this node. If a node's parent is its own index,
50  // then it is a root.
51  uint32_t parent;
52 
53  // for the root of a connected component, the number of components
54  // connected to it. For intermediate values, it's not meaningful.
55  uint32_t size;
56 };
57 
58 static inline unionfind_t *unionfind_create(uint32_t maxid)
59 {
60  unionfind_t *uf = (unionfind_t*) calloc(1, sizeof(unionfind_t));
61  uf->maxid = maxid;
62  uf->data = (struct ufrec*) malloc((maxid+1) * sizeof(struct ufrec));
63  for (int i = 0; i <= maxid; i++) {
64  uf->data[i].size = 1;
65  uf->data[i].parent = i;
66  }
67  return uf;
68 }
69 
70 static inline void unionfind_destroy(unionfind_t *uf)
71 {
72  free(uf->data);
73  free(uf);
74 }
75 
76 /*
77 static inline uint32_t unionfind_get_representative(unionfind_t *uf, uint32_t id)
78 {
79  // base case: a node is its own parent
80  if (uf->data[id].parent == id)
81  return id;
82 
83  // otherwise, recurse
84  uint32_t root = unionfind_get_representative(uf, uf->data[id].parent);
85 
86  // short circuit the path. [XXX This write prevents tail recursion]
87  uf->data[id].parent = root;
88 
89  return root;
90 }
91 */
92 
93 // this one seems to be every-so-slightly faster than the recursive
94 // version above.
95 static inline uint32_t unionfind_get_representative(unionfind_t *uf, uint32_t id)
96 {
97  uint32_t root = id;
98 
99  // chase down the root
100  while (uf->data[root].parent != root) {
101  root = uf->data[root].parent;
102  }
103 
104  // go back and collapse the tree.
105  //
106  // XXX: on some of our workloads that have very shallow trees
107  // (e.g. image segmentation), we are actually faster not doing
108  // this...
109  while (uf->data[id].parent != root) {
110  uint32_t tmp = uf->data[id].parent;
111  uf->data[id].parent = root;
112  id = tmp;
113  }
114 
115  return root;
116 }
117 
118 static inline uint32_t unionfind_get_set_size(unionfind_t *uf, uint32_t id)
119 {
120  uint32_t repid = unionfind_get_representative(uf, id);
121  return uf->data[repid].size;
122 }
123 
124 static inline uint32_t unionfind_connect(unionfind_t *uf, uint32_t aid, uint32_t bid)
125 {
126  uint32_t aroot = unionfind_get_representative(uf, aid);
127  uint32_t broot = unionfind_get_representative(uf, bid);
128 
129  if (aroot == broot)
130  return aroot;
131 
132  // we don't perform "union by rank", but we perform a similar
133  // operation (but probably without the same asymptotic guarantee):
134  // We join trees based on the number of *elements* (as opposed to
135  // rank) contained within each tree. I.e., we use size as a proxy
136  // for rank. In my testing, it's often *faster* to use size than
137  // rank, perhaps because the rank of the tree isn't that critical
138  // if there are very few nodes in it.
139  uint32_t asize = uf->data[aroot].size;
140  uint32_t bsize = uf->data[broot].size;
141 
142  // optimization idea: We could shortcut some or all of the tree
143  // that is grafted onto the other tree. Pro: those nodes were just
144  // read and so are probably in cache. Con: it might end up being
145  // wasted effort -- the tree might be grafted onto another tree in
146  // a moment!
147  if (asize > bsize) {
148  uf->data[broot].parent = aroot;
149  uf->data[aroot].size += bsize;
150  return aroot;
151  } else {
152  uf->data[aroot].parent = broot;
153  uf->data[broot].size += asize;
154  return broot;
155  }
156 }
157 #endif
static unionfind_t * unionfind_create(uint32_t maxid)
Definition: unionfind.h:58
struct ufrec * data
Definition: unionfind.h:44
static uint32_t unionfind_get_representative(unionfind_t *uf, uint32_t id)
Definition: unionfind.h:95
static uint32_t unionfind_get_set_size(unionfind_t *uf, uint32_t id)
Definition: unionfind.h:118
static uint32_t unionfind_connect(unionfind_t *uf, uint32_t aid, uint32_t bid)
Definition: unionfind.h:124
static void unionfind_destroy(unionfind_t *uf)
Definition: unionfind.h:70
uint32_t maxid
Definition: unionfind.h:43
uint32_t parent
Definition: unionfind.h:51
uint32_t size
Definition: unionfind.h:55


apriltags2
Author(s): Danylo Malyuta
autogenerated on Fri Oct 19 2018 04:02:32