Académique Documents
Professionnel Documents
Culture Documents
Ilija Lalovic
0.1 Asimptotske oznake
O - notacija je korisna za analizu programa, posto obuhvata asimptotski rast funkcija i ignorise konstantne mnozitelje.
Konstantni mnozitelji su ionako van nase kontrole kada prevedemo algoritme u programe. Mi koristimo sledece
denicije, mada postoje i alternativne:
Neka f,g: N N :
g(n) = O(f(n)) akko (K R), tako da za dovoljno veliko n
0
za svako n n
0
imamo g(n) K f(n)
Primer 0.1. 1. (1000n
2
+ 100n + 1000) = O(n
3
)
2. n
2
= O(n
3
100n
2
2n)
3. n
i
= O(poly(n)), gde je deg(p) i , a vodeci koecijent p(n) je pozitivan.
f(n) = (g(n)) akko g(n) = O(f(n))
g(n) = (f(n)) akko (g(n)=O(f(n)) i f(n)=O(g(n))
Primer 0.2. Razmotriti sledece funkcije:
n, n, 2n, nlogn, n n
3
+ 7n
5
, n
2
+logn, n
2
, n
3
, logn, n
1/3
+logn, (logn)
2
, n!, lnn,
n
logn
, loglogn, (1/3)
n
, (3/2)
n
, 6.
Grupisati ove funckije tako da su f(n) i g(n) u istoj grupi akko g(n) =O(f(n)) i ispitati grupe u rastucem poretku.
0.2 Primer programa koji ispisuje sopstveni kod
U inzinjerstvu samorepliciranje bi moglo omoguciti snizenje cena proizvodnje. Sledeci C++ program replicira samog
sebe:
# i nc l ude <i os t r eam . h>
main ( )
char s=%c%s%c ;
count . form( s , 10 , 34 , s , 3 4 , 1 0 ) ;
%c ;
count . form( s , 10 , 34 , s , 3 4 , 1 0 ) ;
Autor je lapinski@utexas.edu.
Sledeci C program velicine 800bitova, objavljen u casopisu Byte, Avgust 1980.g. 74.strana, takodje replicira samog
sebe.
main ( )
n
i=1
p
i
T(i), gde je p
i
verovatnoca slozenosti T(i).
Insert sort
Primer 0.3. 1. Worst case slozenost T(n)=O(n
2
)=0+1+. . . +(n-1).
2. Best case slozenost. Ako u svakom koraku element koji umecemo dolazi na prvo mesto imamo T(n)=0+1+. . . +1
=
n1
i=0
i=n-1=O(n).
3. Awerage case slozenost.
Lema 0.1. . Srednji broj inverzija u jednom nizu od n elemenata je
n(n1)
4
.
Dokaz 0.1. Posmatrajmo listu L i njen reverz Lr. Npr. L=(8,34,64,51,32,21), Lr=(21,32,51,64,34,8). (x,y) prave
inverziju ako je y > x. Tacno u jednoj L ili Lr je (x,y) inverzija I=
n(n1)
4
.
Teorema 0.1.. Awerage case slozenost za insert sort je T(n)=O(n
2
).
Dokaz 0.2. Svaki korak u sortiranju eliminise samo jednu inverziju.
0.7 Racionalizacija mnozenja velikog broja kompleksnih brojeva
Mnozenje kompleksnih brojeva (a u odnosu na polje realnih brojeva) moze se posmatrati kao izracunavanje izraza ac-
bd i ad+bc tako da je (a,b)(c,d)=(ac-bd, ad+bc). U ovom slucaju imamo cetiri mnozenja i dva sabiranja/oduzimanja
(+/-). Slozenost algoritama je T(n)=O(n
2
). Do brzeg resenja dolazimo ako za kompleksne brojeve (a,b) i (c,d)
izracunamo:
1. (a+b)(c+d)=ac+ad+bc+bd;
2. ac;
3. bd.
Proizvod dobijamo do shemi (2-3,1-2-3). Ukupno imamo tri mnozenja i pet sabiranja/oduzimanja. Moze se pokazati
da je dobijeni algoritam brzi. Takodje se moze dokazati da su tri mnozenja neophodna i dovoljna.
0.8 Hornerova shema. Kompleksnost izracunavanja vrednosri polinoma.
Posmatramo izracunavanje vrednosti polinoma u tacki X. p(x) = a
n
x
n
+a
n1
x
n1
+. . . +a
1
x +a
0
Ulaz: a
0
, a
1
, a
2
, . . . , a
n1
, a
n
, x
Izlaz: p(x)
Pravilo Hornera:
1. a
1
x +a
0
, za n=1
2. (a
2
x +a
1
)x +a
0
, za n=2
3. ((a
3
x +a
2
)x +a
1
)x +a
0
, za n=3,itd.
Uopste a
0
+ x[a
1
+ x[a
2
+ . . . + a
n
x]. . . ] Za izracunavanje p(x) po Hornerovoj shemi, trebamo n operacija mnozenja
i ne operacija sabiranja. Moze se pokazati da Hornerova shema daje optimalan algoritam za izracunavanje vrednosti
polinoma u datoj tacki x (u odnosu na broj operacija sabiranja i mnozenja).
0.9 Elementarne metode sortiranja: bubble sort, sort izborom i sort
umetanjem. Dizajn i analiza slozenosti.
Neka je niz koji treba sortirati sastavljen od a[i] S, i=1,2,. . . ,n, pri cemu je S linearno uredjen skup. Sortiramo u
rastucem poretku.
Bubble sort(sort mehuricima)
Poredimo a[j] sa a[j+1], j=1,2,...,n-1, i=1,2,...,n-1. Ukoliko je a[j]a[j+1] tada elementima razmenjujemo mesta. Na
taj nacin ce u prvom prolazu najveci element doci na zadnje mesto, u drugom prolazu ce drugi po velicini element
doci na pretposlednje mesto itd. U i-tom prolazu dovodimo i-ti element na odgovarajuce mesto. Nakon nekog broja
prolaza, najvise n-1, svi ce elementi biti sortirani. Napominjemo da uvodjenjem indikatora(zastavice) mozemo uciniti
da algoritam prekine rad cim su brojevi sortirani. Naime, cim u nekom prolazu nema izmena postavljamo indikatori
na 1, a onda izlazimo iz petlje, jer je provera indikatora postavljena u uslovu petlje.
Bubble sort
templ ate <cl assT>1
voi d s or t (Ta , i nt n)
T temp=a [ i ] ;
f o r ( i nt j=I ; j >0 && a [ j i ]>temp ; j )
a [ j ]=a [ j 1] ;
a [ j ]=temp ;
// I nvar i j ant a : a[0] <=a [ 1 ] <=...<=a [ i ]
i nt min=I ;
f o r ( i nt j=i +1; j <n ; j ++)
i f ( a [ j ]<a [ min ] )
min =j ;
// I nvar i j ant a : a [ min]<=a [ j ] za i <=j <n
swap( a [ min ] , a [ i ] ) ;
i f ( s t ar t >stop ) r et ur n 1l
i nt mid=( s t a r t+stop ) /2;
i f ( x==a [ mid ] r et ur n mid ) ;
i f ( x<a [ mid ] r et ur n f i nd ( a , s t ar t , mid1, x ) ;
i f ( x>a [ mid ] r et ur n f i nd ( a , mid+1, stop , x ) ;
r et ur n end ;
u<(a+b) ( c+d ) ;
v<ac ;
w<bd ;
z<v2n + ( uvw)2m/2 + w;
n
i=1
1
n
(T(i 1) +T(n i)) = c n +
2
n
n1
i=0
T(i), c n je vreme podele za n elemenata.
Mi zelimo dokazati ogranicenje T(n) knlogn. T(n) cn+
2
n
n1
i=0
ilogi cn+
2k
n
,
n
2
logn
2
n
2
4
| knlogn+cn
k
2
n Za
k=2c imamo T(n) knlogn. Ocena je postignuta koristeci induktivnu hipotezu T(i) ilogi za i<n, te sledeci kvaziar-
gument
n1
i=0
ilogi =
_
n1
0+
xlogxdx =
x
2
2
logx [
n1
0
_
n1
0+
x
2
2
1
x
dx =
(n 1)
2
2
log(n 1)
x
2
4
[
n1
0
=
(n 1)
2
2
log(n
1)
(n 1)
2
4
//Quick s or t
templ ate <c l a s s T>
voi d qui c ks or t (Ta , i nt Lo , i nt hi )
i f ( Lo>=hi ) r et ur n ;
T pi vot = a [ hi ] ;
i nt i= Lo1l
i nt j=hi ;
whi l e ( i <j )
whi l e ( a[++i ]<pi vot )
whi l e ( j >=0 && a[j ]<pi vot ) ;
i f ( i <j ) swap ( a [ i ] , a [ j ] ) ;
swap( a [ i ] , a [ hi ] ) ;
// I nvar i j ant a : a [ j ]<=a [ i ]<=a [ k ] za Lo<=j <i <k<=hi //
qui c ks or t ( a , Lo , i 1);
qui c ks or t ( a , i +1, hi ) ;
|x|=n
(x)T(x). U opstem slucaju je
1
n!
|x|=n
T(x) i D(m)=minD(T) za sumu dubina listova bilo kojeg
drveta poredjenja sa m listova. Treba dokazati D(m)=nlogn.
Dokaz izvvodimo indukcijom. Za m=1 je trivijalno 0.
Za m>1:
Pretpostavimo da TR ima k listova, tako da je i listova u levom poddrvetu TR
i
i k-i listova u desnom poddrvetu
TR
ki
.
0.19 Dinamicko programiranje. Poredak mnozenja matrica.
Dynamic Programming
Dynamic programming, like the divide-and-conquer method, solves problems by combining the solutions to subprob-
lems. (Programming in this context refers to a tabular method, not to writing computer code.) As we saw in
Chapter 2, divide-and-conquer algorithms partition the problem into independent subproblems, solve the subproblems
recursively, and then combine their solutions to solve the original problem. In contrast, dynamic programming is ap-
plicable when the subproblems are not independent, that is, when subproblems share subsubproblems. In this context,
a divide-and-conquer algorithm does more work than necessary, repeatedly solving the common subsubproblems. A
dynamic-programming algorithm solves every subsubproblem just once and then saves its answer in a table, thereby
avoiding the work of recomputing the answer every time the subsubproblem is encountered.
Dynamic programming is typically applied to optimization problems. In such problems there can be many possible
solutions. Each solution has a value, and we wish to nd a solution with the optimal (minimum or maximum) value.
We call such a solution an optimal solution to the problem, as opposed to the optimal solution, since there may be
several solutions that achieve the optimal value.
The development of a dynamic-programming algorithm can be broken into a sequence of four steps.
Characterize the structure of an optimal solution.
Recursively dene the value of an optimal solution.
Compute the value of an optimal solution in a bottom-up fashion.
Construct an optimal solution from computed information.
Steps 1-3 form the basis of a dynamic-programming solution to a problem. Step 4 can be omitted if only the value of
an optimal solution is required. When we do perform step 4, we sometimes maintain additional information during
the computation in step 3 to ease the construction of an optimal solution.
The sections that follow use the dynamic-programming method to solve some optimization problems. Section 15.1
examines a problem in scheduling two automobile assembly lines, where after each station, the auto under construction
can stay on the same line or move to the other. Section 15.2 asks how we can multiply a chain of matrices so that
the fewest total scalar multiplications are performed. Given these examples of dynamic programming, Section 15.3
discusses two key characteristics that a problem must have for dynamic programming to be a viable solution technique.
Section 15.4 then shows how to nd the longest common subsequence of two sequences. Finally, Section 15.5 uses
dynamic programming to construct binary search trees that are optimal, given a known distribution of keys to be
looked up.
0.19.1 Matrix-chain multiplication
Our next example of dynamic programming is an algorithm that solves the problem of matrix-chain multiplication.
We are given a sequence (chain) A
1
, A
2
, ...,A
n
of n matrices to be multiplied, and we wish to compute the product
(15.10) We can evaluate the expression (15.10) using the standard algorithm for multiplying pairs of matrices as a
subroutine once we have parenthesized it to resolve all ambiguities in how the matrices are multiplied together. A
product of matrices is fully parenthesized if it is either a single matrix or the product of two fully parenthesized
matrix products, surrounded by parentheses. Matrix multiplication is associative, and so all parenthesizations yield
the same product. For example, if the chain of matrices is A
1
, A
2
, A
3
, A
4
, the product A
1
A
2
A
3
A
4
can be fully
parenthesized in ve distinct ways: (A
1
(A
2
(A
3
A
4
)))
(A
1
((A
2
A
3
)A
4
))
((A
1
A
2
)(A
3
A
4
))
((A
1
(A
2
A
3
))A
4
)
(((A
1
A
2
)A
3
)A
4
). The way we parenthesize a chain of matrices can have a dramatic impact on the cost of evaluating the
product. Consider rst the cost of multiplying two matrices. The standard algorithm is given by the following pseu-
docode. The attributes rows and columns are the numbers of rows and columns in a matrix. MATRIX-MULTIPLY(A,
B)
1 i f columns [ A] neq rows [ B]
2 then e r r or i ncompat i bl e di mensi ons
3 e l s e f o r i < 1 to rows [ A]
4 do f or j < 1 to columns [ B]
5 do C[ i , j ] < 0
6 f o r k < 1 to columns [ A]
7 do C[ i , j ] < C[ i , j ] + A[ i , k ] B[ k , j ]
8 r et ur n C
We can multiply two matrices A and B only if they are compatible: the number of columns of A must equal the
number of rows of B. If A is a p x q matrix and B is a q x r matrix, the resulting matrix C is a p x r matrix. The time
to compute C is dominated by the number of scalar multiplications in line 7, which is pqr. In what follows, we shall
express costs in terms of the number of scalar multiplications. To illustrate the dierent costs incurred by dierent
parenthesizations of a matrix product, consider the problem of a chain A
1
, A
2
, A
3
of three matrices. Suppose
that the dimensions of the matrices are 10 x 100, 100 x 5, and 5 x 50, respectively. If we multiply according to the
parenthesization ((A
1
A
2
)A
3
), we perform 10100 5 = 5000 scalar multiplications to compute the 10 x 5 matrix product
A
1
A
2
, plus another 10 5 50 = 2500 scalar multiplications to multiply this matrix by A
3
, for a total of 7500 scalar
multiplications. If instead we multiply according to the parenthesization (A
1
(A
2
A
3
)), we perform 100 5 50 = 25, 000
scalar multiplications to compute the 100 x 50 matrix product A
2
A
3
, plus another 10 100 50 = 50, 000 scalar
multiplications to multiply A
1
by this matrix, for a total of 75,000 scalar multiplications. Thus, computing the
product according to the rst parenthesization is 10 times faster. The matrix-chain multiplication problem can be
stated as follows: given a chain A
1
, A
2
, ..., A
n
of n matrices, where for i = 1, 2, ..., n, matrix A
i
has dimension p
i1
xp
i
, fully parenthesize the product A
1
A
2
A
n
in a way that minimizes the number of scalar multiplications.
0.19.2 Counting the number of parenthesizations
Before solving the matrix-chain multiplication problem by dynamic programming, let us convince ourselves that
exhaustively checking all possible parenthesizations does not yield an ecient algorithm. Denote the number of
alternative parenthesizations of a sequence of n matrices by P(n). When n = 1, there is just one matrix and therefore
only one way to fully parenthesize the matrix product. When n 2, a fully parenthesized matrix product is the
product of two fully parenthesized matrix subproducts, and the split between the two subproducts may occur between
the kth and (k + 1)st matrices for any k = 1, 2, ..., n - 1. Thus, we obtain the recurrence Problem 12-4 asked you
to show that the solution to a similar recurrence is the sequence of Catalan numbers The number of solutions is thus
exponential in n, and the brute-force method of exhaustive search is therefore a poor strategy for determining the
optimal parenthesization of a matrix chain.
0.19.3 The structure of an optimal parenthesization
Our rst step in the dynamic-programming paradigm is to nd the optimal substructure and then use it to construct an
optimal solution to the problem from optimal solutions to subproblems. For the matrix-chain multiplication problem,
we can perform this step as follows. For convenience, let us adopt the notation A
i..j
, where i j, for the matrix
that results from evaluating the product A
i
A
i+1
A
j
. Observe that if the problem is nontrivial, i.e., i j, then any
parenthesization of the product A
i
A
i+1
A
j
must split the product between A
k
and A
k+1
for some integer k in the
range i k j. That is, for some value of k, we rst compute the matrices A
i...k
and A
k+1...n
and then multiply them
together to produce the nal product A
i..j
. The cost of this parenthesization is thus the cost of computing the matrix
A
i..k
, plus the cost of computing A
k+1..n
, plus the cost of multiplying them together. The optimal substructure of
this problem is as follows. Suppose that an optimal parenthesization of A
i
A
i+1
A
j
splits the product between A
k
and A
k+1
. Then the parenthesization of the prex subchain A
i
A
i+1
A
k
within this optimal parenthesization of
A
i
A
i+1
A
j
must be an optimal parenthesization of A
i
A
i+1
A
k
. Why? If there were a less costly way to parenthesize
A
i
A
i+1
A
k
, substituting that parenthesization in the optimal parenthesization of A
i
A
i+1
A
j
would produce another
parenthesization of A
i
A
i+1
A
j
whose cost was lower than the optimum: a contradiction. A similar observation holds
for the parenthesization of the subchain A
k+1
A
k+2
A
j
in the optimal parenthesization of A
i
A
i+1
A
j
: it must be an
optimal parenthesization of A
k+1
A
k+2
A
j
. Now we use our optimal substructure to show that we can construct an
optimal solution to the problem from optimal solutions to subproblems. We have seen that any solution to a nontrivial
instance of the matrix-chain multiplication problem requires us to split the product, and that any optimal solution
contains within it optimal solutions to subproblem instances. Thus, we can build an optimal solution to an instance
of the matrix-chain multiplication problem by splitting the problem into two subproblems (optimally parenthesizing
A
i
A
i+1
A
k
andA
k+1
A
k+2
A
j
), nding optimal solutions to subproblem instances, and then combining these optimal
subproblem solutions. We must ensure that when we search for the correct place to split the product, we have
considered all possible places so that we are sure of having examined the optimal one.
0.19.4 A recursive solution
Next, we dene the cost of an optimal solution recursively in terms of the optimal solutions to subproblems. For the
matrix-chain multiplication problem, we pick as our subproblems the problems of determining the minimum cost of a
parenthesization of A
i
A
i+1
A
j
for 1 i j n. Let m,i, j| be the minimum number of scalar multiplications needed
to compute the matrix A
i...j
; for the full problem, the cost of a cheapest way to compute A
1..n
would thus be m,1, n|.
We can dene m ,i, j| recursively as follows. If i = j, the problem is trivial; the chain consists of just one matrix A
i..i
= A
i
, so that no scalar multiplications are necessary to compute the product. Thus, m[i, i] = 0 for i = 1, 2, ..., n.
To compute m,i, j| when i j, we take advantage of the structure of an optimal solution from step 1. Let us assume
that the optimal parenthesization splits the product A
i
A
i+1
A
j
between A
k
and A
k+1
, where i k j. Then, m,i, j|
is equal to the minimum cost for computing the subproducts A
i...k
and A
k+1...j
, plus the cost of multiplying these two
matrices together. Recalling that each matrix A
i
is p
i1
xp
i
, we see that computing the matrix product A
i..k
A
k+1..j
takes p
i1
p
k
p
j
scalar multiplications. Thus, we obtain m,i, j| = m,i, k| + m,k + 1, j| + p
i1
p
k
p
j
. This recursive
equation assumes that we know the value of k, which we do not. There are only j - i possible values for k, however,
namely k = i, i + 1, ..., j - 1. Since the optimal parenthesization must use one of these values for k, we need only
check them all to nd the best. Thus, our recursive denition for the minimum cost of parenthesizing the product
A
i
A
i+1
A
j
becomes (15.12)
m,i, j| =
_
0, if i = j
min
ik<j
m,i, k| +m,k + 1, j| +p
i1
p
j
p
k
, if i < j
The m,i, j| values give the costs of optimal solutions to subproblems. To help us keep track of how to construct
an optimal solution, let us dene s,i, j| to be a value of k at which we can split the product A
i
A
i+1
A
j
to obtain an
optimal parenthesization. That is, s,i, j| equals a value k such that m,i, j| = m,i, k| + m,k + 1, j| + p
i1
p
k
p
j
.
0.19.5 Computing the optimal costs
At this point, it is a simple matter to write a recursive algorithm based on recurrence (15.12) to compute the minimum
cost m[1, n] for multiplying A
1
A
2
A
n
. As we shall see in Section 15.3, however, this algorithm takes exponential time,
which is no better than the brute-force method of checking each way of parenthesizing the product. The important
observation that we can make at this point is that we have relatively few subproblems: one problem for each choice of i
and j satisfying 1 i j n, or in all. A recursive algorithm may encounter each subproblem many times in dierent
branches of its recursion tree. This property of overlapping subproblems is the second hallmark of the applicability of
dynamic programming (the rst hallmark being optimal substructure). Instead of computing the solution to recurrence
(15.12) recursively, we perform the third step of the dynamic-programming paradigm and compute the optimal cost
by using a tabular, bottom-up approach. The following pseudocode assumes that matrix Ai has dimensions p
i1
xp
i
for i = 1, 2, ..., n. The input is a sequence p = p
0
, p
1
, ..., p
n
, where length,p| = n + 1. The procedure uses an
auxiliary table m,1...n, 1...n| for storing the m,i, j| costs and an auxiliary table s,1...n, 1...n| that records which
index of k achieved the optimal cost in computing m,i, j|. We will use the table s to construct an optimal solution.
MATRIX-CHAIN-ORDER(p)
1 n < l engt h [ p ] 1
2 f o r i < 1 to n
3 do m[ i , i ] < 0
4 f o r l < 2 to n
5 do f or i < 1 to n l + 1
6 do j < i + l 1
7 m[ i , j ] < i nf t y
8 f o r k < i to j 1
9 do q < m[ i , k ] + m[ k + 1 , j ] + p i 1 p kp j
10 i f q < m[ i , j ]
11 then m[ i , j ] < q
12 s [ i , j ] < k
13 r et ur n m and s
The algorithm rst computes m,i, i| 0 for i = 1, 2, ..., n (the minimum costs for chains of length 1) in lines 2-3.
It then uses recurrence (15.12) to compute m[i, i + 1] for i = 1, 2, ..., n - 1 (the minimum costs for chains of length
l = 2) during the rst execution of the loop in lines 4-12. The second time through the loop, it computes m[i, i +
2] for i = 1, 2, ..., n - 2 (the minimum costs for chains of length l = 3), and so forth. At each step, the m[i, j] cost
computed in lines 9-12 depends only on table entries m[i, k] and m[k + 1, j] already computed. Figure 15.3 illustrates
this procedure on a chain of n = 6 matrices. Since we have dened m,i, j| only for i j, only the portion of the
table m strictly above the main diagonal is used. The gure shows the table rotated to make the main diagonal run
horizontally. The matrix chain is listed along the bottom. Using this layout, the minimum cost m[i, j] for multiplying
a subchain A
i
A
i+1
A
j
of matrices can be found at the intersection of lines running northeast from A
i
and northwest
from A
j
. Each horizontal row in the table contains the entries for matrix chains of the same length.
MATRIX-CHAIN-ORDER computes the rows from bottom to top and from left to right within each row. An
entry m,i, j| is computed using the products p
i1
p
k
p
j
for k = i, i + 1, ..., j - 1 and all entries southwest and southeast
from m[i, j].
Figure 15.3: The m and s tables computed by MATRIX-CHAIN-ORDER for n = 6 and the
following matrix dimensions:
matrix dimension
A1 30 35
A2 35 15
A3 15 5
A4 5 10
A5 10 20
A6 20 25
The tables are rotated so that the main diagonal runs horizontally. Only the main diagonal and upper triangle are
used in the m table, and only the upper triangle is used in the s table. The minimum number of scalar multiplications
to multiply the 6 matrices is m,1, 6| = 15,125. Of the darker entries, the pairs that have the same shading are taken
together in line 9 when computing
A simple inspection of the nested loop structure of MATRIX-CHAIN-ORDER yields a running time of O(n
3
) for
the algorithm. The loops are nested three deep, and each loop index (l, i, and k) takes on at most n -1 values. Exercise
15.2-4 asks you to show that the running time of this algorithm is in fact also (n
3
). The algorithm requires (n
2
)
space to store the m and s tables. Thus, MATRIX-CHAIN-ORDER is much more ecient than the exponential-time
method of enumerating all possible parenthesizations and checking each one.
0.19.6 Constructing an optimal solution
Although MATRIX-CHAIN-ORDER determines the optimal number of scalar multiplications needed to compute a
matrix-chain product, it does not directly show how to multiply the matrices. It is not dicult to construct an optimal
solution from the computed information stored in the table s ,1...n, 1...n|. Each entry s ,i, j| records the value of k
such that the optimal parenthesization of A
i
A
i+1
...A
j
splits the product between A
k
and A
k+1
. Thus, we know that
the nal matrix multiplication in computing A
1..n
optimally is A
1..s[1,n]
A
s[1,n]+1..n
. The earlier matrix multiplications
can be computed recursively, since s,1, s,1, n|| determines the last matrix multiplication in computing A
1..s[1,n]
, and
s ,s,1, n| + 1, n| determines the last matrix multiplication in computing A
s[1,n]+1..n
.
The following recursive procedure prints an optimal parenthesization of A
i
, A
i+1
, ..., A
j
, given the s table computed
by MATRIX-CHAIN-ORDER and the indices i and j. The initial call is MATRIX-CHAIN-ORDER (A, s, 1, n).
MATRIXCHAINORDER (A, s , 1 , n)
1 i f i < j
2 then X < MATRIXCHAINORDER (A, s , i , s [ i , j ] )
3 then Y < MATRIXCHAINORDER (A, s , s [ i , j ] + 1 , j )
4 r et ur n MATRIX MULTIPLY (X, Y)
5 e l s e r et ur n Ai
In the example of Figure 15.3, the call MATRIX-CHAIN-MULTIPLY (A, s, 1, 6) computes the matrix-chain product
according to the parenthesization ((A
1
(A
2
A
3
))((A
4
A
5
)A
6
)).
0.19.7 Exercises
Exercises 15.2-1
Find an optimal parenthesization of a matrix-chain product whose sequence of dimensions is 5, 10, 3, 12, 5, 50, 6.
Exercises 15.2-2
Give a recursive algorithm MATRIX-CHAIN-MULTIPLY(A, s, i, j) that actually performs the optimal matrix-chain
multiplication, given the sequence of matrices A
1
, A
2
, ..., A
n
, the s table computed by MATRIX-CHAIN-ORDER,
and the indices i and j. (The initial call would be MATRIX-CHAIN-MULTIPLY(A, s, 1, n))
Exercises 15.2-3
Show that a full parenthesization of an n-element expression has exactly n - 1 pairs of parentheses.
subsectionOsobine najduzeg zajednickog podniza Algoritam grube sile. Numerisati sve odnizove niza X i probati
koji je od njih najduzi i zajednici sa Y podnizom. Postoji 2
m
podnizova od X, pa algoritam zahteva eksponencijalno
vreme sto ga cini nepakticnim. Denisemo i-ti preks od X, i=0,1,...,m kao X
i
= x
1
, x
2
, ..., x
i
. Na primer: X =
A, B, C, B, D, A, B je X
4
= A, B, C, D.
Teorema 0.3.. Neka je X
i
= x
1
, x
2
, ..., x
m
i Y
i
= y
1
, y
2
, ..., y
n
i neka je Z
i
= z
1
, z
2
, ..., z
k
LCS za X i Y.
1. Ako je x
m
= y
n
tada je z
k
= x
m
= y
n
i z
k1
= LCS(x
m1
, y
n1
)
2. Ako je x
m
,= y
n
tada iz z
k
,= x
m
sledi da je z = LCS(x
m1
, y)
3. Ako je x
m
,= y
n
tada iz z
k
,= y
n
sledi da je z = LCS(x, y
n1
)
Dokaz 0.4. 1. Ako je z
k
,= x
m
, tada mozemo dodati y
n
= x
m
na Z i dobiti zajednicki podniz X i Y duzine k+1, sto
je suprotno pretpostavci x
m
= y
n
= z
k
. Pretpostavka z
k1
,= LCS(x
n1
, y
m1
) . Lako dovodi do kontradikcije.
2. Ako je z
k
,= x
m
, tada je Z zajednicki podniz od X
m1
i Y. Ako bi postojao zajednicki podniz X
m1
i Y sa
duzinom vecom od k, tada bi taj podniz W bio zajednicki podniz X
m
i Y, sto je suprotno pretpostavci.
3. Simetricno dokazu 2.
0.19.8 Najduzi zajednicki podniz
X = x
1
, x
2
, ..., x
m
; Z = z
1
, z
2
, ..., z
k
je podniz niza X ako postoji strogo rastuci niz i
1
, i
2
, ..., i
l
indeksa X, tako
da je za svako j=1,2,...,l u vaznosti x
ij
= z
j
.
Primer 0.4. X = A, B, C, B, D, A, B; Z = B, C, D, B je podniz niza X sa odgovarajucim indeksima 2, 3, 5, 7.
Za dva niza X i Y niz Z je zajednicki podniz, ako je Z podniz od oba X i Y.
Primer 0.5. X = A, B, C, B, D, A, B, Y = B, D, C, A, B, A, niz Z = B, C, A je podniz i X i Y. B, C, A nije
najduzi zajednicki podniz, jer je niz B, C, B, A zajednicki i ima duzinu 4. Pri tome je B, C, B, A najduzi zajednicki
podniz X i Y, jer ne postoji zajednicki podniz duzine 5 ili vise.
LCS problem. Dati su nizovi X = x
1
, x
2
, ..., x
m
i Y = y
1
, y
2
, ..., y
n
. Naci najduzi zajednicki podniz Z nizova
X i Y. (Longest Common Subsequence problem)
Rekurzivno resenje problema
Cena je denisana kao duzina LCS od X
i
iY
j
: c,i, j| =
_
_
_
0, za i = 0 ili j = 0
c,i 1, j 1| + 1, za i, j > 0, X
i
= Y
j
max(c,i, j 1|, c,i 1, j|, i, j > 0, X
i
,= Y
i
)
Racunanje duzine LCS
LCS LENGTH ( x , y)
m < l engt h [ x ]
n < l engt h [ y ]
f o r i < 1 to m
do c [ i , 0 ] <0
f o r i <1 to m
do f or j <1 to n
do i f xi = yj
then c [ i , j ] <c [ i 1, j 1]+1
b [ i , j ] < <
e l s e i f c [ i 1, j ]>=c [ i , j 1]
then c [ i , j ] < c [ i 1, j ]
b [ i , j ] < <
e l s e c [ i , j ] < c [ i , j 1]
b [ i , j ] <<
r et ur n c and b
end l s t i l i s t i n g
s ubs ubs ect i on Kons t r ukci j a LCS
begi n l s t l i s t i n g
PRINTLCS( b , X, i , j )
i f i =0 or j =0
then r et ur n
i f b [ i , j ]=<
then PRINTLCS( b , X, i 1, j 1)
pr i nt Xi
e l s e i f b [ i , j ]=<
then PRINTLCS( b , X, i 1, j )
e l s e PRINTLCS ( b , X, i , j 1)
Optimalna triangulacija poligona
Dat je konveksan poligon P = v
0
, v
1
, ..., v
n1
i tezinska funkcija w denisana na trouglovima formiranim stranama i
tetivama P. Problem je naci triangulaciju koja minimizira tezinu trouglova u triangulaciji. Primer tezine. (v
i
v
j
v
k
) =[
v
i
v
j
[ + [ v
j
v
k
[ + [ v
k
v
i
[, gde je [ v
i
v
j
[ Euklidovo rastojanje tacaka v
i
i v
j
.
Korespodencija sa postavljanjem zagrada
Struktura resenja
Triangulacija podpoligona mora biti optimalna, inace, mogli bismo poboljsati globalnu strukturu(triangulaciju). Jedna
optimalna triangulacija P u odnosu na tezinsku funkciju daje parsing drvo za optimalno razmestanje zagrada pri
mnozenju matrice A
1
A
2
...A
n
. Obrnuto nije tacno.
Rekurzivno resenje
y =
_
0, ako je i = j
mint[i, k] +t[k + 1, j] +(v
i1
v
k
v
j
), zai < j, i k j 1
Optimalno binarno drvo za pretrazivanje
Ulaz: lista reci sa ksnim verovatnocama pojavljivanja p
1
, p
2
, ..., p
n
. Problem: Aranzirati ove reci u binarno drvo
pretrazivanja tako da MINIMIZIRAMO ocekivano vreme pretrazivanja. Posto je broj poredjenja do pristupa elemntu
na dubini d jednak d+1, treba minimizirati
i=1
np
i
(1 +d
i
).
rec w
i
verovatnoca p
i
broj niz broj niz broj niz
a 0.22 2 0.44 3 0.66 2 0.44
am 0.18 4 0.72 2 0.36 3 0.54
and 0.20 3 0.60 3 0.60 1 0.20
egg 0.05 4 0.20 1 0.05 3 0.15
if 0.25 1 0.25 3 0.75 2 0.50
the 0.02 3 0.06 2 0.04 4 0.08
two 0.08 2 0.16 3 0.24 3 0.24
1.00 2.43 2.70 2.15
C
left,right
= minp
i
+C
left,i1
+C
i+1,right
+
i1
j=left
p
j
+
right
j=i+1
p
i
= minC
left,i1
+C
i+1,right
+
right
j=left
p
j
0.19.9 Dijkstra algoritam. Najkraci put medju svim parovima vrhova grafa
D
k,i,j
= minD
k1,i,j
+D
k1,i,k
+D
k1,k,j
D
0,i,j
= c
ij
(v
i
, v
j
) / Grane D
ij
= +
D
|v|,i,j
je najkraci put izmedju v
i
i v
j
.
D
k,i,j
je najrkaci put izmedju v
i
i v
j
koji koristi samo vrhove v
1
, v
2
, ..., v
k
.
0.20 Minimizacija vremena cekanja procesa na jednom ili vise procesora.
Greedy (nezasiti) algoritmi.
Postupak: Neki lokalni optimum je izabran i kada se algoritam zavrsi ocekujemo da je lokalni optimum jednak
globalnom optimumu. Ako apsolutno najbolji odgovor nije zahtevan, tada se greedy algoritam koristi za generisanje
pribliznog odgovora. U slucaju da se trazi tacan odgovor, moramo koristiti komplikovanije algoritme. Svakodnevni
primeri:
1. Razmena banknote.
2. Trac jam: da li uci u ulicu u kojoj vas mozda nakon kilometar cekuje zacepljenje ili se vratiti 5km nazad da
bi se izbeglo zacepljenje.
3. Pravljenje rasporeda procesa na jednom ili vise procesora razmatramo detaljnije. U principu su problemi pravl-
jenja rasporeda NP-kompletni.
Dati su poslovi p
1
, p
2
, ..., p
n
, koji se zavrsavaju za vreme t
1
, t
2
, ..., t
n
respektivne.Imamo jedan procesor. Koji je
najbolji nacin da se rasproede ovi poslovi tako da je srednje vreme cekanja minimalno?
posao vreme
p1 15
p2 8
p3 3
p4 10
Prosecno vreme t
sr
=
15 + 23 + 26 + 36
4
= 25
Prosecno vreme t
sr
=
3 + 11 + 21 + 36
4
= 17.75 optimalno.
Resenje problema. Aranziranje po najkracim vremenima cekanja uvek daje oprimalno resenje.
Dokaz 0.5. Raspored p
i1
, p
i2
, ..., p
in
. Prvi posao zavrsava u vremenu t
i1
. Drugi posao zavrsava u vremenu t
i1
+ t
i2
,
treci t
i1
+t
i2
+t
i3
,...
C =
n
k=1
(nk +1)t
ik
= (n+1)
n
k=1
t
ik
k=1
kt
ik
Ako je stavljeno x iza y uz t
ix
< t
iy
, tada razmenom x i y smanjujemo
totalno vreme cekanja. Zbog toga je svaki raspored po rastucim vremenima SUBOPTIMALAN.
Vise procesora Slicno kao u slucaju jednog procesora dokazujemo da se optimalna cena postize ako prvom pro-
cesoru damo proces sa najmanjim vremenom cekanja, drugom procesoru proces sa najmanjim vremenom cekanja u
preostalim procesima, i tako ciklicno dok ne iscrpimo sve procese.
posao vreme
p1 3
p2 5
p3 6
p4 10
p5 11
p6 14
p7 15
p8 18
p9 20
Minimizacija konacnog vremena zavrsavanja Kada ce i poslednji proces zavrsiti? U primerima a i c vreme
zavrsavanja je i 40 i 38 respektivno. Ovaj problem ekvivalentan je problemu pakovanja ranca, pa je prema tome
NP-kompletan(tj. problem minimizacije konacnog vremena). U slucaju b minimalnog vremena izvrsavanja ne moze
biti poboljsan, jer su svi procesori uvek zauzeti.
0.21 Human-ovi kodovi. Human-ov algoritam.
Skup ASCII sastoji se od 100 printabilnih karaktera. ,log
2
100| = 7, pa je potrebno 7 bita za reprezentaciju. Posto je
2
7
=128, imamo i neke neprintabilne karaktere. Osmi bit je dodat za kontrolu parnosti.
Primer 0.6. Datoteka sadrzi a,e,i,s,t,space,new line.
Karakter Kod Frekvencija Broj bitova
a 000 10 30
e 001 15 45
i 010 12 36
s 011 3 9
t 100 4 12
space 101 3 39
new line 110 1 3
total 174
Problem Zainteresovani smo za redukovanje duzine datoteke zbog prenosa telefonskom linijom ili zbog smanjenja
velicine prostora za zapis datoteke na disku. Je li moguce uvesti novi kod i tako smanjiti duzinu datoteke i ukupan
broj potrebnih bita? Odgovor Da! To je moguce i mozemo ustedeti i 25 odsto, a na velikim datotetkama i do 50 -
60 odsto prostora.
Opsta strategija je da se dozvoli da duzina koda varira od karaktera do karaktera i omoguciti da karakteri sa visokim
frekvencijom imaju kraci kod. Ako nam se svi karakteri pojavljuju sa istom frekvencijom, tada verovatno necemo
imati velike ustede.
Predstavljanje koda drvetom
Grana levo znaci 0, a desno znaci 1. Npr. 010 predstavlja i. Cena koja je
d
i
f
i
, gde karakter c
i
ima dubinu d
i
i frekvenciju d
i
. Jeftiniji je donji kod na slici. Kod kod kojeg su vrednosti samo u listovima naziva se PREFIKSNI
KOD.
Zadatak. Izracunati cenu kodova u gornja dva drveta.
Primedba Optimalan kod je predstavljen potpunim drvetom, inace jednog potomka mozemo dici na visi nivo i tako
smanjiti cenu.
Ako su znaci samo na listovima drveta, tada svaka sekvenca moze biti kodirana na jedinstven nacin. Npr, pret-
postavimo da je kodirani string 0100111100010110001000111, sledi da 0 nije znak, 01 nije nak, ali 010 predstavlja i,
pa je prvi karakter i. Tada je 011 s, 11 je nl, a zatim a,sp,t,i,e,nl. Nijedan od znakova nije preks nekog drugog koda
znaka. Ako se karakteri pojavljuju i u cvorovima, tada dekodiranje nije jednoznacno.
Nas problem se svodi na nalazenje KOMPLETNOG BINARNOG DRVETA SA MINIMALNOM TOTALNOM
CENOM, pri cemu se svi znakovi nalaze na listovima.
Optimalan preksni kod
Karakter Kod Frekvencija Broj bitova
a 001 10 30
e 01 15 30
i 10 12 24
s 00000 3 15
t 0001 4 16
space 11 13 26
new line 00001 1 5
total 146
Razmenom dece u drvetu, mozemo dobiti razlicite optimalne kodove.
Human-ov algoritam Neka je C broj razlicitih znakova. Svaki znak predstavljamo drvetom i razmatramo
SUMU drveta. Tezina drveta jednaka je zbiru frekvencija njegovih listova. C-1 puta izaberemo dva drveta T1 i T2
sa najmanjom tezinom ( u slucaju jednakih tezina uzimamo proizvoljno) i formiramo novo drvo sa poddrvetima T1 i
T2. Inicijalno (ulaz) je C suma od drveta sa jednim cvorom za svaki znak. Na kraju (izlaz) postoji jedinstveno drvo i
to je OPTIMALNO HUFFMAN-ovo drvo kodiranja.
Ideje za dokaz korektnosti Human-ovog algoritma:
1. Drvo mora biti potpuno, inace mozemo jedan list podici na nivo za jedan visi i smanjiti cenu.
2. Dva najmanje frekventna karaktera i moraju biti najdublji listovi. Dokaz kontradikcijom: Ako i nisu
najdublji listovi, tada to mora biti neko , jer je drvo kompletno. Swaping sai smanjuje cenu drveta!
3. Dva lista iste duvine mogu zameniti mesta ne narusavajuci optimalnost.
4. Inicijalni korak je dobar.
5. Indukcija kod spajanja drveta. Dati detalje!
Pitanje. Zasto je ovaj algoritam hill climbing (greedy)?
Odgovor. U svakoj fazi mi izvodimo merge lokalno, bez obzira na globalno stanje.
Pitanje. Oceniti slozenost algoritma.
Odgovor.
1. Ako drveta drzimo na heap-u (priority queue) tada je T(c)=O(clogC), jer imamo izgradnju heap-a, 2c-2 brisanja
min i c-2 inserta.
2. Linked list priority queue daje T(c)=O(c
2
). Posto je u ASCII kodu C malo, kvadratna ocena je prihvatljiva.
Napomene.
1. Kodirana informacija mora biti transformisana na pocetak datoteke, inace je necemo moci dekodirat. To je slavo
i skupo za male fajlove.
2. Algoritam ima dva prolaza. Prvi prolaz utvrdjuje frekvenciju podataka, a drugi kodira. Dvoprolaznost je skupa
za velike fajlove.
0.22 Pravljenje rasporeda: minimizacija konacnog vremena cekanja. Prob-
lem pakovanja ranca.
Neka su dati poslovi p
1
, p
2
, ..., p
n
sa vremenima izvrsavanja t
1
, t
2
, ..., t
n
retrospektivno. Treba naci raspored izvrsa-
vanja poslova koji ce minimizirati neku zadatu funkciju. U Minimizacija vremena cekanja procesa na jednom ili vise
procesora. Greedy (nezasiti) algoritmi. razmotrili smo i resili problem rasporeda za jednostavan problem minimizacije
prosecnog vremena cekanja.
U problemu minimizacije KONACNOG VREMENA IZVRSAVANJA trazi se raspored u kome ce vreme izvrsavanja i
poslednjeg procesa biti minimalno(optimalno). Mada je po formulaciji poslednji problem slican prethodnom, pokazuje
se da je on zapravo mnogo tezi. Ovaj problem je NP-kompletan jer je ekvivalentan problemu pakovanja ranca. U
Minimizacija vremena cekanja procesa na jednom ili vise procesora. Greedy (nezasiti) algoritmi dali smo ilustraciju
problema optimizacije konacnog vremena izvrsavanja za jedan specijalni slucaj.
NAPOMINJEMO da mi razmatramo NONPREEMPTIVNE RASPOREDE, tj. ako je neki posao pocet, tada se
on izvrsava do kraja i to bez prekida. Umesto problema pakovanja ranca mi razmatramo ekvivalentan problem
pakovanja u bin-ove (kutije,korpe). Dacemo Greedy(nezasicen) resenje problema pakovanja u bin-ove. Greedy
algoritmi su brzi, ali ne daju uvek optimalno resenje. Dokazujemo da nasa resenja nisu daleko od optimalnih.
Dato je n komada kapaciteta s
1
, s
2
, ..., s
n
. Svi komadi zadovoljavaju 0 < s
i
< 1. PROBLEM PAKOVANJA U
BINOVE je problem pakovanja svih komada u sto manji broj kutija(binova) kapaciteta 1.
Primer 0.7. s
1
= 0.2, s
2
= 0.5, s
3
= 0.4, s
4
= 0.7, s
5
= 0.1, s
6
= 0.3, s
7
= 0.8
0.8
0.2
0.3
0.7
0.5
0.1
0.4
Razlikujemo on-line i o-line algoritme. ON-LINE problem trazi da svaki komad mora biti ubacen u kutiju pre
nego sto sledeci komad bude razmotren. U OFF-LINE problemima ne moramo raditi nista pre nego sto svi komadi
budu ucitani.
0.23 ON-LINE algoritmi : primer pakovanja u binove.
Pokazujemo da ON-LINE algoritmi pakovanja u binove ne moze uvek dati odgovor koji je optimalan. Cak ako
mu dozvolimo neograniceno racunanje, on-line algoritam mora smestiti komad pre nego sto razmotri sledeci komad.
Situaciju ilustrujemo sledecim primerom :
Primer 0.8. Neka su I
1
= (i
1
[[i
1
[ =
1
2
) , [I
1
[ = m i I
2
= (i
2
[[i
2
[ =
1
2
+ ) , [I
2
[ = m, 0 < < 0.01. Neka je
I = I
1
I
2
, gdje je operacija konkatenacije (dopisivanja)nizova.
1. Pretpostavimo da postoji optimalan algoritam A koji pakuje niz I optimalna u m kutija, tako da jedan bin
izgleda kao na slici.
1
2
+
1
2
2. Neka je J = I
1
. Niz J moze biti upakovan u [
m
2
] kutija, ali ce sa optimalnim algoritmom A pakovati isto ako i
pre niz I, dakle u m kutija.
Iz (1) i (2) sledi da ne postoji optimalan on-line algoritam za pakovanje u binove.
Dajemo sledecu kvantitativnu ocjenu.
Teorema 0.5.. Postoji ulaz koji forsira on-line algoritam pakovanja u binove da koristi najmanje
4
3
od optimalnog
broja binova.
Dokaz 0.6. Neka je M2N, a niz I kao u primeru 1. Pretpostavimo suprotno.
1. Nakon m komada A koristi b binova,a optimalno je
m
2
.
Na osnovu pretpostavke slijedi
2b
<
4
3
i odatle 6b > 4m.
2. Nakon 2m komada svi su komadi upakovani. Svi binovi nakon b-tog sadrze najvise jedan komad, jer su svi
1
2
komadi upakovani u b-binova.
Trebamo 2mb binova vise
2mb
m
<
4
3
6b > 4m. Zakljuci pod (1) i (2) su u kontradikciji i to dokazuje
tvrdnju.
POSTOJE TRI JEDNOSTAVNA ZA IMPLEMENTACIJU ALGORITMA KOJI GARANTUJU NE VISE OD
2 (OPTIMALANBROJBINOV A) : NEXT FIT, FIRST FIT, BEST FIT. Razmotrimo ih u sledecim
pitanjima.
0.24 Next t pakovanje
NEXT FIT (SLEDECI ODGOVARAJUCI)
Algoritam: Komad se stavlja u istu kutiju kao i prethodni, a ako to nije moguce stavlja se u novoformiranu kutiju.
Teorema 0.6.. Neka je m optimalan broj kutija potrebnih ya pakovanje niza komada
Dokaz 0.7. B
j
i B
j+1
sadrze komade sa zbirom vecim od 1-inace bi svi komadi iz njih stali u jedan bin. Primijenjeno
na sve parove susjednih binova daje dokaz, jer najvise pola prostora moze biti izgubljeno (nepopunjeno).
Primer 0.9. I = (0.5,
2
n
, 0.5,
2
n
, ...)
0.5
0.5
B1 ...
0.5
0.5
B
n
4
2
n
2
n
2
n
2
n
B
n
4
+1
0.25 Best t pakovanje
Best t (najbolje smestanje)
Umesto stavljanja u prvi bin (kutiju,korpu,boks), trazi se bin u koji komad najbolje pasuje (tesno pasuje).
Primer 0.10. Best t za niz ,0.2, 0.5, 0.4, 0.7, 0.1, 0.3, 0.8|
Prazan
0.1
0.5
0.2
Prazan
0.4
0.3
0.7
Prazan
0.8
Bez dokaza navodimo da best t u najgorem slucaju trosi 1.7 od optimalnog broja binova.
Jednostavan je za kodiranje ako trebamo 0(nlogn) vreme izvodjenja.
0.26 First t pakovanje
First t (Prvi odgovarajuci)
First t strategija skenira binove (kutije,korpe,boksove) i smesta novi komad u prvu pregradu (prvi bin) sa do-
voljno mesta da se prihvati. Nova kutija se kreira samo ako prethodne kutije ne mogu da prihvate element.
Primer 0.11. First t za niz , 0.2,0.5,0.4,0.7,0.1,0.3,0.8 |
Prazan
0.1
0.5
0.2
Prazan
0.3
0.4
Prazan
0.7
Prazan
0.8
Teorema 0.7.. Neka je m optimalan broj binova za pakovanje niza I.
1. Tada First t koristi manje ili jednako od ,
17
10
m| binova.
2. Postoji niz koji zahteva
17
10
(m-1) binova.
Dokaz 0.8. Ovde izostavljamo dokaz (1)
(2) Za ilustraciju dajemo sledeci primer:
Neka u nizu I imamo
6m komada duzine
1
7
+
6m komada duzine
1
3
+
6m komada duzine
1
2
+.
Lako se vidi da optimalno imamo 6m binova, svaki za sve tri vrste elemenata. First t koristi 10m binova umesto 6m.
Prazno
1
7
+
1
7
+
1
7
+
1
7
+
1
7
+
1
7
+
Od B
1
do B
m
Prazno
1
3
+
1
3
+
Od B
m+1
do B
4m
Prazno
1
2
+
Od B
4m+1
do B
10m
Napomena Prakticna merenja pokazuju da u slucaju vrednosti uniformno rasporedjenih u intervalu ,0, 1|, za rst
t trebamo oko 2 posto vise binova.
0.27 O-Line algoritmi : First t decreasing.
U o-line obradi korisno je elemente sortirati pre rasporedjivanja u binove. Za First t algoritam sortiramo u
opadajucem(decreasing) poretku, a za best t zgodnije je sortirati elemente u rastucem (increasing) poretku.
Primer 0.12. First t za niz 0.8, 0.5, 0.4, 0.3, 0.2, 0.1
0.2
0.8 B1
0.3
0.7 B2
0.1
0.4
0.5
B3
Zelimo dokazati da rst-t decreasing algoritam koristi najvise
4m+1
3
binova, ukoliko optimalno pakovanje koristi m
binova.
Lema 0.2. Neka n elemenata niza sortiranog u opadajucem poretku imaju duzine s
1
, ..., s
n
i pretpostavimo da se
optimalno mogu u m binova. Tada svi komadi koji se smestaju u dodatne binove po principu rst t decreasing
imaju duzinu manju ili jednaku
1
3
.
Dokaz 0.9. Dokazimo da za s
i
element koji je prvi smjesten u m+1-om binu vazi [s
i
[
1
3
.
Pretpostavimo da je [ s
i
[>
1
3
. Tada je svaki od s
1
, s
2
, ..., s
i1
>
1
3
jer su sortirani u opadajucem poretku. Zbog
toga svaki od binova B
1
, ..., B
m
imaju najvise dva elementa.
Neka B
x
iB
y
takvi da je 1 x<y m i neka su u B
x
dva komada x
1
i x
2
, a u B
y
jedan komad y
1
. Tada
(x
1
y
1
x
2
s
i
) x
1
+x
2
y
1
+s
i
.
Iz zakljucka implikacije sledi da s
i
moze biti smesten u B
y
, sto je suprotno pretpostavci.
Moramo imati prvo niz binova sa po jednim komadom, a zatim ide niz binova koji sadrze po dva komada. Neka
je prvih j, a drugih m-j. Neka su s
1
, ..., s
j
po jedan u binu, a s
j+1
, s
j+2
, ..., s
i1
i m-j binova, po dva komada zajedno
2(m-j) je ukupan broj komada u tih m-j binova. Ne mogu se svi elementi staviti u m binova, sto je kontradikcija.
Lema 0.3. Broj objekata u dodatnim binovima najvise moze biti m-1.
Dokaz 0.10. Pretpostavimo, suprotno tvrdnji, da u dodatnim binovima imamo m komada(elemenata niza). Posto
s eoptimalno svi elementi niza s
1
, ..., s
n
mogu smestiti u m binova, to je
n
i=1
s
i
m. Sa druge strane, ako oznacimo
s
i
=
_
w
j
, 1
x
i
, ako se s
i
nalazi u dodatnom binu(a ima ih najmanje m po pretpostavci)
imamo da je
n
i=1
s
i
m
j=1
w
j
+
m
j=1
x
j
m
j=1
(w
j
+x
j
)
w
j
+ x
j
> 1, inace bi x
j
moglo biti smesteno u B
j
.
n
j=1
s
i
>
m
j=1
1 > m Kontradikcija! Time je lema
dokazana.
Teorema 0.10.. Neka je m optimalan broj binova za pakovanje niza I elemenata s
1
, ..., s
n
.Tada rst-t decreasing
ne treba vise od
4m+ 1
3
binova.
Dokaz 0.11. m-1 elemenata velicine koja je
1
3
treba ,
m1
3
| ekstra binova. Ukupan broj binova je najvise ,
m1
3
|
m+1
3
|.
Teorema 0.11.. Neka je m optimalan broj binova potrebnih za pakovanje niza I=s
1
, s
2
, ..., s
n
Uz koristenje ove procedure program trosenja resenja u problemu n kraljica mozemo skicirati na sledeci nacin :
s 1 =1;
k=1;
whi l e k>1
whi l e s k <=n
a k<=s k ;
s k=s k +1;
whi l e ( s k<=n && k r a l j i c a ne moze b i t i u redu s k stupca k)
s k=s k+1 ;
i f k=n then z a pi s a t i
e ( a 1 , . . . , a n )
k=k+1;
s k =1;
whi l e ( s k<= && k r a l j i c a ne moze b i t i u redu s k stupca k)
s k=s k+1
k=k1;
i nt a ;
i nt c t r =0;
pr i nt f (n problem n k r a l j i c a ) ;
pr i nt f (n Broj redova za nxn t abl u ) ;
s c anf (%d , &n ) ;
a=( i nt ) ( mal l oc ( s i z e o f ( i nt )n ) ) ;
pr i nt f (n U svakom r e s e nj u su koor di nat e i t e k r a l j i c e date sa ( Red , Kolona ) ) ;
pr i nt f ( n Svi su r edovi i kol one numeri sani od 1 do n ) ;
f o r ( c t r =0; ctr <n ; c t r++)
ge t Pos i t i ons ( a , 0 , c t r ) ;
get char ( ) ;
get char ( ) ;
i nt i , c hoi c e ;
s t a t i c . i nt counter =0;
counter++;
pr i nt f ( n RESENJE #%d , counter ) ;
f o r ( i =0; i <n ; i ++)
pr i nt f ((%d,%d) , i +1, a [ i ] +1) ;
i f ( counter %10==0) pr i nt f ( n Ubes i t e 0 za kraj , j edan za nastavak ) ;
s c anf (%d , &c hoi c e ) ;
i f ( c hoi c e==0) e xi t ( 0 ) ;
;
i nt ctr1 , c t r 2 ;
a 1 [ col no ]=val ;
i f [ col no]==n1
pr i nt f Ar r ay ( a 1 ) ; r et ur n ;
;
f o r ( c t r 1 =0; ctr1<n ; )
/ ova pe t l j a na l az i odgovaraj uce br oj eve kol ona u sl edecem redu /
f o r ( c t r 2 =0; ctr<=col no ; c t r 2++)
i f ( a 1 [ c t r 2]==c t r 1 [ [ ( col no+1c t r 2 ) ( col no+1c t r 2)==( ctr1a 1 [ c t r 2 ]
( ctr1a 1 [ c t r 2 ] ) )
goto mi ss1 ;
ge t Pos i t i ons ( a 1 , col no +1, c t r 1 ) ;
mi ss1 ;
c t r 1++;
/ KRAJ PROGRAMA /
Program za n kraljica koji umesto rekurzije koristi dva steka. Stekovi su implementirani pomocu
nizova (arrays).
#i nc l ude <s t di o . h>
#i nc l ude <s t dl i b . h>
#i nc l ude <ti me . h>
t ypedef s t r uc t i nt x , y ;
po s i t i o n ;
voi d Sol veProbl em( i nt n ) ;
i nt n=0;
voi d main ( )
pr i nt f (n Unes i t e di menzi j u n za t abl u nxn : ) ;
s c anf (%d,&n ) ;
pr i nt f (n U svakom od r e s e nj a koor di nat e nt e k r a l j i c e su date sa ( Red , Kolona ) ) ;
pr i nt f (n Redovi i kol one su numeri sani od 1 do n: n ) ;
Sol veProbl em( n ) ;
get char ( ) ;
counter++ ;
pr i nt f (n SOLUTION #%d : , counter ) ;
f or ( counter1 =0; counter1<=counter3 ; counter1++)
pr i nt f ((%d,%d) , counter1 +1, s t ack2 [ counter1 ] +1) ;
i f ( counter %10==0) pr i nt f (n Enter1 to conti nue , 0 to Exi t ) ;
s c anf (%d , & c hoi c e ) ;
i f ( c hoi c e==0)
e xi t ( 0 ) ;
;
Pos i t i on2 . x=counter3 ;
Pos i t i on2 . y=s t ack2 [ counter3 ];
d [ Pos i t i on2 . y ] [ 0] =0;
d [ Pos i t i on2 . x+ Pos i t i on2 . y ] [ 1] =0;
d [ Pos i t i on2 . x Pos i t i on2 . y+n ] [ 2] =0;
e l s e f or ( counter1=n1; counter1 >=0; counter1 )
i f ( d [ counter1 ] [0]==0 && d [ Pos i t i on1 . x+counter1 ] [1]==0
&& d [ n+Pos i t i on1 . x+1counter1 ] [ 2] ==0)
Pos i t i on3 . x=Pos i t i on1 . x+1;
Pos i t i on3 . y=counter1 ;
head1[++counter2 ]=Pos i t i on3 ;
;
get char ( ) ;
get char ( ) ;
r et ur n0 ;
Problem kraljica. Koliki je maksimalan broj kraljica koje se mogu postaviti na sahovsku plocu n n tako da
nikoje dve ne tuku jedna drugu? Odgovor : n kraljica.
Broj nacina na koje se n kraljica mogu postaviti na plocu n n da ne tuku jedna drugu je (1,0,0,2,10,4,40,92,...) za
n=1,2,3,4,5,6,7,8,...
Na slici je dato 12 neekvivalentnih resenja za n=8. Od njih se rotacijama i simetrijama dobijaju svih 92 resenja.
Na datoj slici je minimalan broj kraljica da zauzimaju ili tuku sva polja ploce 8 8.
0.30 Dodatak A.
0.30.1 Heap sort (sort drvetom)
templ ate <c l a s s T>
voi d heapi f y (Ta , i nt k , i nt n)
T t= a [ k ] ;
whi l e ( k<n/2)
i nt j =2k+i ; // pr et var a j u n a j s t a r i j e g potomka k
i f ( j +1<n && a [ j ]<a [ j +1] ) ++j ;
i f ( t>a [ j ] ) break ;
a [ k]=a [ j ] ;
k=j ;
a [ k]=t ;
T temp=x ;
x=y ;
y=temp ;
n
i=1
(1 +
n
j=i+1
X
ij
)|
=
1
n
n
i=1
(1 +
n
j=i+1
E,ij|)
=
1
n
n
i=1
(1 +
n
j=i+1
1
m
)
= 1 +
1
nm
n
i=1
(n i)
= 1 +
1
nm
(
n
i=1
n
n
i=1
i)
= 1 +
1
nm
(n
2
n(n + 1)
2
)
= 1 +
n 1
2m
= 1 +
d
2
d
2n
= T = (2 +
d
2
d
2n
) = (1 +)
0.30.12 Hes funkcije
Heuristicke:
hashing deljenjem i hashing mnozenjem
Stohasticke: univerzalno hesiranje
Uniformno hesiranje:
Svaki kljuc je podjednako moguce hesirati u bilo koji slot od m, nezavisno od toga gde su hesirani drugi kljucevi.
Teskoce
1. Ne znamo distribuciji verovatnoca sa kojima ce kljucevi biti izvuceni.
2. Kljucevi mogu biti vuceni u zavisnosti jedan od drugog.
Ponekad znamo distribucije: kljuveci su k slucajnih brojeva nezavisno i uniformno distribuirani u 0 k < 1 h(k) =
km| zadovoljava uslov prostog uniformnog hesiranja. Praksa:
1. pt i pts slati u razlicite slotove,
2. zahtevaju se ponekad ostriji uslovi: daleke vrednosti hesirati u bliske slotove.
Kljucevi kao prirodni brojevi
U = N = 0, 1, 2, ... Ako nisu, interpretiramo ih tako.
Primer 0.15. pt=(112,116), (112*128)+116=14452 (ceo broj u osnovi 128)
Metod deljenja.
h(k)=k mod m
Primer 0.16. m=12, k=100, h(k)=4
mora biti m,= 2
p
, jer je h(k)=p najnizih bitova.
Bolje je napraviti hes funkciju zavisnu od svih bitova!
m = 2
p
1 je los izbor, jer permutovanje znakova k
(interpretirano u radix 2
p
) ne menja slot. Dokazati!
Prost broj daleko od 2
p
je dobar izbor.
Primer 0.17. Uvezivanje za kolizije n=2000 stringova znakova (char ima 8 bitova). Nije nam problem pretrazivati u
srednjem 3 elementa.
m=701, h(k)=kmod701, gde je k integer!
701=2001/3 je daleko od 2
n
!
Metod mnozenja.
1. k mnozimo konstantom A, 0 < A < 1 i uzimamo funkcijski deo od kA
2. mnozimo sa m i uzimamo oor kao rezultat
h(k)= m(kAmod1)|,
sa kA mod1 kA-kA|
Tipicno, m nije kritican, pa uzimamo m=2
p
, p Z, jer je implementacija na kompjuteru jednostavnija.
1. Duzina reci masine je w bita.
2. k staje u jednu rec.
3. A je decimalni deo od
s
2
w
, 0 < s < 2
w
.
Rezultat je r
1
2
w
+r
0
.
4. Uzimamo p bitova najvece tezine u r
0
.
D.Knuth sugerise: A
5 1
2
= 0.6180339887.
Primer 0.18. k=123456, p=14, m=2
1
4=16384, w=32.
A decimalni deo
s
2
32
najblize
5 1
2
A=
2654435769
2
32
k s= 327706022297664 = (76300 2
32
) + 17612864
i r
1
=76300, r
0
=17612864 h(k)=67.
0.30.13 Univerzalno hesiranje
Da ne bi svi kljucevi bili kesirani u isti slot, treba izabrati SLUCAJNO hes funckiju. To je UNIVERZALNO HESIR-
ANJE, ako je funkcija izabrana nezavisno od vrednosti kljuceva.
Poredjenje sa Quick-sortom. Izbor hes funkcije iz unapred pazljivo dizajniranog skupa funkcija.
H - konacna kolekcija hes funkcija.
h: U 0, 1, ..., m1
Univerzalna kolekcija akko k, l U, broj h H za koje je h(k)=h(l) najvise
H
m
, tj. sanse da bude kolizija h(k) i
h(l) su
1
m
. Pri tome su h(k) i h(l) nezavisno i slucajno izabrani iz 0, 1, ..., m1.
Teorema 0.15.. Neka je h izabrana iz univerzalne kolekcije H hes funkcija. h se koristi za hesiranje n kljuceva u
tabelu T duzine m, sa uvezivanjem za razresavanje kolizija.
Ako k nije u tabeli, tada je ocekivana duzina E,n
h(k)
| liste u koju se hesira k, najvise .
Ako je k u T, tada je ocekivana duzina E,n
h(k)
| liste sa kljucem k najvise 1+.
Dokaz 0.16. Za k, l denisemo X
kl
= Ih(k) = h(l)
k,l kolidiraju sa verovatnocom
1
m
.
Prh(k) = h(l)
1
m
E,X
kl
|
1
m
.
Denisemo za k
Y
k
=
lT
l=k
X
k
l
E,Y
k
| = E,
lT
l=k
X
k
l| =
lT
l=k
E,X
kl
|
lT
l=k
1
m
k / T n
h(k)
= Y
k
i
[ k [ l T&l ,= k [= n
E,n
h(k)
| = E,Y
k
|
n
m
=
k T&k T,h(k)|& k nije u racunu Y
k
n
h(k)
= Y
k
+ 1 [ l [ l T&l ,= k [= n 1
E,n
h(k)
| = E,Y
k
| + 1
n 1
m+ 1
= 1 +
1
m
< 1 +.
Korolar.
Koristenje univerzalnog hesiranja i resavanja kolizija uvezivanjem u tabeli sa m slota, zahteva T=(n) za bilo koju
sekvencu od n INSERT, SEARCH, DELETE operacija od kojih su njih (m) INSERT.
Dokaz 0.17. [ Ins [= O(m) n = O(m) = O(1)
INSERT, DELETE trebaju O(1) vreme, a takodje i SEARCH. Zbog linearnosti E za citavu sekvencu (niz) treba T=O(n)
koraka.
0.30.14 Otvoreno adresiranje
Svi elementi su u samoj hes tabeli, tj. svaki unos sadrzi ili element ili NIL. Kada trazimo element, pretrazujemo samo
tabelu dok ne nadjemo element ili dok ne bude jasno da tabela ne sadrzi element. Tabela moze biti popunjena do kraja
bez mogucnosti daljeg unosa. Load faktor (faktor popunjenosti) nikada ne moze biti veci od 1.
Umesto pointera racunamo(sledimo) nizove slotova koje treba ispitati. Memorija koju bi koristili pointeri daje veci
broj slotova, potencijalno vodeci ka smanjenju kolizija i brzem pretrazivanju.
INSERT
h: Ux 0, 1, ..., m1 0, 1, ..., m1 zahtevamo:
probni niz h(k,0), h(k,1),...,h(k,m-1) je permutacija 0, 1, ..., m1.
HASHINSERT(T, k)
i < 0
r epeat j < h( k , i )
i f T[ j ]=NIL
then T[ j ] < k
r et ur n j
e l s e i < i +1
unt i l i=m
e r r or hash t abl e over f l ow
HASHSEARCH (T, k)
i < 0
r epeat j < h( k , i )
i f T[ j ]=k
then r et ur n j
i < i +1
unt i l T[ j ]=NIL or i=m
r et ur n NIL
DELETE ce imati poteskoca ako stavimo NIL u izbrisani slot i. Necemo moci izbrisati element za koji je u
postavljanju i nadjen kao popunjen. Izlaz iz problema: umesto NIL stavimo DELETE.
0.30.15 Uniformno hesiranje
Za svaki element probni niz ima jednaku verovatnocu da bude jedan od m! permutacija. Tacno uniformno hesiranje
je tesko za implementaciju.
Umesto pravog UH koristimo i dvostruko hesiranje, linearnu probu, kvadratnu probu.
Linearna proba.
h
: U 0, 1, ..., m1 neka je pomocna hes funkcija. Linearna proba koristi h(k,i)=(h(k)+i) mod m.
Samo je m razlicitih probnih nizova odredjeno sa h(k,0).
JEDNOSTAVNA JE IMPLEMENTACIJA, ali imamo PROBLEM:
primarno klasterovanje! To nam povecava AWERAGE TIME.
CLUSTER: iza i popunjenih, verovatnoca popunjavanja slota i+1 da bude sledeci popunjen je
i + 1
m
- KLAS-
TEROVANJE.
Kvadratna proba.
h(k, i) = (h
(k) +c
1
i +c
2
i
2
)modm
Dvostruko hesiranje.
Kod kvadratne probe h(k
1
, 0) = h(k
2
, 0) h(k
1
, i) = h(k
2
, i), tzv. sekundarno klasterovanje, tj. k
1
i k
2
imaju iste
nizove.
Zbog toga uvodimo dvostruko hesiranje h(k, i) = (h
1
(k) +h
2
(k)), pri cemu h
2
(k) mora biti relativno prost sa duzinom
table.
Primer 0.19. h
1
(k) = kmod 13
h
2
(k) = 1 + (kmod 11)
Za vezbu ubaciti 79,69,98,72,14,50.