Prim算法

概述

Prim算法是應用貪心算法設計策略實現的生成最小支撐樹的算法,又稱為加點法。與其類似的是Kruskal算法,又稱為加邊法。

什么是最小支撐樹

MST性質及其證明

Prim和kruskal都是貪心策略。
都是利用了MST性質。

Prim算法基本思想

設G=(V,E) 是一個連通賦權圖,V={1,2,...,n}。

1. 設置一個空集S。

2. 隨機選擇一個頂點作為起始加入S,例如加入1,S={1}.

3. 作貪心選擇:從V-S中選取 j 加入S,j 要滿足<i,j>為最小,i∈S。

4. 重復3直至S中包含所有頂點。

Prim算法C實現

1.算法描述

關鍵之處在于如何選擇最小的<i,j>,因此設置兩個數組lowcost,closest。

lowcost[i] = Min(lowcost[i],<i,j>) ,j∈S。

lowcost[i]存儲V-S中 i 頂點到S各頂點的邊中的最小邊權值,例如,S中有頂點1,2,則lowcost[i] = MIn{ <i,1>,<i,2>}。

closest[i] 存儲lowcost[i]最小邊的另一頂點。

S中有頂點1,2,則lowcost[i] = MIn{ <i,1>,<i,2>},假設<i,2>最小則closest[i]=2。

故prim算法可分為如下3部分

1. 初始化lowcost和closest數組,和S數組(S[i]=1,表示i頂點已經進入S集和)

選擇一個初始頂點start,lowcost初始化,lowcost[i]=<i,start>,closest[i]=start。

2. 找到遍歷 lowcost 找最小,如lowcost[k]最小且k不在S中,k加入S,k∈V-S。

3. k加入S后 要更新lowcost和closest。

此時遍歷lowcost,locost[i] = Min{Min(lowcost[i],<i,k>) },k為剛加入S中的頂點,i∈V-S。
若lowcost[i] > <i,k> ,則lowcost[i] = <i,k>,closest[i] = k.

4.重復2,3直至S中包含所有頂點。

2.代碼


void Prim(int *lowcost,int *closest,Graph G)
{
    int count=1,min,*s,start,k,*lowcost,*closest;
    s = malloc((G->n+1)*sizeof(int));
    start =1;
     lowcost = malloc((G->n+1)*sizeof(WItem));
    closest = malloc((G->n+1)*sizeof(int));
// 初始化數組
    for(int i=1;i<=G->n;i++){
        lowcost[i] = G->a[i][start];
        closest[i]=start;
        s[i]=0;
    }

    s[start]=1;printf(" %d ",start);

    while(count<G->n){

// 找最小邊
    min = G->NoEdge;
    for(int i=1;i<=G->n;i++ )
        if(lowcost[i]<min && (!s[i]))
        {
            min = lowcost[i];
            k=i;
        }

// k加入S
    s[k]=1;
    count++;
    printf(" %d ",k);

// 更新數組
    for(int i=1;i<=G->n;i++)
        if(G->a[i][k] < lowcost[i] && (!s[i])) 
        { lowcost[i] = G->a[i][k];
         closest[i] = k;
        }
    }// while
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容