Acerca del árbol de expansión mínimo mágico --- Explicación detallada del algoritmo Prim

Explicación detallada mínima del árbol de expansión del algoritmo Prim

Primero, expliquemos qué es un árbol de expansión mínimo:
Inserte la descripción de la imagen aquí
Obviamente, este es un gráfico con pesos, es decir, la estructura de la red. El llamado costo mínimo es n vértices, conecte un gráfico conectado con (n-1) aristas y minimice la suma de pesos. Llamamos al árbol de expansión de costo mínimo para construir un gráfico conectado como el árbol de expansión mínimo.

Algoritmo prim


Permítanme darles la matriz de adyacencia de esta imagen: (De hecho, el algoritmo de matriz crítica de búsqueda en profundidad primero debería proporcionarse aquí para encontrar la matriz de adyacencia que necesitamos, pero hay especialidades en la industria técnica. Solo hablamos de Prim , y como soy vago, te daré una matriz directamente)

    v0  v1  v2  v3  v4  v5  v6  v7  v8 
v0 {
    
     0  10  ∞   ∞   ∞   11   ∞   ∞   ∞} 
v1 {
    
     10  0  18  ∞   ∞   ∞   1612} 
v2 {
    
     ∞   ∞  0  22   ∞   ∞    ∞   ∞   8}
v3 {
    
     ∞   ∞  22  0   20  ∞    ∞  16  21}
v4 {
    
     ∞   ∞  ∞  20   0   267}
v5 {
    
     11  ∞  ∞   ∞   26  0   17   ∞   ∞}
v6 {
    
    16  ∞   ∞   ∞   17   0  19}
v7 {
    
     ∞   ∞  ∞  16   719   0}
v8 {
    
    12  8  21   ∞   ∞   ∞    ∞   0}

No hay mucho que decir, codifique primero;

#define INF 65535           //代表无穷大 
1.void MinispanTree-Prim(Mgraph G)
2.{
    
    
3.	int min,i,j,k;
4.	int low[G.vex];          //定义一个数组,存储权值
5.	int vex[G.vex];          //存储顶点变化,请认真注意数组变化
6.	//初始化 
7.	vex[0]=0;                //初始化第一个权值为0,即V0加入生成树   
8.	low[0]=0;                //初始化第一个顶点下标为0
9.	//以下代码见下详解 
10.	for(i=1;i<G.vex;i++)
11.	{
    
    
12.		vex[i]=0;
13.		low[i]=G.arc[0][i];   
14.	 } 
15.	 
16.	 for(i=1;i<G.vex;i++)        //循环次数 
17.	 {
    
    
18.	    min=INF;                 
19.	    k=0;
20.	 	for(j=1;j<G.vex;j++)
21.		 {
    
    
22.		 	if(low[j]!=0 && low[j]<min)
23.	 	    {
    
    
24.	 		   min=low[j];
25.	 		   k=j;
26.		    } 
27.		  } 
28.		  printf("(%d,%d)\n",vex[k],k);
29.	 	low[k]=0;
30.	 	for(j=1;j<G.vex;j++)
31.	 	{
    
    
32.	 		if(low[j]!=0 && G.arc[k][j]<low[j])
33.	 		{
    
    
34.	 			low[j]=G,arc[k][j];
35.	 			vex[j]=k;
36.			 }
37.		 }	 
38.	 }
39.} 

Ahora desmontemos el código anterior que no es demasiado largo y veámoslo paso a paso:

10.	for(i=1;i<G.vex;i++)   //这段代码作用就是初始化,简单明了
11.	{
    
    
12.		vex[i]=0;
13.		low[i]=G.arc[0][i];   
14.	 } 

Vertex ** vex [] ** resultado de inicialización de matriz

v0 v1 v2 v3 v4 v5 v6 v7 v8
0 0 0 0 0 0 0 0 0

Inicializar la matriz de peso ** resultado bajo [] **

j 0 1 2 3 4 5 6 7 8
bajo 0 10 11

Tenga en cuenta que el resultado de la matriz baja aquí es el mismo que los datos de la fila v0 de la matriz de adyacencia, por lo que podemos dejar en claro que la función de la matriz baja es almacenar temporalmente los pesos.
Presta atención, el algoritmo central de prim está por llegar, publicaré muchas imágenes aquí.

for(i=1;i<G.vex;i++)        //循环次数 ,因为有9个顶点,所以我们需要循环(9-1)次,因为V0点我们默认
                           //已经进入了最小生成树
	 {
    
    
	    min=INF;          //INF是最大值,代表无穷大
	    k=0;
	 	for(j=1;j<G.vex;j++)
		 {
    
    
		 	if(low[j]!=0&&low[j]<min)
	 	    {
    
    
	 		   min=low[j];     //找出权值数组中最小的权值,并且记录下标
	 		   k=j;
		    } 
		  } 
		  printf("(%d,%d)\n",vex[k],k); 
		 ................
	 }

Creo que la función de este código es reflejar la palabra "mínimo", la variable min busca el peso mínimo en la matriz de peso bajo, y su propósito es encontrar un mínimo para unirse al árbol de expansión.
Después de recorrer y buscar, encontramos que en la matriz baja, el peso más pequeño es 10, y su valor j es 1 , es decir, k = 1 , por lo que la salida aquí debería ser ( 0 , 1 );

Ahora mire lo más importante en este código, bajo [k] = 0 significa que el peso de este vértice se ha agregado al árbol de expansión mínimo, por lo que lo dejamos ser 0 , lo que significa que se ha usado;

for(i=1;i<G.vex;i++)        //循环次数 
	 {
    
    
	   .............
	 	low[k]=0;        
	 	for(j=1;j<G.vex;j++)

	 	{
    
    
	 		if(low[j]!=0&&G.arc[k][j]<low[j])
	 		{
    
    
	 			low[j]=G,arc[k][j];
	 			vex[j]=k;
			 }
		 }	
		 
	 }

En este punto, hemos encontrado un vértice V1 para unirse al árbol de expansión mínimo, entonces, ¿cuál debería ser el siguiente paso?
Por supuesto, es para encontrar el siguiente punto adyacente. No hay duda de que el peso de este punto también debe ser el más pequeño. Por lo tanto, en este momento, debemos encontrar el peso más pequeño entre los puntos adyacentes del punto V1. En este momento , K = 1, ahora ingresemos este bucle for mágico:

primero mire esto si las condiciones de juicio en el valor de potencia son 0, creemos que se ha unido al árbol de expansión mínimo, tenga en cuenta que aquí está el bajo peso de la matriz, asegúrese de ver; en Entre los pesos de los puntos vecinos de V1, encontramos algunos pesos, y estos pesos son más pequeños que los pesos de los puntos vecinos de V0. Al encontrar pesos más pequeños, nuestro enfoque debe ser patear los grandes y poner los pequeños hacia afuera. Tire hacia adentro;
matriz de peso de 0 puntos

j 0 1 2 3 4 5 6 7 8
bajo 0 10 11

Recuerda bajo [K] = 0

Punto V1 10 0 18 dieciséis 12

Después de la comparación, encontramos que cuando j = 2 y j = 6, j = 8, el peso del punto adyacente de v1 es menor que el peso del punto adyacente de v0, por lo que colocamos el peso pequeño de v1 en el original. matriz baja, por lo que se genera una nueva matriz baja:

j 0 1 2 3 4 5 6 7 8
bajo 0 0 18 11 dieciséis 12

¿Qué puntos agregamos a la nueva matriz de pesos? En este momento, introducimos la matriz de vértices vex [] para registrar las coordenadas de los vértices de los puntos agregados a la matriz de bajo peso,
por lo que la matriz vex [] se convierte en:

v0 v1 v2 v3 v4 v5 v6 v7 v8
0 0 1 0 0 0 1 0 1

En este punto, el primer ciclo ha terminado. Lo anterior es el algoritmo básico y las ideas de prim. A continuación, daré el valor k de los dos ciclos siguientes, el cambio de la matriz de bajo peso y el cambio de la matriz de vértice vex .
El segundo ciclo:

bajo cambio de matriz

j 0 1 2 3 4 5 6 7 8
bajo 0 0 18 11 dieciséis 12

Después de comparar el tamaño del peso, obtenemos
K = 5
Recuerda bajo [K] = 0

Punto V5 11 26 0 17

Nueva matriz baja

j 0 1 2 3 4 5 6 7 8
bajo 0 0 18 26 0 dieciséis 12

matriz vex

v0 v1 v2 v3 v4 v5 v6 v7 v8
0 0 1 0 5 0 1 0 1

El tercer ciclo:

bajo cambio de matriz

j 0 1 2 3 4 5 6 7 8
bajo 0 0 18 26 0 dieciséis 12

Después de comparar los pesos, obtenemos
K = 8
Recuerda bajo [K] = 0

Punto V8 12 8 21 0

Nueva matriz baja

j 0 1 2 3 4 5 6 7 8
bajo 0 0 8 21 26 0 dieciséis 0

matriz vex

v0 v1 v2 v3 v4 v5 v6 v7 v8
0 0 8 8 5 0 1 0 1

El resto depende de todos para avanzar lentamente. Este algoritmo debe impulsarse lentamente, porque la primera vez que escribo un blog, muchas cosas no son muy competentes y no se pueden expresar por completo. Perdóneme, si es útil para usted, No puedo hacerlo tres veces. Incluso, ¡recuerda que me gusta! ! ! ! ! ! ¡Hasta la próxima!

Supongo que te gusta

Origin blog.csdn.net/weixin_43420303/article/details/103337056
Recomendado
Clasificación