Ambos se pueden implementar utilizando exactamente el mismo algoritmo genérico de la siguiente manera:
Inputs:
G: Graph
s: Starting vertex (any for Prim, source for Dijkstra)
f: a function that takes vertices u and v, returns a number
Generic(G, s, f)
Q = Enqueue all V with key = infinity, parent = null
s.key = 0
While Q is not empty
u = dequeue Q
For each v in adj(u)
if v is in Q and v.key > f(u,v)
v.key = f(u,v)
v.parent = u
Para Prim, pase f = w(u, v)
y para Dijkstra pase f = u.key + w(u, v)
.
Otra cosa interesante es que por encima de Generic también se puede implementar Breadth First Search (BFS), aunque sería excesivo porque la cola de prioridad costosa no es realmente necesaria. Para convertir el algoritmo genérico anterior en BFS, pase lo f = u.key + 1
que equivale a aplicar todos los pesos a 1 (es decir, BFS da el número mínimo de bordes necesarios para atravesar desde el punto A al B).
Intuición
Aquí hay una buena manera de pensar en el algoritmo genérico anterior: comenzamos con dos cubos A y B. Inicialmente, coloque todos sus vértices en B para que el cubo A esté vacío. Luego, movemos un vértice de B a A. Ahora mire todas las aristas de los vértices en A que cruzan a los vértices en B. Elegimos una arista usando algunos criterios de estas aristas cruzadas y movemos el vértice correspondiente de B a A. Repita este proceso hasta que B esté vacío.
Una forma de fuerza bruta para implementar esta idea sería mantener una cola de prioridad de los bordes para los vértices en A que cruzan a B. Obviamente, eso sería problemático si el gráfico no fuera escaso. Entonces, la pregunta sería ¿podemos mantener la cola de prioridad de vértices? Esto, de hecho, podemos decidir finalmente qué vértice elegir de B.
Contexto histórico
Es interesante que la versión genérica de la técnica detrás de ambos algoritmos sea conceptualmente tan antigua como 1930, incluso cuando no existían computadoras electrónicas.
La historia comienza con Otakar Borůvka, quien necesitaba un algoritmo para un amigo de la familia que intentaba averiguar cómo conectar ciudades en el país de Moravia (ahora parte de la República Checa) con líneas eléctricas de costo mínimo. Publicó su algoritmo en 1926 en una revista relacionada con las matemáticas, ya que la informática no existía entonces. Esto llamó la atención de Vojtěch Jarník, quien pensó en una mejora en el algoritmo de Borůvka y lo publicó en 1930. De hecho, descubrió el mismo algoritmo que ahora conocemos como el algoritmo de Prim y lo redescubrió en 1957.
Independientemente de todo esto, en 1956 Dijkstra necesitaba escribir un programa para demostrar las capacidades de una nueva computadora que había desarrollado su instituto. Pensó que sería genial que una computadora encontrara conexiones para viajar entre dos ciudades de los Países Bajos. Diseñó el algoritmo en 20 minutos. Creó un gráfico de 64 ciudades con algunas simplificaciones (porque su computadora era de 6 bits) y escribió código para esta computadora de 1956. Sin embargo, no publicó su algoritmo porque principalmente no había revistas de informática y pensó que esto podría no ser muy importante. Al año siguiente se enteró del problema de conectar terminales de computadoras nuevas de modo que se minimizara la longitud de los cables. Pensó en este problema y redescubrió a Jarník / Prim ' s que utiliza de nuevo la misma técnica que el algoritmo de ruta más corta que había descubierto un año antes. Élmencionó que ambos algoritmos fueron diseñados sin usar lápiz o papel. En 1959 publicó ambos algoritmos en un artículo de tan solo dos páginas y media.