Ambos podem ser implementados usando exatamente o mesmo algoritmo genérico da seguinte maneira:
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, passe f = w(u, v)
e para Dijkstra pass f = u.key + w(u, v)
.
Outra coisa interessante é que o Genérico acima também pode implementar Breadth First Search (BFS), embora seja um exagero porque a fila de prioridade cara não é realmente necessária. Para transformar o algoritmo genérico acima do BFS, passe o f = u.key + 1
que é o mesmo que impor todos os pesos a 1 (isto é, o BFS fornece o número mínimo de arestas necessárias para atravessar do ponto A ao B).
Intuição
Aqui está uma boa maneira de pensar sobre o algoritmo genérico acima: Começamos com dois depósitos A e B. Inicialmente, coloque todos os seus vértices em B para que o depósito A fique vazio. Em seguida, movemos um vértice de B para A. Agora olhe para todas as arestas dos vértices em A que se cruzam para os vértices em B. Escolhemos uma aresta usando alguns critérios dessas arestas cruzadas e movemos o vértice correspondente de B para A. Repita este processo até que B esteja vazio.
Uma forma de força bruta de implementar essa ideia seria manter uma fila de prioridade das arestas para os vértices em A que cruza para B. Obviamente, isso seria problemático se o gráfico não fosse esparso. Então a questão seria: podemos, em vez disso, manter a fila de prioridade de vértices? Isso de fato podemos, pois nossa decisão final é qual vértice escolher de B.
Contexto histórico
É interessante que a versão genérica da técnica por trás de ambos os algoritmos seja conceitualmente tão antiga quanto 1930, mesmo quando os computadores eletrônicos não existiam.
A história começa com Otakar Borůvka, que precisava de um algoritmo para um amigo da família tentando descobrir como conectar cidades no país da Morávia (agora parte da República Tcheca) com linhas elétricas de custo mínimo. Ele publicou seu algoritmo em 1926 em um jornal relacionado à matemática, já que a Ciência da Computação ainda não existia. Isso chamou a atenção de Vojtěch Jarník, que pensou em uma melhoria no algoritmo de Borůvka e o publicou em 1930. Ele de fato descobriu o mesmo algoritmo que agora conhecemos como algoritmo de Prim que o redescobriu em 1957.
Independente de tudo isso, em 1956 Dijkstra precisava escrever um programa para demonstrar as capacidades de um novo computador desenvolvido por seu instituto. Ele achou que seria legal que o computador encontrasse conexões para viajar entre duas cidades da Holanda. Ele projetou o algoritmo em 20 minutos. Ele criou um gráfico de 64 cidades com algumas simplificações (porque seu computador era de 6 bits) e escreveu o código para este computador de 1956. No entanto, ele não publicou seu algoritmo porque basicamente não havia periódicos de ciência da computação e ele achou que isso pode não ser muito importante. No ano seguinte, ele aprendeu sobre o problema de conectar terminais de novos computadores de forma que o comprimento dos fios fosse minimizado. Ele pensou sobre este problema e redescobriu Jarník / Prim ' s algoritmo que novamente usa a mesma técnica que o algoritmo de caminho mais curto que ele descobriu um ano antes. Elemencionou que ambos os algoritmos foram projetados sem o uso de caneta ou papel. Em 1959, ele publicou os dois algoritmos em um artigo de apenas 2 páginas e meia.