]> mj.ucw.cz Git - saga.git/blob - opt.tex
Soft heaps: time complexity.
[saga.git] / opt.tex
1 \ifx\endpart\undefined
2 \input macros.tex
3 \fi
4
5 \chapter{Approaching Optimality}
6
7 \section{Soft heaps}
8
9 Recently, Chazelle \cite{chazelle:ackermann} and Pettie \cite{pettie:ackermann}
10 have presented algorithms for the MST with worst-case time complexity
11 $\O(m\timesalpha(m,n))$. We will devote this chapter to their results
12 and especially to another algorithm by Pettie and Ramachandran \cite{pettie:optimal},
13 which is provably optimal.
14
15 At the very heart of all these algorithms lies the \df{soft heap} discovered by
16 Chazelle \cite{chazelle:softheap}. It is a~meldable priority queue, roughly
17 similar to the Vuillemin's binomial heaps \cite{vuillemin:binheap} or Fredman's
18 and Tarjan's Fibonacci heaps \cite{ft:fibonacci}. The soft heaps run faster at
19 the expense of \df{corrupting} a~fraction of the inserted elements by raising
20 their values (the values are however never decreased). This allows for
21 an~trade-off between accuracy and speed controlled by a~parameter~$\varepsilon$.
22 The heap operations take $\O(\log(1/\varepsilon))$ amortized time and at every
23 moment at most~$\varepsilon n$ elements of the~$n$ elements inserted can be
24 corrupted.
25
26 \defnn{Soft heap operations}%
27 The soft heap contains distinct elements from a~totally ordered universe and it
28 supports the following operations:
29 \itemize\ibull
30 \:$\<Create>(\varepsilon)$ --- create an~empty soft heap with the given accuracy parameter,
31 \:$\<Insert>(H,x)$ --- insert a~new element~$x$ to the heap~$H$,
32 \:$\<Meld>(P,Q)$ --- merge two heaps into one, more precisely insert all elements of a~heap~$Q$
33   to the heap~$P$, destroying~$Q$ in the process (both heaps must have the same~$\varepsilon$),
34 \:$\<DeleteMin>(H)$ --- delete the minimum element of the heap~$H$ and return its value
35   (optionally signalling that the value has been corrupted).
36 \endlist
37
38 \defnn{Soft queues}
39 The soft heap is built from \df{soft queues} (we will omit the adjective soft
40 in the rest of this section). Each queue has a~shape of a~binary tree.\foot{%
41 Actually, Chazelle defines the queues as binomial trees, but he transforms them in ways that are
42 somewhat counter-intuitive, albeit well-defined. We prefer describing the queues as binary
43 trees with a~special distribution of values. In fact, the original C~code in the Chazelle's
44 paper uses this representation internally.}
45 Each vertex~$v$ of the tree remembers a~doubly-linked list $\<list>(v)$ of values. The
46 item list in every left son will be used only temporarily and it will be kept
47 empty between operations. Only right sons and the root have their lists
48 permanently occupied. The former vertices will be called \df{white}, the latter
49 \df{black.} (See the picture.)
50
51 The first value in the list is called the \df{controlling key} of the vertex,
52 denoted by $\<ckey>(v)$. If the list is empty, we keep the most recently used
53 value or we set $\<ckey>(v)=+\infty$. The \<ckey>'s obey the standard \df{heap order}
54 --- a~\<ckey> of a~parent is always less than the \<ckey>'s of its sons.
55
56 Each vertex is also assigned its \df{rank,} which is a~non-negative integer.
57 The rank of leaves is always zero, the rank of every internal vertex must be strictly
58 greater than the ranks of its sons. We define the rank of a~queue to be equal to the
59 rank of its root vertex and similarly for its \<ckey>.
60
61 A~queue is called \df{complete} if every two vertices joined by an~edge have rank
62 difference exactly one. In other words, it is a~complete binary tree and the
63 ranks correspond to vertex heights.
64
65 \figure{softheap1.eps}{\epsfxsize}{\multicap{A~complete and a~partial soft queue tree\\
66 (black vertices contain items, numbers indicate ranks)}}
67
68 \obs
69 A~complete queue of rank~$k$ contains exactly~$2^{k+1}-1$ vertices, $2^k$~of which are
70 black (by induction). Any other queue can be trivially embedded to a~complete queue of the same
71 rank, which we will call the \df{master tree} of the queue. This embedding preserves vertex
72 ranks, colors and the ancestor relation.
73
74 The queues have a~nice recursive structure. We can construct a~queue of rank~$k$ by \df{joining}
75 two queues of rank~$k-1$ under a~new root. The root will inherit the item list of one
76 of the original roots and also its \<ckey>. To preserve the heap order, we will choose
77 the one whose \<ckey> is smaller.
78
79 Sometimes, we will need to split a~queue to smaller queues. We will call this operation
80 \df{dismantling} the queue and it will happen only in cases when the item list in the root
81 is empty. It suffices to remove the leftmost (all white) path going from the root. From
82 a~queue of rank~$k$, we get queues of ranks $0,1,\ldots,k-1$, some of which may be missing
83 if the original queue was not complete.
84
85 We will now combine the soft queues to the soft heap.
86
87 \figure{softheap2.eps}{\epsfxsize}{Joining and dismantling of soft queues}
88
89 \defn A~\df{soft heap} consists of:
90 \itemize\ibull
91 \:a~doubly linked list of soft queues of distinct ranks (in increasing order of ranks),
92   we will call the first queue the \df{head}, the last queue will be its \df{tail};
93 \:\df{suffix minima:} each queue contains a~pointer to the queue with minimum \<ckey>
94 of those following it in the list;
95 \:and a~global parameter~$r\in{\bb N}$, to be set depending on~$\varepsilon$.
96 \endlist
97
98 \>We will define the \df{rank} of a~heap as the highest of the ranks of its queues
99 (that is, the rank of the heap's tail).
100
101 The heap always keeps the \df{Rank invariant:} When a~root of any tree has rank~$k$,
102 its leftmost path has length at least~$k/2$.
103
104 \para
105 \em{Melding} of two soft heaps involves merging of their lists of queues. We disassemble
106 the heap with the smaller maximum rank and we insert its queues to the other heap.
107 If two queues of the same rank~$k$ appear in both lists, we \em{join} them to
108 a~single queue of rank~$k+1$ as already described and we propagate the new queue as
109 a~\df{carry} to the next iteration, similarly to addition of binary numbers.
110 Finally we have to update the suffix minima by walking the new list backwards
111 from the last inserted item.
112
113 \em{Creation} of a~new soft heap is trivial, \em{insertion} is handled by creating
114 a~single-element heap and melding it to the destination heap.
115
116 \algn{Creating a~new soft heap}
117 \algo
118 \algin A~parameter~$\varepsilon$.
119 \:Allocate memory for a~new heap structure~$H$.
120 \:Initialize the list of queues in~$H$ as an~empty list.
121 \:Set the parameter~$r$ to~$2\lceil\log(1/\varepsilon)\rceil+2$ (to be justified later).
122 \algout A~newly minted soft heap~$H$.
123 \endalgo
124
125 \algn{Melding of two soft heaps}
126 \algo
127 \algin Two soft heaps~$P$ and~$Q$.
128 \:If the heap~$P$ has smaller rank than the heap~$Q$, exchange their item lists.
129 \:$p\=\<head>(P)$.
130 \brk\cmt{Whenever we run into an~end of a~list in this procedure, we assume that it contains
131 an~empty queue of infinite rank.}
132 \:While $Q$ still has some queues:
133 \::$q\=\<head>(Q)$.
134 \::If $\<rank>(p) < \<rank>(q)$, then $p\=$ the successor of~$p$,
135 \::else if $\<rank>(p) > \<rank>(q)$, remove~$q$ from~$Q$ and insert it before~$p$,
136 \::otherwise (the ranks are equal, we need to propagate the carry):
137 \:::$\<carry>=p$.
138 \:::$p\=$ the successor of~$p$.
139 \:::While $\<rank>(q)=\<rank>(\<carry>)$:
140 \::::Remove~$q$ from~$Q$.
141 \::::$\<carry>\=\<join>(q, \<carry>)$.
142 \::::$q\=\<head>(Q)$.
143 \:::Insert~\<carry> before~$q$.
144 \:Update the suffix minima: Walk with~$p$ backwards to the head of~$P$:
145 \::$p'\=$ successor of~$p$.
146 \::If $\<ckey>(p) < \<ckey>(p')$, set $\<suffix\_min>(p)\=p$.
147 \::Otherwise set $\<suffix\_min>(p)\=\<suffix\_min>(p')$.
148 \:Destroy the heap~$Q$.
149 \algout The merged heap~$P$.
150 \endalgo
151
152 \algn{Insertion of an~element to a~soft heap}
153 \algo
154 \algin A~heap~$H$ and a~new element~$x$.
155 \:Create a~new heap~$H'$ with the same parameters as~$H$. Let~$H'$ contain a~sole queue of rank~0,
156   whose only vertex has the element~$x$ in its item list.
157 \:$\<Meld>(H,H')$.
158 \algout An~updated heap~$H$.
159 \endalgo
160
161 \para
162 So far, the mechanics of the soft heaps was almost identical to the binomial heaps
163 and the reader could rightfully yawn. The things are going to get interesting
164 now as we approach the parts where corruption of items takes place.
165
166 If all item lists contain at most one item equal to the \<ckey> of the particular
167 vertex, no information is lost and the heap order guarantees that the minimum item
168 of every queue stays in its root. We can however allow longer lists and let the items
169 stored in a~single list travel together between the vertices of the tree, still
170 represented by a~common \<ckey>. This data-structural analogue of car pooling will
171 allow the items to travel at a~faster rate, but as only a~single item can be equal
172 to the \<ckey>, all other items will be inevitably corrupted.
173
174 We of course have to be careful about the size of the lists, as we must avoid corrupting
175 too many items. We will control the growth according to the vertex ranks. Vertices
176 with rank at most~$r$ will always contain just a~single item. Above this level,
177 the higher is the rank, the longer list will we allow.
178
179 \para
180 \em{Deleting of minimum} will follow this principle. The minimum is easy to locate
181 --- we follow the \<suffix\_min> of the head of the heap to the queue with the minimum
182 \<ckey> and we look inside the item list of the root of this queue. We remove the \em{last}
183 item from the list (we do not want the \<ckey> to change) and return it as the minimum.
184 (It is not necessarily the real minimum of all items, but always the minimum of those
185 uncorrupted.)
186
187 If the list becomes empty, we \em{refill} it with items from the lower levels of the
188 same tree. This can be best described recursively: We ask the left son to refill itself
189 (remember that the left son is always white, so there are no items to lose). If the new
190 \<ckey> of the left son is smaller than of the right son, we immediately move the left
191 son's list to its parent. Otherwise, we exchange the sons and move the list from the
192 new left son to the parent. This way, we obey the heap order and the same time we keep
193 the white left son free of items.
194
195 Ocassionally, we repeat this process once again and we concatenate the resulting lists
196 (we append the latter list to the former, using the smaller of the two \<ckey>'s). This
197 makes the lists grow longer and we want to do that roughly on every other level of the
198 tree. The exact condition will be that either the rank of the current vertex is odd,
199 or the difference in ranks between this vertex and its right son is at least two.
200
201 If refilling of the left son fails because there are no more items in that subtree
202 (we report this by setting its \<ckey> to $+\infty$), the current vertex is no longer
203 needed, as the items would just travel through it unmodified. We therefore want to
204 remove it. Instead of deleting it directly, we will rather make it point to its former
205 grandsons and we will remove the (now orhpaned) original son. This helps us to ensure
206 that both sons always have the same rank, which will be useful for the analysis.
207
208 When all refilling is done, we update the suffix minima by walking from the current
209 queue to the head of the heap exactly as we did in the \<Meld> procedure.
210
211 Our only remaining worry is that the Rank invariant can be broken after the
212 refilling. When the leftmost path of the tree becomes too short, we just
213 \em{dismantle} the tree as already described and we meld the new trees back to
214 the heap. This is easier to handle when the item list at the root vertex is
215 empty. We will therefore move this check before the refilling of the root list.
216 It will turn out that we have enough time to always walk the leftmost path
217 completely, so no explicit counters are needed.
218
219 Let us translate these ideas to real (pseudo)code:
220
221 \algn{Deleting the minimum item of a~soft heap}
222 \algo
223 \algin A~soft heap~$H$.
224 \:Use \<suffix\_min> of the head queue of~$H$ to locate the queue~$q$ with the smallest \<ckey>.
225 \:Remove the last element~$x$ of the item list in the root of~$q$.
226 \:If the item list is empty:
227 \::Count the vertices on the leftmost path of~$q$.
228 \::If there are less than $\<rank>(q)$ of them:
229 \:::Remove~$q$ from the list of queues.
230 \:::Recalculate the suffix minima as in the \<Meld> procedure.
231 \:::Dismantle~$q$ and create a~heap~$H'$ holding the resulting trees.
232 \:::Meld them back: $\<Meld>(H,H')$.
233 \::Otherwise:
234 \:::Call \<Refill> on the root of~$q$.
235 \:::If $\<ckey>(q)=+\infty$ (no items left), remove the tree~$q$.
236 \:::Recalculate the suffix minima.
237 \algout The deleted minimum item~$x$ (possibly corrupted).
238 \endalgo
239
240 \algn{Refilling the item list of a~vertex}
241 \algo
242 \algin A~soft queue and its vertex~$v$ with an~empty item list.
243 \:Handle trivial cases: If~$v$ has no children or both have $\<ckey>=+\infty$,
244   set $\<ckey>(v)$ to~$+\infty$ and return.
245 \:Let \<left> and~\<right> denote the sons of~$v$.
246 \:Recurse: call $\<Refill>(\<left>)$.
247 \:If $\<ckey>(\<left>) > \<ckey>(\<right>)$, swap the sons.
248 \:Move the item list from \<left> to~$v$ (implying $\<ckey>(v)=\<ckey>(\<left>)$).
249 \:If $\<rank>(v) > r$ and either $\<rank>(v)$ is odd or $\<rank>(v) > \<rank>(\<right>)+1$, recurse once more:
250 \::Repeat steps 3--4.
251 \::Append the item list from \<left> to the item list at~$v$.
252 \:Clean up. If $\<ckey>(\<right>) = +\infty$:
253 \::If $\<ckey>(\<left>) = +\infty$, unlink and discard both sons.
254 \::Otherwise relink the sons of \<left> to~$v$ and discard \<left>.
255 \algout A~modified soft queue.
256 \endalgo
257
258 \paran{Analysis of accuracy}
259 The description of the operations is complete, let us analyse their behavior
260 and verify that we have delivered what we promised --- first the accuracy of
261 the structure, then the time complexity of operations. In the whole analysis,
262 we will denote the total number of elements inserted in the history of the
263 structure by~$n$. We will also assume that the threshold~$r$ is even.
264
265 We start by bounding the size of the item lists.
266
267 \lemma
268 For every vertex~$v$ of a~soft queue, the size $\ell(v)$ of its item list
269 satisfies:
270 $$\ell(v) \le \max(1, 2^{\lceil \<rank>(v)/2 \rceil - r/2}).$$
271
272 \proof
273 Initially, all item lists contain at most one item, so the ineqality trivially
274 holds. Let us continue by induction. Melds can affect it only in the favorable
275 direction (they sometimes move an~item list to a~vertex of a~higher rank)
276 and so do deletes (they only remove items from lists). The only potentially
277 dangerous place is the \<Refill> procedure.
278
279 Refilling sometimes just moves items upwards, which is safe, and sometimes it
280 joins two lists into one, which generally is not. When $\<rank>(v) \le r$,
281 no joining takes place and~$\ell(v)$ is still~1. Otherwise we join when either
282 $\<rank>(v)$ is odd or $\<rank>(w) < \<rank>(v)-1$ for any son~$w$ of~$v$ (remember
283 that both sons have the same rank). In both cases, $\lceil\<rank>(w)/2\rceil \le
284 \lceil\<rank>(v)/2\rceil - 1$. By the induction hypothesis, the size of each
285 of the two joined lists is at most $2^{\max(1,\lceil\<rank>(v)/2\rceil - 1 - r/2)}$,
286 so the result has at most $2^{\lceil\<rank>(v)/2\rceil - r/2}$ items. (The maximum
287 has disappeared since $\<rank>(v)>r$ and therefore the desired bound is at least~2.)
288 \qed
289
290 We will now sum the sizes of the lists over all vertices containing corrupted items.
291
292 \lemma
293 At any given time, the heap contains at most~$n/2^{r-2}$ corrupted items.
294
295 \proof
296 We first prove an~auxiliary claim: The master trees of all queues contain at most~$n$
297 black vertices. This follows by induction: If no deletions have taken place,
298 there are exactly~$n$ of them, because insertion adds one black vertex and
299 melding preserves their number. A~deletion affects the master trees only when
300 dismantling takes place and then it only removes a~black vertex.
301
302 An~obvious upper bound on the number of corrupted items is the total size of item
303 lists in all vertices of rank greater than~$r$. We already know from the previous
304 lemma that the list sizes are limited by a~function of the ranks. A~complete tree
305 is obviously the worst case, so we will prove that this lemma holds for the master
306 tree of every queue in the heap. The actual trees can be much sparser, but the
307 above claim guarantees that the total size of the master trees is bounded by the
308 number of insertions properly.
309
310 So let us consider a~complete tree of~rank~$k$. It has exactly $2^{k-i}$ vertices
311 of rank~$i$ and each such vertex contains a~list of at most~$2^{\lceil i/2\rceil - r/2}$
312 items by the previous lemma. Summing over all ranks greater than~$r$, we get that
313 the total number of corrupted items in this tree is at most:
314 $$
315 \sum_{i=r+1}^k 2^{k-i}\cdot 2^{\lceil i/2\rceil - r/2}
316 = 2^{k-r/2} \cdot \sum_{i=r+1}^k 2^{\lceil i/2\rceil - i}
317 \le 2^{k-r/2} \cdot \sum_{i=r+1}^k 2^{-i/2}
318 \le 2^{k-r} \cdot \sum_{i=0}^\infty 2^{-i/2}.
319 $$
320 The sum of a~geometric series with quotient $2^{-1/2}$ is less than four, so the
321 last formula is less than $2^{k-r+2}$. Since the tree contains $n_k=2^k$ black vertices,
322 this makes less than $n_k/2^{k-2}$ corrupted items as we asserted.
323 \qed
324
325 \paran{Analysis of time complexity}
326 Now we will analyse the amortized time complexity of the individual operations.
327 We will show that if we charge $\O(r)$ time on every element inserted, it suffices
328 to cover the cost of all other operations. We take a~look at the melds first.
329
330 \lemma
331 The amortized cost of a~meld is $\O(1)$, except for melds induced by dismantling
332 which take $\O(\<rank>(q))$, where $q$~is the queue to be dismantled.
333
334 \proof
335 The real cost of a~meld of heaps $P$ and~$Q$ is the smaller of their ranks plus
336 the time spent on carry propagation. The latter is easy to dispose of: since
337 every time there is a~carry, the total number of trees in all heaps decreases
338 by one, it suffices to charge $\O(1)$ on creation of a~tree. An~insert creates
339 one tree, dismantling creates at most $\<rank>(q)$ trees, all other operations
340 alter only the internal structure of trees.
341
342 As for the $\O(\min(\<rank>(P),\<rank>(Q)))$ part, let us assume for a~while that
343 no dismantling ever takes place and consider the \df{meld forest.} It is a~forest
344 whose leaves correspond to the $n$~single-element heaps constructed by \<Insert>
345 and each internal vertex represents a~heap arisen from melding its sons. The left
346 son will be the one with the greater (or equal) rank. We therefore want to bound
347 the sum of ranks of all right sons.
348
349 For every right son, we will distribute the change for its rank~$k$ on all leaves
350 in its subtree. There are at least $2^k$ such leaves. No leaf ever receives the same
351 rank twice, because the ranks of right sons on every path from the root of the
352 tree to a~leaf are strictly decreasing. (This holds because melding two heaps
353 of the same rank always produces a~heap of higher rank.) Hence at most~$n/2^k$
354 right sons have rank~$k$ and the total time charged to the leaves is bounded by:
355 $$
356 \sum_{k=0}^{\rm max. rank}k\cdot {n\over 2^k} \le n\cdot\sum_{k=0}^\infty {k\over 2^k} = \O(n).
357 $$
358
359 Let us return dismantling to the game. When a~queue is dismantled, melding the parts
360 back to the heap takes $\O(\<rank>(q))$ time. We can therefore let the dismantling pay for it
361 and omit such induced melds from the meld forest. As the rank of the heap is never increased
362 by induced melds, the above calculation is still a~proper upper bound on the cost
363 of the regular melds.
364 \qed
365
366 To estimate the time spent on deletions, we first analyse the refills.
367
368 \lemma
369 Every call of the \<Refill> procedure spends time $\O(1)$ amortized.
370
371 \proof
372 Every call of \<Refill> can be split to the bottom part (rank~$r$ and below) and the
373 upper part. Whenever we recurse on the bottom part when processing the upper one,
374 we spend at most~$\O(r)$ time there. We will show that 
375
376 We will prove that all refills together take time $\O(nr)$, which will be charged on the
377 inserts.
378
379 \qed
380
381 \endpart