Entendiendo el algoritmo de Kruskal

    En este tutorial, aprenderá cómo funciona el algoritmo de Kruskal. Además, encontrará ejemplos en lenguaje C.
    El algoritmo de Kruskal es un algoritmo de árbol de expansión mínimo que toma un gráfico como entrada y encuentra un subconjunto de los bordes del gráfico.

  • Forma un árbol con cada vértice
  • Tiene la suma más pequeña de pesos entre todos los árboles que se pueden formar a partir del gráfico.
Cómo funciona el algoritmo de Kruskal

    Pertenece a una clase de algoritmos llamados algoritmos codiciosos Este algoritmo espera encontrar el óptimo global buscando el óptimo local.
    Comenzamos con el borde con el menor peso y seguimos agregando bordes hasta llegar a la meta.
    Los pasos para implementar el algoritmo de Kruskal son los siguientes:

  1. Ordene todos los bordes por peso de menor a mayor
  2. Tome el borde con el peso más pequeño y agréguelo al árbol de expansión. Si agregar un borde provoca un bucle, este borde no se utiliza.
  3. Continúe agregando bordes hasta alcanzar todos los vértices.
Ejemplo de algoritmo de Kruskal

Inserte la descripción de la imagen aquí
    A partir del gráfico ponderado,
Inserte la descripción de la imagen aquí
    seleccione el borde con el peso más pequeño. Si hay varios bordes,
Inserte la descripción de la imagen aquí
    seleccione el siguiente borde más corto y agréguelo.
Inserte la descripción de la imagen aquí
    Seleccione el siguiente borde más corto que no cree un bucle y agréguelo. Seleccione el siguiente borde más corto que no crea un bucle y lo agrega
Inserte la descripción de la imagen aquí
    . Agréguelo y
Inserte la descripción de la imagen aquí
    repita los pasos anteriores hasta que se genere un árbol de expansión

Pseudocódigo del algoritmo de Kruskal

    Cualquier algoritmo de árbol de expansión mínimo gira en torno a si agregar bordes crea un bucle.
    El método más común es un algoritmo llamado Union-Find. El algoritmo Union-Find divide los vértices en grupos y verifica si los dos vértices pertenecen al mismo grupo, juzgando así si agregar un borde crea un bucle.

KRUSKAL(G):
A = ∅
For each vertex v ∈ G.V:
    MAKE-SET(v)
For each edge (u, v) ∈ G.E ordered by increasing order by weight(u, v):
    if FIND-SET(u) ≠ FIND-SET(v):       
    A = A ∪ {
    
    (u, v)}
    UNION(u, v)
return A
C ejemplo
// Kruskal's algorithm in C

#include <stdio.h>

#define MAX 30

typedef struct edge {
    
    
  int u, v, w;
} edge;

typedef struct edge_list {
    
    
  edge data[MAX];
  int n;
} edge_list;

edge_list elist;

int Graph[MAX][MAX], n;
edge_list spanlist;

void kruskalAlgo();
int find(int belongs[], int vertexno);
void applyUnion(int belongs[], int c1, int c2);
void sort();
void print();

// Applying Krushkal Algo
void kruskalAlgo() {
    
    
  int belongs[MAX], i, j, cno1, cno2;
  elist.n = 0;

  for (i = 1; i < n; i++)
    for (j = 0; j < i; j++) {
    
    
      if (Graph[i][j] != 0) {
    
    
        elist.data[elist.n].u = i;
        elist.data[elist.n].v = j;
        elist.data[elist.n].w = Graph[i][j];
        elist.n++;
      }
    }

  sort();

  for (i = 0; i < n; i++)
    belongs[i] = i;

  spanlist.n = 0;

  for (i = 0; i < elist.n; i++) {
    
    
    cno1 = find(belongs, elist.data[i].u);
    cno2 = find(belongs, elist.data[i].v);

    if (cno1 != cno2) {
    
    
      spanlist.data[spanlist.n] = elist.data[i];
      spanlist.n = spanlist.n + 1;
      applyUnion(belongs, cno1, cno2);
    }
  }
}

int find(int belongs[], int vertexno) {
    
    
  return (belongs[vertexno]);
}

void applyUnion(int belongs[], int c1, int c2) {
    
    
  int i;

  for (i = 0; i < n; i++)
    if (belongs[i] == c2)
      belongs[i] = c1;
}

// Sorting algo
void sort() {
    
    
  int i, j;
  edge temp;

  for (i = 1; i < elist.n; i++)
    for (j = 0; j < elist.n - 1; j++)
      if (elist.data[j].w > elist.data[j + 1].w) {
    
    
        temp = elist.data[j];
        elist.data[j] = elist.data[j + 1];
        elist.data[j + 1] = temp;
      }
}

// Printing the result
void print() {
    
    
  int i, cost = 0;

  for (i = 0; i < spanlist.n; i++) {
    
    
    printf("\n%d - %d : %d", spanlist.data[i].u, spanlist.data[i].v, spanlist.data[i].w);
    cost = cost + spanlist.data[i].w;
  }

  printf("\nSpanning tree cost: %d", cost);
}

int main() {
    
    
  int i, j, total_cost;

  n = 6;

  Graph[0][0] = 0;
  Graph[0][1] = 4;
  Graph[0][2] = 4;
  Graph[0][3] = 0;
  Graph[0][4] = 0;
  Graph[0][5] = 0;
  Graph[0][6] = 0;

  Graph[1][0] = 4;
  Graph[1][1] = 0;
  Graph[1][2] = 2;
  Graph[1][3] = 0;
  Graph[1][4] = 0;
  Graph[1][5] = 0;
  Graph[1][6] = 0;

  Graph[2][0] = 4;
  Graph[2][1] = 2;
  Graph[2][2] = 0;
  Graph[2][3] = 3;
  Graph[2][4] = 4;
  Graph[2][5] = 0;
  Graph[2][6] = 0;

  Graph[3][0] = 0;
  Graph[3][1] = 0;
  Graph[3][2] = 3;
  Graph[3][3] = 0;
  Graph[3][4] = 3;
  Graph[3][5] = 0;
  Graph[3][6] = 0;

  Graph[4][0] = 0;
  Graph[4][1] = 0;
  Graph[4][2] = 4;
  Graph[4][3] = 3;
  Graph[4][4] = 0;
  Graph[4][5] = 0;
  Graph[4][6] = 0;

  Graph[5][0] = 0;
  Graph[5][1] = 0;
  Graph[5][2] = 2;
  Graph[5][3] = 0;
  Graph[5][4] = 3;
  Graph[5][5] = 0;
  Graph[5][6] = 0;

  kruskalAlgo();
  print();
}
Algoritmo Kruskal vs algoritmo Prim

    El algoritmo de Prim es otro algoritmo popular de árbol de expansión mínimo, que utiliza una lógica diferente para encontrar el MST (árbol de expansión mínimo) del gráfico. El algoritmo de Prim no comienza desde un borde, sino desde un vértice, y continúa agregando bordes con el menor peso que no están en el árbol hasta que se cubren todos los vértices.

La complejidad del algoritmo de Kruskal

    La complejidad temporal del algoritmo de Kruskal es: O (E log E).

Aplicación del algoritmo de Kruskal
  • Distribuya el cableado eléctrico
  • Para red informática (conexión LAN)
Documentos de referencia

[1] Parewa Labs Pvt. Ltd. Algoritmo de Kruskal [EB / OL] .https: //www.programiz.com/dsa/kruskal-algorithm,2020-01-01.

Supongo que te gusta

Origin blog.csdn.net/zsx0728/article/details/115209971
Recomendado
Clasificación