Professional Documents
Culture Documents
=
a #
i
i
a
1
Funcia C corespunztoare specificaiei smax(s) este ilustrat n figura 1(a).
Corectitudinea este evident, din moment ce sunt parcurse toate subsecvenele
posibile ale secvenei s, reprezentat ca un vector. Complexitatea rezult (n
2
),
unde n este lungimea secvenei
2
.
a) Complexitate (n
2
) b) Complexitate (n)
int summax(int s[], int n) {
int summax(int s[], int n) {
2
Exist i o variant naiv cu complexitate (n
3
), care are un ciclu suplimentar pentru
lungimea subsecveelor parcurse.
Cristian Giumale/Note de curs 11
int smax=0;
for(i=0; i<n; i++) {
int sum=0;
for(j=i; j<n; j++) {
sum+=s[j];
if(sum>smax) smax=sum;
}
return smax;
}
int i,sum,smax;
if(n == 0) return 0;
smax = sum = s[0];
for(i=1; i< n; i++) {
sum = sum < 0? s[i]:sum+s[i];
if(sum > smax) smax = sum;
}
return smax;
}
Figura 1 Funcii C pentru summax
O observaie simpl conduce ns la o rezolvare n timp liniar. Doar o parte din
subsecvenele din s contribuie la soluie. ntr-adevr, n momentul n care suma
subsecvenei curent prelucrate devine negativ, prelucrarea subsecvenei poate fi
abandonat pentru c suma ei nu va putea depi suma oricrei alte subsecvene ce
ncepe cu un numr pozitiv. Figura 2 ilustreaz acest fenomen. Dintr-un total de 120
de subsecvene nevide, doar 5 trebuie prelucrate, anume: 1 3 -2 5 -9, -4,
3 -1 6 -3 5 -7 -8, -3 i 6.
1 3 -2 5 -9 -4 3 -1 6 -3 5 -7 -8 -3 6
Figura 2 Variaia sumei maxime a subsecvenelor
Rezolvarea imperativ, n timp liniar, a problemei corespunde funciei C din
figura 1(b) i are un avantaj suplimentar: este eficient pentru secvene foarte lungi.
Deoarece fiecare numr din secvena s este parcurs o singur dat, nu este necesar
memorarea ntregii secvene. Secvena poate fi citit incremental, doar numrul
curent fiind pstrat pe durata adugrii lui la suma curent calculat.
Dei, intuitiv, funciile - specificate imperativ - din figura 1(b) sunt uor de
neles, drumul de la specificaia formal smax(s) la codul respectiv nu este de loc
uoar. Evitm aceste complicaii i ne concentrm atenia asupra unei rezolvri care
s fie ct mai apropiat de specificaia problemei.
Rezolvarea declarativ de mai jos, n CLIPS, urmrete ad litteram specificaia
problemei, descriind de fapt ce se nelege prin secven de sum maxim. Varianta
declarativ are dou particulariti notabile: (a) n afara sumei maxime, sunt
determinate, fr cod suplimentar, toate subsecvenele de sum maxim; (b) o
singur regul esenial de rezolvare, anume summax, poate prelucra "simultan" mai
multe secvene pentru a le determina suma maxim.
12 Cristian Giumale/Note de curs
(deffunction sum (?subsecventa)
(bind ?s 0)
(progn$ (?n ?subsecventa) (bind ?s (+ ?n ?s)))
?s)
(defrule summax
(secventa ?id $? $?x $?)
(not (summax ?id ?))
(not (secventa ?id $? $?y&:(> (sum $?y) (sum $?x)) $?))
=> (assert (summax ?id (sum $?x)))
(printout t ?id ": sum" $?x "=" (sum $?x) crlf))
(defrule date
=> (printout t "file: ")
(load-facts (readline)))
O secven este reprezentat de afirmaia (secven nume numere). Numele
este necesar pentru a putea calcula "simultan", cu aceeai regul, suma maxim a
fiecrei secvene date. Rezultatul este tiprit i nregistrat n baza de cunotine a
programului sub forma afirmaiei (summax nume valoare). Un exemplu de rulare a
programului este n tabelul 1.
Tabelul 1. Suma maxim a elementelor subsecvenelor unei secvene
fiier sumclp.dat rezultate
(secventa a 4 -1 8 -1)
(secventa b 2 3 4 -1 2 -3 5)
(secventa c 3 -5 -1 2 3 -6 1 15 -1)
(secventa d -1 8 -1 8 -1)
(secventa e)
CLIPS> (reset)
CLIPS> (run)
file: sumclp.dat
e: sum()=0
d: sum(8 -1 8)=15
c: sum(1 15)=16
b: sum(2 3 4 -1 2 -3 5)=12
a: sum(4 -1 8)=11
Programul de mai sus este concis i uor de construit. n contrapartid, preul
pltit este complexitatea semnificativ a rezolvrii. Ignornd timpul necesar identificrii
abloanelor, complexitatea programului declarativ rezult (n
5
) fat de complexitatea
(n) a variantei scrise n C.