relaxed_heap.hpp 17 KB

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