魔法の最小全域木について---プリムアルゴリズムの詳細な説明

最小全域木-プリムアルゴリズムの詳細な説明

まず、最小全域木とは何かを説明しましょう。
ここに画像の説明を挿入
明らかに、これは重み付きのグラフ、つまりネットワーク構造です。いわゆる最小コストはn個の頂点であり、接続されたグラフを(n-1)個のエッジで接続し、重みの合計を最小化します。接続されたグラフを構築するための最小コストスパニングツリーを最小スパニングツリーと呼びます。

プリムアルゴリズム

この図の隣接行列を示します:(
実際、必要な隣接行列を見つけるには、深さ優先探索クリティカル行列アルゴリズムをここで指定する必要がありますが、技術業界には専門分野があります。Primについてのみ説明します。 、そして私は怠惰なので、マトリックスを直接提供します)

    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}

言うまでもありませんが、最初にコードを記述してください。

#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.} 

次に、長すぎない上記のコードを逆アセンブルして、段階的に見ていきましょう。

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

頂点** vex [] **配列の初期化結果

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

重み配列を初期化します** low [] **結果

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

ここでの下位配列の結果は隣接行列のv0行データと同じであるため、下位配列の機能が重みを一時的に格納することであることを明確にできることに注意してください。
注意してください、プリムのコアアルゴリズムが来ています、私はここにたくさんの写真を投稿します

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); 
		 ................
	 }

このコードの機能は「最小」という単語を反映することであり、変数minは重みの低い配列で最小の重みを探し、その目的はスパニングツリーに参加するための最小値を見つけることだと思います。
トラバーサル後検索、我々は低い配列に、最小量は10であり、そのことが分かっJの値は1であり、K = 1ここで出力がなければならないので、(01)。

ここで、このコードで最も重要なことを見てください。low[k] = 0は、この頂点の重みが最小全域木に追加されたことを意味しますしたがって0とすると、使用されたことを意味します。

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;
			 }
		 }	
		 
	 }

この時点で、最小全域木に結合する頂点V1が見つかったので、次のステップは何でしょうか。
もちろん、次の隣接点を見つけることです。この点の重みも最小になることは間違いありません。したがって、この時点で、点V1の隣接点の中で最小の重みを見つける必要があります。このとき、K = 1、この魔法のforループに入りましょう:
電力値の判断条件が0の場合、
最初にこれを見てください。彼は最小スパンツリーに参加していると思います。ここでは配列の重みが小さいことに注意してください。を参照してください。V1の隣接する点の重みの中にいくつかの重みがあり、これらの重みはV0の隣接する点の重みよりも小さいです。小さい重みに遭遇した場合、私たちのアプローチは大きなものを追い出して置くことでなければなりません。小さいものを引き出します。引き込みます。v0ポイントウェイトアレイ

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

low [K] = 0を覚えておいてください

V1ポイント 10 0 18 16 12

比較の結果、j = 2およびj = 6、j = 8の場合、v1の隣接点の重みがv0の隣接点の重みよりも小さいことがわかったため、v1の小さい重みを元の値に入れました。低配列、したがって、新しい低配列が生成されます。

j 0 1 2 3 4 5 6 7 8
0 0 18 11 16 12

新しいウェイト配列にどのポイントを追加しましたか?このとき、頂点vex []配列を導入して、低重み配列に追加されたポイントの頂点座標を記録する
ため、vex []配列は次のようになります。

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

この時点で、最初のループは終了します。上記はprimの基本的なアルゴリズムとアイデアです。次に、次の2つのループのk値、つまり低重み配列の変更と頂点vex配列の変更を示します。 。
2番目のサイクル:

低いアレイ変更

j 0 1 2 3 4 5 6 7 8
0 0 18 11 16 12

おもりの大きさを比較すると、
K = 5になります。
low [K] = 0を覚えておいてください

V5ポイント 11 26 0 17

新しいローアレイ

j 0 1 2 3 4 5 6 7 8
0 0 18 26 0 16 12

vex配列

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

3番目のサイクル:

低いアレイ変更

j 0 1 2 3 4 5 6 7 8
0 0 18 26 0 16 12

重みを比較すると、
K = 8になります。
low [K] = 0を覚えておいてください

V8ポイント 12 8 21 0

新しいローアレイ

j 0 1 2 3 4 5 6 7 8
0 0 8 21 26 0 16 0

vex配列

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

残りはゆっくりとプッシュするのは全員の責任です。このアルゴリズムはゆっくりとプッシュする必要があります。初めてブログを書くときは、あまり熟練しておらず、十分に表現できないことが多いためです。ご容赦ください。 3回はできませんが、それでも気に入るのを忘れないでください!またね!

おすすめ

転載: blog.csdn.net/weixin_43420303/article/details/103337056