Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Programming: Optimal Binary Search Tree

Allright, I'm hoping someone can explain this to me. I'm studying for finals and I can't quite figure something out.

The problem is dynamic programming; constructing an optimal binary search tree (OBST). I understand dynamic programming in general and the concepts of this problem in particular, but I don't understand the recursive form of this problem.

I get that we're constructing optimal binary search trees for an increasing subset of these nodes and keeping the answers in a table as we go along to avoid recalculation. I also get that when you root the tree at a_{k}, all of the successful nodes from a_{1} through a_{k-1} along with their corresponding fictitious unsuccessful nodes (i.e. the leaves of the tree) are in the left subtree, and then the ones in the right subtree are a_{k+1} through a_{n}.

Here's the recursive form of the equation that I don't understand:

c(i, j) = min (i < k <= j) {c(i, k-1) + c(k, j) + p(k) + w(i, k-1) + w(k +j)}

where w(i, j) = q(i) + sum from i+1 to j (q(l) + p(l)).

So in c(i,j), from left to right, we have the cost of left subtree + cost of right subtree + probability of successful search for root + w(i, k-1) + w(k +j).

My confusion is how c(i, k-1) differs from w(i, k-1).

The text is Computer Algorithms by Horowitz, Sahni, and Rajasekeran but I've also read CLRS on OBSTs and searched online, and nothing I've come across does a good job of explaining the difference between those parts of the equation.

like image 379
rpmartz Avatar asked Dec 15 '12 13:12

rpmartz


2 Answers

c(i,j) represents the expected cost of searching an optimal binary search tree containing the keys ki, ..., kj. w(i,j) represents the probability sum of the subtree containing the keys ki, ..., kj. For the formula:

c(i, j) = min (i < k <= j) {c(i, k-1) + c(k, j) + p(k) + w(i, k-1) + w(k,j)}

c(i,k-1)+w(i,k-1) reresents the cost for the left subtree if we choose key k as the root. c(k,j)+w(k,j) represents the cost for the right subtree. p(k) represents the cost for the root k.

Notice that: If we choose key k as the root, then the left subtree contains the keys ki, ..., k(k-1) and the right subtree contains the kyes k(k+1), ..., kj. But we can not simply say that:

c(i,j)=min (i < k <= j) {c(i, k-1) + c(k, j) + p(k)}

Because when we choose the key k for the root, the generated subtrees has their depth added by 1. So c(i,k-1)+w(i,k-1) will be the right cost for the left subtree!

like image 138
Chasefornone Avatar answered Oct 06 '22 16:10

Chasefornone


This is a subtle way of calculating frequency*depth for a node at a particular depth.

Each time a node is evaluated as a root, while summing up its left (or right) subtree, you are adding sum of frequency to increase depth of all children.

For example, assume nodes 'A','B' and 'C', where 'A' is root, 'B' is left child of 'A' and 'C' is left child of 'B'. (There are no right children to make things simple.)

In bottom up manner, with leaf 'C' as root:

cost is Pr(C) = freqC*1  (no children)

with 'B' as root:

cost = Pr(B) + Cost[C,C] + sum of children freq 
     = freqB*1 + freqC*1 + freqC*1
     = freqB*1 + freqC*2 

where Pr(B) = freqB*1
     Cost[C,C] = freqC*1
     sum of children freq = freqC*1

And finally, with 'A' as root:

cost = Pr(A) + Cost[C,B] + sum of children freq 
     = freqA*1 + freqB*1 + freqC*2 + freqB*1 + freqC*1
     = freqA*1 + freqB*2 + freqC*3

where Pr(A) = freqA*1
     Cost[C,B] = freqB*1 + freqC*2
     sum of children freq = freqB*1 + freqC*1
like image 41
mithya Avatar answered Oct 06 '22 15:10

mithya