Teoria de Algoritmos
Teoria de Algoritmos
Theory of Algorithms
-Course Handouts-
Guillermo Morales-Luna
www.sociedadmatematicamexicana.org.mx
Theory of Algorithms
– Course Handouts –
Cinvestav-IPN
Foreword
This course follows general lines in Algorithm Design as suggested by the Asso-
ciation of Computing Machinery (ACM). It is addressed to both the professional
engineer or technician, working on software implementation of general computing
procedures, and to students in Computer Engineering or Computer Science, who are
prospective instructors or developers.
We follow closely classical texts in the area. Indeed, textbooks that are also con-
tinuous reference books. In chronological order, a short list contains
[Aho et al(1974)Aho, Hopcroft, and Ullman], [Brassard and Bratley(1988)] (with a
version in Spanish, [Brassard and Bratley(1990)]), [Manber(1989)],
[Sedgewick and Flajolet(1996)], [Papadimitriou and Steiglitz(1998)],
[Hopcroft et al(2001)Hopcroft, Motwani, and Ullman],
[Cormen et al(2003)Cormen, Leiserson, Rivest, and Stein] and [Levitin(2007)].
Textbooks with emphasis in implementational matters are
[Gonnet and Baeza-Yates(1991)], [Wood(1993)] and [Cattaneo and Italiano(1999)].
In the Algorithms Design a good background in Mathematics is always necessary.
Here the suggested lectures are [Graham et al(1994)Graham, Knuth, and Patashnik]
and [Knuth(1999)]. For the interested reader in the Computing limitations, the clas-
sical reference is [Garey and Johnson(1979)].
The current exposition has been taught in a series of courses lectured at the In-
formation Technology Laboratory, Cinvestav-IPN, in Tamaulipas.
v
Contents
1 Basic Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Best, average and worst case behaviors . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.1 General definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.2 A particular example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.3 Estimating computational costs . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Asymptotic analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.1 Growth orders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.2 Polynomials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.3 Exponentials and logarithms . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.4 Factorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3 Sums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.1 Telescopic sums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.2 Sums of integer powers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.3 Power sums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.4 Empirical measurements of performance . . . . . . . . . . . . . . . . . . . . . . . 13
1.5 Time and space tradeoff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.6 Recurrence relations in recursive algorithms analysis . . . . . . . . . . . . . 15
1.6.1 A divide and conquer algorithm . . . . . . . . . . . . . . . . . . . . . . . . 15
1.6.2 Substitution method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.6.3 Iteration method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.6.4 Master method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2 Algorithmic Strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.1 Brute-force algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.2 Greedy algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.2.1 Activities-selection problem . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.2.2 Knapsack problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.3 Divide-and-conquer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.3.1 Raising to an integer power . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.3.2 Integer multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
vii
viii Contents
3 Fundamental Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3.1 Simple numerical algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3.2 Sequential and binary search algorithms . . . . . . . . . . . . . . . . . . . . . . . . 61
3.3 Quadratic sorting algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
3.4 Quicksort type algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
3.5 Hash tables, including collision-avoidance strategies . . . . . . . . . . . . . 63
3.6 Binary search trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
3.7 Representations of graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.7.1 Adjacency-lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.7.2 Adjacency-matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.8 Depth- and breadth-first traversals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.9 Topological sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
3.10 Shortest-path algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
3.11 Transitive closure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
3.12 Minimum spanning tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4 Distributed Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
4.1 Distributed systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
4.1.1 Networks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
4.1.2 Transition systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Contents ix
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Chapter 1
Basic Analysis
Abstract We introduce here the most basic concepts in measuring algorithms com-
plexities. Initially we distinguish behaviors according to the computational costs due
to their inputs. Then we introduce some mathematical functions of extended use in
measuring algorithmic performances, and the growth orders of maps. We study the
sums, with either finite or countable number of summands, and the convergence
properties. We outline some policies in order to get good algorithm implementa-
tions. Then we discuss the tradeoff among time and space in computing algorithms.
Finally we sketch the most fundamental criteria of growth estimation of functions
determined by recurrence relation. The current chapter is a introduction to the math-
ematics of the analysis of algorithms.
1
2 1 Basic Analysis
For any algorithm A and for each non-negative integer n ∈ N, let dom n (A) =
Σ n ∩ dom (A) be the collection of input words of length n producing an output under
A. Let us define the following maps:
Time. TA : N → N, n 7→ max{tA (σ )| σ ∈ dom n (A)}.
Space. SA : N → N, n 7→ max{sA (σ )| σ ∈ dom n (A)}.
Thus, TA (n) is the greatest number of steps that can be achieved by an input of
length n within algorithm A. SA (n) is analogous with respect to space. Both maps
are dependent on the algorithm A and on lengths of words, not just on words.
The maps TA and SA determine the complexity measures of algorithm A, the first
gives the time complexity and the other the space complexity.
Clearly, for each integer x ∈ Z, len (ρ1 (ρ0 (x))) = (`(|x|) + 1) + w(ρ1 (ρ0 (x))) where
w(ρ1 (ρ0 (x))) is the number of 1’s in ρ1 (ρ0 (x)). Consequently, len (ρ1 (ρ0 (x))) ≤
2(`(|x|) + 1).
Let ρ2 : Z∗ → (0 + 1)∗ be the map that to each finite sequence of integers x =
(x0 , . . . , xm−1 ) it associates the bit-string
Thus the length len (ρ2 (x)) can be upperly bounded by a polynomial expression
depending on x, or rather on its dimension m and its entries x j .
Alternatively we may fix a given size to represent positive integers and use a
convention for negative integers (as two’s complement). This has been, as is well
known, the standard approach in industrial implementations, and can be checked in
detail in several texts [Fernandez et al(2003)Fernandez, Garcia, and Garzon].
InsertionSort
Input. An integer array A ∈ Z∗
Output. The same array ordered non-decreasingly
1. For each j ∈ [[2, len (A)]] Do
a. CurVal := A[ j] ;
b. i := j − 1 ;
c. While (i > 0) ∧ (A[i] > CurVal) Do
i. A[i + 1] := A[i] ;
ii. i − −
d. A(i + 1) := CurVal
We see that the worst case and the averages cases produce a quadratic cost function.
The ratio of them is such that limn→+∞ TTwa (n) 1
(n) = 2 , thus in the limit the worst case is
twice as expensive as the average case. However limn→+∞ TTba (n)(n) = 0 thus in the limit
the cost of the best case is negligible with respect to the average case.
The best cases of an algorithm correspond to lower computational costs but also
to particular assumptions on the inputs that may be hard to be achieved. The worst
cases correspond to higher computational costs and may also appear in extremely
uncommon, bad luck indeed, cases. The average cases may computational costs
lying between the worst and the best cases. For some algorithms these may be closer
to the worst cases, as for the shown InsertionSort, but for other algorithms
they can be closer to the best cases.
For practical purposes the estimation of time-complexities is useful in order to
know the size of instances suitable to be treated in reasonable times. Let us consider
the nanosecond (ns) as an unit of time (typically the time required to execute a
primitive instruction in a physical conventional computer). Another time unit u is a
multiple of ns, let len (u) denote the length of u, as a multiple of ns, expressed in
base 2. The following table summarizes the values of len (u):
f3 is the identity map and it is, obviously, a linear map. The maps f1 and f2 are
sublinear and the maps fk , k ∈ [[4, 9]], are superlinear. For each of these superlinear
increasing maps, fk , let Dk be the interval consisting of those values n ∈ N such that
fk (n), measured in ns, lies between one second and one century. Then:
6 1 Basic Analysis
fk Dk
f4 (n) = n · log(n) 4 × 10 ≤ n ≤ 6 × 1016
7
Observe that the polynomial map f7 initially restricts n to be very small compared
with the initial value of the exponential map f8 . However at the end of the shown
time scale, f7 allows a greater value for n than f8 . This is just an illustration that
although initially a polynomial map may seem to have a greater growth than an
exponential map, eventually the exponential growth will win the race!
Remark 1.1. For any two maps f , g : N → N the following conditions are direct:
1. g(n) = O( f (n)) ⇔ f (n) = Ω (g(n)),
2. g(n) = Θ ( f (n)) ⇔ [g(n) = O( f (n))] ∧ [g(n) = Ω ( f (n))].
(here, the symbol “∧” is read and).
in other words,
g(n)
g(n) = o( f (n)) ⇔ lim = 0,
n→+∞ f (n)
1.2 Asymptotic analysis 7
in this case it is said that the growth order of g is strictly lower than that of f , and
g(n)
g(n) = ω( f (n)) ⇔ lim = +∞,
n→+∞ f (n)
and in this case it is said that the growth order of g is strictly greater than that of f .
f (n) = O( f (n)).
1.2.2 Polynomials
m
A one-variable polynomial has the form p(X) = ∑ ai X i . The integer m is called the
i=0
degree of the polynomial, ∂ p, and the real numbers a0 , . . . , am are the coefficients
of the polynomial. The coefficient am corresponding to the power of the degree is
called the leading coefficient.
m
A several-variables polynomial has the form p(X) = ∑ ai Xi , where A ⊂ Nk is a
i∈A
k
i
finite set and if X = (X1 , . . . , Xk ) and i = (i1 , . . . , ik ) then Xi = ∏ X j j .
j=1
Here we will consider just one-variable polynomials. Those of degree 1 are called
linear polynomials, those of degree 2 quadratic polynomials and those of degree 3
cubic polynomials. For any two polynomials p1 (X), p2 (X):
8 1 Basic Analysis
1.2.3.1 Exponentials
a0 = 1 & ∀n ∈ N : an+1 = an · a.
1
For negative exponents, say n1 = −n with n ∈ N, it is defined an1 = an . If the base
p
p
number a is positive, for any rational number with q > 0, it is defined a q = x
q,
where x is the real positive number x such that xq = a p . By continuity, az is well
defined for any z ∈ R.
The following power rules hold:
Conventional base numbers are, for instance, a = 10 or a = 2, but the most im-
portant base number in mathematics is e, the base of natural logarithms, which is
defined, among a great variety of different ways, as
1 n
e = lim 1 + (1.4)
n→+∞ n
xm x2 x3 x4
∀x ∈ R : ex = ∑ = 1+x+ + + +··· (1.5)
m≥0 m! 2 6 24
1.2 Asymptotic analysis 9
1.2.3.2 Logarithms
For any positive base number a > 0, the logarithm in base a of x > 0 is the real
number loga x = y such that ay = x. In symbols:
loga x = y ⇔ ay = x (1.6)
The first equation in (1.7) asserts that, for each base a > 0, the logarithm function
is a homomorphism among the multiplicative structure of the real positive numbers
and the additive structure of the whole real line.
On the other hand, let us consider the “reciprocal map”, t 7→ 1/t, defined over
the positive real numbers, and its integral,
Z x
dt
F : x 7→ .
1 t
Clearly, ∀x, y ∈ R+ :
Z xy
dt
F(xy) =
1 t
Z x Z xy
dt dt
= +
1 t x t
Z x Z y
dt d(xt1 )
= +
1t 1 (xt1 )
Z x Z y
dt dt
= +
1 t 1 t
= F(x) + F(y)
xm x2 x3 x4 x5 x6
ln(1 + x) = ∑ (−1)1+m m = x−
2
+ − + − ··· .
3 4 5 6
(1.9)
m≥1
xym
ln y = nx + ln xy = nx + ∑ (−1)1+m m (1.10)
m≥1
For any positive base number a > 0, and any positive integer m, from relations (1.8)
and (1.5) we have
nm
lim n = 0 (1.11)
n→+∞ a
hence nm = o(an ). Thus, whenever a > 0 and f (n) = nO(1) necessarily f (n) =
o(an ). Consequently, any exponential function grows faster than any polynomially
bounded map. [
Let (loga n)O(1) = O((loga n)m ) be the class of functions bounded polylog-
m≥0
arithmically. In order to compare this class with the polynomials, let us write
n1 = loga n. Then, from relation (1.11),
1.2.4 Factorial
way,
√ n n √ n n+ 1 · 1
12 n
2πn ≤ n! ≤ 2πn .
e e
Hence n! = o(nn ), n! = ω(2n ), and log(n!) = Θ (n log n).
1.3 Sums
+∞ n
∑ an = ∑ an = lim
n→+∞
∑ ai .
n=1 n≥0 i=1
thus
12 1 Basic Analysis
m−1
m m m k
(i + 1) − i = ∑ i (1.12)
k=0 k
Summing-up these values gives a telescopic sum, hence
m−1
m
(n + 1)m − 1m = ∑ skn (1.13)
k=0 k
(n + 1) − 1 = s0n
(n + 1)2 − 1 = s0n + 2s1n
(n + 1)3 − 1 = s0n + 3s1n + 3s2n
(n + 1)4 − 1 = s0n + 4s1n + 6s2n + 4s3n
(n + 1)5 − 1 = s0n + 5s1n + 10s2n + 10s3n + 5s4n
(n + 1)6 − 1 = s0n + 6s1n + 15s2n + 20s3n + 15s4n + 6s5n
.. ..
. .
s0n = n
1 1
s1n = n(1 + n) = s0n (1 + n)
2 2
1 1
s2n = n(1 + n)(1 + 2n) = s1n (1 + 2n)
6 3
1
s3n = n2 (1 + n)2 = s21n
4
1 1
s4n = n(1 + n)(1 + 2n)(−1 + 3n + 3n2 ) = s2n (−1 + 3n + 3n2 )
30 5
1 2 1
s5n = n (1 + n)2 (−1 + 2n + 2n2 ) = s3n (−1 + 2n + 2n2 )
12 3
.. ..
. .
n
∑ im = O nm+1 .
Clearly,
i=1
Given a recurrence relation, one may guess a bounding function and then to prove
the correctness of that bound.
For instance, let us consider:
n si n = 1,
T (n) =
2T n2 + n si n > 1.
According to the above example, we may guess that the solution has order
O(n log n). So let us prove that there is a constant c such that T (n) ≤ cn log n.
We may proceed by induction on n.
Let us assume as induction hypothesis: T 2n ≤ c 2n log 2n . Then,
jnk jnk
T (n) ≤ 2c log +n
2 2
n
≤ cn log + n
2
≤ cn log n − cn log 2 + n
≤ cn log n − cn + n
≤ cn log n
1.6 Recurrence relations in recursive algorithms analysis 17
whenever c > 1.
As a second example, let us consider
l n m j n k
T (n) = T +T +1
2 2
and let us conjecture that its solution is O(n). Let us prove that T (n) ≤ cn − b for
some constants c, b.
As induction hypothesis let us assume T (m) ≤ cn − b, for any m < n. Then
lnm jnk
T (n) ≤ c −b + c −b +1
2 2
≤ cn − 2b + 1
≤ cn − b
whenever c, b > 1.
Sometimes it is convenient to do a change√of variables.
For instance, let us consider T (n) = 2T (d ne) + log2 n.
Let m = log
l 2 n.mThen n = 2m and the recurrence relation can be written as
m
T (2m ) = 2T 2 2 + m. Hence it has the form S(m) = 2S m2 + m, which
has solution S(m) = O(m log m). Thus the solution of the original recurrence is
T (n) = O(log n log log n).
k
3 1
Since 3log4 n = nlog4 3 and ∑ = = 4, then
k≥0 4 1 − 34
Theorem 1.1 (Master’s –). Let a, b > 0 and f : N → R be a map. The solution of
the recurrence n
T (n) = aT + f (n)
b
satisfies the following relations which are dependent of f :
1. If f (n) = O nlogb a−ε for some ε > 0, then T (n) = Θ nlogb a .
n
∃c ∈]0, 1[, n0 ∈ N : (n ≥ n0 ⇒ a f ≤ c f (n)),
b
then T (n) = Θ ( f (n)).
In other words, the growth of the solution is determined by the comparison among
f and nlogb a :
1.6 Recurrence relations in recursive algorithms analysis 19
• If f “is below, a little bit more” than nlogb a , then the solution grows as nlogb a .
• If f “grows” as nlogb a , then the solution grows as nlogb a log n.
• If f “is above, a little bit less” than nlogb a , then the solution grows as f .
The proof of the theorem is out of the scope of our presentation, it can be found
in full detail in [Cormen et al(2003)Cormen, Leiserson, Rivest, and Stein].
Θ n2 .
log 3 1
2
= n0 = 1, and
Example 1.2. Let T (n) = T 3n + 1. Since n 2
log 3 1
f (n) = 1 = Θ (1) = Θ (n 2 ),
Example 1.3. Let T (n) = 3T n4 + n log n. Since nlog4 3 = O n0.793 , and f (n) =
n log n
= log n = o(nε ),
nlog2 2
for any ε > 0. Thus there is no ε > 0 such that f (n) = Ω nlog2 2+ε . Consequently,
There are other solving methods as the method of generator maps, and the method
of powers.
Problems
1.2. Which is the greatest value of n > 1 such that any algorithm with running time
8n2 runs slower than an algorithm with time 2n in the same computer?
1.3. Which is the greatest value of n > 1 such that any algorithm with running time
2n runs faster than an algorithm with time 100n2 in the same computer?
n2 , n!
n3 , (log2 n!)
(log2 n!) , ln ln n
ln ln n , ln n
ln n , n ln n
1.6 Recurrence relations in recursive algorithms analysis 21
nlog2 log2 n , 1
1 , 2log2 n
2log2 n
p
, log2 n
(n + 1)! , 4log2 n
4log2 n , en
en , (log2 n)log2 n
1.24. Show that for any two constants a, b > 0 we have (n + a)b = Θ (nb ).
1.27. Find tight bounds (upper and lower) to the recurrence T (n) = 3T (n/3 + 5) +
n/2.
1.28. Find tight bounds (upper and lower) to the recurrence T (n) = T (n − 1) + 1/n.
n
n
1.29. Calculate the sum ∑ i .
i=1 i
n
n
1.30. Calculate the sum ∑ .
i=1 i
22 1 Basic Analysis
n
1.31. Calculate the sum ∑ iai .
i=1
T (0) = c
T (n) = aT (n − 1) + bn.
T (0) = c
T (n) = aT (n − 1) + bnk .
T (0) = c
n
T (n) = T + bn log n.
2
1.35. Write a program to approximate e according to relation (1.4).
without common divisors among them. Find recursive relations to calculate the se-
quences of numbers (pn )n≥1 and (qn )n≥1 .
1.40. Write a program to calculate the sequences (pn )n≥1 and (qn )n≥1 introduced
above. Decide whether the harmonic series ∑k≥1 1k is convergent.
Abstract We present here general strategies for algorithms design with representa-
tive examples. The brute-force algorithms are variants of exhaustive search for ef-
fective solutions and they depend on the enumeration processes of the search space.
Greedy algorithms tend to build a solution based on immediate gains of some utility
function. Divide-and-conquer are typical for algorithm optimization, and they are
intended to reduce time complexities of algorithms. Backtracking is a search proce-
dure based on a stacking device and depth-first traversing of tree structured search
spaces. Heuristics is at present time an important area of development in Computer
Engineering. The algorithms on syntactical pattern matching are illustrative of some
procedures to reduce times on query processing through a preprocessing. Finally, in
numerical approximation although there are no exact solutions they provide effec-
tively and efficiently approximations to the solutions with different levels of close-
ness.
In section 1.1.1 we have seen several connotations of algorithm. Also, the notion of
problem has several connotations.
A decision problem can be formally stated as a set of words Σ ∗ and a partition
{Y, N,U} of Σ ∗ into three sets: the Yes-answered instances, the No-answered in-
stances, and the Undefined-answer instances. And for a given instance x ∈ Σ ∗ the
goal of the decision problem is to decide whether x ∈ Y or x ∈ N or x ∈ U.
A search problem instead can be seen as a set P ∈ Σ ∗ × Σ ∗ . If (x, y) ∈ P then
it is said that y is a solution for the instance x. For any instance x ∈ Σ ∗ let P(x) =
{y ∈ Σ ∗ | (x, y) ∈ P} be the set of solutions corresponding to x. The goal of a search
problem is that, given an instance x ∈ Σ ∗ it should find y ∈ Σ ∗ such that y ∈ P(x), if
such a y does exist, or recognize that P(x) is empty, otherwise.
Example 2.1 (Factorization). Given an integer number it is required to obtain the
integers dividing that number.
23
24 2 Algorithmic Strategies
Example 2.3 (Factorization). Let us continue the example 2.1. Given a positive inte-
ger x ∈ N, which in base 2 is written with, say k bits, according to the Prime Number
Theorem the number of primes less than x is approximately
x 2k
∼ = O(2k ). (2.1)
ln x k
Thus a naive brute-force algorithm has exponential time complexity. √
However, if x is has a proper factor then it has a prime factor less than x which
can be written with 2k bits. The number of such prospective primes is approximately
k k+2
22 2 2
k
= . (2.2)
2
k
2.2 Greedy algorithms 25
Example 2.4 (Eight queens puzzle). Let us consider the following puzzle: Locate 8
queens in a chessboard in such a way that no queen is attacking any other queen.
Let us assume first that the queens are enumerated as q1 , . . . , q8 . Then the number
of ways to locate these queens in the 64-cells chessboard is
64!
c0 = 64 · 63 · · · · · 58 · 57 = = 178, 462, 987, 637, 760
56!
However, if we make abstraction of the queens numbering, then the number of ways
to select 8 cells in order to put in there the queens is
64 c0
c1 = = = 4, 426, 165, 368
8 8!
But, since the queens cannot attack each other, at each column j in the chessboard
there must be a queen in a row, say i j , and no two such row values can coincide.
Thus the map π : j 7→ i j is a permutation [[1, 8]] → [[1, 8]]. Namely, the search space
can be restricted to the space of permutations of 8 elements, and its cardinality is
c2 = 8! = 40, 320
The brute-force algorithm based on this last search space consists in an enumeration
of the permutations [[1, 8]] → [[1, 8]].
These algorithms deal mostly with optimization problems: Given a real function de-
fined in a domain f : D → R it is required to calculate an extreme value x0 ∈ D such
that f (x0 ) ≤ f (x), ∀x ∈ D, if it is a minimization problem or f (x0 ) ≥ f (x), ∀x ∈ D, if
it is a maximization problem. A greedy algorithm proceeds by local approximations:
at any current point, it moves in the direction pointing to the greatest gain in opti-
mizing the objective function. The main disadvantage with this approach is that it
does not always succeed in its goal: the procedure may fall into a local extreme point
rather than in a global extreme point. However, for certain settings in the problem,
greedy algorithms may be effective, and most probably, also efficient.
26 2 Algorithmic Strategies
Let us assume a set of activities A = {Ai }i∈I ,each with a duration interval [bi , ei [,
ci < ai , where bi is the beginning time and ei is its ending time, and let us assume
that there is just one server, or processor, able to realize the activities, one at any
time. A set of activities AJ = {Ai }i∈J⊂I is consistent if
∀ j1 , j2 ∈ J : ( j1 6= j2 ⇒ [b j1 , e j1 [∩[b j2 , e j2 [= 0).
/
Proof. If AJM is maximal and its first activity AM1 is not the first activity A1 of the
whole collection, then we may substitute AM1 by A1 within AJM , and this substitu-
tion produces a maximal consistent set as claimed. u t
2.3 Divide-and-conquer 27
In these problems there is a collection of items, each having a volume and producing
an utility, and there is also a knapsack with a fixed capacity. The goal of the problems
is to put into the knapsack a collection of items in such a way that the knapsack’s
capacity is not exceeded by the sum of the put item volumes and the total utility of
the put items is maximal. In (0-1)-knapsack, or integer knapsack, it is allowed just to
put a given item entirely, while in fractional knapsack it is allowed to put fractions
of items into the knapsack, with proportional volume and utility.
Problem (0-1)-Knapsack.
Instance: A collection C = {Ci = (ti , ui )|1 ≤ i ≤ n} of n items (as pairs volume-
utility) and a total capacity T .
Solution: A subset I ⊂ [[1, n]] such that ∑i∈I ti ≤ T and ∑i∈I ui is maximal.
Problem Fractional Knapsack.
Instance: A collection C = {Ci = (ti , ui )|1 ≤ i ≤ n} of n items (as pairs volume-
utility) and a total capacity T .
Solution: A subset I ⊂ [[1, n]] and a sequence of fractions Q = (qi )i∈I ⊂ Q+ such
that ∑i∈I qiti ≤ T and ∑i∈I qi ui is maximal.
2.3 Divide-and-conquer
Given a problem, say P(x), with input size s(x) = n, it is split as a smaller problems,
P0 (x0 ), . . . , Pa−1 (xa−1 ), with instances of reduction ratio b, s(x j ) = nb , with a, b ∈
Z+ , producing corresponding solutions y0 , . . . , ya−1 . Then they are merged in order
28 2 Algorithmic Strategies
to obtain y = M(y0 , . . . , ya−1 ) as a solution of the original problem P(x). In fig. 2.1
we sketch this procedure with a = b = 2. In section 1.6.1 we have already given an
x y0
-0 -
P n
2
x - -y
- -
x1 y1
Dn Pn2 Mn
Pn
Fig. 2.1 Divide-and-conquer scheme: Dn is an instance divider or splitter, Pk is a solver for in-
stances of size k, and Mn is a merger of solutions of size n instances.
where d(n), m(n) are the respective measures of the divider Dn and the merger Mn .
Either the substitution method or the Master’s Theorem 1.1 gives a solution of the
recurrence (2.3).
For instance, for a = b = 2, whenever d(n) + m(n) = Θ (n), the solution of the
recurrence (2.3) is T (n) = O(n log n). Hence the complexity of a divide-and-conquer
algorithm is, for a = b = 2, n log n, thus it is superlinear but subquadratic (in fact it
is closer to a linear behavior: n log n − n = o(n2 − n log n)).
We will illustrate this algorithmic paradigm through several typical examples.
and due to bit-carry the result may consist of 2n bits. The whole evaluation of ex-
pression (2.4) entails O(n2 ) bit-products.
Alternatively, let us write
n −1 n −1 n −1 n −1
2 2 2 2
j
xlow = ∑ 2 xj ; xhigh = ∑ 2 j x n2 + j ; ylow = ∑ 2 yj j
; yhigh = ∑ 2 j y 2n + j
j=0 j=0 j=0 j=0
n n
Then, x = 2 2 xhigh + xlow and y = 2 2 yhigh + ylow . Consequently
n
z = 2n xhigh · yhigh + 2 2 xlow · yhigh + xhigh · ylow + xlow · ylow .
Thus, n
z = 2n z2 + 2 2 (z3 − z1 − z2 ) + z1 (2.5)
where
3K n2 if n > 0
∀n : K(n) = (2.6)
1 if n = 1
Given a finite set X = ((xi , yi ))ni=1 of points in the real plane, it is asked to find the
pair {(xi0 , yi0 ), (xi1 , yi1 )} of points in X realizing the minimum distance.
A brute-force approach would check all pairs, hence it has complexity O(n2 ).
A divide-and-conquer algorithm proceeds as follows:
1. Sort X according to the abscissae: i < j ⇒ xi ≤ x j .
2. Divide X into two sets Xle f t , Xright , of almost equal cardinality, such that the
abscissae of points in Xle f t are all not greater than the abscissa of any point in
Xright .
3. Find the pairs {(x j0 , y j0 ), (x j1 , y j1 )} and {(xk0 , yk0 ), (xk1 , yk1 )} realizing respec-
tively, the minimum distances dle f t and dright in Xle f t and Xright .
4. The solution {(xi0 , yi0 ), (xi1 , yi1 )} of the original problem P may have either its
both points at Xle f t , or its both points at Xright or have its points in different sets.
In the first two possibilities, the solution shall coincide with the solution of the
set giving the least distance. In order to deal with last situation:
a. Let d = min{dle f t , dright } and let ` : x = xλ be a boundary line between Xle f t
and Xright .
b. Let L = {(x, y) ∈ X| |x − xλ | ≤ d} be the collection of points whose distance
to ` is bounded by d.
c. Sort L according to the y-coordinate.
d. For each point in L check whether it has a neighbor closer than d.
5. Output the found closest pair.
In an implementation, the first sorting can be made as a preprocessing step, hence it
can be assumed that the whole list X is already sorted.
Given a finite set X = ((xi , yi ))ni=1 of points in the real plane, it is asked to find the
convex hull of X.
The convex hull of a set X is the smallest convex set containing X, it is indeed
the smallest convex polygon having as vertices some points of X and covering the
whole set X.
A divide-and-conquer algorithm proceeds as follows:
1. Sort X according to the abscissae: i < j ⇒ xi ≤ x j .
2. Divide X into two sets Xle f t , Xright , of almost equal cardinality, such that the
abscissae of points in Xle f t are all not greater than the abscissa of any point in
Xright .
3. Find the respective convex hulls Yle f t , Yright of Xle f t , Xright .
2.3 Divide-and-conquer 31
4. Let Tm be a common tangent line of Yle f t and Yright such that both of them lie
completely at the same side of Tm . Let (xlm , ylm ) and (xrm , yrm ) be the vertices at
Yle f t and Yright passing through Tm .
5. Let TM be a common tangent line of Yle f t and Yright such that both of them lie com-
pletely at the same side of TM , opposite side of Tm . Let (xlM , ylM ) and (xrM , yrM )
be the vertices at Yle f t and Yright passing through TM .
6. The points (xlm , ylm ) and (xlM , ylM ) split Yle f t into two segments, in a clockwise
traversing, [(xlm , ylm ), (xlM , ylM )] and [(xlM , ylM ), (xlm , ylm )], this last one is closer
to Yright .
7. Similarly, the points (xrm , yrm ) and (xrM , yrM ) split Yright into two segments, in a
clockwise traversing, [(xrm , yrm ), (xrM , yrM )] and [(xrM , yrM ), (xlm , ylm )], the first
one is closer to Yle f t .
8. Suppress [(xlM , ylM ), (xlm , ylm )] and add the edge [(xlM , ylM ), (xrM , yrM )]. Sup-
press [(xrm , yrm ), (xrM , yrM )] and add the edge [(xrm , yrm ), (xlm , ylm )].
9. Output the resulting polygon.
The search of the tangents Tm and TM can be done by clockwise traversing the ver-
texes of Yle f t and by counterclockwise traversing the vertexes of Yright .
Given two matrices A = [ai j ]1≤i, j≤n , B = [bi j ]1≤i, j≤n it is required to calculate the
matrix product C = A · B.
By definition we have
n
∀i, j ∈ [[1, n]] : ci j = ∑ aik bk j .
k=1
Let Td (n) be the number of products necessary to compute the whole matrix multi-
plication. Since for each entry there are involved n products, we have Td (n) = n3 .
The Strassen method reduces the number of multiplications. Let us partition the
factor matrices as
A11 A12 B11 B12
A= & B= .
A21 A22 B21 B22
7Ts 2n if n > 0
∀n : Ts (n) =
1 if n = 1
2.4 Backtracking
Let us recall that a tree is a connected graph T = (V, E), where V is the set of
vertexes and E is the set of edges, such that any two vertices are connected by just
one path and there is a distinguished vertex υ ∈ V called the root. For any vertex
v ∈ V , the parent of v is the first vertex, say u, visited by the unique path going from
v to the root υ, and it is written u = parent (v). In this case it is also said that v is
a child of u. The vertexes with no children are called leaves, and the vertexes which
are not leaves are called inner. An ordered tree is a tree such that for each inner tree
the collection of its children is totally ordered. Thus an ordered tree can be specified
as a list of registers in V ×V ∗ : if (v; [v0 , . . . , vk−1 ]) appears in that list it means that
v is a node with children v0 , . . . , vk−1 .
A depth-first traversing in an ordered tree is such that at any vertex, the traversing
firstly visits the children, in their own ordering, and thereafter it visits that vertex,
i.e. for any (v; v0 , . . . , vk−1 ) the visiting sequence is v0 → · · · → vk−1 → v.
2.4 Backtracking 33
Depth-first
Input. An ordered tree as a list (v, children(v))v∈V .
Output. A numbering v 7→ i ∈ N according to the depth-first travers-
ing
1. Let stack := [(υ, on)] ; counter := 0 ;
2. While stack 6= [] Do
a. (v, signal) := pop(stack) ;
b. If signal = on Then
i. If children(v) 6= [] Then
A. push((v, off), stack) ;
B. For each u ∈ children(v) Do push((u, on), stack)
Else
A. counter + + ; i[v] := counter ;
Else
i. counter + + ; i[v] := counter ;
3. Output [ i[v]| v ∈ V ]
A backtracking procedure is basically a brute-force procedure in which the
search space, or domain space, has a structure of an ordered tree and the ordering
of testing is a depth-first traversing of the domain space.
The diagram of this ordering is an ordered tree, and its leaves correspond exactly to
the permutations [[1, n]] → [[1, n]], namely, there are n! leaves in the tree.
A depth-first traversing of this tree gives an enumeration of the whole set Dn .
Let us show now some examples of some particular backtracking procedures.
Suppose given n cities in a region and a distance di j associated to each pair {ci , c j }
of cities. The traveling salesman problem (TSP) consists in selecting the minimum-
distance traversing of all the cities without passing twice through any city.
34 2 Algorithmic Strategies
Let Cn be the set of cities. If the salesman visits r cities, since he is not allowed to
visit a city twice, then his traversing may be seen as an r-combination in the set Cn .
Then using an effective enumeration of the cities, the set Cn may be identified with
the set [[1, n]] and the collection of allowed traversings with the collection Dn of all
r-combinations in n indexes, r ≤ n. For any combination [c0 , . . . , cr−1 ], its weight is
r−1
w[c0 , . . . , cr−1 ] = ∑ d(c j−1 , c j ).
j=1
min{w(c)| c ∈ Dn }
Graham’s scan
Input. A set X = ((xi , yi ))ni=1 of points in the real plane.
Output. The convex hull co(X).
1. Let x0 be the point in X with least x-coordinate.
2. Sort X − {x0 } according to the angle of the segment joining each
point with x0 and the parallel line to the “y”-axis passing through
x0 . Let us assume that after sorting, X − {x0 } = {x1 , . . . , xn−1 }.
3. Initially, let CH := [x1 , x0 ], and ToBeTested := [x2 , . . . , xn−1 ]
4. While ToBeTested 6= [] Do
a. Let xmiddle , x prev be the first two elements at CH ;
b. xnew := pop(ToBeTested) ;
c. While
the angle (xmiddle , x prev , xmiddle , xnew ) is a right turn
Do
i. drop(xmiddle ,CH) ;
ii. let xmiddle , x prev be the first two elements at CH ;
d. push(xnew ,CH) ;
5. Output CH.
The step 4.c is properly a backtracking procedure till a turn to the left is got in the
three current tested points. In order to decide whether going from a vector x0 =
(u0 , v0 ) to a vector x1 = (u1 , v1 ) makes a left turn or a right turn it must be checked
u v
d(x0 , x1 ) = det 0 0 = u0 v1 − u1 v0 :
u1 v1
2.5 Heuristics
many cases it is quite effective and its computational cost is negligible! When pack-
ing items of odd-shape into a box, usually one tries to put the largest items first
and to use the available space to place smaller items. Similarly, TSP may be solved
in a greedy way: At each city, the traveller continues his route through the closest
non-yet-visited city.
General rules hinting particular ways to build heuristics for specific classes
of problems are called metaheuristics. The greedy algorithms, as reviewed in
section 2.2 provide a metaheuristic. Simulated annealing, tabu search, genetic
algorithms, and Lagrangian relaxation, among others, give proper metaheuris-
tics [Michalewicz and Fogel(2004)].
Example 2.5 (Assignment problem). Let us assume there are n tasks and n proces-
sors and a cost matrix C = (ci j )i, j∈[[0,n−1]] : ci j is the cost to assign the j-th task to the
i-th processor. It is sought the assignment α : [[0, n − 1]] → [[0, n − 1]] of least cost
cα = ∑n−1
i=0 ciα(i) .
The first approach is to proceed randomly: For each processor i select randomly
a task among the not-yet-assigned tasks and let α(i) be this chosen task.
This is a quite economical assignment: it runs in linear time. But since it does
not take care of the cost matrix, the probability to find a minimum-cost assignment
is rather small.
As an alternative, for each k ∈ [[0, n − 1]], let m be the least cost appearing at the
current cost matrix and let i, j be such that ci j = m. Let α(i) = j and suppress the
i-th row and the j-th column in the cost matrix.
Evidently in the more advanced stages of the algorithm, the “freedom of choice”
is narrower. Thus it may happen that the criteria to broke the ties, when choosing
the current minima, may affect the algorithm effectiveness.
Let us remark finally that in the shown heuristics no mathematical formulation
has been done. The goal may be stated as an integer programming problem which
has an effective solution (although computationally expensive, since Integer Pro-
gramming is NP-hard [Aho et al(1974)Aho, Hopcroft, and Ullman]).
This technique is used to locate extreme values of a given real function defined over
a certain domain. Let us assume that the extrema sought values are minima. The
most general discrete algorithms proceed through a local search: Beginning at an
initial point, at each current point the algorithm updates it by choosing a neighbor
point according to a determined criterion in search of an extreme value i.e. the al-
gorithm descends following a pick direction, and this step is repeated until some
halting conditions are fulfilled.
Simulated annealing is a substantial variation of that strategy. For most occasions
it proceeds as outlined but in order to avoid falling into local minima, instead of the
sought global minima, at the first stages of the search it jumps with higher probabil-
2.5 Heuristics 37
ities to other parts in the domain in order to reinitiate the descent. At more advanced
steps the jump probability is lower. In “physical terms”, initially the system is rather
hot and as time passes the system is getting colder in a controlled way. This is a
motivation of the given name.
Let C : R+ → [0, 1] be a decreasing function such that limt&0 C(t) = 0 and
limt%+∞ C(t) = 1. The map C is a cooling strategy. For instance, for any constant
k
k > 0 the map t 7→ e− t is a cooling strategy. In Fig. 2.2, there appears the graph of
this map for k = 2 and k13 ≤ t ≤ 20k.
k
Fig. 2.2 The graph of t 7→ e− t for k = 2 and 1
k3
≤ t ≤ 20k.
As in simulated annealing, tabu search has an updating rule that sometimes may
opt for worst updatings in the hope to escape from local minima. Let us assume
that D is a domain such that for each x ∈ D there is a neighborhood N(x) ⊂ D, and
that f : D → R is an objective function to be minimized. Now, there is a tabu list T
whose aim is to track the local minima already found, and the paths leading to them,
in order to avoid repetition of any path. The updating rule may be synthesized as:
xnew ∈ N(xold ) & [ f (xnew ) < f (xold ) or xnew 6∈ T ] =⇒ xold := xnew . (2.9)
SimulatedAnnealing
Input. A cooling strategy C : R+ → [0, 1].
An energy function f : D → R.
Output. A minimum energy point x0 ∈ D.
1. Initially Pick xold ∈ D ; vold := f (xold ) ;
2. t0 :=(some small threshold) ; % Threshold for the system to get cool
3. t := (enough high value) ; % just to begin with a hot system
4. cool := (t < t0 ) ;
5. While (Not cool) Do
a. Repeat
i. Pick xnew ∈ N(xold ) ; vnew := f (xnew ) ;
ii. ∆ f := vnew − vold ;
iii. If ∆ f < 0 then Update {xold := xnew ; vold := vnew }
Else
A. Pick r ∈ [0, 1] ;
B. If r < C(t) then Update {xold := xnew ; vold := vnew }
Until No Updating has been done in several trials % Thermal equilibrium
is got
b. Decrease t ;
c. cool := (t < t0 ) ;
6. Output x0 = xold
TabuSearch
Input. An objective function f : D → R.
Output. An intended minimum point x0 ∈ D: f (x0 ) ≤ f (x), ∀x ∈ D.
1. Let xmc ∈ D be a (local) minimum of f ;
2. xc := xmc ;
3. T := [xc ] ;
4. Repeat
a. Pick x ∈ N(xc ) − T ;
b. AppendTo[T, x] ;
c. If f (x) < f (xmc ) then xmc := x ;
d. xc := x ;
e. Update T
Until some ending condition is fulfilled
5. Output xmc
The search at step 1. is done through any conventional procedure. Steps 4.c and
4.d implement the updating rule (2.9). In steps 4.b and 4.e some storage consider-
ations may be implemented. In short term memory, 4.b can be skipped most times,
and in step 4.e there can be stored just selected values of xc . In long term memory,
every tested point can be stored in order to avoid repetitions not just of paths but
even of mere points.
The genetic algorithms treat mainly with optimization problems. Given a real ob-
jective function f : D → R, the problem consists in finding an extreme value x0 ∈ D,
say a minimum, of the function f .
Here, at each stage of a genetic algorithm there is a whole collection of points
with the corresponding function values. Naturally, in the collection those points giv-
ing lesser values are preferred. Hence some points are discarded and the remaining
points are combined in order to increase the number of current points and the whole
process is repeated until improvements in the objective function are either impos-
sible (the minimum has already found) or implausible (a closer approximation to
the minimum is computationally hard). Due to the biological inspiration of the al-
gorithms, the jargon is this domain is quite particular. We will use it since currently
it has become conventional. However the reader should be aware that at any time
we will be dealing with points, values and maps and the biological terms are just
naming (although in a metaphoric way) those objects or particular procedures.
The genetic algorithms involve characteristic subprocesses:
Initialization. Many individual solutions are randomly chosen within the domain
D to form an initial population. These first elements either are uniformly dis-
tributed in order to form a representative and unbiased sample of points or may
be seeds in likely regions to contain solutions of the problem. The size of the
initial populations is chosen ad-hoc.
Selection. The current population is called a generation. A subset of the current
population is selected in terms of good-fitness, in order to breed a new generation.
The selection process may involve either the rating of all the individuals or just a
randomly chosen sample of individuals, and in this case the stochastic procedures
in selecting the individuals to be tested should guarantee the diversity of the
generation in order to avoid premature convergence to poor solutions. Among
well-studied selection procedures there are the so called roulette wheel selection
and tournament selection.
Reproduction. There are to main operators: crossover, and mutation. For each
prospective child in a new generation, a couple of parents is selected and they
are combined in order to breed the child point. Of course, a couple of just two
parents is an arbitrary decision, and couples with more than just two members
may provide better performance. Also, individual children may mutate in order
to get better fitness.
40 2 Algorithmic Strategies
All the combinations are designed with the purpose to improve the average fitness
of the current population.
Termination. Several ending conditions may be stated in terms of the reached
number of generations, or the value of the average fitness, or the value of the best
fitness, or the number of repetitions of some population features.
The sketch of the general procedure is the following:
Genetic algorithm
Input. An objective function f : D → R.
Output. An intended minimum point x0 ∈ D: f (x0 ) ≤ f (x), ∀x ∈ D.
1. ctr := 0 ;
2. Initialize a population P(ctr) ;
3. Evaluate the population P(ctr) ;
4. While Termination conditions fail Do
a. ctr + + ;
b. Select P(ctr) from P(ctr − 1) ;
c. Crossover P(ctr) ;
d. Mutate P(ctr) ;
e. Evaluate P(ctr) ;
5. Output a chosen x0 ∈ P(ctr)
Minimizev∈Rn f (v)
(2.10)
subject to Ev = d & ` ≤ v ≤ u
and consequently
Thus η has an unique maximum. Hence, solving the dual problem is an easier
task than solving the primal problem, and a solution of the dual problem entails a
solution of the primal problem.
A particular case in the use of Lagrange multipliers is Lagrangian relaxation. Let
us consider the Linear Integer Problem:
Minimizev∈Zn cT v
(2.12)
subject to Av = d & Bv = e
where c ∈ Zn , A ∈ Zm0 ×n , d ∈ Zm0 , B ∈ Zm1 ×n and e ∈ Zm1 . We may think that the
condition Bv = e imposes easy restrictions (for instance, if B is the identity matrix
and e = 0 the consition states v ≥ 0), while the condition Av = d imposes hard
restrictions. Then the corresponding dual problem becomes
where
η : w 7→ min{cT v + wT (Av − d)| v ∈ Zn & Bv = e}. (2.14)
The dual problem (2.13) may be easier to solve, because due to the concavity of
the corresponding objective map, it can be treated by “classical methods” in Rn and
then to round-up to a solution in Zn , while the evaluation of η according to (2.14)
involves just “easy” restrictions.
42 2 Algorithmic Strategies
A language is a set of words and a word is a string of finite length over a given
alphabet A. The zero-length word, i.e. the word containing no symbols, is the empty
word λ . Let A∗ denote the set of words. Thus a language is a set L ⊂ A∗ . For instance,
the empty language 0/ contains no words, while the total language, or dictionary A∗ ,
contains all possible words. A language may be given as an exhaustive list consisting
of the words in that language. Obviously this is feasible, although probably not
possible, only when the language is finite.
Example 2.6. A database is a language. Each register in the data base is properly a
word, which is, in turn a concatenation of “symbols” which are the values taken by
the attributes in the database relational scheme. Thus the alphabet is the union of all
attribute domains.
Example 2.7 (Chess). In chess, a match is a sequence of, let us say, positions, steps
or configurations. Each configuration is a 64-length word over the alphabet P con-
sisting of the figures, or pieces, white and black, and a “blank” figure to point that a
cell may be empty. This alphabet has thus 16 + 16 + 1 = 33 symbols. Let C denote
the collection of configurations, C ⊂ P64 ⊂ P∗ . Since each figure may appear in at
most one cell, the number of configurations is bounded by
32 32
64 64!
card (C) ≤ ∑
j
j! = ∑ (64 − j)! ∼ 1054 .
j=2 j=2
1. S → A initialize
2. A → aABC add a’s ad for each a b and a c should be added
3. A → abC stop a’s addition and balance it with a b and a c
4. CB → BC move the c’s to the right of all b’s
5. bB → bb change the provisional B’s for terminal b’s
6. bC → bc begin to change the C’s
7. cC → cc change the provisional C’s for terminal c’s
Example 2.9 (Chess). Let us get back to example 2.7. There is an initial configura-
tion, the well known starting position in chess. Then a match is obtained through
a finite sequence of legal moves. These are indeed also well known and they are
formalized as productions in the language of configurations. The configurations ob-
tained from the initial one are the ending configurations: checkmate to a king or
draw configurations.
The complexity of these problems depend on the level at the Chomsky hierarchy.
The Word Problem is easily solvable within regular languages (given L find the min-
imum automaton recognizing it, and for any query word x apply it to the automaton:
it arrives to a success state if and only if the query word lies indeed in the language),
hence communication protocols as TCP/IP can efficiently be implemented; but the
Word Problem is unsolvable for recursive languages.
The following problems have simple statements, the first has an existential
flavour while the second is of an universal kind:
Substring problem. Given two words, a text and a pattern, decide whether the
pattern occurs at the text.
Occurrences problem. Given a text and a pattern, find all occurrences of the pat-
tern within the text.
In spite of their simple statements, the problems above have important applications
in several areas of Computer Engineering: Image Processing, Word Processing,
Database Management, Bioinformatics, Operative Systems, etc.
As concrete examples of syntactic algorithms, let us sketch some conventional
procedures to solve the Substring Problem.
Let y ∈ A∗ be the text and let x ∈ A∗ be the pattern. Let us construct an automaton
R recognizing the language A∗ x consisting of all words that have x as a suffix. Then
the pattern appears in the text if and only if when applying y into R a terminal state
is visited at least once. In figure 2.5 we sketch the procedure.
y=
x=
x= σ a σ b
For the purpose of the current algorithm, let us number the symbols at any string
from the index 0: m = len (z) =⇒ z = z0 · · · zm−1 .
Suppose that the repeated prefix σ has length k. If the letter b appears at position
j then it will be useful to remember that k symbols before b form a prefix of the
2.6 Pattern matching and syntactical algorithms 45
ResearchWithAutomaton
Input. The text y ∈ A∗ and the pattern x ∈ A∗ .
Output. A Yes-No decision whether the pattern occurs at the text.
1. n := len (x) ;
2. for each i ∈ [[0, n]] let xi be the prefix of length i of x ;
3. let R := (Q, A,t, x0 ) be the automaton defined as follows:
States: Q = {xi }ni=0 .
Transitions: ∀xi ∈ Q , a ∈ A,
xi a ∈ Q =⇒ t(xi , a) = xi a
xi a 6∈ Q =⇒ t(xi , a) = longest suffix at xi a being a prefix of x
pattern, because when matching the pattern with a current segment of the text, if
a discrepancy occurs at b then the pattern x may be shifted in order to align the
prefix σ , say σ (1) , with its second occurrence, say σ (2) , and to continue with the
comparison process.
y: a0
σ a σ b
σ a σ b
x= GCATGCT
Trackx = −1 0 0 0 0 1 2
The Knuth-Morris-Pratt algorithm (KMP) exploits the table Trackx . The proce-
dure at figure 2.6 outlines the construction of the table.
The algorithm KMP shifts the pattern along the text in order to find an occur-
rence. The shift is not done by moving just one place, instead, whenever there is a
discrepancy, the pattern moves to the first non-tested place in which the matching
46 2 Algorithmic Strategies
KMPTrackingTable
Input. The pattern x ∈ A∗ .
Output. The table Trackx .
1. n := len (x) ;
2. Trackx [0] := −1 ; Trackx [1] := 0 ;
3. j := 2 ; i := 0 ;
4. While j ≤ n Do
a. If x[ j − 1] == x[i] Then
i. Trackx [ j] := i + 1 ;
ii. j + + ; i + +
Else
i. If i > 0 Then i := Trackx [i]
Else {Trackx [ j] := 0 ; j + +} ;
5. Output Trackx .
may continue. This is done with the help of the tracking table. The procedure is
shown at figure 2.7.
KMP
Input. The text y ∈ A∗ and the pattern x ∈ A∗ .
Output. The first occurrence of x in y if it does occur.
1. Trackx := KMPTrackingTable(x) ;
2. ny := len (y) ; nx := len (x) ;
3. jy := 0 ; jx := 0 ;
4. While jx + jy < ny Do
a. If x[ jx ] == y[ jy + jx ] Then
i. jx + + ;
ii. If jx == nx Then Output jy
Else
i. jy := jy + jx − Trackx [ jx ] ;
ii. If jx > 0 Then jx := Trackx [ jx ] ;
5. Output “The pattern x does not appear in the text y”
Fig. 2.7 Procedure KMP: Decides whether a pattern occurs within a text.
|(1:parangaracatirimicuaro)|leaf
tree:|
| | | |(5:ngaracatirimicuaro)|leaf
| | |(4:a)|
| | | |(10:catirimicuaro)|leaf
| |(3:r)|
| | |(22:o)|leaf
|(2:a)|
| |(5:ngaracatirimicuaro)|leaf
| |
| |(10:catirimicuaro)|leaf
| |
| |(12:tirimicuaro)|leaf
|
| | |(5:ngaracatirimicuaro)|leaf
| |(4:a)|
| | |(10:catirimicuaro)|leaf
|(3:r)|
| |(15:imicuaro)|leaf
| |
| |(22:o)|leaf
|
|(5:ngaracatirimicuaro)|leaf
|
|(6:garacatirimicuaro)|leaf
|
| |(11:atirimicuaro)|leaf
|(10:c)|
| |(19:uaro)|leaf
|
|(12:tirimicuaro)|leaf
|
| |(14:rimicuaro)|leaf
|(13:i)|
| |(16:micuaro)|leaf
| |
| |(18:cuaro)|leaf
|
|(16:micuaro)|leaf
|
|(19:uaro)|leaf
|
|(22:o)|leaf
Table 2.1 Suffix tree for the string parangaracatirimicuaro of length 22. It has 8 branch-
ing nodes.
If the string y is such that a proper prefix coincides with a proper prefix, say
∃x, z ∈ A∗ : y = xzx, with len (x) > 0, then no suffix tree may exist for y. Thus, in
order to avoid this problem, usually it is considered a symbol $ not in A and the
word y$ instead of y.
Let us sketch a very basic procedure to build suffix trees. Let us assume that the
string y = u1 · · · um is given. Let, for each i ≤ m, yi = ui · · · um $ be the suffix ranging
1 http://www.allisons.org/ll/AlgDS/Tree/Suffix/
48 2 Algorithmic Strategies
| | |(7:aedadysiglosdichososaquellosalosquelosantiguos)|leaf
| |(2:ichos)|
| | |(25:osaquellosalosquelosantiguos)|leaf
|(1:d)|
| |(10:adysiglosdichososaquellosalosquelosantiguos)|leaf
| |
| |(12:ysiglosdichososaquellosalosquelosantiguos)|leaf
tree:|
| | |(7:aedadysiglosdichososaquellosalosquelosantiguos)|leaf
| |(3:chos)|
| | |(25:osaquellosalosquelosantiguos)|leaf
|(2:i)|
| | |(16:losdichososaquellosalosquelosantiguos)|leaf
| |(15:g)|
| | |(50:uos)|leaf
|
| |(7:aedadysiglosdichososaquellosalosquelosantiguos)|leaf
|(3:chos)|
| |(25:osaquellosalosquelosantiguos)|leaf
|
| |(7:aedadysiglosdichososaquellosalosquelosantiguos)|leaf
|(4:hos)|
| |(25:osaquellosalosquelosantiguos)|leaf
|
| | |(8:edadysiglosdichososaquellosalosquelosantiguos)|leaf
| |(7:a)|
| | |(28:quellosalosquelosantiguos)|leaf
| | |
| | |(36:losquelosantiguos)|leaf
| | |
| | |(46:ntiguos)|leaf
|(5:os)|
| |(19:dichososaquellosalosquelosantiguos)|leaf
| |
| |(25:osaquellosalosquelosantiguos)|leaf
| |
| |(39:quelosantiguos)|leaf
|
| | |(8:edadysiglosdichososaquellosalosquelosantiguos)|leaf
| |(7:a)|
| | |(28:quellosalosquelosantiguos)|leaf
| | |
| | |(36:losquelosantiguos)|leaf
| | |
| | |(46:ntiguos)|leaf
|(6:s)|
| |(14:iglosdichososaquellosalosquelosantiguos)|leaf
| |
| |(19:dichososaquellosalosquelosantiguos)|leaf
| |
| |(25:osaquellosalosquelosantiguos)|leaf
| |
| |(39:quelosantiguos)|leaf
|
| |(8:edadysiglosdichososaquellosalosquelosantiguos)|leaf
|(7:a)|
| |(11:dysiglosdichososaquellosalosquelosantiguos)|leaf
| |
| |(28:quellosalosquelosantiguos)|leaf
| |
| |(36:losquelosantiguos)|leaf
| |
| |(46:ntiguos)|leaf
|
| |(9:dadysiglosdichososaquellosalosquelosantiguos)|leaf
|(8:e)|
| | |(32:losalosquelosantiguos)|leaf
| |(31:l)|
| | |(43:osantiguos)|leaf
|
|(12:ysiglosdichososaquellosalosquelosantiguos)|leaf
|
| |(16:losdichososaquellosalosquelosantiguos)|leaf
|(15:g)|
| |(50:uos)|leaf
|
| | |(19:dichososaquellosalosquelosantiguos)|leaf
| |(17:os)|
| | | |(36:losquelosantiguos)|leaf
| | |(35:a)|
| | | |(46:ntiguos)|leaf
| | |
| | |(39:quelosantiguos)|leaf
|(16:l)|
| |(32:losalosquelosantiguos)|leaf
|
| |(32:losalosquelosantiguos)|leaf
|(28:quel)|
| |(43:osantiguos)|leaf
|
| | |(32:losalosquelosantiguos)|leaf
| |(30:el)|
| | |(43:osantiguos)|leaf
|(29:u)|
| |(51:os)|leaf
|
|(46:ntiguos)|leaf
|
|(47:tiguos)|leaf
from the i-th to the last position. Let Ti be the suffix tree codifying just the suffixes
y1 . . . , yi . The goal is to build Tm . Let us proceed recursively.
Clearly, T1 consists of just one edge labelled by y1 = y$. The edge has as ex-
tremes the root vertex and a leaf, marked as 1.
Let us assume that T j has been constructed already. Find the largest prefix z j+1
of y j+1 obtained as concatenation of labels in T j from its root to a vertex in T j . The
right extreme of z j+1 should be between two nodes u and v of T j . In other words,
there is a suffix wl ∈ A∗ of z j+1 and two vertexes u and v in T j such that the label
of the edge (u, v) is wl wr , with wr ∈ A∗ . Then split the edge (u, v) and add a new
leaf. Explicitly, add two vertexes u0 , v0 , and the edges (u, u0 ), (u0 , v) and (u0 , v0 ) with
respective labels wl , wr , and the complementary suffix of z j+1 within y j+1 . Mark v0
as the ( j + 1)-th leaf. The resulting tree is T j+1 .
The reader may check this algorithm with the example displayed at table 2.1.
Since there are m suffixes each of different length between 1 and m, we see that
the mentioned algorithm requires O(m2 ) comparisons of symbols. An alternative
algorithm [Ukkonen(1995)] requires O(m) comparisons, thus the quadratic naive
mentioned algorithm is far from the linear complexity of suffix trees construction.
However, the representation is very economical. Since the suffix tree has m
leaves, then necessarily it should have 2m − 1 vertexes. On the other hand, the orig-
inal string has, for each i ≤ m, m − i + 1 substrings of length i. Thus, there are
1 2
2 m(m − 1) = O(m ) non-empty substrings. Hence a linear space is used to store a
quadratic number of objects.
It is interesting to observe that the suffix trees for words of the form abk a and
a bk are remarkably similar.
k
The Substring Problem can be solved in linear time with suffix trees: Namely,
give a text y and a pattern x, construct the suffix tree Ty of y, then in a breadth-first
way locate the vertex v with an edge labelled with a word having the beginning of
the pattern, and parse the pattern along the descendants of v. Reply in accordance
with the parsing success.
The Occurrences Problem also can be solved in linear time with suffix trees:
Namely, once a pattern has been decided to occur in the text, and the parsing has led
to a vertex w in the suffix tree, then all occurrences of the pattern are realized as the
leaves of the subtree rooted at w.
The longest common subsequence of two sequences x, y can also be efficiently
solved. Namely, let z = x#y$ and construct the suffix tree Tz of z. Then the longest
common subsequence is the longest pattern w of length at most min{ len (x), len (y)}
that occurs in a suffix of x of length greater than len (w) and in a suffix of y of length
greater than len (w).
For any function f : Rn → R and any point x ∈ Rn , the following notions are con-
ventional:
Partial derivatives. For each j ∈ [[1, n]] the partial derivative of f at x is
∂f 1
∂ j f (x) = (x) = lim [ f (x + te j ) − f (x)] , (2.15)
∂xj t→0 t
where e j is the j-th vector at the canonical basis of Rn , i.e. it is the vector that
has the value 0 at each entry, except at the j-th entry in which it has the value 1.
Gradient. The gradient of f at x is
∂f ∂f
∇ f (x) = (x) · · · (x) .
∂ x1 ∂ xn
In other words, the gradient is the (1 × n)-matrix whose entries are the partial
derivatives. Naturally, the gradient can be identified with the vector whose com-
ponents are the partial derivatives,
n
∂f
∇ f (x) ≈ ∑ ∂ x j (x)e j .
j=1
For any enough smooth function f : Rn → R and any point x0 ∈ Rn a local first order
approximation is obtained as
Remark 2.4. The problem to find the roots of a function is closely related to the
problem to find unconstrained function extrema.
Remark 2.5. The problem to find the simultaneous roots of n real functions is closely
related to the problem to find fixed points of maps Rn → Rn .
Given f1 , . . . , fn : Rn → R, let
52 2 Algorithmic Strategies
A function g : Rn → Rn is a contraction if
Since 0 ≤ c < 1, we have ck −→k→+∞ 0. The above inequalities entail that (xk )+∞
k=0
is a Cauchy sequence in Rn . Hence there exists a point x∞ such that xk −→k→+∞ x∞ .
Necessarily, x∞ = g(x∞ ), and x∞ is indeed a fixed point of g. u
t
Let us observe that, since the final inequality (2.20) is satisfied for all ` ≥ k, it
will be satisfied by the limit point, e.g.
kx1 − x0 k k
∀k ∈ N : kx∞ − xk k ≤ c. (2.21)
1−c
Thus, given a threshold ε > 0, if the iteration is continued till
2.7 Numerical approximation algorithms 53
−1
1−c
ln kx1 −x0 k ε
k≥
ln(c−1 )
then the approximation error done by the iteration process will be bounded by ε.
Proposition 2.1 (Newton’s method). If the sequence (xk )+∞ k=0 built according to
rules (2.22) converges to a limit point x∞ ∈ Rn , then this point is a root of f .
The special case for n = 1 is well determined and for f : R → R the Newton-
Raphson method is the following:
Choose x0 ∈ R.
)
−1 (2.23)
∀k ≥ 0 : xk+1 = xk − ddxf (xk ) f (xk ).
Choose x0 ∈ Rn .
(2.24)
∀k ≥ 0 : xk+1 = xk − (D f (xk ))−1 f (xk ).
the whole context of the problem. However, whenever the method converges, the
convergence is at least quadratic:
Ax = b (2.25)
The method depends on the chosen matrix B. In practice, this matrix is chosen in
dependence of matrix A. Namely, let D = diag [a11 · · · ann ] be the diagonal (n × n)-
matrix whose non-zero values are those appearing at the diagonal of A, let L =
[`i j ]i, j∈[[1,n]] be the lower triangular matrix consisting of the lower triangular block
of matrix A: (i > j ⇒ `i j = ai j ) ; (i ≤ j ⇒ `i j = 0) , and let U = [ui j ]i, j∈[[1,n]] be
the upper triangular matrix consisting of the upper triangular block of matrix A:
(i ≥ j ⇒ ui j = 0) ; (i < j ⇒ ui j = ai j ) . The following procedures result:
Jacobi method. Let B = D. Then Idn − B−1 A = −D−1 (L +U).
Gauss-Seidel method. Let B = D − L. Then Idn − B−1 A = −(D + L)−1U.
The inversion of diagonal and triangular matrices can be computed efficiently. Thus,
the iterative methods would be more efficient than the calculation of the inverse
matrix.
2.7 Numerical approximation algorithms 55
where F : Rk+2 → R is a continuous map and for each κ ≤ k, y(κ) (x) = ∂κ y(x). A
solution in a real interval [a, b] ⊂ R is a map y : [a, b] → R such that for each point
x ∈ [a, b], eq. (2.26) holds.
The Cauchy problem consists in solving the differential equation restricted to an
initial condition:
Find a solution y of eq. (2.26) such that y(a), y(1) (a), . . . , y(k) (a) = y0 ∈ Rk+1 .
Problems
2.1. Write a program to solve the Eight Queens puzzle by Brute-Force as explained
in example 2.4.
2.7. Write a program to solve the Eight Queens puzzle by a backtracking procedure
as explained in section 2.4.4.
2.9. Write a program implementing the Strassen method for matrix multipli-
cation as explained in section 2.3.5.
2.16. Write a program implementing the search of a fixed point according to Ba-
nach’s Theorem (see theorem 2.1). Test the implementation with [0, π2 ] and the map
f : x 7→ cos(x).
2.7 Numerical approximation algorithms 57
2.18. Write a program implementing the iterative method to solve systems of linear
equations as explained in section 2.7.2 using the Jacobi method.
2.19. Write a program implementing the iterative method to solve systems of linear
equations as explained in section 2.7.2 using the Gauss-Seidel method.
Chapter 3
Fundamental Algorithms
Abstract In this chapter we expose succinctly classical algorithm that serve as pro-
totypes of the general design lines in the previous chapter. In numerical algorithms
we pose the interpolation problem and the solution given by Legendre polynomials
and by solving systems of linear equations. The queries to databases entail local-
ization of given registers. The sequential search solve this problem in linear time
while the binary search works in logarithmic time. Typical sorting algorithms work
on quadratic time, but by using a divide-and-conquer approach sorting can be done
in n lg n time through Quicksort. Hash tables help to store information in compact
forms, and binary trees are also storage devices structuring the information in such
a way to reduce, to logarithmic costs, the most basic relational operations. The final
part of the chapter is devoted to Graph Theory problems with wide applications.
The final part of the chapter is devoted to Graph Theory problems with wide ap-
plications. Here, the breadth-first and depth-first traversal help to solve important
problems as calculation of shortest-paths and of minimum spanning trees.
y1 − y0
y= (x − x0 ) + y0 .
x1 − x0
59
60 3 Fundamental Algorithms
Thus the expression at the right hand side is the linear polynomial interpolating the
two given points.
In order to solve the Interpolation Problem let us consider the
Lagrange method. Suppose that `i (X) is a n degree polynomial such that
Relations (3.1) and (3.2) determine an algorithm to solve the Interpolation Problem.
The polynomials satisfying relation (3.1) are
∏ j∈[[0,n]]−{i} (X − x j ) X −xj
`i (X) = = ∏
∏ j∈[[0,n]]−{i} (xi − x j ) x −xj
j∈[[0,n]]−{i} i
thus we have a system u = Va, with solution a = V −1 u, provided that the matrix V
is non-singular. One can see that the matrix V is indeed non- singular because
detV = ∏ (x j − xi ).
0≤i< j≤n
However this value could be very close to zero if the distance among consecutive
abscissae is smaller than 1. This renders the problem rather ill-conditioned.
In section 2.7 some other numerical algorithms have been discussed.
3.2 Sequential and binary search algorithms 61
For a given finite sequence A of objects of the same type, and a query object x it is
asked to decide whether x appears in A and if it appears indeed, then to locate its
position in the sequence.
The sequential search consists in checking consecutively whether each element
in the array coincides with the query object x. The procedure, shown at figure 3.1,
is quite direct.
SequentialSearch
Input. An array A[1 : n], and a query value x.
Output. The position at A in which x occurs, or an indication that it does not
occur, otherwise.
1. pcurr := 0 ;
2. Stop := False ;
3. While Not(Stop) && pcurr < len (A) Do
a. pcurr + + ;
b. Stop := (x == A[pcurr ]) ;
4. If Stop Then Output pcurr
Else Output ’x does not occur in A’
Let us assume that for each entry i ∈ [[1, n]] at the array, pi is the probability that
the query object x coincides with A[i]. Hence W = (pi )ni=1 is a probability distribu-
tion on A. Let χ be the random variable χ : x 7→ i, that for each query object gives
the number of tests in SequentialSearch realized to find it in the array. The
expected number of tests is thus
n
E(χ) = ∑ i pi ∈ [1, n],
i=1
Thus according with the time estimations performed at section 2.3 the expected
number of tests in finding x is O(log n).
When sorting an array of items in an ordered set, the most intuitive algorithm is a
round-robin comparison among its entries as shown in figure 3.2.
Round-robinSort
Input. An array A = A[1 : n].
Output. The sorted array A.
1. For i = 1 to n − 1 do
a. For j = i + 1 to n do
i. If A[i] > A[ j] Then switch A[i] and A[ j] ;
2. Output A
Divide Given an array A split it into two subarrays A = A1 ∪ A2 such that each
entry at A1 is not greater than any entry at A2 .
Conquer Sort each subarray Ai , i = 1, 2, using the current procedure.
No merge is required due to the “divide” condition. The procedure is sketched at
figure 3.3.
Quicksort
Input. An array A and extreme indexes 1 ≤ p ≤ r ≤ n
Output. The subarray A[p · · · r] sorted.
1. If p < r Then
a. q := SplittingIndex(A, p, r) ;
b. Quicksort(A, p, q) ;
c. Quicksort(A, q + 1, r) ;
There are several criteria to choose the splitting index, at step 1.a., and they de-
pend on the selection of a pivot. Namely, given a pivot x in the range of A, let
J1 = { j| A[ j] < x} and J2 = { j| A[ j] ≥ x}. Clearly, when recognizing J1 , the ele-
ments of A may be switched if necessary in order to guarantee the condition in the
“divide” step. The splitting index is thus q = p + card (J1 ).
Each criterion for pivot selection produces a variant of Quicksort. Among the
criteria, there are the following:
• the first entry A[1],
• the middle entry A p+r
2 ,
√
• the entry in “golden ratio” proportion A [dp + γ(r − p)e], where γ = 5−1
2 ,
A[p]+A[r]
• the middle value of extremes 2 ,
• the value in “golden ratio” proportion of the extremes A[p] + γ(A[r] − A[p]) if
A[r] ≥ A[p], or A[r] + γ(A[p] − A[r]) otherwise,
• etc.
Quicksort will show better performances whenever the splitting index is closer
to the middle number of current entries p+r
2 and the probabilistic distribution of the
values at the input array will determine whether this condition is fulfilled. In best
and average cases, the time complexity of Quicksort is Θ (n log n).
Within an universal hash family, one can have a hash map h : x 7→ hx (x), where
hx ∈ H is chosen randomly for each x ∈ A. Obviously, it is necessary to record the
used map hx for each x.
Remark 3.1. If H is universal, then for each a ∈ A the expected value of the number
of collisions involving a is n−1
m .
Proof. For each u, v ∈ A, u 6= v, let cuv = 1 if h(u) = h(v) , or cuv = 0 otherwise; and
let Cu = ∑v6=u cuv . Then E(cuv ) = m1 and E(Cu ) = ∑v6=u E(cuv ) = n−1m . u t
let f : N → Z be a one-to-one map. Then if the value b = h(a) has been taken by
a previous a1 , the associate to a the value b + f (k), where k is the minimum index
such that b + f (k) has not been assumed formerly.
As another direct possibility, a tagging could be used in order to distinguish dif-
ferent objects in A colliding into the same hash values.
A binary tree is either an empty tree or a leaf or a root which is the parent of a left
binary tree and a right binary tree. In this last case, the root of the left subtree is the
left child and the root of the right subtree is the right child of the parent root. Thus
in any binary tree any internal node is the parent of two children. For any node x let
Left(x) denote the left subtree and Right(x) the right subtree that have x as parent.
If n is the number of vertexes in a binary tree and k is its height then k = O(log n)
and n = O(2k ), i.e. the number of vertexes is exponential with the height and the
height is logarithmic with the number of vertexes. Besides in a binary tree, the num-
ber of leaves is around half the total number of vertexes.
An inorder labeling is a map L : {vertexes} → Z such that
y ∈ Left(x) ⇒ L(y) < L(x)
∀x, ∀y : (3.5)
y ∈ Right(x) ⇒ L(y) > L(x)
The labels may be the values of a hashing function, thus a binary tree may be
used as a data structure containing the keys of the database. The elementary access
functions can be efficiently performed:
Find the minimum key. Just go to the leftmost leaf.
Find the maximum key. Just go to the rightmost leaf.
Find successor. Given a vertex x, if Right(x) is not empty, the successor of x
is the minimum element in Right(x); otherwise, ascend in order to find the first
ancestor in the left line, the successor of x is this ancestor.
Find predecessor. Given a vertex x, if Left(x) is not empty, the predecessor
of x is the maximum element in Left(x); otherwise, ascend in order to find the
first ancestor in the right line, the predecessor of x is this ancestor.
Search a query key. Compare the query key z with the root x. If z < L(x) then
search z in Left(x), if z = L(x) then exit successfully the search, and if z > L(x)
then search z in Right(x). A search procedure in an empty tree is always a failure
process.
The time complexity is proportional with the height, thus it is logarithmic with
the length of the input array.
Insertion of a labelled node. Given a key z and a binary tree T , consider z as a tree
consisting just of one leaf. Find the position, using tree search, at which z should
be at T . If x is the node to act as parent of z then define the pointers as it was
necessary.
66 3 Fundamental Algorithms
Deletion of a labelled node. Given a vertex x for deletion in a binary tree T , let us
consider three cases according to the number of children of x in T . If x has no
children, i.e. it is a leaf, just suppress it and redefine the pointer to x of its parent.
If x has one child, just overskip it, i.e. suppress it and redefine the pointers of its
parent and its child. If x has two children then its right son y should be the left
son of successor(y).
The binary trees entail thus procedures with expected logarithmic time complex-
ities. However, the worst cases may maintain linear complexities.
An elaborated technique is given by the red-black trees that maintains all trees
balanced, and consequently even the worst case cases have logarithmic complexity,
but this technique is out of the scope of the current presentation.
3.7.1 Adjacency-lists
[(u, w({v, u}))]{v,u}∈E and has type (V ×R)∗ . The length of Adj(v) is the degree ∂ (v)
of v. Thus the whole graph can be represented by a structure of type (V ∗ )∗ .
For a directed graph G = (V, E) its adjacency-list is Adj(v) = [u](u,v)∈E . The
length of Adj(v) is the in-degree ∂ + (v). The calculation of out-degrees is rather
expensive since it is necessary to check all adjacency-lists.
3.7.2 Adjacency-matrices
Thus, MG ∈ {0, 1}n×n , where n = card (V ) is the number of vertexes in the graph,
and the number of 1’s appearing in MG is 2m where m = card (E) is the number of
edges in the graph. Let us remark that Mg is a symmetric matrix and the entries at
the diagonal are all zero. Thus, instead of storing the whole matrix MG it is worth to
store just the 12 n(n − 1) entries above the main diagonal.
The adjacency matrix of a digraph is defined similarly, but it is not necessarily
symmetric.
The invariant condition states that at any time the white part has not yet been dis-
covered, the black region has been discovered and the gray region separates those
former regions.
The procedure uses a queue working in a principle “First-In–First-Out”. It is
sketched in figure 3.4.
The steps 3. and 4.d essentially just paste the adjacency-lists of s and u.
The procedure determines a tree structure in the connected component of the
source vertex s and it is indeed traversing the tree in a breadth-first traversal.
68 3 Fundamental Algorithms
BreadthFirst
Input. A graph G = (V, E) as a list of adjacency-lists and a source vertex s ∈ V .
Output. The connected component ConG (v).
1. Initially paint the source point gray ;
2. let d(s) := 0 ;
3. enqueue all pairs (s, v) ∈ E ;
4. Repeat
a. dequeue an edge {v, u} painted (gray,white) ;
b. paint it (black, gray) ;
c. declare v as the parent of u ; let du := dv + 1 ;
d. enqueue all pairs (u, w) ∈ E with w white ;
until the queue is empty ;
5. Output the black region
For a precedence map π, let Gπ = (V, Eπ ) be the digraph with edges (π(v), v), v ∈ V .
Gπ is a subgraph of G, probably not-connected, hence it is a forest, and it is called a
depth-first forest.
In order to build such a forest, let us use, as before, a vertex coloring with three
colors: white, gray and black. Besides, as map d before, let us use two time marks:
dv is the discovering time of vertex v, while fv is the moment when its adjacency-list
has been exhausted and v is turning black. In figure 3.5 we show an algorithm for
calculation of a depth-first forest.
DepthFirst
Input. A digraph G = (V, E) as a list of adjacency-lists.
Output. A predecessor map and the corresponding depth-first forest.
1. For each v ∈ V Do {color(v) := white ; πv := nil} ;
2. time := 0 ;
3. For each v ∈ V Do If color(v) := white Then TraverseDepthFirst(v)
;
4. Output maps π, d and f
TraverseDepthFirst
Input. A digraph G = (V, E) and a vertex v ∈ V .
Output. Depth-first traversal of the tree rooted at v.
1. color(v) := gray ;
2. time + + ; dv := time ;
3. For each u ∈ Adj(v) Do
a. If color(u) := white Then {πu := v ; TraverseDepthFirst(u)} ;
b. color(u) := black ;
4. time + + ; fv := time
Let G = (V, E) be a directed acyclic graph, a dag for short. A topological sort is an
enumeration e : V → [[1, n]] such that
This condition entails that the graph may be drawn in a horizontal line and all ver-
tices are going form left to right. Obviously, a digraph with cycles cannot posses a
topological sort.
In order to construct a topological sort we may use the DepthFirst procedure
shown at figure 3.5. Namely, apply this algorithm on G = (V, E) in order to obtain
the predecessor map π, the initial-times map d and the ending-times map f of a
depth-first traversal of the graph G. Then a sorting of the set of vertexes V according
to f defines a topological sort in G.
Consequently, the topological sort can be obtained in time complexity Θ ( card (V )+
card (E)).
70 3 Fundamental Algorithms
duk ≤ du1 + 1
∀i < k : dui ≤ dui+1
DijkstraAlgorithm
Input. A weighted digraph G = (V, E, w), with non-negative weights, and a
source vertex s ∈ V .
Output. The distance of the shortest path from s to any other vertex in V .
1. Reached := {s} ; ρ(s) := 0 ;
2. For each x ∈ V − {s} Do ρ(x) := w(s, x) ;
3. While Reached 6= V Do
a. let x := arg min{ρ(y)| y ∈ V − Reached} ;
b. Add x into Reached ;
c. For each y ∈ V − Reached Do ρ(y) := min{ρ(y), ρ(x) + w(x, y) ;
4. Output the array ρ
with the connotation: if the weight diminishes, replace the segment from vi to vk by
two segments through the intermediate point v j .
If the triangle operation is iterated over all j’s and realized for all other pairs i, k,
beginning with the weights at the graph, then the distances will take the values of the
shortest paths. The algorithm is displayed in figure 3.8, which has time complexity
O(n(n − 1)2 ).
FloydWarshallAlgorithm
Input. A weighted digraph G = (V, E, w), with non-negative weights.
Output. A matrix D ∈ Rn×n giving the distances of the shortest paths among
vertex pairs in V .
1. For i = 1 To n Do For k = 1 To n Do
If i == k Then dii := ∞ Else dik := w(vi , vk ) ;
2. For each j = 1 To n Do
a. For each i ∈ [[1, n]] − { j} Do
i. For each k ∈ [[1, n]] − { j} Do Triangle(D; i, j, k) ;
3. Output the array D
By keeping track of the changes made by the triangle operation at step 2.a.i, as
defined by relation (3.7), then it is possible to recover the actual shortest path among
any pair of vertexes.
Given a digraph G = (V, E), its transitive closure is the graph G∗ = (V, E ∗ ) such
that
Although it is not hard to prove this proposition, we skip the proof (the interested
reader may consult [Papadimitriou and Steiglitz(1998)]).
The resulting algorithm is direct: Starting with the forest consisting of trees
formed by the vertices with no edges, {({v}, 0)} / v∈V , choose the edge with mini-
mum weight and initiate a tree with this edge. Thereafter to having the current tree,
find the minimum weight edge with just an extreme in this tree and extend the tree.
The algorithm is displayed in figure 3.9, which has time complexity O(n2 ).
3.12 Minimum spanning tree 73
PrimMST
Input. A weighted graph G = (V, E, w), as a distance matrix W = [wi j ]i j .
Output. A spanning tree of minimal weight.
1. let {v, u} ∈ E be the minimal weight edge ;
2. U := {v} ; F := 0/ ;
3. For each u ∈ V −U Do closestU (u) := v ;
4. While U 6= V Do
a. let v := arg min{d(u, closestU (u))| u ∈ V −U} ;
b. U := U ∪ {v} ; F := F ∪ {{v, closestU (v)}} ;
c. For each u ∈ V −U Do
If d(u, closestU (u)) > d(u, v) Then closestU (u) := v ;
5. Output (U, F)
4.1.1 Networks
A network is properly a graph G = (V, E). The graph is undirected if the commu-
nications along the edges is bidirectional and the graph is directed if just one-way
communications are allowed. Let us recall that the degree of a node is the num-
ber of its adjacent neighbors. The degree of a graph is the maximum degree of its
vertexes, the diameter of G is the maximum distance among any two vertexes on
the graph and the bisection width is the minimal number of edges to be removed in
order to split G into two disjoint subgraphs G0 = (V0 , E0 ), G1 = (V1 , E1 ) such that
V = V0 ∪V1 and | card (V1 ) − card (V0 )| ≤ 1.
75
76 4 Distributed Algorithms
Let T0 be the tree consisting of just one vertex. This vertex is the root as well as the
leaf of T0 and it has no edges.
For k ≥ 1, let Tk be the tree consisting of a root with exactly two children: each
being the root of a tree isomorphic to Tk−1 .
Thus Tk is the complete binary tree network. In Tk each vertex is able to com-
municate with any neighbor vertex: either its parent or its children. It has height k,
2k+1 − 1 vertexes and 2k leaves. Each vertex is either a leaf or it has exactly two chil-
dren. As a graph, it has diameter 2k and its bisection width is 1. As a network, the
root of Tk is a bottleneck since in order to connect two vertexes in different copies
of Tk−1 the root necessarily should be visited.
For instance, in order to select the minimum value among an array of n values
using a circuit Tk let us assign 2nk values to each leaf. Initially, in parallel, each leaf
selects the minimum value among its assigned values. Consecutively, each node
receives the minima of its two children and then it sends the minimum resulting
value to its parent. The root will have the minimum value of the whole array.
This procedure entails k communication steps.
Let us consider the lattice Zdm with the neighboring notion given as differences lying
in the canonical basis of Rd : x and y are neighbors if and only if ∃i ∈ [[0, d − 1]],
ε ∈ {−1, +1}: x − y = εei . As a graph, Zdm has md vertexes, the degree of each
vertex is at most 2d and its diameter is d(m − 1). The bisection width is upperly
bounded by md−1 : along any coordinate i ∈[[0, d − 1]] let Ex , x ∈ Zm d−1 , be the edge
m
{y, z} such that the i-th entry of y is yi = 2 , the i-th entry of z is zi = m2 − 1, and
the remaining entries of y and z are given by x. For even m, the removal of all edges
d−1 , bisects the graph.
Ex , x ∈ Zm
For instance, let us consider the odd-even transposition sort (OETS) within a
linear (d = 1) array of m processors. Given an array of n numerical values initially
each processor is provided with a mn -length subarray. Then, in parallel, each proces-
sor sorts its subsequence using Quicksort. Consecutively in m steps, let us pro-
ceed as follows: at odd indexed steps, each even numbered processor p2i sends its
sorted sequence to its left neighbor p2i−1 , which merges both subsequences, keeps
the smaller half and sends back the larger half to p2i ; at even indexed steps, each
even numbered processor p2i sends its sorted sequence to its right neighbor p2i+1 ,
which merges both subsequences, keeps the larger half and sends back the smaller
half to p2i .
OETS is accomplishing its task in O mn log mn + n computing steps and m com-
4.1.1.3 Hypercubes
Let Zd2 be the d-dimensional hypercube. Its edges are of the form {x, x + ei } where
w ∈ Zd2 and ei is a vector in the canonical basis and addition is assumed modulo 2.
Zd2 is a regular graph of degree d and its diameter is also d.
For each k ≤ d, there are dk 2d−k subgraphs isomorphic to Zk2 within Zd2 . Hence,
C(A) ≥ ( card (A0 ) − card (A0 ∩ A1 )) + ( card (Ac0 ) − card (Ac0 ∩ A1 )) + card (A1 )
= 2d−1 − card (A1 ) + card (A1 ).
= 2d−1
Thus any pair among the 2d nodes in Zd2 can communicate within a route of
length at most d, in other words, the communicating length is logarithmic with re-
spect to the number of nodes, as is the case in the complete binary networks. How-
ever here there are no bottle-necks. Instead, the “connectedness degree” is rather
high in the hypercube, as seen in proposition 4.1.
78 4 Distributed Algorithms
Definition 4.1 (Routing procedures). Let G = (V, E) be a graph. For any two nodes
u, v ∈ V let Puv be the class of paths in G beginning in u and ending in v. A routing is
a map R : (u, v) 7→ R(u, v) ∈ Puv that associates to each pair (u, v) a path in G going
from u to v. For any permutation π ∈ SV a π-routing is a map ρπ : u 7→ ρπ (u) ∈ Pu,π(u)
giving a path, for each vertex u, going from u into π(u). If µu is the message that
node u should send to π(u) then ρπ is the route that message µu will follow.
In the hypercube G = Zd2 a direct routing procedure acts according to the “Bit-
Fixing Strategy”, and it is sketched in figure 4.1.
BitFixingRouting
Input. A permutation π ∈ SV
Output. A π-routing ρπ : u 7→ ρπ (u) ∈ Pu,π(u)
In the Bit Fixing Strategy, in order to go from a node u into another node v in
the hypercube Zd2 , the bits of u and v are compared from left to right: if there is a
discrepancy then the current point is moved along that discrepancy’s direction.
BitFixingStrategy
Input. Two nodes u, v ∈ V
Output. A path joining u with v
1. let crpt := u ; path := [crpt] ;
2. For each i ∈ [[1, d]] do
a. If crpt[[i]] 6= v[[i]] then
i. crpt := crpt + ei ;
ii. AppendTo[path, crpt] ;
3. Output path
Let (u0 , v0 ), (u1 , v1 ) be two pairs of vertexes. Let ρ0 ∈ Pu0 v0 , ρ1 ∈ Pu1 v1 be paths
joining the pairs. We say that there is a path crossing at step i ≤ d if ρ0 [[i]] = ρ1 [[i]].
Clearly BitFixingStrategy will produce paths with a crossing if the pairs
can be expressed as u0 = u0p wus0 , v0 = v0p wvs0 , u1 = u1p wus1 , v1 = v1p wvs1 , for some
non-empty subwords u’s and v’s, and v0p wus0 = v1p wus1 . In this case, this common
value determines a path crossing. At this crossing, BitFixingStrategy will
produce as many skips as the length of the infix w. From here it follows that any two
paths leaving a coincidence will never meet again.
4.1 Distributed systems 79
RandomMiddle
Input. A permutation π ∈ SV
Output. A π-routing ρπ : u 7→ ρπ (u) ∈ Pu,π(u)
Since each vertex v in the hypercube has nk neighbors at distance k, k ∈ [[0, d]],
Let R be a routing strategy. For each edge a = {u, v}, let Wa be the number of paths,
connecting pairs {w, π(w)}, that pass through the edge a. Then, for each edge a, the
expected value of Wa is
d
2 d 2d
E(Wa ) = ∑ = = 1.
w d2d−1 2 d2d−1
Then, for each u, E(∑v Huv ) ≤ d2 E(Wa ) = d2 . Clearly, ∑v Huv is the number of “de-
lays” that the message µu should wait due to “edge collisions”. According to Cher-
nov’s inequalities [Schnitger(2007)], for any β > 0,
80 4 Distributed Algorithms
d β2 d
Pr ∑ Huv ) ≥ (1 + β ) ≤ e− 3 2 .
v 2
Thus, with probability at least 1 − 2 exp − d2 the first stage 1.b of procedure
4.1.1.4 Butterflies
Let Bd = Zd2 × [[0, n]] be the Cartesian product of the hypercube Zd2 and the set con-
sisting of the first n + 1 natural numbers. Let
Ehd = {{(x, j), (x, j + 1)}| j ∈ [[0, n − 1]], x ∈ Zd2 } : horizontal edges
Ecd = {{(x, j), (y, j + 1)}| j ∈ [[0, n − 1]], x ∈ Zd2 , y = x + e j } : crossing edges
The graph (Bd , Ehd ∪Ecd ) is called the d-dimensional butterfly network. In figure 4.4
we sketch the graphs of the butterflies for d ∈ [[1, 4]].
The butterfly can be realized as transitions in the hypercube made in parallel.
Also, it can be seen that a d-dimensional butterfly contains two subgraphs isomor-
phic to the (d − 1)-dimensional butterfly.
A wrapped butterfly is obtained by substituting [[0, n]] by Zn and letting addition
of indexes modulo n (thus the last level j = n in the butterfly is identified with the
initial level j = 0). Let WBd denote the d-dimensional wrapped butterfly network.
We have:
• The butterfly network Bd is a graph of order 4 (each inner node is the extreme of
4 edges, and the nodes at the extreme levels have 2 neighbors). The number of
nodes in Bd is (d + 1) 2d and the number of edges is d 2d+1 . The diameter of Bd
is 2d and its bisection width is Θ (2d ).
• The wrapped butterfly network WBd is a regular graph of order 4. The number of
nodes in WBd is d 2d and the number of edges is d 2d+1 . The diameter of WBd is
b 3d d
2 c and its bisection width is 2 .
4.1 Distributed systems 81
d=1 d=2
d=3 d=4
The communication protocols involve proof methods for safety and liveness prop-
erties, as well as event dependency, message transmission and network routing as
well as avoidance of store-and-forward packet deadlocks.
A transition system is a triplet T = (C, T,C0 ) where C is a non-empty set of
configurations, T ⊂ C ×C is a transition relation (usually, if (cb , cc ) ∈ T it is written
cb → cc ) and C0 ⊂ C is a subset of initial configurations. A partial execution is a
sequence [c0 , c1 , . . . , ck ] of configurations such that c0 ∈ C0 and ∀i > 0, ci → ci+1 . In
∗ ∗
this case, we write c0 → ck . An execution is a maximal partial execution. If c0 → ck
through an execution then ck is called an ending configuration. A configuration c ∈ C
∗
is reachable if ∃c0 ∈ C0 : c0 → c.
A property Φ on states is a safety requirement if it holds on any reachable state
at an execution and it is a liveness requirement if it holds on some reachable state at
an execution.
For two properties Φ,Ψ on states, we write {Φ} → {Ψ } if the following impli-
cation holds:
[(cb → cc ) & Φ(cb )] =⇒ Ψ (cc ).
82 4 Distributed Algorithms
→i,p ⊂ S p × S p
∀µ ∈ M : →s,µ,p ⊂ S p × S p
∀µ ∈ M : →r,µ,p ⊂ S p × S p
Let → p =→i,p ∪ →s,µ,p ∪ →r,µ,p , i. e.,
S
µ∈M
∀c, d ∈ S p : (c → d) ⇐⇒ (c →i,p d) or ∃µ ∈ M c →s,µ,p d or c →s,µ,p d .
where
(∀q ∈ P − {p} : dq = cq ) &
c p →i,p d p =⇒ (4.3)
∀q ∈ P : νq∗ = µq∗
(∀q ∈ P − {p} : dq = cq )&
c p →s,µ,p d p =⇒ ∀q ∈ P − {p} : νq∗ =µq∗ & (4.4)
ν p∗ = µ p∗ − {µ}
(∀q ∈ P − {p} : dq = cq )&
c p →r,µ,p d p =⇒ ∀q ∈ P − {p} : νq∗ =µq∗ & (4.5)
ν p∗ = µ p∗ ∪ {µ}
4.1 Distributed systems 83
It is said that the events at the left sides of (4.3-4.5) are applicable at the configura-
tion on the left side of (4.2), and each produces the configuration at the right side.
As described above, the distributed system is called asynchronous.
In event (4.7) the local events at the left side are called corresponding.
Let Γ = (γκ )kκ=0 be an execution in a synchronous distributed system. For each
κ > 0 let eκ be the event such that γκ = eκ (γκ−1 ). Let Γ = (eκ )kκ=1 be the corre-
sponding sequence of events.
Let Γ be the smallest ordering relation in the collection of local events satisfy-
ing the following conditions:
• If e0 and e00 are events in the same process and e0 is applied before than e00 in the
execution Γ , then e0 Γ e00 .
• If e0 is a send event and e00 is the corresponding receive event in the execution Γ ,
then e0 Γ e00 .
“≺Γ ” is called the causal order determined by Γ .
Two events e0 and e00 are concurrent, e0 ke00 , if neither e0 Γ e00 nor e00 Γ e0 .
Let π : [[1, k]] → [[1, k]] be a permutation consistent with the clausal order:
∀i, j ∈ [[1, k]] : eπ(i) Γ eπ(i) =⇒ i ≤ j .
k
Let ∆ = dκ = eπ(κ) κ=1
. Then ∆ determines an execution ∆ in the distribution
system.
Proposition 4.3. ∆ and Γ have the same length and the last configuration of ∆
coincides with the last configuration of Γ .
∆ and Γ are thus equivalent executions. This notion defines, indeed, an equiva-
lent relation on the whole collection of executions.
A logical clock is a map ω : {events} → N that is increasingly monotone with
respect to a clausal ordering and the usual ordering in N.
Let us see some examples of distributed algorithms.
The goal of the algorithm is that some processor eventually will claim ’I
am the leader’, and, if required, any other will claim ’I am not the
leader’. The setting is the following:
Messages. Processors UID’s (these are labels in N) and an empty message, to
represent that no message is sent.
States. {⊥, leader}.
Initial states. Each processor knows its own UID and is in state ⊥.
Each process acts as follows:
1. Let v := Receive ;
2. If v >UID Then Send(v)
Else
a. If v =UID Then leader
Else
i. Do Nothing
Clearly, the elected leader would be that with greatest UID and the elected proces-
sor will realize that within n rounds. This process involves O(n2 ) message transmis-
sions.
Example 4.2 (Bidirectional leader election). Also in this case, let us assume a ring
of n processors, p0 , . . . , pn−1 , and each, pi , is now able to send a message to both its
successor, pi+1 , and its predecessor, pi−1 (indexes are taken modulus n).
As before, the elected leader would be that with greatest UID. The messages
should be pairs
1. For each round k ≥ 1 Do
a. each processor sends its UID to both sides with the aim to reach processors at
distance 2k and return to the original processor,
i. If the traveling UID is less than the UID of a visited processor, the traveling
UID is lost,
ii. Once the traveling UID returns to its original processor, a new round be-
gins.
b. If a traveling UID arrives to its original processor in the “on-going” direction,
then that node claims itself as the leader.
Each message consists of the UID and two indexes: The first tracks the number of
visited processors in the “on-going” direction, while the second tracks the number
of visited processors in the “returning” direction.
We may see that the leader will be elected within 1 + dlog2 xe rounds and the
total number of sent messages is 8n(1 + dlog2 xe) = O(n log n). Indeed initially each
processor sends at most 4 messages, and at each new round k, the processors thats
end messages are those that have not been defeated, and at each group of 2k−1 + 1
only one goes to the next round, hence they will remain just b 2k−1n +1 c processors,
hence the number of messages in that round will be 4 · 2k · b 2k−1n +1 c ≤ 8n.
4.2 Concurrency 85
Example 4.3 (Breadth-first search). Let G = (V, E) be a directed graph and let s ∈ V
be a source vertex. A breadth-first traversal of G is a spanning tree rooted at s such
that any node at distance d from s is at height d in the tree.
Initially the source vertex is declared as the only marked node and it sends a
search message to its neighbors. Thereafter, when a non-marked node receives a
search message then it is declared as a marked node, it declares the transmitting
node as its own parent, and it sends a search message to its neighbors.
Clearly, the algorithm produces a tree which is indeed a breadth-first traversal
similar as the traversal produced by the procedure at figure 3.4. At each round,
any vertex with distance (i.e. the length of the shortest path connecting it with s) not
exceeding the round index has been marked and an assigned parental. The algorithm
has time complexity O(k) where k is the diameter of the graph and sends O(e)
messages, where e is the number or edges in the graph.
4.2 Concurrency
an unbounded shared memory. Thus, for instance k,`∈N CRCW-C (nk , [log(n)]` ) is
S
Problem ZeroCounting.
Instance: A word σ = s0 · · · sn−1 ∈ 0+ 1+ .
Solution: The position i such that si = 0 and si+1 = 1.
Problem Boolean-OR.
Instance: A word σ ∈ (0 + 1)∗ .
Solution: max1≤i≤ len (σ ) si .
Problem Parity.
Instance: hA word σ i∈ (0 + 1)∗ .
len (σ )
Solution: ∑i=1 si mod 2 .
EREWMaxArray
Input. A numeric array S
Output. The max-array [max j∈[[0,i]] S[[ j]]]i∈[[0, len (S)−1]]
1. n := len (S) ;
2. If n == 1 then output S
Else
a. For i = 0 To d n−12 e − 1 Do (in parallel)
{ T [[i]] := max{S[[2i]], S[[2i + 1]]} } ;
b. N := MaxArray(T ) ;
c. For i = 0 To n − 1 Do (in parallel)
i. Case odd i: M[[i]] := max{N[[(i − 1)/2]], S[[i]]} ;
ii. Case even i: M[[i]] := N[[i/2]] ;
3. Output M
CREWFirstMax
Input. A numeric array S
Output. The pairs such that (i, S[[i]]) such that S[[i]] = max j∈[[0, len (S)−1]] S[[ j]]
1. n := len (S) ;
2. If n == 1 Then Output (0, S[[0]])
Else
a. For i = 0 To n − 1 Do (in parallel) A[[i]] := 1 ;
b. For Each pair (i, j) with 0 ≤ i < j ≤ n − 1 Do (in parallel)
{ If S[[i]] < S[[ j]] Then GT[[i, j]] := 0 Else GT[[i, j]] := 1 } ;
c. For Each pair (i, j) with 0 ≤ i < j ≤ n − 1 Do (in parallel)
{ A[[i]] := min(A[[i]], GT[[i, j]]) } ;
d. For i = 0 To n − 1 Do (in parallel)
{ If A[[i]] == 1 Then Output (i, S[[i]])
CREWSecondMax
Input. A numeric array S
Output. The pairs such that (i, S[[i]]) such that S[[i]] = max j∈[[0, len (S)−1]] S[[ j]]
√
1. For i = 0 To n − 1 Do (in parallel)
√ √
a. Si := S[[ j| n i ≤ j < n (i + 1)]] ;
b. T [[i]] := CREWSecondMax(Si ) ;
2. mx := CREWFirstMax(T ) ;
3. Output mx
CREWThirdMax
Input. A numeric array S
Output. The pairs such that (i, S[[i]]) such that S[[i]] = max j∈[[0, len (S)−1]] S[[ j]]
n
1. For i = 0 To log log n − 1 Do (in parallel)
n
t3 (n) = t0 (log log n) + t2
log log n
= O(log log log n) + O(log log n)
= O(log log n).
The work is
n
w3 (n) = w0 (log log n) + w2
log log n
= O(log log log n) + O(n)
= O(n).
CREWRank
Input. An increasing numeric array X, a value y ∈ R and a fixed number of
processors p ∈ Z+ .
Output. R(y, X)
1. n p := n+1
p ;
2. ic := 0 ;
3. Repeat dlog p (n + 2)e times
a. For i = 1 To p Do (in parallel)
i. If X[[ic + (i − 1)n p ]] ≤ y ≤ X[[ic + in p − 1]] Then
n
{ ic := ic + (i − 1)n p ; n p := pp } ;
b. For i = 1 To p Do (in parallel)
i. If X[[ic + in p − 1]] < y < X[[ic + in p ]] Then
Output (ic + in p − 1)
This is a typical problem illustrating the appearances of deadlocks when some re-
sources are shared in a distributed environment.
Dining philosophers problem
At any moment, a dining philosopher is either thinking or eating. Since the menu consists
just of spaghetti, any philosopher should be provided with two forks in order to begin to eat.
Let us assume that p philosophers are sit around a circular table with the spaghetti bowl at
the center. In between two adjacent philosopher lies a fork. Thus in order to begin to eat,
each philosopher should use the two forks adjacent to him.
A deadlock situation appears when each philosopher is granted to use his left fork.
Each is waiting for his right fork to be free, and no philosopher is able to begin to
eat!
The deadlock may be broken by introducing a waiter. A waiter may schedule
an eating roll, thus he may assign fork pairs (and eventually to take care of forks
cleaning after any use!) to dining philosophers.
A very well known algorithm for deadlock breaking without the participation of
any external agents is the following:
4.3 Routing 91
4.3 Routing
In a battle field, a General gives an order to either attack or retreat. The order is
transmitted by the subordinates and all participants should agree on a value of the
order: Either to attack or to retreat. The General may be a participant and all subor-
dinates are participants as well. Among participants there are traitors that may alter,
when transmitting it, the sense of the order. Even the General may be a traitor. The
goal of the problem is thus to make agree all the non-traitor subordinates on the
General’s order.
In the language of distributed systems the problem is posed as follows: A source
processor transmits a bit. Among the processors there are correct and faulty proces-
sors. The faulty processors may change the value of the message bit. The goal of the
correct processors is to convene in the value of the original message bit emitted by
the source processor.
Let S denote the source processor. For any processors X,Y let
In the above situation, for just three participants X,Y, S, it is not possible for X to
decide which of the other two participants is faulty.
Let p denote the number of processors and let q be the number of faulty proces-
sors. If 3q < p then an agreement protocol does exist.
Let us consider the following subprocedures:
OM(0)
Input. S source processor and a bit bS .
Output. bS transmitted to neighbors of S
1. For each neighbor Y of S Do bs is sent form S to Y ;
2. Y assumes bS
OM(m)
Input. S source processor and a bit bS .
Output. An agreed value of bS transmitted from S
1. S sends bS to all processors ;
2. For each processor X Do (in parallel)
a. bX = ΞS (X) ;
b. OM(m − 1) (X, bX ) (X acts as source and resends its bit value
to all processors different than S and X itself)
3. For each processor X Do (in parallel)
X assumes the most frequent value among (ΦY (X)| Y 6= X, S).
The Routing problem consists in select the “best” pat connecting two nodes in
a network. Any solving procedure should be correct (any path selected among two
nodes, should indeed connect them), efficient (the selected paths are optimal among
the paths connecting the nodes) and robust (the paths should be selected without
prior knowledge of the, possible varying, networks topology).
Any network may be realized as a graph G = (V, E) (either undirected or di-
rected). A cycle is a path whose extreme points coincide. A simple path is a path
without internal cycles.
In static networks a general strategy may be the computation of spanning trees.
For any node v ∈ V , let Tv be a spanning tree of the network rooted at v. Then for
each node u ∈ V in the connected component of v, let the branch connecting v with
u be the selected route.
4.3 Routing 93
DistributedFloydWarshall
Input. A weighted graph G = (V, E) with non negative weights modeling a net-
work.
Output. The arrays Dv and Iv , v ∈ V .
1. For each v ∈ V Do (in parallel)
a. Rv := {v} ;
b. Dv [[v]] := 0 ; Iv [[v]] :=⊥ ;
c. For each u ∈ V − {v} Do (in parallel)
i. If u ∈ Nv Then { Iv [[u]] := u ; Dv [[u]] := wvu }
Else { Iv [[u]] :=⊥ ; Dv [[u]] := +∞ } ;
2. For each v ∈ V Do (in parallel)
a. While ¬(Rv == V ) do
i. Broadcast (Iv , Dv ) ;
ii. For each w ∈ V − Rv Do (in parallel)
A. Broadcast (Iw , Dw ) ;
B. For each u ∈ V − {v, w} Do (in parallel)
{ pnw := Dv [[w]] + Dw [[u]] ;
If pnw < Dv [[u]] Then
{ Iv [[u]] := Iv [[w]] ; Dv [[u]] := pnw }
};
iii. Rv := Rv ∪ {w} ;
3. Output {(Iv , Dv )| v ∈ V }.
ChandyMisra
Input. A weighted graph G = (V, E) with non negative weights modeling a net-
work.
Output. The arrays Dv and Iv , v ∈ V .
1. For each v ∈ V Do (in parallel)
a. Dv [[v]] := 0 ;
b. For each u ∈ V − {v} Do (in parallel)
i. If u ∈ Nv Then { Iv [[u]] := u ; Dv [[u]] := wvu }
Else { Iv [[u]] :=⊥ ; Dv [[u]] := +∞ } ;
2. For each v ∈ V Do (in parallel) For each u ∈ V − {v} Do (in parallel)
a. For each w ∈ V − {v, u} Do (in parallel)
{ pnw := Dv [[w]] + Dw [[u]] ;
If pnw < Dv [[u]] Then
{ Iv [[u]] := Iv [[w]] ; Dv [[u]] := pnw }
};
3. Output {(Iv , Dv )| v ∈ V }.
References
[Aho et al(1974)Aho, Hopcroft, and Ullman] Aho AV, Hopcroft JE, Ullman J (1974) The De-
sign and Analysis of Computer Algorithms. Addison-Wesley Longman Publishing Co., Inc.,
Boston, MA, USA, URL http://portal.acm.org/citation.cfm?id=578775
[Brassard and Bratley(1988)] Brassard G, Bratley P (1988) Algorithmics: theory & practice.
Prentice-Hall, Inc., Upper Saddle River, NJ, USA
[Brassard and Bratley(1990)] Brassard G, Bratley P (1990) Algor´ı́tmica: Concepción y Análisis.
Editorial Masson
[Cattaneo and Italiano(1999)] Cattaneo G, Italiano G (1999) Algorithm engineering. ACM Com-
put Surv p 3, DOI http://doi.acm.org/10.1145/333580.333582
[Cormen et al(2003)Cormen, Leiserson, Rivest, and Stein] Cormen TH, Leiserson CE, Rivest
RL, Stein C (2003) Introduction to Algorithms, 2nd edn. McGraw-Hill Science /
Engineering / Math, URL http://www.amazon.com/exec/obidos/redirect?tag=citeulike07-
20&path=ASIN/0072970545
[Fernandez et al(2003)Fernandez, Garcia, and Garzon] Fernandez JJ, Garcia I, Garzon E (2003)
Educational issues on number representation and arithmetic in computers: an undergraduate
laboratory. IEEE Transactions on Education 46(4):477–485, DOI 10.1109/TE.2003.815237
[Garey and Johnson(1979)] Garey MR, Johnson DS (1979) Computers and Intractability : A
Guide to the Theory of NP-Completeness. Series of Books in the Mathematical Sciences, W.H.
Freeman & Company, URL http://www.amazon.com/exec/obidos/redirect?tag=citeulike07-
20&path=ASIN/0716710455
[Gonnet and Baeza-Yates(1991)] Gonnet GH, Baeza-Yates R (1991) Handbook of algorithms and
data structures: in Pascal and C (2nd ed.). Addison-Wesley Longman Publishing Co., Inc.,
Boston, MA, USA
[Graham et al(1994)Graham, Knuth, and Patashnik] Graham RL, Knuth DE, Patashnik O (1994)
Concrete Mathematics: A Foundation for Computer Science (2nd Edition), 2nd edn. Addison-
Wesley Professional, URL http://www.amazon.com/exec/obidos/redirect?tag=citeulike07-
20&path=ASIN/0201558025
[Hopcroft et al(2001)Hopcroft, Motwani, and Ullman] Hopcroft JE, Motwani R, Ullman JD
(2001) Introduction to automata theory, languages, and computation, 2nd edition. SIGACT
News 32(1):60–65, DOI http://doi.acm.org/10.1145/568438.568455
[Kfoury et al(1991)Kfoury, Arbib, and Moll] Kfoury AJ, Arbib MA, Moll RN (1991) Program-
ming Approach to Computability. Springer-Verlag New York, Inc., Secaucus, NJ, USA
[Knuth(1999)] Knuth DE (1999) Mathematics for the Analysis of Algorithms. Birkhauser Boston
[Levitin(2007)] Levitin AV (2007) Introduction to the Design and Analysis of Algorithms, 2-nd
Edition. Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA
[Manber(1989)] Manber U (1989) Introduction to Algorithms: A Creative Approach. Addison-
Wesley Longman Publishing Co., Inc. Boston, MA, USA
[Michalewicz and Fogel(2004)] Michalewicz Z, Fogel DB (2004) How to Solve It: Mod-
ern Heuristics. Springer, URL http://www.amazon.com/exec/obidos/redirect?tag=citeulike07-
20&path=ASIN/3540224947
[Papadimitriou and Steiglitz(1998)] Papadimitriou CH, Steiglitz K (1998) Combi-
natorial Optimization : Algorithms and Complexity. Dover Publications, URL
http://www.amazon.com/exec/obidos/redirect?tag=citeulike07-20&path=ASIN/0486402584
[Schnitger(2007)] Schnitger G (2007) Parallel and Distributed Algorithms. Institut f
ür Informatik, Johann Wolfgang Goethe-Universität, Frankfurt am Main, URL
http://www.thi.informatik.uni-frankfurt.de/Parallele/index.html
[Sedgewick and Flajolet(1996)] Sedgewick R, Flajolet P (1996) An introduction to the analysis
of algorithms. Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA
[Stoer and Bulirsch(1980)] Stoer J, Bulirsch R (1980) Introduction to Numerical Analysis.
Springer-Verlag, New York and Berlin
[Ukkonen(1995)] Ukkonen E (1995) On-line construction of suffix trees. Algorithmica
14(3):249–260
96 4 Distributed Algorithms
97
98 Index