Counting Binary Combinations

advertisement
Counting Binary Combinations
Counting Nested Pairs
The following question was inspired by a passage on page 6 i SICP where it is pointed out that prefix
notation does not leave room for ambiguity. In contrast, infix notation requires either a set of precedence rules or a consistent use of parentheses to ensure unambiguity. The question is: Given a list of n
terms and n – 1 operators (t1 o1 t2 … tn-1 on-1 tn) how many unambiguous combinations can we produce
solely by the use of parentheses. If we require that an expression such as (a o b p c), where o and p
are operators, must have one of the two interpretations (a o (b p c)) and ((a o b) p c), even if o = p, we
do not have to consider the operators and can formulate the questions as follows: In how many ways
can we combine the elements of a list of numbers by pairing sub expressions, such that each element
of a pair is either a number or a pair.? E.g. (a, b) is a pairing of itself, (a, (b c)) and ((a b) , c) are the
two nested pairings of (a, b, c), and ((a, b) , (c, d)) is one of the nested pairing of (a, b, c, d)? A combination is a nest of ordered pairs where the innermost pairs contain numbers. Let (L) be the set of
combinations of the list L. For every subdivision (X, Y) of L the combinations of X and Y together =
(X) × (Y), and the set of combinations of L is the union of the cartesian products of the combinations of all binary sub divisions of L. E.g. (a, b, c, d) has the binary divisions (a, (b, c, d)), ((a, b) ,
(c, d)) , ((a, b, c) , d). The singletons and the pairs have one combination each and the triples have
two: (a) = {(a)}, (a, b) = {(a, b)} and (a, b, c) = {(a, (b, c)), ((a, b) , c)}. This gives the products
(a) × (b, c, d,) = {(a, (b, (c, d))), (a, ((b, c) , d))}
(a, b) × (c, d) = {((a, b) , (c, d))}





(1)
(a, b c) × (d) = {(((a, b) , c) , d), ((a, (b, c)) , d)},
and the union of these is


{(a, (b, (c, d))), (a, ((b, c) , d)), ((a, b) , (c, d)), (((a, b) , c) , d), ((a, (b, c)) , d)}.
(2)
Generally, for the list (t1, .., tn), we have
(t1) = {(t1)}, (t1, t2) = {(t1 t2)},
(t1, .., tn) = (t1) × (t2, .., tn)  ..  (t1, .., tn–1) × (tn), for n > 2
(3)
Since a combination is a nest of ordered pairs every combinations is distinct, thus |( X) × ( Y)| =
|(X)|  |(Y)| and we can define the function  | N  N, (x) = the number of combinations of a list
of x elements, as follows:
(n) = (1)(n – 1) + .. + (n – 1)(1) =
n-1
∑ (i)·(n−i) , n > 2
(4)
i=1
We know that (1) = (2) = 1, and then (3) = 11 + 11 = 2, (4) = 12 + 11 + 21 = 5, etc.
(5)
Counting Binary Trees
Can we reason the same way as above about the problem of finding the number of binary trees with n
nodes? The answer is not immediately clear since a binary tree is a combination of triples whereas a
parenthetical structure is a combination of pairs. We cannot argue that a binary operation is a triple
with the operator in the middle, since the operator does not enter into the computation.
A binary tree is either empty or a triple (L, n, R) where n is a node, typically a number, and L and R are
binary trees such that every node in L is less than n, and every node in R is greater than n. We can omit
the references to empty subtrees without loss of information, thus (, n, R)  (n, R), (L, n, )  (L, n)
and (, n, )  (n).
Let B be the set of binary trees, let  | B  2N, (X) = the set of nodes in X, and let  | N 2  2B,
(x, y) = {X  B | (X) = [x, y]}. Then, given the numbers n and k  n,
the set of binary trees where k is the root = (1, k – 1)  (k + 1, n),
(6)
Since there is one such set for every number from 1 to n we have that
(1, 0) = , (1, 1) = {(1)},
and

(7)



(1, n) =   (2, n)  (1, 1)  (3, n),  ..., (1, n – 1)  .


E.g.

(1, 2) = {((1) 2), (1 (2))},
and
(8)
(1, 3) = {(((1) 2) 3), ((1 (2)) 3), ((1) 2 (3)), (1 ((2) 3)), (1 (2 (3)))}.
By a similar argument as the one we applied to the problem of counting nested pairs we can define the
function  | N  N, (x) = the number of binary trees with n nodes, as follows
(n) = (0)(n – 1) + .. + (n – 1)g(0) =
n-1
∑ (i)·(n−i) , n > 2
(9)
i=1
We know that
and then
(0) = (1) = 1,
(10)
(2) = 11 + 11 = 2, (3) = 12 + 11 + 21 = 5, etc.
(11)
and we see that
(x) = (x + 1) for every x > 0,
i.e. the number of binary threes with x nodes equals the number of parenthetical combinations of a
sequence of x + 1 elements.
(12)
Implementation
To implement we need a function for the sum:
(k, n) =
n-1
∑ (i)·(n−i)
(13)
i=k
(n) = (1, n), for n > 2.
(n, n) = 0, (i, n) = (i)·(n − i) + (i + 1, n), for 0 < i < n
(14)
The implementation looks like this:
(15)
(define (p1 n)
(define (s i n)
(if (= i n)
0
(+ (* (p1 i) (p1 (- n i))) (s (+ i 1) n))))
(if ( n 2) 1 (s 1 n)))
This gives  (p1 (n))  3n. The following iterativ solution gives  (p2 (n))  n2. By (3) we can compute (i+1) by means of the list of the results that we already have obtained, ((1), ..., (i)), by taking
the sum of the products of the list of results and its reversal. E.g. we compute f(7) and then f(8) from
the results list thus:
1
1
2
5
14
42
42
14
5
2
1
1
1
(7) =  +  +  +  +  + 
(8) =  +
132
= 42 + 14 + 10 + 10 + 14 + 42 = 132
1
2
5
14
42 132
 +  +  +  +  + 
42
14
5
2
1
1
= 132 + 42 + 28 + 25 + 28 + 42 + 132 = 429
(16)
The implementation looks like this:
(17)
(define (p2 n)
(define (s i sums)
; sums = (sum1 .. sumi–1).
(let ((sum (apply + (map * sums (reverse sums)))))
(if (= i n)
sum
(s (+ i 1) (cons sum sums)))))
(if (<= n 2) 1 (s 3 (list 1 1))))
As can be seen from (16) the result list is symmetrical around the middle, making it possible to at least
halve1 the number of multiplications, i.e., if we have an even number of sums, we double the sum of
the products of the first half, and if we have an odd number of sums, we add the square of the sum in
the middle to the double of the sum of the products up to the middle. E.g.
(1  42 + 1  14 + 2  5 + 5  2 + 14  1 + 42  1)
= 2(1  42 + 1  14 + 2  5)
(18)
2
(1  132 + 1  42 + 2  14 + 5  5 + 14  2 + 42  1 + 132  1) = 2(1  132 + 1  42 + 2  14) + 5 .
(The implementation is straightforward but somewhat lengthy compared to (17), so I do not show it here.)
1
For some reason this solution reduces the workload by 2/3, not only by 1/2, i.e.  (p3 (n)) =  (p2 (n))/3.
Now, assume that there is a function  such that (n) = (n)(n–1). As it turns out, there is such a
function, and that function it is linear, thus there must be an implementation p4 of f such that
 (p4(n)) = n.
(14)
((2) / (1), …, (n) / (n – 1)) =
1,
2,
1
2 —,
2
4
2 —,
5
1
3 —,
7
3,
1
3 —,
4
1
3 —,
3
2
3 —,
5
5
3—
11
(15)
There is a pattern here that we can make more appearant by multipling the numerators and
denominators of some of the fractions:
2
—,
2
=
6
—,
3
10
—,
4
14
—,
5
18
—,
6
22
—,
7
26
—,
8
30
—,
9
34
—,
10
38
—
11
(17)
We see that the numerator = 2(2 denominater – 3), thus
(n) = 2(2n – 3)/n = (4 – 6/n)
(18)
(Notice that for large n, (n)  4(n – 1), which means that  grows almost exponentially.)
The Scheme implementation looks like this:
(define (p4) (if (< n 2) 1 (* (- 4 (/ 6 n)) (f (- n 1)))))
(19)
We can rewrite  in terms of the factorial through the following steps.
2(2n – 3)  (n – 1)
(n) = ———————, n > 1
(1) = 1,
(20)
n
2(22 – 3) 2(23 – 3) ... 2(2n – 3)
2n–113 ... (2n – 3)
2n–113  ...  (2n – 3)24 ... (2n – 4)
(n) = 1 ——————————————— = ———————— = ———————————————

2
3
 ... 
n
n!  2  4  ...  (2n – 4)
n!
(22)
2 (2n – 3)!
———————
n!24 ... (2n – 4)
n–1
=
2 (2n – 3)!
——————
2n–2 n! (n – 2)!
n–1
=
2(2n – 3)!
= ————
n!(n – 2)!
=
2(n – 1)n(2n – 3)!
———————— = … =
n!(n – 2)!(n – 1)n
n(2n – 2)!
—————
(n!)2
(This of course just a rearrangment of terms that has no bearing on the growth order of an implementation.)
(23)
Download