¿Cuál es la diferencia entre los algoritmos de Dijkstra, Kruskal y Prim?

¿Cuál es la diferencia entre los algoritmos de Dijkstra, Kruskal y Prim?

La primera distinción es que el algoritmo de Dijkstra resuelve un problema diferente al de Kruskal y Prim. Dijkstra resuelve el problema de la ruta más corta (desde un nodo específico), mientras que Kruskal y Prim encuentran un árbol de expansión de costo mínimo. La siguiente es una forma modificada de una descripción que escribí en esta página: Algoritmos gráficos.

  • Para cualquier gráfico, un árbol de expansión es una colección de bordes suficiente para proporcionar exactamente un camino entre cada par de vértices. Esta restricción significa que no puede haber circuitos formados por los bordes elegidos.
    • Un árbol de expansión de costo mínimo es aquel que tiene el peso total más pequeño posible (donde el peso representa el costo o la distancia). Puede haber más de un árbol, pero Prim y Kruskal tienen la garantía de encontrar uno de ellos.
    • Para un vértice especificado (digamos X), un árbol de ruta más corta es un árbol de expansión de manera que la ruta desde X a cualquier otro vértice es lo más corta posible (es decir, tiene el mínimo peso posible).

Prim y Dijkstra “hacen crecer” el árbol desde un vértice inicial. En otras palabras, tienen un enfoque “local”; En cada paso, solo consideramos aquellos bordes adyacentes a los vértices elegidos previamente, eligiendo la opción más barata que satisfaga nuestras necesidades. Mientras tanto, Kruskal es un algoritmo “global”, lo que significa que cada borde se elige (con avidez) de todo el gráfico. (En realidad, podría considerarse que Dijkstra tiene algún aspecto global, como se indica a continuación).

Para encontrar un árbol de expansión de costo mínimo:

  • Kruskal (enfoque global): en cada paso, elija el borde más barato disponible en cualquier lugar que no viole el objetivo de crear un árbol de expansión.
  • Prim (enfoque local): elija un vértice inicial. En cada paso sucesivo, elija la arista disponible más barata adjunta a cualquier vértice elegido previamente que no viole el objetivo de crear un árbol de expansión.

Para encontrar un árbol de expansión de camino más corto:

  • Dijkstra: en cada paso, elija el borde adjunto a cualquier vértice previamente elegido (el aspecto local) que hace que la distancia total desde el vértice inicial (el aspecto global) sea lo más pequeña posible, y no viola el objetivo de crear un árbol de expansión .

Los árboles de costo mínimo y los árboles de camino más corto se confunden fácilmente, al igual que los algoritmos Prim y Dijkstra que los resuelven. Ambos algoritmos “crecen” desde el vértice inicial, en cada paso eligiendo un borde que conecta un vértice Y que está en el árbol con un vértice Z que no lo está. Sin embargo, mientras Prim elige el borde más barato, Dijkstra elige el borde que da como resultado el camino más corto de X a Z.

Una ilustración simple es útil para comprender la diferencia entre estos algoritmos y los árboles que producen. En el gráfico a continuación, comenzando desde el vértice A, tanto Prim como Dijkstra comienzan eligiendo el borde AB y luego agregando el borde BD. Aquí es donde los dos algoritmos divergen: Prim completa el árbol agregando el borde DC, mientras que Dijkstra agrega AC o BC, porque los caminos AC y ABC (ambos con una distancia total de 30) son más cortos que el camino ABDC (distancia total 31).

Los tres algoritmos se usan para calcular diferentes cosas.

El algoritmo de Dijkstra se utiliza para calcular la distancia mínima desde un nodo a todos los demás nodos en un gráfico ponderado.

El algoritmo de Kruskal y Prim se usa para calcular el árbol de expansión mínimo.

Voy a hablar un poco sobre cómo estos dos algoritmos son diferentes.

Asumimos un N nodos, M bordes gráfico no dirigido conectado. Elegir entre ellos depende mucho de los valores de N, M y cuál es el formato en el que se da su gráfico.

Kruskal

Comienza con un conjunto de N árboles. Cada árbol está compuesto por un nodo. En cada paso, elige un borde que conecta dos árboles diferentes. Esta ventaja es la que tiene el costo mínimo que aún no se ha elegido.

Para hacer esto, debe ordenar los bordes y luego realizar un seguimiento de los nodos que forman cada árbol. Para esto, es probable que desee utilizar una estructura de datos de conjunto Disjoint .

Remilgado

Prim comienza desde un nodo arbitrario e intenta expandirse a otros nodos y agregarlos al árbol de expansión. Lo hace eligiendo siempre el nodo que puede conectarse a un nodo que ya está en el árbol por un borde de longitud mínima.

La principal dificultad es identificar el nodo que está más cerca de los que ya se agregaron en el árbol de expansión y puede hacerlo en O (log N) utilizando un montón.


Lo que presenté anteriormente es una simplificación de los algoritmos. Si desea obtener más detalles o entender por qué funcionan, intente revisar estos enlaces:

http://faculty.washington.edu/dc

Algoritmo de Kruskal – Wikipedia

More Interesting

¿Cuál es una explicación intuitiva del ataque de cumpleaños en criptografía?

¿Cómo mejorarías el algoritmo de autocorrección?

La inmutabilidad es primordial en la mayoría de los dominios de FP, pero ¿hacen copias superficiales o profundas?

¿Debo postularme a trabajos de desarrollo web si puedo construir aplicaciones CRUD pero no asimilo la notación Big O y nunca he trabajado en un proyecto grupal?

Cómo realizar un recorrido de orden posterior en un árbol binario

¿Cuál es el mejor algoritmo de procesamiento de imágenes para comparar una pintura recibida como entrada contra la base de datos y seleccionar la coincidencia más cercana?

¿Hay algún algoritmo fijo para resolver el cubo de Rubik? Si es así, ¿qué es?

Cómo resolver este problema usando árboles de segmentos

¿Cuáles son ejemplos de la secuencia de Fibonacci en el campo de la ciencia y las artes liberales (economía, sociología, incluso historia, etc.)?

¿Es correcto mi nuevo estado de ánimo? Ingresé a la programación desde un punto de vista de programación algorítmica y, como tal, tengo una inclinación a querer saber cómo funcionan las cosas debajo. Pero ahora, después de un tiempo en el mundo de los desarrolladores, finalmente tengo que darme cuenta de que se trata menos de eso. ¿Lo que usted dice?

¿Cuáles son las ventajas de una matriz?

Cómo escribir un programa ruby ​​para mostrar los números de Armstrong en una matriz (siendo la matriz; Números = [123,124,153,370,234,23,45]

¿Cuáles son los algoritmos que uno debería usar para generar automáticamente intentos de chatbots?

Suponiendo una memoria infinita, ¿siempre es posible aumentar la complejidad de cualquier programa sin introducir redundancia?

Cómo implementar este algoritmo usando Matlab