Peor caso, promedio y amortizado no son lo mismo
Un algoritmo puede ser rápido casi siempre, lento para una entrada particular y aun así tener costo constante amortizado. Separar esas tres ideas evita promesas de rendimiento engañosas.
Para este tema conviene tener claro:Complejidad algorítmica, visualmente
Decir que una operación “normalmente es rápida” puede esconder tres afirmaciones distintas: que la mayoría de las entradas son fáciles, que el azar suele ayudar o que una operación cara ocurre muy pocas veces. Caso promedio y costo amortizado no son sinónimos.
Mejor y peor caso
En una búsqueda lineal, el mejor caso ocurre cuando el objetivo está primero: una sola comparación, . El peor ocurre cuando está último o no aparece: .
El peor caso da una garantía: ninguna entrada de tamaño puede obligar al algoritmo a hacer más que esa cota. Es especialmente importante cuando una demora excepcional rompe un límite de tiempo, congela una interfaz o deja vencer una operación.
Antes de seguir, predecí
El promedio necesita una distribución
El caso promedio necesita una distribución de probabilidades sobre las entradas. Si el objetivo de una búsqueda lineal está presente y es igualmente probable en cualquier posición, se hacen en promedio
comparaciones. Sigue siendo , aunque la constante sea aproximadamente la mitad del peor caso.
Sin decir qué entradas son probables, “promedio” no está definido. Los datos reales rara vez son uniformes, y una distribución equivocada vuelve irrelevante el cálculo.
Quicksort, donde declarar el caso cambia todo
Quicksort muestra por qué conviene declarar el caso. Si cada pivote divide el arreglo en partes parecidas, hay niveles con trabajo por nivel: . Si el pivote queda siempre en un extremo, aparecen niveles: .
Elegir el pivote al azar no elimina el peor caso; lo vuelve muy improbable para entradas independientes del azar. La garantía sigue siendo cuadrática, mientras que el costo esperado es . Son dos afirmaciones verdaderas sobre el mismo algoritmo.
El arreglo dinámico y su inserción cara
Un arreglo dinámico suele agregar elementos en , pero cuando se llena necesita reservar un bloque mayor y copiar todo. Esa inserción particular cuesta . ¿Cómo puede decirse entonces que agregar al final es constante?
La respuesta no usa probabilidades. Mira una secuencia completa de operaciones. Si la capacidad se duplica —1, 2, 4, 8— las copias totales antes de guardar elementos son
Amortizado: el total dividido por las operaciones
Las inserciones normales cuestan y todas las redimensiones juntas cuestan menos de . El trabajo total es menor que , así que dividido entre operaciones da una constante por inserción: amortizado.
Capacidad 1, un elemento. La primera inserción es directa.
No significa que cada llamada tarde lo mismo. Una puede copiar miles de elementos. Significa que no puede ocurrir muchas veces sin que antes hayan ocurrido suficientes operaciones baratas. Las operaciones comunes “pagan” de a poco la cara.
Promedio y amortizado no son lo mismo
El caso promedio promedia sobre entradas posibles y necesita supuestos probabilísticos. El análisis amortizado promedia sobre una secuencia, sin azar: garantiza un costo total incluso si un adversario elige las operaciones.
Una tabla hash suele tener acceso esperado bajo supuestos sobre la función hash. Un vector dinámico tiene inserción amortizada aunque la secuencia sea la peor imaginable. La palabra que acompaña al costo cambia qué se está garantizando.
Cuándo el amortizado no alcanza
El costo amortizado puede ser insuficiente cuando importa la latencia de cada operación. Un servidor que responde rápido 999 veces y se frena un segundo en la número 1000 quizá tenga buen promedio y mala experiencia.
En esos casos se reparte el trabajo caro entre varias operaciones, se reserva capacidad antes o se elige una estructura con peor caso acotado. El análisis asintótico no decide la arquitectura solo: hay que preguntar si importa el throughput total o el máximo de cada respuesta.
Cuál de los tres mirar
| Peor caso | Promedio | Amortizado | |
|---|---|---|---|
| Qué afirma | ninguna operación supera esto | el costo esperado sobre entradas al azar | n operaciones seguidas cuestan esto en total |
| Depende de | nada | una distribución supuesta | nada: es una garantía |
| Sirve para | sistemas con límite de latencia, tiempo real, seguridad | estimar rendimiento típico | estructuras con redimensión o reorganización |
| Se rompe cuando | nunca, es una cota | alguien elige las entradas a propósito | importa cada operación por separado |
| Ejemplo | mergesort: O(n log n) | quicksort: O(n log n) | arreglo dinámico: O(1) por inserción |
Más a fondo · formalLos tres métodos para demostrarlo
El análisis amortizado tiene tres técnicas, y todas prueban lo mismo de formas distintas.
El agregado es el que usa este post: se cuenta el costo total de operaciones y se divide por . Es el más simple y sólo sirve cuando todas las operaciones son parecidas.
El contable le asigna a cada operación un costo ficticio mayor que el real y guarda la diferencia como crédito sobre la estructura. Cada inserción barata paga 3 en vez de 1 y deja 2 ahorrados; cuando llega la redimensión, la paga con lo ahorrado. Hay que probar que el crédito nunca se vuelve negativo.
El potencial generaliza al anterior: se define una función del estado de la estructura —para el arreglo dinámico, algo como — y el costo amortizado de cada operación es su costo real más el cambio de . Las operaciones baratas suben el potencial y la cara lo consume.
Los tres dan el mismo resultado. El del potencial es el que se usa para estructuras más complicadas —splay trees, heaps de Fibonacci— donde no alcanza con contar.
Cierre
Cuando alguien diga “esta operación es ”, la pregunta correcta es: ¿peor caso, esperado o amortizado? El peor caso promete un techo por operación; el promedio depende de una distribución; el amortizado limita una secuencia completa. Nombrar bien la garantía es parte de diseñar bien la estructura.
Autoevaluación
¿Lo entendiste?
Práctica