Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Evaluación Perezosa

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 15

TEMA: EVALUACION PEREZOSA

ALUMNO: LUIS ENRIQUE VAZQUEZ JUAREZ


DOCENTE: EFREN VEGA

EVALUACIN PEREZOSA
Comencemos la evaluacin de la expresin cuadrado (3 + 4).
La secuencia de reduccin es:
Cuadrado (3+4)
= {definicin de +}
Cuadrado 7
= {definicin de cuadrado}
7 x7
= {definicin de c}
49
Otra opcin
Cuadrado (3 + 4)
= {definicin de cuadrado}
(3 + 4) x (3 + 4)
= {definicin de +}
7 x (3 + 4)
= {definicin de +}
7x7
= {definicin de x}
49
Estas ilustran las estrategias de reduccin, llamadas respectivamente ms interna
y ms externa.
Otro ejemplo:
Fst (cuadrado 4, cuadrado 2)
= {definicin de cuadrado}
Fst (4 x 4, cuadrado 2)
= {definicin de x}
Fst (16, cuadrado 2)
= {definicin de cuadrado}
Fst (16, 2 x 2)
= {definicin de x}
Fst (16,4)
= {definicin de fst}
16
La estrategia de reduccin ms externa para la misma expresin produce

Fst (cuadrado 4, cuadrado 2)


= {definicin de fst}
Cuadrado 4
= {definicin de cuadrado}
4x4
= {definicin de x}
16
Las dos estrategias de reduccin tienen caractersticas diferentes.
Sin embargo, si ambos mtodos terminan, entonces darn el mismo resultado.
La reduccin ms externa tiene la propiedad importante de que si una reduccin
tiene forma normal, entonces la reduccin ms externa la encontrara. La reduccin
ms externa tambin se llama orden normal.
La reduccin ms externa a veces puede necesitar ms pasos que la reduccin
ms interna.
La diferencia entre la reduccin ms externa y la ms interna puede hacerse
arbitrariamente grande.
Se puede resolver este problema representando las expresiones como grafos en
lugar de como rboles.

Representa la expresin (3 + 4) x (3 + 4). Cada aparicin de 3 + 4 se representa


mediante una flecha, llamada puntero, a una nica aparicin de (3 + 4).

La representacin de expresiones mediante grafos significa que se puede


compartir y reducir mximo una vez las subexpresiones duplicadas. A la reduccin
ms externa de grafos, evaluacin perezosa, y a la reduccin de grafos ms
interna como evaluacin impaciente.
La evaluacin perezosa tiene dos propiedades:
1.- Termina siempre que cualquier otro orden de reduccin termine
2.- no requiere ms (sino posiblemente menos) pasos que la evaluacin
impaciente.
En particular, el nmero de pasos de redaccin no se corresponde exactamente
con el tiempo que transcurre desde que se somete a evaluacin una expresin
hasta que se obtiene el resultado.
Dado que las expresiones pueden ser arbitrariamente grandes, no se puede
suponer que este tiempo de bsqueda sea constante. No se tiene en cuenta el
proceso de impresin.
Para imprimir la lista [11000] no se necesitan 1000 unidades de espacio,
supongamos que definimos.
Numero = [11000]
El espacio no se puede desechar despus, una consecuencia de la evaluacin
perezosa es que ninguna expresin al final de una flecha se evale ms de una
vez, el espacio ocupado por un guion puede crecer con las evaluaciones repetidas
de las funciones que contiene.

ESTUDIO ASINTTICO DEL COSTE


Estamos menos interesados en estimar el coste de evaluar una expresin
particular que en comparar las diferencias de eficiencia de una definicin de
funcin con respecto a otra.
Ejemplo:
Reverse [ ] = [ ]
Reverse (x: xs) = reverse xs ++ [x]
Reverse = foldl prefijar [] where prefijar xs x = x: xs
El objetico de esta seccin es mostrar cmo se pueden hacer ms precisas tales
afirmaciones y cmo justificarlas.
LA NOTACIN-O
Ha llegado el momento de remplazarla por algo ms breve.

Dadas 2 funciones f y g sobre nmeros naturales, decimos que f est en el orden


de2 g, o que f es 0 (g), y lo que escribimos f = 0(g), si existe una constante positiva
C y un nmero natural no tales que f(n) <= Cg(n) para todo n >= no
Si bien escribimos f = 0(g), realmente no queremos decir que f es igual a 0(g). Es
mejor pensar que 0(g), considerado aisladamente en la parte derecha de una
ecuacin.

Diremos que f est en el orden de al menos g, o que f es (g), y lo que


escribiremos f = (g) y lo escribiremos f = (g), si existe una constante positiva C
y un nmero no tales que f(n) >= cg(n) para todo n>= no.
ANALISIS DE TIEMPO
Dada la funcin f escribiremos T(f) (n). para denotar una estimacin asintonica del
numero de pasos de reduccin requeridos en el peor caso para evaluar f sobre un
argumento de tamao n.
Ejemplo:
T (reverse) (n) = (n*n)
T (reverse) (n) = (n)
La definicin T requiere alguna extensin, T (f) se refiere a la complejidad de una
definicin nada de f. El coste de evaluar xs ++ ys se mide en trminos de m y n,
siendo m = length y n = length ys.
El caso simple en el que xss es una lista de longitud m compuesta de listas todas
ellas de longitud n, tenemos.
T (concat) (m, n) = (mn)
La tercera observacin consiste en destacar que T (f) (n) es exclusivamente una
estimacin para el caso de peor tiempo de ejecucin.
La cuarta crucial observacin es que T (f) (n) determinada bajo un modelo
impaciente de evaluacin
Minlist = head * ordenar
Bajo evaluacin impaciente.
T (minilist) (n) = T (ordenar) (n) + T (head) (n)
FUNCIONES REVERSE Y CONCAT
Analicemos ahora el programa para reverse.
T (reverse) (0) = 0 (1)
T (reverse) (n + 1) = T (reverse) (n) + T (++) (n, 1)

La ecuacin recursiva T(reverse) es simple de resolver. Utilizando la estimacin


T(++)(n,m) = 0(n) obtenemos.

Acum tiene 2 argumentos denotado por m y n


T (acum) (m, 0) = 0(1)
T (acum) (m, n + 1) = 0(1) + T (acum) (m, n)
La funcin concat se puede definir directamente
Concat [ ] = [ ]
Concat (xs: xss) = xs ++ concat xss
Es exactamente la que obtendramos a partir de la definicin concat = flodr (++)
eliminado la llamada a flodr. Eliminando flodl de reverse obtemos.
Concat xss = acum [] xss
Acum ws [ ] = wss
Acum ws (xs: xss) = acum (ws ++ xs) xss
PARAMETROS ACUMULADORES
A veces podemos mejorar el tiempo de ejecucin aadiendo un parmetro
adicional a una funcin. Se aade un parmetro adicional a una funcin
revConcat :: [] -> [] -> []
revConcat xs ys = reverse xs ++ ys
Tambin pueden ser definidos en reverse en trminos de revConcat.
revConcat [] ys = ys
revConcat (x: xs) ys = revConcat xs (x: ys)
De modo equivalente, revConcat = foldr f, siendo f x g = g * (x:).
(++) = flodr consPunto id where consPunto x g = (x:) * g
Podemos argumentar que
Reverse xs
= {dado que [] es el nmero neutro de ++}
(++) (reverse xs)[]
= {Expresin anterior de ++}
(flodr consPunto id (reverse xs)) []
= {tercer teorema de dualidad}
Flodl (flip consPunto) id xs []

Aplanando un rbol binario


Aplanar xt = apConcat xt [] lo cual para apConcat nos da
apConcat (Hoja x) xs = x:xs
apConcat (Unir xt yt) xs = apConcat xt (apConcat yt xs)
Comparemos ahora los tiempos de ejecucin de aplanar y apConcat.
T (aplanar) (0) = 0(1)
T (aplanar) (h+1) = 2T (aplanar) (h) + T (++) (2h, 2 h)
Esta ecuacin satisface porque los 2 subrboles de un rbol binario.
RECORRIDO EN PROFUNDIDAD
Se puede aplicar exactamente la misma tcnica a la funcin aplicar de las
rasadelfas.
Sea T(aplanar) (h, k) la estimacin de tiempo necesario para aplanar un rbol kario perfecto de altura (h+1)
S(h,k) = (k h+1 -1) / (k - 1) = (kh)
Donde s = s (h, k). El termino T (map aplanar) (h, k) estima el tiempo de ejecucin
de map aplanar sobre una lista de k rboles de altura h.
TUPLAMIENTO.
La tcnica de optimacin de programas conocida como tuplamiento , es dual de la
de los parmetros acumuladores: se generaliza una funcin no incluyendo un
argumento extra sino incluyendo un resultado adicional.
Se generaliza una funcin, no incluyendo un argumento extra, sino incluyendo un
resultado adicional.
CONSTRUYENDO UN RBOL
Xs es una lista de longitud 2 k .El tiempo para calcular length xs, siendo m = 2 k 1
se tiene.
T (construirArBin) (0) = 0(1)
T (construirArBin) (k + 1) = 2T (ConstruirArBin) (k) + (2 k)
FUNCIN DE FIBONACCI
Otro ejemplo donde la tcnica de tuplamiento puede mejorar el orden de
complejidad en tiempo de un programa lo tenemos en la funcin de Fibonacci:
fibO

=0 fib 1 =1

fib(n + 2) = fib n + fib (n + 1)

El tiempo para evaluar fib n mediante estas ecuaciones viene dado por T(fib)(ri),
donde:
T(fib)(0)

= 0(1)

T(fib)(l) = 0(1)
T(fib)(n + 2) = T(fib)(ri) + T{fib)(n + 1) + 0(1)

La funcin T(fib) satisface por tanto ecuaciones muy similares a las de fib. Es fcil
comprobar por induccin que T(fib)(n) = (fib n), por tanto el tiempo para calcular
fib es proporcional al tamao del resultado. Dado que fib n = 0(3>n), donde $ es la
razn urea $ = (1 + >/5)/2, el tiempo es exponencial en n.
Consideremos ahora la funcin fibDos definida mediante
fibDos n = (fib n, fib (n+ 1))
Claramente, fib n = fst (fibDos n). La sntesis de un programa recursivo para
fibDos proporciona:
fibDos O

= (0,1)

fibDos (n + 1) = (b, a + b) where (a, b) = fibDos n

LLENANDO PRRAFOS
Los ejemplos anteriores tupiaban dos funciones, pero se puede utilizar la misma
idea con buenos resultados tupiando una lista de funciones. En esta versin, la
tcnica de tuplamiento recibe usualmente el nombre de tabulacin. Se nos da una
lista ws de palabras y queremos calcular una lista de lneas wss tal que ws =
concat wss, con la restriccin adicional de que cada lnea de wss debera tener
como mximo una longitud dada y adems wss debe minimizar cierta nocin de
desperdicio. Para simplificar, supondremos que se determina el desperdicio
mediante una funcin numrica dada desp que toma el valor oo si el prrafo
contiene una lnea que no cabe en la anchura dada.
La definicin de llenar toma la forma:
llenar :: [Palabra] [Linea] llenar = mejor llenados
mejor :: [[Linea]] -~[Linea] mejor = foldll mejor Que
where mejorQue uss vss = if desp uss < desp vss then uss else vss

La funcin llenados da todos los modos posibles de llenar el prrafo:


llenados

:: [Palabra] [[Linea]]

llenados []

= [[ ]]

llenados (w: ws) = [us : vss \ (us,vs) descomp (w: ws), vs llenados vs]
Se especifica la funcin descomp mediante la condicin de que si xs es una lista
no vaca, entonces descomp xs devuelve la lista de todos los pares (us, vs) tales
que us ++ vs = xs y us es no vaca. Se puede definir la funcin descomp de varias
maneras; una de ellas es la siguiente:
descomp

:: [a] [([a], [a])]

descomp (w: ws) = zip (map (w.) (inits ws)) (tails ws)
Aqu, inits ws devuelve la lista de los segmentos iniciales de ws en orden creciente
de longitud, y tails ws devuelve los segmentos finales en orden decreciente de
longitud. Por tanto, la funcin descomp devuelve la lista de todas las formas
posibles de partir la entrada de manera que el primer componente de cada par sea
una lista no vaca.
Para mejorar el programa, necesitamos la suposicin adicional
mejor -map {us :) = (us:) - mejor
Dicho con palabras: fijada una primera lnea, se obtiene el mejor prrafo tomando
el mejor prrafo para las siguientes lneas. Esta condicin es una aplicacin de lo
que en los textos de diseo de algoritmos se conoce como principio de
optimalidad.
Dada la suposicin anterior, es fcil comprobar que llenar se puede definir
mediante
llenar [ ]

=[]

llenar (w: ws) = mejor [LZS : llenar vs \ (us, vs) -descomp (w: ws)]
Suponiendo que tanto mejor como descomp emplean tiempo lineal, tenemos
T(llenar)(0) = 0(1)
T(llenar)(n +1) = 0(n) + Xk=o T(llenar)(k)
La solucin de esta relacin de recurrencia es T(llenar)(n) = 0(2"); por tanto, llenar
necesita todava tiempo exponencial. La razn es que, para toda secuencia final
de ws, se recalcula llenar vs. La situacin es muy similar a la de la funcin de

Fibonacci, excepto que en vez de tener dos trminos recursivos, tenemos una lista
de ellos. La solucin es similar: definimos llenarColas mediante:
llenarColas = map llenar tails
Tenemos que llenar = head llenarColas; por tanto, se puede calcular llenar
calculando llenarColas. Slo resta dar un programa recursivo para llenarColas. El
caso base:
llenarColas [ ] = [[ ]]
Es fcil, y para el caso recursivo argumentamos primero que llenar
(w: ws) = {definicin de llenar}
=

{definicin de descomp}

mejor [us: llenar vs \ (us, vs) zip (map (w:) (inits ws)) (tails ws)]
=

{conjetura}

mejor [(w : us) : vss \ (us, vss) zip (inits ws) (map llenar (tails ws))]
=

{definicin de llenarColas}

mejor [(w: us) : vss \ (us, vss) *-zip (inits ws) (llenarColas ws)]
La demostracin de la conjetura empleada se deja como ejercicio. Ahora
podemos deducir
llenarColas (w: ws)
{definicin de llenarColas, ms algunas simplificaciones de rutina} llenar (w: ws) :
llenarColas ws =
{por el clculo anterior de llenar, definiendo fts = llenarColas
ws}
mejor [(w: us) : vss \ (us, vss) zip (inits ws) fts)] : fts.
LA MEDIA ARITMTICA.
El ltimo ejemplo para ilustrar la tcnica de tuplamiento consigue una mejora de
eficiencia ms modesta. Se define la funcin media para listas no vacas de
nmeros mediante:
media :: [Float] -~Float media xs = (sum xs)/(length xs)
La evaluacin de media necesita dos recorridos del argumento, pero mediante
tupia- miento podemos conseguir que se haga slo uno. Definimos sumaLong
mediante
sumaLong xs = (sum xs, length xs)

Se tiene que media = uncurry (/) - sumaLong. La definicin recursiva directa de


sumaLong es
sumaLong [x]

= (x, 1)

sumaLong (x: y: xs) = (x+ z, n + 1), where (z, n) = sumaLong (y: xs)
CONTROLANDO EL ESPACIO.
Consideremos la reduccin del trmino sum [1..1000], donde sum = foldl (+) 0:
sum [1..1000]
= foldl (+) 0 [1..1000]
= foldl (+) (0 + 1) [2..1000]
= foldl (+) ((0 + 1) + 2) [3..1000]
= foldl (+) (...((0 + 1) + 2) + ...+ 1000) []
= (...((0 + 1) + 2) + ...+ 1000)
= 500500
El punto a resaltar es que, al calcular sum [1..] mediante reduccin ms externa,
la expresin crece hasta un tamao proporcional a n. Por otra parte, si utilizamos
una mezcla juiciosa de pasos de reduccin ms externa y ms interna, entonces
podemos obtener la siguiente secuencia de reduccin:
sum [1..1000]
= foldl (+) 0 [1..1000]
= foldl (+) (0 + 1) [2..1000]
= foldl (+) 1 [2..1000]
= foldl (+) (1 + 2) [3..1000]
= foldl (+) 3 [3..1000]
= foldl (+) 500500 []
= 500500
Resumiendo, al reducir sum [l..n] a forma normal mediante reduccin ms externa
pura necesitamos espacio en D(n), mientras que una combinacin de reduccin
ms externa y ms interna requiere solamente espacio en 0(1).
FORMA NORMAL DBIL Y LA FUNCIN STRICT.

Se puede controlar el orden de reduccin utilizando la funcin especial strict. Para


reducir un trmino de la forma strict fe, primero se reduce e a forma normal dbil4,
y despus se aplica f.
En la expresin strict fe, el trmino e ser reducido mediante reduccin ms
externa, excepto, por supuesto, si aparecen llamadas a strict mientras reducimos
e. A modo de ejemplo sencillo, sea succ x = x + 1. Entonces
succ {succ (8 x 5))
= succ (8 x 5) + 1
=

((8 X 5) + 1) + 1

(40+l) + l

41 + 1

42

Por otra parte,


strict succ (strict succ (8 x 5))
= strict succ {strict succ 40)
= strict succ (succ 40)
= strict succ (40 + 1)
= strict succ 41 = succ 41 = 41 + 1 = 42
Ambos casos realizan los mismos pasos de reduccin, pero en orden diferente.
La currificacin se aplica a strict del modo habitual. De ello se deduce que si f es
una funcin de tres argumentos, la expresin strict {fe i) e2 e3 hace que el
segundo argumento e2 se reduzca antes, pero no el primero ni el tercero.
A partir de aqu, podemos definir una funcin sfoldl, una versin estricta de foldl,
como sigue:
sfoldl () a [ ]

=a

sfoldl () a (x: xs) = strict {sfoldl ()) {a e x) xs Siendo sum = sfoldl (+) 0
tenemos ahora:
sum [1..1000]
= sfoldl (+) 0 [1..1000]
= strict (sfoldl (+)) (0 + 1) [2..1000]

= sfoldl (+) 1 [2..1000]


= strict (sfoldl (+)) (1 + 2) [3..1000]
= sfoldl (+) 3 [3..1000]
= sfoldl (+) 500500 [ ]
= 500500
Esta secuencia de reduccin evala sum en espacio constante.
Consideremos ahora la funcin media de la seccin precedente; se puede definir
esta funcin mediante
media = uncurry (/) sumaLong
sumaLong = foldl f (0,0)
where f (s, n) x = (s + x, n + 1)
La secuencia de reduccin revisada ahora es
sumaLong [1..1000]
=

sfoldl f (0, 0) [1..1000]

strict (sfoldl f) (strict (strict tupia (0 + 1)) (0 + 1)) [2..1000]

strict (sfoldl f) (strict (strict tupia (0 + 1)) 1) [2..1000]

strict (sfoldl f) (strict (strict tupia 1) 1) [2..1000]

strict (sfoldl f) (1, 1) [2..1000]

sfoldl f (1, 1) [2..1000]

Y as sucesivamente. Es obvio que esta secuencia tiene el comportamiento


deseado.
Se puede reexpresar la definicin operacional de strict del modo siguiente:
strict fx = if x = J_then _Lelse fx
Recordemos que se dice que una funcin f es estricta si f x = x. De la ecuacin se
deduce que f = strict f si y slo si f es una funcin estricta. Para ver esto,
simplemente consideremos los valores de fx y strict f x en los dos casos x = iyx^ i.
Esto explica el nombre strict.
Ms an, si f es estricta, pero no totalmente indefinida, y e =#= x, entonces la
reduccin de f e implica finalmente la reduccin de e. As, si f es una funcin
estricta, la evaluacin defe realiza exactamente los mismos pasos de reduccin

que la de strict f e, aunque posiblemente en orden diferente. En otras palabras,


cuando f es estricta, el reemplazarla por strict f no cambia el significado o el
tiempo asinttico requerido para aplicarla, aunque puede cambiar el espacio
requerido para el clculo.
Revisin de las funciones fold
El primer teorema de dualidad dado en la Seccin 4.5 establece que si (ffi) es
asociativo y tiene como elemento neutro e, entonces
foldr()exs = foldl () exs
Para todas las listas finitas xs. Por otra parte, las dos funciones pueden tener
diferentes complejidades en tiempo y en espacio. La decisin de cul usar
depende de las propiedades de .
Primero, supongamos que es estricta en ambos argumentos, y que se puede
calcular en tiempo 0(1) y en espacio 0(1). Ejemplos que entran en esta categora
son (+) y (x). En este caso, no es difcil verificar que tanto foldr () e como foldl ()
e requieren ambos tiempo 0(n) y espacio 0(n) sobre una lista de longitud n. Sin
embargo, el mismo argumento usado anteriormente para sum se generaliza para
demostrar que, en este caso, se puede reemplazar de forma segura foldl por
sfoldl. Mientras que sfoldl () a requiere todava tiempo 0(n) para evaluarse sobre
una lista de longitud n, solamente necesita espacio 0(1). Por tanto, en este caso,
sfoldl es el ganador indiscutible.
Si no satisface las propiedades anteriores, entonces la eleccin de un ganador
no es tan fcil. Sin embargo, una buena regla prctica es que si es no estricta
en cualquiera de los argumentos, entonces normalmente foldr es ms eficiente
que foldl. Vimos un ejemplo en la Seccin 7.2: la funcin concat se calcula ms
eficientemente utilizando foldr que foldl. Observemos que, mientras que ++- es
estricta en su primer argumento, es no estricta en el segundo.
FUSIN, DIFERENCIACIN FINITA Y DEFORESTACIN.
El grupo final de tcnicas tienen un aspecto comn y se tratan mejor juntas. En
todas ellas, una vez expresada la solucin de un problema en trminos de la
composicin f\ f2 fn de un cierto nmero de funciones, se puede
incrementar la eficiencia combinando, o fusionando, dos o ms de las funciones
auxiliares fk en una sola funcin.
Hemos encontrado ya la fusin en el contexto de las operaciones fold sobre listas.
Recordemos de la Seccin 4.5 que:
= foldr h (f a)

Siempre que f sea una funcin estricta y f- (g x) = (h x) f. Operacionalmente, el


lado izquierdo dice que se calcula un valor a partir de los elementos de una lista y
dicho valor es consumido por una funcin para producir un segundo valor. El lado
derecho dice que, siempre que se cumpla una cierta condicin, se puede producir
directamente el segundo valor a partir de los elementos de la lista. La condicin f
{g x) = (h x) f establece que se puede calcular incrementalmente el valor devuelto
por f.

CONCLUSION:
La evaluacin perezosa, nos da a entender de que no se evala nada hasta tanto
deba ser avaluado, esto permite que uno puede, por ejemplo, definir una lista
infinita de primos sin caer en una recursin infinita. Slo los elementos de esta
lista que sean realmente usados sern computados. La evaluacin perezosa hace
esta operacin de manera ms limpia.

También podría gustarte