¿Dónde se usa la cola prioritaria?

Digamos que usted está a cargo de un hospital, manejando a los pacientes en la sala de espera. Llegan todo tipo de pacientes en momentos aleatorios, cada uno con una lesión diferente. ¿Quién puede ver primero al médico y en qué orden deben ser admitidos a cirugía?

El sentido común dice que la persona más lastimada debe ser tratada primero. En otras palabras, los doctores deben ver a los pacientes en orden de cuán urgentemente necesitan tratamiento, sin importar el orden en que realmente ingresaron a la sala de espera.

Entonces, digamos que tenemos los siguientes pacientes, que llegan a la sala de espera en el siguiente orden:

  1. Chico con un corte de papel (Prioridad: muy baja )
  2. Amigo con un hacha en la cabeza (Prioridad: MUY ALTA)
  3. Mujer con una mordedura de perro desagradable (Prioridad: ALTA)
  4. Niño que se rascó la rodilla (Prioridad: baja )

Si el hospital corre por orden de llegada, entonces el tipo con el corte de papel sería tratado antes que el tipo con el hacha en la cabeza. ¡Ese es un orden de tratamiento terrible, terrible ! El tipo con el hacha en la cabeza debe ser tratado antes que el tipo con el corte de papel, porque de lo contrario va a morir .

Para eso sirve una cola de prioridad (PQ). Si primero necesita manejar algo con una prioridad más alta, independientemente del orden en que lleguen los artículos, utilice un PQ.

Aquí hay dos aplicaciones comunes de colas prioritarias:

Heapsort

Este algoritmo es un algoritmo de ordenación, como la ordenación por inserción, mergesort, quicksort, etc. Heapsort se basa en un tipo específico de cola prioritaria llamada “montón” (por eso se llama “heapsort”).

Si se trata de números, por ejemplo, los números más pequeños obtienen una “prioridad” más alta, y los números más grandes obtienen una “prioridad” más baja. Primero arrojamos todos nuestros números al PQ en el orden que queramos. Luego, vaciamos el contenido del PQ uno a la vez. El orden de los números que salen estará en el orden de mayor prioridad a menor prioridad, como cualquier otro PQ. Dado que los números más pequeños tienen mayor prioridad, eso significa que los números saldrán del PQ en orden de menor a mayor.

¡Y ahí está tu lista ordenada de números!

Algoritmo de Dijkstra

El algoritmo de Dijkstra es un algoritmo de búsqueda de ruta de uso común que resuelve el problema de “dado un ‘laberinto’ de un montón de rutas diferentes que lo atraviesan, ¿cómo encontrar la ruta más corta desde el punto inicial del laberinto hasta el final? ?

No repasaré el algoritmo en esta respuesta (pero puedes leer sobre esto aquí). Sin embargo, una de las subrutinas en el algoritmo requiere que elija un punto intermedio en el “laberinto” que tenga la menor distancia conocida entre sí mismo y el punto de inicio. Estos puntos intermedios podrían haberse descubierto en cualquier orden arbitrario, pero lo importante es que elija el que tenga la distancia más corta entre sí mismo y el punto de partida. ¿Cuál es la forma más eficiente de hacer eso? ¡Una cola prioritaria, por supuesto! En este caso, decimos que los puntos con una distancia conocida más corta obtienen una “prioridad” más alta, y las rutas con una distancia conocida más larga obtienen una “prioridad” más baja. Para elegir el punto en el PQ que tiene la distancia más corta, todo lo que tenemos que hacer es expulsar el “siguiente elemento” en el PQ, que será, por definición, el elemento con mayor prioridad; en este caso, será el punto con la ruta más corta conocida a la ubicación inicial.

Muchos algoritmos comunes hacen uso de la cola de prioridad. Aquí hay algunos:

  • Algoritmo de Dijkstra: este es quizás el algoritmo de búsqueda de ruta más popular que existe. Es probable que Google use una forma más avanzada en Google Maps. La idea detrás de este algoritmo es mantener una cola prioritaria de los nodos que se procesan, ordenados por “distancia recorrida hasta el momento”. En cada iteración del algoritmo, saltaría de la cola de prioridad para obtener el nodo de distancia más corta y tomaría un paso, e iteraría hasta encontrar la distinción. Las formas más avanzadas de este algoritmo incluyen el algoritmo A * y el algoritmo D * (Lite).
  • Algoritmo de línea de barrido: si tiene un montón de datos espaciales (como puntos en un plano) y desea realizar un procesamiento global sobre ellos, es probable que utilice un algoritmo de línea de barrido. Por ejemplo, dado un montón de segmentos de línea en un plano, ¿dónde están todos los puntos de intersección? Una solución de fuerza bruta lleva tiempo [matemático] O (n ^ 2) [/ matemático]. Pero usando una cola prioritaria, es posible bajarla a [math] O (n \ log (n)) [/ math]. Las aplicaciones de los algoritmos de línea de barrido son infinitas, incluidos los diagramas de Voronoi y las triangulaciones de Delauney, que son realmente útiles en el procesamiento de imágenes.
  • Simulaciones controladas por eventos: suponga que desea simular una mesa de billar. Una vez que una pelota está en movimiento, deberá asegurarse de que las bolas colisionen correctamente. Una forma de hacerlo es aumentar el tiempo en pequeñas cantidades y verificar las colisiones para cada paso de tiempo (conocidas como simulaciones basadas en el tiempo). Una forma más inteligente de hacer esto es verificar todas las posibles colisiones y volcar estos “eventos” en una cola prioritaria, ordenada para cuando se produzcan las colisiones. Hacerlo es mucho más eficiente, y muchos fenómenos físicos pueden simularse de esta manera.
  • Colas de prioridad: ¡ Obviamente, las colas de prioridad se pueden usar para mantener una cola de prioridad aplicable! Por ejemplo, suponga que es un servidor que necesita programar qué trabajos se servirán a continuación. Puede ordenar estos trabajos mediante varios criterios diferentes, como el tamaño del trabajo y el tiempo de espera. Una buena forma de hacerlo es a través de una cola prioritaria.
  • Una búsqueda * (ordenar por el límite inferior más pequeño en la distancia total) y varios otros algoritmos de búsqueda
  • Simulaciones discretas de eventos (ordenar por tiempo)
  • Heapsort
  • Fusionar múltiples (> 2) flujos de datos ordenados

El nombre lo dice todo: siempre que necesite acceder a los M elementos de mayor prioridad entre N elementos, es la forma más óptima.

Es una generalización de un árbol binario ordenado.

Implementé uno como parte de un sistema de mensajería en pantalla en uno de los juegos en los que trabajé. Teníamos tres tipos de mensajes. Alertas que siempre se muestran de inmediato, incluida la eliminación de lo que haya en la pantalla. Teníamos instrucciones que se podían poner en cola y que solo se mostrarían una vez que se hubieran descartado los que estaban frente a él. Y, finalmente, recordatorios que solo se muestran después de que todas las instrucciones se hayan ido y que también se hayan puesto en cola en el orden en que entraron.

Las colas de prioridad se usan generalmente para problemas de programación de trabajos, en sistemas de archivos y otros problemas relacionados con la programación.

Se utiliza cuando los problemas involucran tiempo de finalización, hora de inicio, plazos, importancia.