Sunteți pe pagina 1din 3

1

Complejidad de peor caso

Sea Dn el conjunto de entradas de tamaño n para el problema en consideración, y sea I un


elemento de Dn. Sea t(I) el número de operaciones básicas que el algoritmo ejecuta con la
entrada I. Definimos la función T así:

T(n) = máx {t(I) | I є Dn}

La función T(n) es la complejidad de peor caso del algoritmo. T(n) es el número máximo de
operaciones básicas que el algoritmo ejecuta con cualquier entrada de tamaño n.

En muchos casos es relativamente fácil calcular T(n). La complejidad de peor caso es valiosa
porque proporciona una cota superior del trabajo ejecutado por el algoritmo. El análisis de peor
caso podría ayudarnos a estimar un límite de tiempo para una implementación dada de un
algoritmo.

Podría parecer que una forma más útil y natural de describir el comportamiento de un algoritmo
es indicar cuánto trabajo efectúa en promedio; es decir, calcular el número de operaciones
ejecutadas con cada entrada de tamaño n y luego sacar el promedio. En la práctica, algunas
entradas podrían presentarse con mayor frecuencia que otras, por lo que un promedio ponderado
sería más informativo.

Complejidad promedio

Sea P(I) la probabilidad de que se presente la entrada I. Entonces, el comportamiento promedio


del algoritmo se define como

A(n) = Σ P(I) t(I)


I є Dn

Determinamos t(I) analizando el algoritmo, pero P(I) no se puede calcular analíticamente. La


función P(I) se determina por la experiencia y/o con base en información especial acerca de la
aplicación que se piensa dar al algoritmo, o haciendo algún supuesto simplificador (por ejemplo
que todas las entradas de tamaño n tienen la misma probabilidad de presentarse). Si P(I) es
complicada, se dificulta el cálculo del comportamiento promedio. Además, claro, si P(I)
depende de una aplicación dada del algoritmo, la función A describe el comportamiento
promedio del algoritmo sólo para esa aplicación.

Los ejemplos siguientes ilustran el análisis de peor caso y caso promedio

Ejemplo: Búsqueda de un elemento en un arreglo no ordenado.

Problema: Sea E un arreglo que contiene n entradas (llamadas claves), E[0], … E[n-1], sin un
orden específico. Encontrar el índice de una clave dada, k, si k está en el arreglo; devolver -1
como respuesta si k no está en el arreglo.

Estrategia: Comparar k con cada elemento por turno hasta encontrar una coincidencia o hasta
agotar el arreglo. Si k no está en el arreglo, el algoritmo devuelve -1 como respuesta.

Algoritmo:

Entradas: E, n, k, donde E es un arreglo con n entradas (indexadas 0,…, n-1) y k es el elemento


buscado. Por sencillez, suponemos que k y los elementos de E son enteros, lo mismo que n.

Salidas: Devolver respuesta, la ubicación de k en E (-1 si no se encuentra k).


2

int BusquedaSec(int E[], int n, int k)


{
int respuesta, índice;
respuesta = -1 // Suponer fracaso.
for(indice = 0; índice < n; índice++)
if(k = = E[índice])

{
respuesta = índice;
break;
}
return respuesta;
}

Operación básica: Comparación de k con un elemento del arreglo.

Análisis de peor caso: Obviamente T(n) = n. Los peores casos se presentan cuando k aparece
sólo en la última posición del arreglo y cuando k no está en el arreglo. En ambos casos se
compara con las n entradas.

Análisis de comportamiento promedio: Primero postularemos varios supuestos


simplificadores a fin de presentar un ejemplo sencillo, y luego haremos un análisis un poco más
complicado con diferentes supuestos. Supondremos que todos los elementos del arreglo son
distintos y que, si k está en el arreglo, es igualmente probable que esté en cualquier posición
dada.
Como primer paso, supondremos que k está en el arreglo, y denotaremos este suceso con
“éxito” según la terminología de probabilidades. Las entradas se pueden clasificar según la
posición en la que k aparece en el arreglo, de modo que debemos considerar n entradas.
Para 0 <= i < n, Ii representará el suceso de que k aparece en la iésima posición del arreglo.
Entonces, sea t(I) el número de comparaciones efectuadas (el número de veces que se prueba la
condición if(k = = E[indice])) por el algoritmo en la entrada I. Es evidente que, para 0 <= i < n,
t(I) = i+1. así pues,

n-1
Aéxito(n) =  P(Ii | éxito) t(Ii)
i= 0

Aéxito(n) = (1/n)(i + 1) = (1/n)(n(n+1)/2) = (n + 1)/2

El subíndice “éxito” denota que en este cálculo estamos suponiendo que la búsqueda tuvo éxito.
El resultado deberá satisfacer nuestra intuición de que, en promedio, se examinará la mitad del
arreglo.

Consideremos ahora el suceso de que k no está en el arreglo, lo que llamaremos “fracaso”.


Sólo hay una entrada para este caso, que llamaremos Ifracaso. El número de comparaciones en este
caso es

t(Ifracaso) = n, así que

Afracaso (n) = n

Por último, combinamos los casos en los que k está en el arreglo y no está en el arreglo.

Sea p la probabilidad de que k está en el arreglo


3

A(n) = P(éxito) Aéxito(n) + P(fracaso) Afracaso (n)


= p * ((n + 1)/2) + (1 - p) * n
= n(1 – p/2) + p/2

Si p = 1, es decir, si k siempre está en el arreglo, entonces A(n) = (n + 1)/2, igual que antes. Si p
= ½, es decir, si hay una posibilidad de 50 – 50 de que k no esté en el arreglo, entonces A(n) =
3n/4 + ¼; o sea que se examinan aproximadamente las ¾ partes del arreglo

El ejemplo anterior ilustra la interpretación que debemos dar a Dn, el conjunto de entradas de
tamaño n. En lugar de considerar todos los posibles arreglos de nombres, números o lo que sea,
que podrían presentarse como entradas, identificamos las propiedades de las entradas que
afectan el comportamiento del algoritmo; en este caso, si k está o no en el arreglo y, si está en
qué posición. Un elemento I de Dn puede verse como un conjunto (o clase de equivalencia) de
todos los arreglos y valores de k tales que k aparece en la posición especificada del arreglo (o no
aparece). Entonces t(I) es el número de operaciones efectuadas en cualquiera de las entradas de
I.

Observe también que la entrada con la cual el algoritmo tiene su peor comportamiento depende
del algoritmo empleado, no del problema. En el caso del presente algoritmo el peor caso se
presenta cuando la única posición del arreglo que contiene a k es la última. En el caso de un
algoritmo que examina el arreglo de atrás hacia delante (es decir, comenzando con índice = n-
1), un peor caso se presentará si k apareciera solo en la posición 0. (Otro peor caso sería, una
vez más, si k no está en el arreglo).

Por último, el ejemplo ilustra un supuesto que solemos hacer al efectuar un análisis promedio de
algoritmos para ordenar o buscar: que los elementos son distintos. El análisis promedio para el
caso de elementos distintos da una buena aproximación del comportamiento promedio en casos
en que hay pocas repeticiones. Si puede haber muchas repeticiones, es más difícil hacer
supuestos razonables acerca de la probabilidad de que la primera aparición de k en el arreglo se
dé en alguna posición específica.

S-ar putea să vă placă și