Professional Documents
Culture Documents
O estudo da eci ncia de algoritmos refere-se ao comportamento assimpt tico de algoritmos e o que informa da depend ncia do tempo de execucao de um algoritmo em funcao de um par metro e a de entrada. Este par metro e, em geral, um natural que traduz a dimens o do argumento. Por a a exemplo, no caso das listas, este par metro e o seu comprimento. No que se segue os algoritmos a s o codicados em Mathematica a
W(g) = { f : $c1 IR+ $n0 IN "nn0 0 c1 g(n) f (n)} Naturalmente f = O(g) e f = W(g) sse f=Q(g).
5.2 Um exemplo
Para ilustrar o tipo de consideracoes que s o efectuadas consideramos um primeiro exemplo a (simples) que e o algoritmo da determinacao da soma n k. Para facilidade de raciocnio k=1 consideram-se duas colunas, uma com o tempo associado a execucao de cada comando (TE) ` e outra com o n mero de vezes que esse comando e efectuado durante o processamento do u algoritmo (#):
# 1 1 n+1 n n
Os comandos r=0 e k=0 demoram tempos c1 e c2 e s o executados uma unica vez. Sendo n a o conte do da vari vel n (que permanece inalterada) tem-se que o teste da guarda do While e u a executado n + 1 vezes e os comandos do corpo do While s o executados n vezes. A constante a c3 , referente a avaliacao da guarda k!=n, signica que se assume que o tempo da avaliacao ` 1 desta express o e independente dos valores de k e n envolvidos . A constante c4 signica que a se assume tamb m que o tempo da atribuicao r=r+(k+1) n o depende dos valores de r e k. e a Para a constante c5 as consideracoes s o semelhantes. a
O tempo de avaliacao de uma express o o(e1 , ..., en ) , e uma soma denida in a dutivamente na estrutura da express o e que corresponde a soma dos tempos a ` necess rios a determinacao dos valores a1 , ..., an das express es e1 , ..., en argua ` o mento, mais o tempo necess rio a determinacao do resultado de o(a 1 , ..., an ). a ` Assume-se, neste texto, que o tempo da avaliacao de express es aritm ticas o e ou booleanas b sicas e independente dos argumentos em questao. a
O tempo associado a uma atribuicao x=e e a soma do tempo da determinacao do resultado da express o e com uma constante c= correspondente a a ` associacao desse valor a vari vel x. ` a
Esta simplicac frequente, mas n inteiramente correcta em Mathematica, como se discutir em ao e ao e a ap endice.
64
No exemplo anterior, tem-se, em particular, que o tempo de avaliacao de r*(k+1) e o tempo c r , associado a localizacao do valor de r, mais o tempo ck+1 da determinacao do valor de k+1 (que ` corresponde ao tempo associado a localizacao do valor de k, mais o tempo associado a soma) ` ` mais o tempo c* da determinacao do produto daqueles valores. Como referimos, considera-se que estes tempos s o independentes dos valores de k de r. Mais ainda, considera-se tamb m que a e a atribuicao r=r*(k+1) demora um tempo c= , tamb m independente do valor da express o e a r*(k+1). A constante c4 da tabela e, portanto, c4 = cr + ck+1 + c* + c= . Sendo n o valor da vari vel n conclui-se nalmente que o algorimo anterior demora um tempo a TsomaNat (n) = c1 + c2 + c3 (n + 1) + c4 n + c5 n = k1 + k2 n, a que corresponde um comportamento assimpt tico linear. Ou seja: TsomaNat = Q(ln.n). o
5.3 Funcoes
A invocacao de uma funcao levanta algumas quest es que se referem de seguida. Considere-se o a funcao somaNaturais correspondente ao algoritmo j apresentado: a
O tempo associado a determinacao da express o somaNaturais[arg] e determinado co` a mo se segue: Em primeiro lugar h que determinar o valor da express o argumento arg, a a o que demora Targ . Seja a este valor. Depois h que localizar a funcao somaNaturais, a associar o par metro n ao valor a da express o argumento e criar as vari veis locais r e a a a k. Seja cinv a constante correspondente a soma dos tempos associados a estas actividades ` (e independente do valor a da express o argumento). Posto isto, h que executar o corpo a a da funcao, que e o algoritmo j referido (com n associado a a), seguido da avaliacao de a r. Seja TsomaNat (a) o tempo associado ao algoritmo da determinacao da soma e c res a cons tante associada a avaliacao da vari vel do resultado. Tem-se que avaliacao de somaNatu` a rais[arg] demora TsomaNaturais (a) = Targ + cinv + TsomaNat (a) + cres . O tempo Targ depende da express o argumento em quest o. No caso da invocacao somaNaturais[m], com m a a uma vari vel com valor m teremos que Targ e constante e independente do valor de m pelo que a TsomaNaturais (m) = c + cinv + TsomaNat (m) + cres = a1 + a2 m e linear em m. No caso da invocacao somaNaturais[somaNaturais[m]] vir agora Targ (m) = k1 +k2 m e, notando que o valor a do argumento da invocacao exterior e o valor de somaNaturais[m]= m i = m(m+1) , vir a i=1 2 m m TsomaNaturais (m) = Targ (m) + cinv + TsomaNat (i=1 i) + cres = k1 + k2 m + cinv + k1 + k2 (i=1 i) + cres = a + bm + cm2 , ou seja, um comportamento quadr tico em m. a
65
A determinacao do tempo associado a invocacao f[exp1,...,expn] e ` T = Targ + cinv + Tcor po onde Targ e o tempo associado a determinacao dos valores das express os ` a argumento, Tcor po o tempo associado a execucao do corpo da funcao (e que ` depende, em geral, dos valores daqueles argumentos) e c inv e uma constante associada a invocacao da funcao. `
Note-se que T (m) = c1 + T (m - 1) = 2 c1 + T (m - 2) = i c1 + T (m - i). Para i = m vem T (m) = m c1 + T (0). Temos assim que T = Q(lm.m) o que indica um comportamento assimpt tico do mesmo tipo que a vers o imperativa (linear). o a
Profundidade de Recurs ao
A profundidade de recurs o corresponde ao n mero de invocacoes de uma funcao recursiva que a u est o pendentes. Por exemplo, a determinacao de somaNaturais[3] necessita de somaNaa turais[2] que necessita de somaNaturais[1] que necessita de somaNaturais[0]. 66
Assim, quando se invoca somaNaturais[0] est o pendentes 4 invocacoes (incluindo soa maNaturais[0]), o que signica uma profundidade de recurs o de 4. A invocacao de a 2 somaNaturais[n] implica uma profundidade de recurs o de n + 1. Por omiss o, o sisa a tema Mathematica dene 256 como a profundidade m xima de recurs o: a a
somaNaturaisRecursiva = Function[n, If[n == 0, 0, n + somaNaturaisRecursiva[n 1]]] Function[n, If[n == 0, 0, n + somaNaturaisRecursiva[n 1]]] somaNaturaisRecursiva[253] 32131 somaNaturaisRecursiva[254]
E, no entanto, possvel alterar este valor. Sugere-se o encapsulamento din amico da vari vel a $RecursionLimit, num comando Block. O encapsulamento din mico signica encapsua lamento no tempo, ou seja, que os novos valores das vari veis no corpo de Block s lhes est o a o a atribudos durante a execucao do corpo de Block. No nal da execucao estas vari veis voltam a a ter os valores que lhes estavam atribudos antes da execucao do corpo de Block.
Block[{$RecursionLimit = }, somaNaturaisRecursiva[254]] 32385
67
0.8
0.6
0.4
0.2
2500
5000
7500
10000
12500
15000
17500
Nota: as estrelas correspondem ao tempo de execucao da vers o recursiva e os losangos ao da a vers o imperativa. a
5.6 Listas
Na sequ ncia ser estudado o comportamento assimpt tico de funcoes com argumento e resule a o tado em listas. O sistema Mathematica e implementado internamente em C e, em particular, as listas s o implementadas sobre vectores em C. Isto signica que as operacoes com resultado a em listas criam um novo vector, que representa a lista resultado. Desta forma as operacoes com resultado em listas dependem (pelo menos) linearmente do comprimento da lista criada.
68
Construcao O tempo associado as operacoes que constroem listas (Table, Prepend, Append, In sert, ...) depende linearmente do comprimento da lista resultado. Assim o tempo associado a determinacao da express o Table[i, i,1,N ] que dene uma lista de comprimento N e ` a linear em N. Sendo L o comprimento da lista guardada em l, o tempo associado a determinacao das ex` press es Prepend[l,5], Append[l,5] e Insert[l,1,5] dependem linearmente de o L + 1. Eliminacao de elementos O tempo associado as operacoes que eliminam elementos depende linearmente do comprimento ` da lista resultado. Assim, sendo L o comprimento da lista l, a operacao Rest[l] depende linearmente de L - 1. O mesmo e verdade para Drop[l,-1]. Outros casos ser o referidos a quando necess rio. a Atribuicao A atribuicao a uma vari vel de uma lista j construda e independente do comprimento dessa a a lista. Por exemplo, a atribuicao l=l1 e constante e independente da lista guardada em l1. Comparacao de listas
Como se referiu, em casos mais complexos, h que determinar o tempo de execucao total coa mo a soma dos tempos envolvidos na determinacao das v rias parcelas. Assim, por exem a plo, sendo L1 o comprimento da lista associada a vari vel , o tempo associado a atribuicao ` a ` l1=Prepend[Table[i, i,1,N ],First[Rest[l1]]] e a soma TRest +cFirst +TT able + TPrepend + c= = [a + b(L1 - 1)] + cFirst + [a + b N] + [a + b (N + 1)] + c= . Este tempo depende linearmente quer de N quer de L.
supremo=Function[l,Module[ r,k,comp , r=-Infinity; k=0; comp=Length[l]; cLength While[k!=comp, c4 If[r>l[[k+1]],r=l[[k+1]]] ; c5 ou c5 + c6 k=k+1]; c7 r]] c8
TE cinv c2 c3
# 1 1 1 1 L+1 L L 1
N o h diculdade em preencher o quadro anterior, recordando que o tempo associado a dea a ` terminacao do comprimento da lista cLength e independente do comprimento desta. A guarda do While e testada L + 1 vezes. Quanto ao If[ ] h sempre que testar a condicao (o a que demora c5 ). Consoante a condicao seja verdadeira ou falsa haver ou n o que executar a a r=l[[k+1]]. O tempo desta atribuicao e independente do comprimento da lista, pois, como referimos, o acesso aos elementos e directo. Assim, a execucao do If demora ou c 5 ou c5 + c6 . A an lise desta quest o e abordada de seguida. a a Melhor e pior casos As duas possibilidades de execucao do If levam a considerar dois casos: o melhor caso, em que o mnimo e o primeiro elemento da lista e, portanto, a execucao do If demora sempre c5 ; e o pior caso em que o mnimo e o ultimo elemento da lista, e, portanto, a execucao do If demora sempre c5 +c6 . (Considera-se que a lista e n o vazia, j que o que se pretende e entender a a o comportamento do algoritmo para listas com muitos elementos). Tem-se, para estes casos:
melhor Tsup (L) = cinv + c2 + c3 + cLength + c4 (L + 1) + c5 L + c7 L + c8 = k + k L
Como em ambos os casos o comportamento e linear, conclui-se que o comportamento as simpt tico de Tsup e sempre linear, ou seja o
melhor pior Tsup = Tsup = Tsup = Q(lL.L)
70
TE cinv c2 c3 c4 c5 ou c5 + c6 c7 LRl p + c 7 c8
# 1 1 1 L+1 L L 1
Nota-se que o tempo de execucao da atribuicao lp=l e considerado constante e independente do comprimento da lista l e que o tempo de execucao do teste Length[lp] != 0 e, tamb m, e independente de lp (pois o tempo da determinacao de Length[lp] e independente de lp). O tempo de execucao do teste r>First[lp] e tamb m constante, pois o acesso ao primeiro e elemento n o depende do comprimento da lista. a Finalmente, a diferenca importante relativamente a solucao anterior e a determinacao da ex ` press o Rest[lp] na atribuicao lp=Rest[lp]. A determinacao de Rest[lp] correspona de a construcao de uma nova lista para que e necess rio um tempo linear no comprimento L Rl p ` a de Rest[lp]. Este comprimento varia entre L - 1 na primeira iteracao e 1 - 1 na ultima. Tem-se assim
melhor Tsup (L) = cinv + c2 + c3 + c4 (L + 1) + c5 L + (c7 LRl p + c ) + c8 7 L-1 LRl p =0
c ) 7
LRl p =0
melhor Desta forma Tsup (L) = k + k L + k L2 tem um comportamento quadr tico em L: a melhor Tsup = Q(lL.L2 )
= c7 LRl p +
L-1 LRl p =0
O pior caso e semelhante e assim esta vers o da funcao supremo e quadr tica em L. a a Claramente a solucao anterior e melhor em termos de eci ncia. No gr co seguinte comparam e a se os tempos de execucao (em segundos) das duas vers es do supremo para listas entre 1000 o e 14 000 elementos, ordenados por ordem crescente (pior caso). As estrelas correspondem a ` vers o quadr tica (progresso em listas) e os losangos a vers o linear (progresso em ndice). a a ` a
c 7
LRl p =0
1 = c7
L-1
(L - 1)(L) + c L 7 2
71
2000
4000
6000
8000
10000
12000
14000
A determinacao do comportamento assimpt tico desta funcao passa tamb m pelo comporta o e mento no melhor e pior casos, que se denem em termos do comprimento L da lista argumento. Melhor caso
melhor Para o melhor caso temos Tsup1 (0) = c0 , onde c0 inclui a invocacao da funcao, o teste da melhor guarda, e a determinacao da express o correspondente. Para L 0 vem Tsup1 (L) = cinv + a melhor cl==={} + cFirst[l] + [a + b(L - 1)] + Tsup1 (L - 1) + c> + cFirst[l] . O termo [a + b(L - 1)] vem de se melhor determinar Rest[l] e o termo Tsup1 (L - 1) vem da determinacao do supremo de Rest[l]. Em resumo: melhor Tsup1 (L) = ;
c0 se L = 0 melhor c1 + c2 L + Tsup1 (L - 1) se L 0
Fazendo i = L vir a
L-1
Ou seja:
L(L - 1) 2
E importante notar que comportamento quadr tico para o melhor caso vem da determinacao de a Rest[l]. Pior Caso Quanto ao pior caso vir Tsup1 (0) = c0 mas, para L 0, tem-se agora a Tsup1 (L) = cinv +cl==={} +cFirst[l] +aRest +bRest (L-1)+Tsup1 (L-1)+c> +aRest +bRest (L-1)+Tsup1 (L-1) ou seja Tsup1 (L) = ;
pior pior pior pior pior pior
c0 se L = 0 pior c1 + c2 L + 2Tsup1 (L - 1) se L 0
A solucao (iterativa) desta recorr ncia e: e Tsup1 (L) = c1 + c2 L + 2Tsup1 (L - 1) = c1 + c2 L + 2c1 + 2c2 (L - 1) + 4Tsup1 (L - 2) = ... e assim
pior Tsup1 (L) pior pior
Ou seja:
= 2 c1 + 2k c2 (L - k) + 2i Tsup1 (L - i)
i-1 i-1 k pior k=0 k=0
Tsup1 = Q(lL.2L )
pior
Esta situacao e catastr ca em termos de eci ncia e decorre do facto de se determinar duas o e vezes o supremo1[Rest[l]]. Dada a diferenca fundamental entre o melhor e pior casos, seria importante vericar qual o caso m dio. N o o faremos aqui (n o e difcil vericar que e do e a a mesmo tipo do pior caso). O que nos interessa e encontrar solucoes melhores para esta quest o. a 73
Solucao quadr tica a Nesta solucao evita-se a dupla avaliacao de supremo[Rest[l]] guardando este resultado numa vari vel auxiliar. a
supremo2 = Function[l, Module[{s}, If[l == {}, -Infinity, s = supremo2[Rest[l]]; If[First[l] > s, First[l], s]]]]
c0 se L = 0 pior c1 + c2 L + Tsup2 (L - 1) se L 0
pelo que a nova solucao e sempre quadr tica em L. (O melhor caso e semelhante). a De qualquer forma existe ainda uma diferenca importante face a primeira vers o imperativa, ` a que era linear em L. Como se referiu n o h necessariamente diferenca essencial entre o coma a portamento assimpt tico das vers es recursivas e imperativas, pelo que a diferenca agora notada o o dever ter outra causa. Como j se referiu a causa e o facto de se utilizar progresso em listas, a a ou seja porque se determina Rest[l]. E, no entanto, possvel escrever vers es recursivas da funcao supremo, percorrendo a lista com o um ndice, em vez de a percorrer usando Rest[l]. Solucao linear A solucao linear evita a avaliacao de Rest[l] porque considera uma representacao das listas semelhante a que j se apresentou com vectores em C. Assim, a lista original l e associado um ` a ` incio e um m, o que permite representar Rest[l] como sendo a mesma lista, mas com o incio adiantado de 1. A nova solucao utiliza uma funcao auxiliar que progride no incio da lista original.
supremo3 = Function[l, Module[{auxsupremo}, auxsupremo = Function[{incio, fim}, Module[{s}, If[incio == fim + 1, -Infinity, s = auxsupremo[incio + 1, fim]; If[l[[incio]] > s, l[[incio]], s]]]]; auxsupremo[1, Length[l]]]]
Para esta solucao Tsup3 (L) = cinv + caux... + Tauxsupremo(1,L) , onde caux... refere a constante relativa a ` atribuicao do nome auxsupremo a funcao correspondente. ` Quanto a Tauxsupremo(1,l) e f cil vericar que o seu tempo de execucao depende da diferenca a fim+1-incio (com incio=1 e fim=L) e facilmente se chega a
pior
pior
pior
74
A solucao desta recorr ncia j foi apresentada a prop sito da funcao somaNaturais e obt m e a o e pior pior pior pior se Tauxsupremo (L) = k0 + k1 L. Recordando que Tsup3 (L) = cinv + caux.. + Tauxsupremo (L) vir Tsup3 (L) = a k0 + k1 L, ou seja, como se pretendia, linear em L. O melhor caso e semelhante e omite-se. Comparacao entre a solucao linear e a quadr tica a No gr co seguinte mostram-se os tempos de execucao (em segundos) dos piores casos das a solucoes linear e quadr tica para listas entre 100 e 8 000 elementos. a
5 4 3 2 1 2000 4000 6000 8000
c0 se L = 0 pior c1 + Tauxsupremo (L - 1) se L 0
Comparacao entre as solucoes lineares recursiva e imperativa No gr co seguinte mostram-se os tempos de execucao (em segundos) dos piores casos das a solucoes lineares recursiva e imperativa para listas entre 100 e 14 000 elementos. Como se espera, embora do mesmo tipo, a solucao imperativa e mais r pida que a recursiva. a
3.5 3 2.5 2 1.5 1 0.5
2000
4000
6000
8000
10000
12000
14000
a lista {4, 3, 2, 1} pode utilizar-se a lista (de listas) {4, {3, {2, {1, {}}}}}. Desta forma cada lista (` a excepcao da lista vazia) tem dois elementos: o valor e a lista restante. A funcao seguinte determina o supremo de uma lista (nesta representacao) em tempo linear (no n mero de elementos a percorrer): u
supremo=Function[ll,Module[ s ,If[ll=== , -Infinity, s=supremo[ll[[2]]]; If[s>ll[[1]],s,ll[[1]]]]]]
No gr co seguinte apresentam-se os tempos de execucao da funcao anterior para o pior caso da a determinacao do supremo de listas (na representacao referida) contendo at 15.000 elementos: e
5.6.6 Pesquisa
No caso da pesquisa h duas situacoes a ter em consideracao: determina-se o tempo quando a a pesquisa tem sucesso e o tempo quando a pesquisa n o tem sucesso. a Sucesso Comecemos pela primeira situacao. Como o tempo de execucao depende da posicao em que se encontrar o elemento x que se pesquisa, vamos determin -lo assumindo que a posicao em que a se encontra (primeiro) o elemento x e a posicao i (com 1 i L). Temos assim:
TE pesquisa=Function[ l,x ,Module[ r,k,comp , cinv r=False; c2 k=0; c3 comp=Length[l]; k1 While[k!=comp && Not[r], c4 r= (l[[k+1]]==x) ; c5 k=k+1]; c6 r]] c7
76
N o e difcil vericar que o n mero de vezes N(i) que e executada a guarda do While e N(i) = a u i + 1. Temos assim Tpesq (L, i) = a + bi. Melhor e pior casos No melhor caso (i = 1) vir Tpesq (L) = a . No pior caso (i = L) vir Tpesq (L) = a + bL. a melhor a pior Conclumos que o comportamento assimpt tico no pior caso e linear em L e que no melhor caso o e constante. Vale assim a pena determinar o caso m dio. e Caso m dio e O caso m dio corresponde a m dia dos tempos de execucao para as diversas listas de come ` e primento L. Se n o existe informacao adicional sobre a distribuicao dos elementos da lista, a o elemento a pesquisar pode estar em qualquer posicao, sem que se prera uma a outra. Isto signica que a probabilidade de x se encontrar numa posicao i e igual a de se encontrar numa ` outra i . Temos portanto que esta probabilidade e p(i) = 1/ L. A m dia dos tempos e e Tpesq (L) = Tpesq (L, i) p(i) =
L L i=1 i=1 L
Tpesq (L, i) L
Tem-se assim:
L
Conclui-se que o tempo deste algoritmo de pesquisa e, em m dia, linear em L: e Tpesq = Q(lL.L) Insucesso
O caso de o elemento n o se encontrar na lista e exactamente o pior caso analisado anteriora mente, e, portanto, linear em L.
Como j vimos, por raz es de eci ncia, e conveniente representar a recurs o por interm dio a o e a e de ndices representando o incio e o m da lista argumento. E essa a solucao que utilizaremos:
pesquisa2 = Function[{l, x}, Module[{auxpesquisa}, auxpesquisa = Function[{incio, fim}, If[incio == fim + 1, False, Or[l[[incio]] == x, auxpesquisa[incio + 1, fim]]]]; auxpesquisa[1, Length[l]]]]
Sucesso Omite-se o estudo do melhor e pior casos. O caso m dio e analisado de seguida. e
i Primeira solucao A primeira solucao corresponde a considerar os tempos Tpesq (L) correspon dentes a execucao da funcao pesquisa, sabendo que o elemento x se encontra na posicao i da ` lista argumento (a lista n o pode ser vazia, neste caso). a i i Para tal h que notar primeiro que Tpesq (L) = c + Tauxpesquisa(1,L) (onde a constante c inclui a a invocacao e a atribuicao auxpesquisa = ...). i Quanto a determinacao de Tauxpesquisa(1,L) e conveniente determinar primeiro a express o de ` a i Tauxpesquisa( j,L) com j i. Se i = j, vir a i Tauxpesquisa(i,L) = cinv + c== + c== = c1
pois x encontra-se na posicao inicial. Nota-se que a avaliacao do Or e sequencial, pelo que, se l[[inicio]] == x o resultado e True sem que se tenha de avaliar o segundo argumento do Or. Se j < i vir a
i i i Tauxpesquisa( j,L) = cinv + c== + c== + Tauxpesquisa( j+1,L) = c1 + Tauxpesquisa( j+1,L)
Quando j + k = i vir a
i i Tauxpesquisa( j,L) = (i - j)c1 + Tauxpesquisa(i,L) = (i - j + 1)c1
Portanto
i Tauxpesquisa(1,L) = ic1
Assim
i Tpesq (L) = c + ic1
78
i Finalmente, o valor m dio de Tpesq (L) e a m dia dos diversos Tpesq (L). Recordando que assumie e mos que a probabilidade de x se encontrar em i e 1/ L tem-se L pesq (L) = i=1 (c + ic1 ) = c + c1 (L + 1) T L 2
Desta forma a funcao pesquisa tem um comportamento assimpt tico linear para o caso m dio: o e Tpesq = Q(lL.L) Segunda solucao A segunda solucao e obtida observando que a probabilidade de x se encon trar na primeira posicao e 1/ L e a probabilidade de se encontrar noutra posicao e (L - 1)/ L. Seja 1 Tauxpesquisa (1, L) o tempo da execucao da funcao auxpesquisa quando x se encontra na primeira posicao e T auxpesquisa (1, L) a m dia dos tempos de execucao da funcao auxpesquisa quando e x n o se encontra na primeira posicao. a A m dia dos tempos de execucao ser a soma destes tempos, pesada pelas respectivas probabie a lidades: Tauxpesquisa (1, L) =
1 Tauxpesquisa (1, L)
1 Tem-se que Tauxpesquisa (1, L) = cinv + cI f + c== + cOr = c1 . Por outro lado, T auxpesquisa (1, L) = cinv + cI f + c== + cOr + cinicio+1 + c f im + Tauxpesquisa (2, L) = c2 + Tauxpesquisa (2, L). Ora, o tempo m dio Tauxpesquisa (2, L) de processamento da lista original desde a posicao 2 at a posicao L e e e` id ntico ao tempo m dio de processamento de uma lista de comprimento L - 1. Desta forma, e e T auxpesquisa (1, L) = c2 + Tauxpesquisa (2, L) = c2 + Tauxpesquisa (1, L - 1).
Vem ent o a
c L-1 Tauxpesquisa (1, L) = 1 + (c - 2 + Tauxpesquisa (1, L - 1)) L L que e equivalente a LTauxpesquisa (1, L) = c1 + c2 (L - 1) + (L - 1)Tauxpesquisa (1, L - 1)
Designando f(L) = LTauxpesquisa (1, L) a equacao anterior escreve-se: f(L) = c1 + c2 (L - 1) + f(L - 1) Esta recorr ncia em f resolve-se por iteracao obtendo-se f(L) = a + bL2 . Como f(L) = e LTauxpesquisa (1, L) vir que Tauxpesquisa (1, L) e linear em L. O resto da resolucao e como se aprea sentou na primeira solucao obtendo-se Tpesq = Q(lL.L) Insucesso A situacao de insucesso deixa-se como exerccio. 79
Seja T : IN IR uma func positiva e crescente (em sentido lato) que satisfaz a recorr ao encia T (n) = aT (n/ b) + f (n) (para todo o n n0 ), onde a, b IR+ .
log Se existe e > 0 tal que f = O(ln.nlogb (a)-e ) ent T = Q(ln.n b (a) ) ao
Se f = Q(ln.nlogb (a) ) ent T = Q(ln. log(n) nlogb (a) ) ao 2 Se existe e > 0 tal que f = W(ln.nlogb (a)+e ) e $0c1 <1 $n1 "nn1 a f (n/ b) c f (n) ent T = ao Q(ln. f (n))
A prova deste teorema pode ser encontrada em [2]. No enunciado do teorema anterior pode substituir-se a recorr ncia T (n) = aT (n/ b) + f (n) por T (n) = aT (dn/ bt) + f (n) ou por T (n) = e aT (`n/ bp) + f (n). (Recorda-se que, para x IR + , dxt = max{n IN0 : n x} e que `xp = min{n IN0 : n x}.)
Um elemento arbitr rio x numa lista l (em determinada posicao k), ir ocupar uma posicao nal a a p na lista depois ordenada (posicao essa que depende do seu relacionamento com os outros elementos de l). Assumimos, de acordo com o que se disse acima, que a probabilidade de esta posicao nal p ser uma determinada posicao entre 1 e L (o comprimento de l) e 1/ L. Isto corresponde a armar que todas as posicoes s o equiprov veis, pois n o existe raz o para a a a a preferir uma a outra.
81
O pior caso corresponde a pk+1 = 1 (para todo o k) que signica que o elemento l[[k + 1]] era menor que todos os anteriores e ir ser colocado no incio da lista. Esta situacao corresponde a a ` lista estar ordenada por ordem decrescente. Sendo assim temos
melhor Tins (L)
= c1 + c2 (L + 1) + c3 L + c4 L + c5 1 + c8 L + c9 L = a + bL
L-1 k=1 L-1 L-1
Caso m dio e
Para a an lise do caso m dio utiliza-se o valor m dio de N(k, pk+1 ) = (k + 1 - pk+1 ) + 1, para a e e cada k. Ora pk+1 e a posicao nal do elemento l[[k + 1]] (que vai ser analisado) na sublista da lista original que vai das posicoes 1 at k + 1. N o existe raz o para preferir alguma daquelas e a a posicoes a outra, pelo que existe igual probabilidade de pk+1 ocupar uma das posicoes entre 1 e 1 k + 1. Essa probabilidade e, evidentemente, k+1 . Desta forma o valor m dio de N(k, pk+1 ) = (k + 1 - pk+1 ) + 1 e e (k + 1 - pk+1 ) + 1 1 N(k, pk+1 ) = =k+2N(k) = p k+1 k+1 k + 1 p =1 k+1 p =1 p =1
k+1 k+1 k+1
k+1 k+1 k+1
e assim
N(k) = k + 2 -
1 (k + 2)(k + 1) k + 2 = k+1 2 2
Quanto ao tempo m dio de processamento do algoritmo de insercao directa tem-se e Tins (L) = c1 + c2 (L + 1) + c3 L + c4 L + c5 N(k) + (c6 + c7 ) (N(k) - 1) + c8 L + c9 L
L-1 L-1 k=1 k=1 L-1 L-1
ou seja
82
5.8.2 Quicksort
A vers o deste algoritmo que iremos considerar e a seguinte: a quicksort=Function[l,Module[ x , If[l=== , , x=First[l]; Join[quicksort[Select[l,Function[y,y<x]]], Select[l,Function[y,y==x]], quicksort[Select[l,Function[y,y>x]]]]]]] O estudo da eci ncia deste algoritmo pressup e, por raz es de simplicidade, que n o existem e o o a elementos repetidos na lista original. A quest o mais relevante neste algoritmo e a de determinar qual a relacao entre as sublistas dos a elementos respectivamente estritamente menores e maiores que x. Pior caso A pior situacao corresponde a x ser o mnimo (ou o m ximo) da lista. Nesta situacao a lista a dos elementos estritamente superiores a x ou a lista dos elementos estritamente inferiores a x, tem comprimento L - 1 (se L for o comprimento da lista original). O pior caso corresponde a ` repeticao recursiva desta situacao, ou seja, escolha repetida ou do mnimo ou do m ximo das a listas que s o recursivamente argumento da funcao quicksort. a Considerando que determinacao de cada Select e linear em L, que a juncao destas tr s listas e tem comprimento L e que, portanto, a determinacao de Join e tamb m linear em L vem (para e L 0):
pior pior pior
A solucao desta recorr ncia tem como resultado Tquick = Q(lL.L2 ). e Melhor caso Quanto ao melhor caso e obtido quando (recursivamente) se divide a lista original em duas, ou seja quando o elemento escolhido e recursivamente a mediana da lista em quest o. a Tem-se
melhor melhor melhor Tquick (L) = cinv + c=== + c= + TSelects + Tquick (d(L - 1)/ 2t) + Tquick (`(L - 1)/ 2p) + TJoin
].
melhor Recorrendo ao teorema principal obt m-se Tquick = Q(lL.L log2 (L)). e
Caso M dio e Para o caso m dio consideramos as diversas possibilidades de comparacao do elemento escoe lhido x com os outros elementos da lista. Estas possibilidades s o caracterizadas por um ndice 5 a i que indica quantos elementos s o menores ou iguais a x na lista argumento (recorda-se que a assumimos serem todos distintos). Claramente 1 i L e qualquer destas L situacoes e equiprov vel. Fixado um i, o tempo a i Tquick (L) da execucao desta funcao e, assim, cinv + c=== + c= mais o tempo da determinacao dos v rios Select, mais o tempo da determinacao da funcao quicksort em listas de comprimento a i - 1 (dos menores que x) e L - i (dos maiores que x) mais o tempo de Join. Em m dia o e tempo da determinacao da funcao quicksort em listas de comprimento i - 1 e L - i e Tquick (i - 1) e Tquick (L - i) respectivamente, pelo que, xado i o tempo m dio de execucao e, Tquick (L) = e i cinv + c=== + c= + a + bL + Tquick (i - 1) + Tquick (L - i), onde o termo a + bL e a soma da contribuicao dos tempos dos v rios Select e do Join. a Finalmente, o tempo m dio de execucao da funcao quicksort e a m dia dos tempos (m dios) e e e para cada i, ou seja: Tquick (L) =
L i=1
Tquick (i - 1) + Tquick (L - i) + a + bL L
Tquick (i-1)+Tquick (L-i) L
A ultima igualdade decorre de o segundo somat rio ser igual ao primeiro o o que se pode concluir com a mudanca de vari vel k = L - i + 1 (e trocando a ordem dos termos a somados). Temos assim Tquick (L) = a + bL + 2
L i=1
= a + bL + L i=1
Tquick (i-1) L
+ L i=1
Tquick (L-i) L
Tquick (i - 1) L
Para L - 1 vir a
Tquick (L - 1) = a + b(L - 1) +
2 = a + bL + Tquick (i - 1) L i=1
L
Multiplicando a primeira igualdade por L e a segunda por L - 1 obt m-se e LTquick (L)-(L-1)Tquick (L-1) = (a+bL)L-(a+b(L-1))(L-1)+2( Tquick (i-1)- Tquick (i-1))
L L-1 i=1 i=1
2 T (i - 1) L - 1 i=1 quick
L-1
o que implica
A estat stica de ordem i de x em l a posic de x em l depois de l ser ordenada. Assim i - 1 e indica quantos e ao elementos de l s menores que x. O ao ndice i referido precisamente esta estat e stica.
5
84
e ainda LTquick (L) - (L + 1)Tquick (L - 1) = (a + bL)L - (a + b(L - 1))(L - 1) = a + b + 2bL Dividindo por L(L + 1) obt m-se e Tquick (L) L+1 Designando
Tquick (L) L+1
Tquick (L - 1) L
a + b + 2bL L(L + 1)
a + b + 2b(L - i) (L - i)(L - i + 1)
O integral tem como solucao ((a + b)ln(x) + (b - a)ln(x + 1))|L que e Q(lL.ln(L)). 1 Como f(L) = tem-se nalmente6 Tquick = Q(lL.L log2 (L))
5.8.3 MergeSort
Recorda-se a funcao que ordena por fus o bin ria e que depende da funcao combina. a a ordena=Function[l,Module[ m , If[Length[l]<=1,l, m=Quotient[Length[l]+1,2]; combina[ordena[Take[l,m]],ordena[Drop[l,m]]]]]] Tem-se para o tempo de execucao desta funcao (passo) Tmerge (L) = cinv + c= + a + bL + Tmerge (dL + 1/ 2t) + T (L - dL + 1/ 2t) + Tcombina (L)
a relac entre logaritmos de bases distintas. ao
6 Recorde
85
onde o termo a + bL decorre da determinacao de Take e Drop. A equacao que nos interessar a e Tmerge (L) a + bL + 2Tmerge (dL/ 2t) + Tcombina (L) A depend ncia da funcao combina e fundamental. Uma vers o j apresentada e a seguinte: e a a combina=Function[ l1,l2 , If[l1=== ,l2, If[l2=== ,l1, If[First[l1]<First[l2], Prepend[combina[Rest[l1],l2],First[l1]], Prepend[combina[l1,Rest[l2]],First[l2]]]]]] A funcao combina depende dos comprimentos L1 e L2 das listas argumentos e tem-se (no passo): Tcombina (L1 + L2 ) = cinv + c=== + c=== + c< + a + b(L1 + L2 ) + Tcombina (L1 + L2 - 1) onde o termo a + b(L1 + L2 ) tem duas contribuicoes: a determinacao de Rest (que constr i o uma lista de comprimento L1 - 1 ou L2 - 1) e a determinacao de Prepend que constr i uma o lista de comprimento L1 + L2 - 1 + 1. Designando L = L1 + L2 tem-se Tcombina (L) = a + b L + Tcombina (L - 1) Esta recorr ncia tem uma solucao quadr tica em L. Desta forma, com esta solucao, vir para e a a a funcao ordena Tmerge (L) = 2T (L/ 2) + a1 + b1 L + c1 L2 com solucao quadr tica (pelo teorema a principal). Importante E, no entanto, importante notar que n o e difcil encontrar uma funcao combina, com dea pend ncia linear em L1 + L2 (com inspiracao na vers o C desta funcao). e a Nesse caso para a funcao ordena ter-se- Tmerge (L) 2Tmerge (L/ 2) + a + b L, com solucao em a Tmerge = Q(lL.L log2 (L)) (tamb m pelo teorema principal). e A funcao combina alternativa apresenta-se de seguida. Na nova vers o utiliza-se uma funcao a recursiva combinaaux que percorre as duas listas a combinar utilizando ndices de nicio e m para cada uma delas. Esta funcao altera colateralmente uma lista lr que, inicialmente, e preenchida a zeros, e que, no nal, conter o resultado da combinacao. a Em cada invocacao de combinaaux e preenchida uma posicao de lr. A posicao a preencher e dada pelo ultimo argumento (o), que e o ndice onde se coloca o valor agora determinado. O caso base da execucao de combinaaux corresponde a uma das duas listas originais ter sido totalmente processada faltando acrescentar os elementos da outra.
86
combina = Function[{l1, l2}, Module[{lr, combinaaux}, combinaaux = Function[{i1, w1, f1, i2, w2, f2, o}, If[i1 f1 && i2 f2, If[w1[[i1]] w2[[i2]], lr[[o]] = w1[[i1]]; combinaaux[i1 + 1, w1, f1, i2, w2, f2, o + 1], lr[[o]] = w2[[i2]]; combinaaux[i1, w1, f1, i2 + 1, w2, f2, o + 1]], lr = Join[Take[lr, o 1], Take[l1, {i1, f1}], Take[l2, {i2, f2}]]]]; lr = Table[0, {i, 1, Length[l1] + Length[l2]}]; combinaaux[1, l1, Length[l1], 1, l2, Length[l2], 1]; lr]]
E importante notar que, na funcao anterior, al m de se percorrerem as listas argumento por e interm dio de ndices, tamb m se percorre a lista resultado com um ndice o. Uma solucao ale e ternativa que seria comecar com lr= e executar em cada passo da recurs o Append do valor a conveniente levaria tamb m a uma solucao quadr tica (porque o comportamento assimpt tico e a o desta operacao Append e linear no comprimento da lista resultado). Na gura seguinte encontra-se o gr co dos tempos de processamento da combinacao de duas a listas iguais (o que corresponde ao pior caso), de comprimentos em absissas.
10 8 6 4 2 5000 10000 15000
87
Pesquisa funcional
Uma vers o funcional da pesquisa em listas e a funcao seguinte, onde, numa primeira fase se a constr i a lista Map[Function[y, y == x], la] que, em cada posicao tem ou True o ou False consoante o elemento da lista argumento la, na mesma posicao, e igual ou n o ao a valor de x. O resultado e a disjuncao (Or) destes valores l gicos. o
pesquisaF = Function[la, x, Apply[Or, Map[Function[y, y == x], la]]]
O comportamento assimpt tico desta funcao e linear no comprimento da lista original pois o inclui a construcao da lista Map[Function[y, y == x], la]. Tamb m a determinacao e da disjuncao destes valores e, no pior caso de serem todos False, linear. Veremos, de seguida, como o tempo de execucao desta funcao compara com o tempo de execucao das vers es imperativa e recursiva seguintes: o
pesquisaI = Function[{la, x}, Module[{r, i}, r = False; i = 0; While[i < Length[la] && !r, r = (la[[i + 1]] == x); i = i + 1]; r]] pesquisaR = Function[{l, x}, Module[{auxpesquisa}, auxpesquisa = Function[{inicio, l, fim}, If[inicio == fim + 1, False, Or[l[[inicio]] == x, auxpesquisa[inicio + 1, l, fim]]]]; auxpesquisa[1, l, Length[l]]]]
No gr co seguinte apresentam-se os tempos de execucao destas tr s funcoes, no pior caso, a e para listas de comprimento at 20.000: e
88
Os losangos correspondem a vers o recursiva, as estrelas a imperativa e os quadrados corres` a ` pondem a vers o funcional da pesquisa. ` a No gr co seguinte incluiu-se tamb m os tempos de execucao da funcao pr -denida Mema e e berQ:
1.75 1.5 1.25 1 0.75 0.5 0.25 5000 10000 15000
89