Máximo y segundo máximo de un arreglo
Supongamos que deseamos encontrar el máximo y el segundo máximo elemento de . Una solución simple es encontrar el máximo y luego volver a encontrar el máximo entre los elementos restantes. Esto nuevamente cuesta comparaciones. ¿Será óptimo? ¿Será que este problema es intrínsecamente más difícil que el de encontrar el máximo y el mínimo?
La analogía con el torneo de tenis nos sugiere una forma mucho mejor de resolver este problema. En un torneo de tenis, el segundo mejor debe haber jugado contra el primero, y sólo contra éste puede haber perdido. Como el primero realizó (y ganó) partidas, hay sólo candidatos para el segundo puesto. Una vez realizado el torneo de tenis para encontrar el máximo, podemos encontrar el segundo máximo entre los que perdieron contra el máximo usando comparaciones. El costo total es entonces , lo que muestra que este problema es en realidad más fácil que el de encontrar el máximo y el mínimo, pues aquél requiere de comparaciones.
La pregunta natural es si nuestro algoritmo es óptimo, o el problema se puede resolver aún mejor.
Cota inferior incorrecta
Intentemos reusar el modelo de la tabla, con los siguientes conjuntos:
- es el cardinal del conjunto de los elementos que nunca han sido comparados;
- es el cardinal del conjunto de los elementos que se han comparado alguna vez y han ganado (han resultado mayores) en todas sus comparaciones;
- es el cardinal del conjunto de los elementos que han perdido (han resultado menores) exactamente una vez; y
- es el cardinal del conjunto de los elementos que han perdido más de una vez.
El estado inicial es y el final debe ser . La tabla es como sigue:
Tal como en el caso del mínimo y máximo, obtenemos una cota inferior de . ¡Pero esto no puede ser, ya tenemos una cota superior menor! ¿Qué ha ocurrido?
Lo que ha ocurrido es que nos hemos equivocado al suponer que es necesario llegar al estado para poder responder. En el torneo de tenis, casi la mitad de los jugadores juega un solo partido y queda descartada como primero o segundo, sin necesidad de haber perdido dos veces. La razón es la transitividad: si se pierde contra alguien que no es el mejor, no se puede ser el segundo mejor. Es decir, el algoritmo infiere cosas por transitividad, sin hacer comparaciones directas. Incluimos este ejemplo para mostrar que debe tenerse cuidado al aplicar esta técnica, asegurándose de que realmente es necesario llegar al estado final para poder responder correctamente.
Cota inferior correcta
Digamos que en un algoritmo que encuentra el máximo hay elementos que se comparan directamente (y pierden) contra quien finalmente resulta ser el máximo. El segundo máximo es entonces el mayor de estos candidatos (el segundo máximo debe haberse comparado contra el máximo, pues si no, ganó todas sus comparaciones y el adversario podría hacerlo arbitrariamente grande, incluso mayor que quien el algoritmo entrega como el máximo).
Consideremos de nuevo el modelo del grafo que se conecta. Si quitamos al nodo del máximo y a las aristas que lo conectan con los candidatos a segundo máximo, el grafo debe aún resultar conexo para poder determinar el segundo máximo. De no ser así, existen dos componentes conexas que se unían sólo pasando por el máximo, y el paso por el máximo no sirve para determinar en cuál de las dos componentes está el segundo máximo.
Por lo tanto el grafo debe tener al menos aristas, y se necesitan al menos comparaciones para encontrar el máximo y el segundo máximo ( para el primero y para el segundo). Mostraremos que un adversario puede conseguir que .
Consideremos el siguiente modelo para la cota inferior. Se asocia un peso a cada celda , inicialmente . Cuando un elemento pierda una comparación, su pasará a ser cero. Por lo tanto, para entregar el máximo correctamente, se requiere que haya un único (donde será entonces el máximo).
Ahora diseñemos un adversario adecuado. Cuando el algoritmo compara con , hay tres casos:
- Si , el adversario responde que . Esto es consistente porque no ha perdido ninguna comparación. Asimismo, el adversario actualiza y . Este caso incluye el , mediante intercambiar y .
- Si , el adversario se comporta como en el caso anterior, eligiendo arbitrariamente quién es y quién .
- En otro caso, el adversario da cualquier respuesta que sea consistente con las anteriores (es decir, si de las comparaciones pasadas se puede deducir el resultado de esta comparación, ese resultado debe mantenerse). En este caso, no se actualizan las .
Puede verse que este adversario agrega un par de invariantes más al modelo: (1) todas las suman siempre , y (2) cuando un crece, a lo sumo se duplica. Eso implica que, para cuando el algoritmo puede responder correctamente que es el máximo, vale que , y como llegamos de a a lo sumo duplicándolo en cada comparación, el elemento debe haberse comparado directamente al menos veces.
Note que la cota inferior de comparaciones para el máximo no requiere que el adversario responda de alguna manera especial en las comparaciones, por lo que podemos usar en particular este adversario para garantizar que, además de las comparaciones para encontrar el máximo, se requerirán otras para el segundo máximo.
Finalmente, note que ningún algoritmo puede decir cuál es el segundo máximo si no sabe cuál es el máximo, pues eso significa que el segundo máximo propuesto no ha perdido ninguna comparación, y el adversario podría hacer que el segundo máximo propuesto fuera tan grande como quisiera. Por lo tanto, encontrar el segundo máximo es equivalente en dificultad a encontrar el primer y segundo máximo.