relaxed_heap.hpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. // Copyright 2004 The Trustees of Indiana University.
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Authors: Douglas Gregor
  6. // Andrew Lumsdaine
  7. #ifndef BOOST_RELAXED_HEAP_HEADER
  8. #define BOOST_RELAXED_HEAP_HEADER
  9. #include <functional>
  10. #include <boost/property_map/property_map.hpp>
  11. #include <boost/optional.hpp>
  12. #include <vector>
  13. #include <climits> // for CHAR_BIT
  14. #include <boost/none.hpp>
  15. #ifdef BOOST_RELAXED_HEAP_DEBUG
  16. # include <iostream>
  17. #endif // BOOST_RELAXED_HEAP_DEBUG
  18. #if defined(BOOST_MSVC)
  19. # pragma warning(push)
  20. # pragma warning(disable:4355) // complaint about using 'this' to
  21. #endif // initialize a member
  22. namespace boost {
  23. template<typename IndexedType,
  24. typename Compare = std::less<IndexedType>,
  25. typename ID = identity_property_map>
  26. class relaxed_heap
  27. {
  28. struct group;
  29. typedef relaxed_heap self_type;
  30. typedef std::size_t rank_type;
  31. public:
  32. typedef IndexedType value_type;
  33. typedef rank_type size_type;
  34. private:
  35. /**
  36. * The kind of key that a group has. The actual values are discussed
  37. * in-depth in the documentation of the @c kind field of the @c group
  38. * structure. Note that the order of the enumerators *IS* important
  39. * and must not be changed.
  40. */
  41. enum group_key_kind { smallest_key, stored_key, largest_key };
  42. struct group {
  43. explicit group(group_key_kind kind = largest_key)
  44. : kind(kind), parent(this), rank(0) { }
  45. /** The value associated with this group. This value is only valid
  46. * when @c kind!=largest_key (which indicates a deleted
  47. * element). Note that the use of boost::optional increases the
  48. * memory requirements slightly but does not result in extraneous
  49. * memory allocations or deallocations. The optional could be
  50. * eliminated when @c value_type is a model of
  51. * DefaultConstructible.
  52. */
  53. ::boost::optional<value_type> value;
  54. /**
  55. * The kind of key stored at this group. This may be @c
  56. * smallest_key, which indicates that the key is infinitely small;
  57. * @c largest_key, which indicates that the key is infinitely
  58. * large; or @c stored_key, which means that the key is unknown,
  59. * but its relationship to other keys can be determined via the
  60. * comparison function object.
  61. */
  62. group_key_kind kind;
  63. /// The parent of this group. Will only be NULL for the dummy root group
  64. group* parent;
  65. /// The rank of this group. Equivalent to the number of children in
  66. /// the group.
  67. rank_type rank;
  68. /** The children of this group. For the dummy root group, these are
  69. * the roots. This is an array of length log n containing pointers
  70. * to the child groups.
  71. */
  72. group** children;
  73. };
  74. size_type log_base_2(size_type n) // log2 is a macro on some platforms
  75. {
  76. size_type leading_zeroes = 0;
  77. do {
  78. size_type next = n << 1;
  79. if (n == (next >> 1)) {
  80. ++leading_zeroes;
  81. n = next;
  82. } else {
  83. break;
  84. }
  85. } while (true);
  86. return sizeof(size_type) * CHAR_BIT - leading_zeroes - 1;
  87. }
  88. public:
  89. relaxed_heap(size_type n, const Compare& compare = Compare(),
  90. const ID& id = ID())
  91. : compare(compare), id(id), root(smallest_key), groups(n),
  92. smallest_value(0)
  93. {
  94. if (n == 0) {
  95. root.children = new group*[1];
  96. return;
  97. }
  98. log_n = log_base_2(n);
  99. if (log_n == 0) log_n = 1;
  100. size_type g = n / log_n;
  101. if (n % log_n > 0) ++g;
  102. size_type log_g = log_base_2(g);
  103. size_type r = log_g;
  104. // Reserve an appropriate amount of space for data structures, so
  105. // that we do not need to expand them.
  106. index_to_group.resize(g);
  107. A.resize(r + 1, 0);
  108. root.rank = r + 1;
  109. root.children = new group*[(log_g + 1) * (g + 1)];
  110. for (rank_type i = 0; i < r+1; ++i) root.children[i] = 0;
  111. // Build initial heap
  112. size_type idx = 0;
  113. while (idx < g) {
  114. root.children[r] = &index_to_group[idx];
  115. idx = build_tree(root, idx, r, log_g + 1);
  116. if (idx != g)
  117. r = static_cast<size_type>(log_base_2(g-idx));
  118. }
  119. }
  120. ~relaxed_heap() { delete [] root.children; }
  121. void push(const value_type& x)
  122. {
  123. groups[get(id, x)] = x;
  124. update(x);
  125. }
  126. void update(const value_type& x)
  127. {
  128. group* a = &index_to_group[get(id, x) / log_n];
  129. if (!a->value
  130. || *a->value == x
  131. || compare(x, *a->value)) {
  132. if (a != smallest_value) smallest_value = 0;
  133. a->kind = stored_key;
  134. a->value = x;
  135. promote(a);
  136. }
  137. }
  138. void remove(const value_type& x)
  139. {
  140. group* a = &index_to_group[get(id, x) / log_n];
  141. assert(groups[get(id, x)] != 0);
  142. a->value = x;
  143. a->kind = smallest_key;
  144. promote(a);
  145. smallest_value = a;
  146. pop();
  147. }
  148. value_type& top()
  149. {
  150. find_smallest();
  151. assert(smallest_value->value != none);
  152. return *smallest_value->value;
  153. }
  154. const value_type& top() const
  155. {
  156. find_smallest();
  157. assert(smallest_value->value != none);
  158. return *smallest_value->value;
  159. }
  160. bool empty() const
  161. {
  162. find_smallest();
  163. return !smallest_value || (smallest_value->kind == largest_key);
  164. }
  165. bool contains(const value_type& x) const { return groups[get(id, x)]; }
  166. void pop()
  167. {
  168. // Fill in smallest_value. This is the group x.
  169. find_smallest();
  170. group* x = smallest_value;
  171. smallest_value = 0;
  172. // Make x a leaf, giving it the smallest value within its group
  173. rank_type r = x->rank;
  174. group* p = x->parent;
  175. {
  176. assert(x->value != none);
  177. // Find x's group
  178. size_type start = get(id, *x->value) - get(id, *x->value) % log_n;
  179. size_type end = start + log_n;
  180. if (end > groups.size()) end = groups.size();
  181. // Remove the smallest value from the group, and find the new
  182. // smallest value.
  183. groups[get(id, *x->value)].reset();
  184. x->value.reset();
  185. x->kind = largest_key;
  186. for (size_type i = start; i < end; ++i) {
  187. if (groups[i] && (!x->value || compare(*groups[i], *x->value))) {
  188. x->kind = stored_key;
  189. x->value = groups[i];
  190. }
  191. }
  192. }
  193. x->rank = 0;
  194. // Combine prior children of x with x
  195. group* y = x;
  196. for (size_type c = 0; c < r; ++c) {
  197. group* child = x->children[c];
  198. if (A[c] == child) A[c] = 0;
  199. y = combine(y, child);
  200. }
  201. // If we got back something other than x, let y take x's place
  202. if (y != x) {
  203. y->parent = p;
  204. p->children[r] = y;
  205. assert(r == y->rank);
  206. if (A[y->rank] == x)
  207. A[y->rank] = do_compare(y, p)? y : 0;
  208. }
  209. }
  210. #ifdef BOOST_RELAXED_HEAP_DEBUG
  211. /*************************************************************************
  212. * Debugging support *
  213. *************************************************************************/
  214. void dump_tree() { dump_tree(std::cout); }
  215. void dump_tree(std::ostream& out) { dump_tree(out, &root); }
  216. void dump_tree(std::ostream& out, group* p, bool in_progress = false)
  217. {
  218. if (!in_progress) {
  219. out << "digraph heap {\n"
  220. << " edge[dir=\"back\"];\n";
  221. }
  222. size_type p_index = 0;
  223. if (p != &root) while (&index_to_group[p_index] != p) ++p_index;
  224. for (size_type i = 0; i < p->rank; ++i) {
  225. group* c = p->children[i];
  226. if (c) {
  227. size_type c_index = 0;
  228. if (c != &root) while (&index_to_group[c_index] != c) ++c_index;
  229. out << " ";
  230. if (p == &root) out << 'p'; else out << p_index;
  231. out << " -> ";
  232. if (c == &root) out << 'p'; else out << c_index;
  233. if (A[c->rank] == c) out << " [style=\"dotted\"]";
  234. out << ";\n";
  235. dump_tree(out, c, true);
  236. // Emit node information
  237. out << " ";
  238. if (c == &root) out << 'p'; else out << c_index;
  239. out << " [label=\"";
  240. if (c == &root) out << 'p'; else out << c_index;
  241. out << ":";
  242. size_type start = c_index * log_n;
  243. size_type end = start + log_n;
  244. if (end > groups.size()) end = groups.size();
  245. while (start != end) {
  246. if (groups[start]) {
  247. out << " " << get(id, *groups[start]);
  248. if (*groups[start] == *c->value) out << "(*)";
  249. }
  250. ++start;
  251. }
  252. out << '"';
  253. if (do_compare(c, p)) {
  254. out << " ";
  255. if (c == &root) out << 'p'; else out << c_index;
  256. out << ", style=\"filled\", fillcolor=\"gray\"";
  257. }
  258. out << "];\n";
  259. } else {
  260. assert(p->parent == p);
  261. }
  262. }
  263. if (!in_progress) out << "}\n";
  264. }
  265. bool valid()
  266. {
  267. // Check that the ranks in the A array match the ranks of the
  268. // groups stored there. Also, the active groups must be the last
  269. // child of their parent.
  270. for (size_type r = 0; r < A.size(); ++r) {
  271. if (A[r] && A[r]->rank != r) return false;
  272. if (A[r] && A[r]->parent->children[A[r]->parent->rank-1] != A[r])
  273. return false;
  274. }
  275. // The root must have no value and a key of -Infinity
  276. if (root.kind != smallest_key) return false;
  277. return valid(&root);
  278. }
  279. bool valid(group* p)
  280. {
  281. for (size_type i = 0; i < p->rank; ++i) {
  282. group* c = p->children[i];
  283. if (c) {
  284. // Check link structure
  285. if (c->parent != p) return false;
  286. if (c->rank != i) return false;
  287. // A bad group must be active
  288. if (do_compare(c, p) && A[i] != c) return false;
  289. // Check recursively
  290. if (!valid(c)) return false;
  291. } else {
  292. // Only the root may
  293. if (p != &root) return false;
  294. }
  295. }
  296. return true;
  297. }
  298. #endif // BOOST_RELAXED_HEAP_DEBUG
  299. private:
  300. size_type
  301. build_tree(group& parent, size_type idx, size_type r, size_type max_rank)
  302. {
  303. group& this_group = index_to_group[idx];
  304. this_group.parent = &parent;
  305. ++idx;
  306. this_group.children = root.children + (idx * max_rank);
  307. this_group.rank = r;
  308. for (size_type i = 0; i < r; ++i) {
  309. this_group.children[i] = &index_to_group[idx];
  310. idx = build_tree(this_group, idx, i, max_rank);
  311. }
  312. return idx;
  313. }
  314. void find_smallest() const
  315. {
  316. group** roots = root.children;
  317. if (!smallest_value) {
  318. std::size_t i;
  319. for (i = 0; i < root.rank; ++i) {
  320. if (roots[i] &&
  321. (!smallest_value || do_compare(roots[i], smallest_value))) {
  322. smallest_value = roots[i];
  323. }
  324. }
  325. for (i = 0; i < A.size(); ++i) {
  326. if (A[i] && (!smallest_value || do_compare(A[i], smallest_value)))
  327. smallest_value = A[i];
  328. }
  329. }
  330. }
  331. bool do_compare(group* x, group* y) const
  332. {
  333. return (x->kind < y->kind
  334. || (x->kind == y->kind
  335. && x->kind == stored_key
  336. && compare(*x->value, *y->value)));
  337. }
  338. void promote(group* a)
  339. {
  340. assert(a != 0);
  341. rank_type r = a->rank;
  342. group* p = a->parent;
  343. assert(p != 0);
  344. if (do_compare(a, p)) {
  345. // s is the rank + 1 sibling
  346. group* s = p->rank > r + 1? p->children[r + 1] : 0;
  347. // If a is the last child of p
  348. if (r == p->rank - 1) {
  349. if (!A[r]) A[r] = a;
  350. else if (A[r] != a) pair_transform(a);
  351. } else {
  352. assert(s != 0);
  353. if (A[r + 1] == s) active_sibling_transform(a, s);
  354. else good_sibling_transform(a, s);
  355. }
  356. }
  357. }
  358. group* combine(group* a1, group* a2)
  359. {
  360. assert(a1->rank == a2->rank);
  361. if (do_compare(a2, a1)) do_swap(a1, a2);
  362. a1->children[a1->rank++] = a2;
  363. a2->parent = a1;
  364. clean(a1);
  365. return a1;
  366. }
  367. void clean(group* q)
  368. {
  369. if (2 > q->rank) return;
  370. group* qp = q->children[q->rank-1];
  371. rank_type s = q->rank - 2;
  372. group* x = q->children[s];
  373. group* xp = qp->children[s];
  374. assert(s == x->rank);
  375. // If x is active, swap x and xp
  376. if (A[s] == x) {
  377. q->children[s] = xp;
  378. xp->parent = q;
  379. qp->children[s] = x;
  380. x->parent = qp;
  381. }
  382. }
  383. void pair_transform(group* a)
  384. {
  385. #if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
  386. std::cerr << "- pair transform\n";
  387. #endif
  388. rank_type r = a->rank;
  389. // p is a's parent
  390. group* p = a->parent;
  391. assert(p != 0);
  392. // g is p's parent (a's grandparent)
  393. group* g = p->parent;
  394. assert(g != 0);
  395. // a' <- A(r)
  396. assert(A[r] != 0);
  397. group* ap = A[r];
  398. assert(ap != 0);
  399. // A(r) <- nil
  400. A[r] = 0;
  401. // let a' have parent p'
  402. group* pp = ap->parent;
  403. assert(pp != 0);
  404. // let a' have grandparent g'
  405. group* gp = pp->parent;
  406. assert(gp != 0);
  407. // Remove a and a' from their parents
  408. assert(ap == pp->children[pp->rank-1]); // Guaranteed because ap is active
  409. --pp->rank;
  410. // Guaranteed by caller
  411. assert(a == p->children[p->rank-1]);
  412. --p->rank;
  413. // Note: a, ap, p, pp all have rank r
  414. if (do_compare(pp, p)) {
  415. do_swap(a, ap);
  416. do_swap(p, pp);
  417. do_swap(g, gp);
  418. }
  419. // Assuming k(p) <= k(p')
  420. // make p' the rank r child of p
  421. assert(r == p->rank);
  422. p->children[p->rank++] = pp;
  423. pp->parent = p;
  424. // Combine a, ap into a rank r+1 group c
  425. group* c = combine(a, ap);
  426. // make c the rank r+1 child of g'
  427. assert(gp->rank > r+1);
  428. gp->children[r+1] = c;
  429. c->parent = gp;
  430. #if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
  431. std::cerr << "After pair transform...\n";
  432. dump_tree();
  433. #endif
  434. if (A[r+1] == pp) A[r+1] = c;
  435. else promote(c);
  436. }
  437. void active_sibling_transform(group* a, group* s)
  438. {
  439. #if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
  440. std::cerr << "- active sibling transform\n";
  441. #endif
  442. group* p = a->parent;
  443. group* g = p->parent;
  444. // remove a, s from their parents
  445. assert(s->parent == p);
  446. assert(p->children[p->rank-1] == s);
  447. --p->rank;
  448. assert(p->children[p->rank-1] == a);
  449. --p->rank;
  450. rank_type r = a->rank;
  451. A[r+1] = 0;
  452. a = combine(p, a);
  453. group* c = combine(a, s);
  454. // make c the rank r+2 child of g
  455. assert(g->children[r+2] == p);
  456. g->children[r+2] = c;
  457. c->parent = g;
  458. if (A[r+2] == p) A[r+2] = c;
  459. else promote(c);
  460. }
  461. void good_sibling_transform(group* a, group* s)
  462. {
  463. #if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
  464. std::cerr << "- good sibling transform\n";
  465. #endif
  466. rank_type r = a->rank;
  467. group* c = s->children[s->rank-1];
  468. assert(c->rank == r);
  469. if (A[r] == c) {
  470. #if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
  471. std::cerr << "- good sibling pair transform\n";
  472. #endif
  473. A[r] = 0;
  474. group* p = a->parent;
  475. // Remove c from its parent
  476. --s->rank;
  477. // Make s the rank r child of p
  478. s->parent = p;
  479. p->children[r] = s;
  480. // combine a, c and let the result by the rank r+1 child of p
  481. assert(p->rank > r+1);
  482. group* x = combine(a, c);
  483. x->parent = p;
  484. p->children[r+1] = x;
  485. if (A[r+1] == s) A[r+1] = x;
  486. else promote(x);
  487. #if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
  488. dump_tree(std::cerr);
  489. #endif
  490. // pair_transform(a);
  491. } else {
  492. // Clean operation
  493. group* p = a->parent;
  494. s->children[r] = a;
  495. a->parent = s;
  496. p->children[r] = c;
  497. c->parent = p;
  498. promote(a);
  499. }
  500. }
  501. static void do_swap(group*& x, group*& y)
  502. {
  503. group* tmp = x;
  504. x = y;
  505. y = tmp;
  506. }
  507. /// Function object that compares two values in the heap
  508. Compare compare;
  509. /// Mapping from values to indices in the range [0, n).
  510. ID id;
  511. /** The root group of the queue. This group is special because it will
  512. * never store a value, but it acts as a parent to all of the
  513. * roots. Thus, its list of children is the list of roots.
  514. */
  515. group root;
  516. /** Mapping from the group index of a value to the group associated
  517. * with that value. If a value is not in the queue, then the "value"
  518. * field will be empty.
  519. */
  520. std::vector<group> index_to_group;
  521. /** Flat data structure containing the values in each of the
  522. * groups. It will be indexed via the id of the values. The groups
  523. * are each log_n long, with the last group potentially being
  524. * smaller.
  525. */
  526. std::vector< ::boost::optional<value_type> > groups;
  527. /** The list of active groups, indexed by rank. When A[r] is null,
  528. * there is no active group of rank r. Otherwise, A[r] is the active
  529. * group of rank r.
  530. */
  531. std::vector<group*> A;
  532. /** The group containing the smallest value in the queue, which must
  533. * be either a root or an active group. If this group is null, then we
  534. * will need to search for this group when it is needed.
  535. */
  536. mutable group* smallest_value;
  537. /// Cached value log_base_2(n)
  538. size_type log_n;
  539. };
  540. } // end namespace boost
  541. #if defined(BOOST_MSVC)
  542. # pragma warning(pop)
  543. #endif
  544. #endif // BOOST_RELAXED_HEAP_HEADER