1. 程式人生 > >最小生成樹,普里姆演算法(Python實現)

最小生成樹,普里姆演算法(Python實現)

December 16, 2015 12:01 PM

1.相關概念

1)生成樹 一個連通圖的生成樹是它的極小連通子圖,在n個頂點的情形下,有n-1條邊。生成樹是對連通圖而言的,是連同圖的極小連通子圖,包含圖中的所有頂點,有且僅有n-1條邊。非連通圖的生成樹則組成一個生成森林;若圖中有n個頂點,m個連通分量,則生成森林中有n-m條邊。

2)和樹的遍歷相似,若從圖中某頂點出發訪遍圖中每個頂點,且每個頂點僅訪問一次,此過程稱為圖的遍歷, (Traversing Graph)。圖的遍歷演算法是求解圖的連通性問題、拓撲排序和求關鍵路徑等演算法的基礎。圖的遍歷順序有兩種:深度優先搜尋(DFS)和廣度優先搜尋(BFS)。對每種搜尋順序,訪問各頂點的順序也不是唯一的。

3)在一個無向連通圖G中,其所有頂點和遍歷該圖經過的所有邊所構成的子圖G′ 稱做圖G的生成樹。一個圖可以有多個生成樹,從不同的頂點出發,採用不同的遍歷順序,遍歷時所經過的邊也就不同。

在圖論中,常常將樹定義為一個無迴路連通圖。對於一個帶權的無向連通圖,其每個生成樹所有邊上的權值之和可能不同,我們把所有邊上權值之和最小的生成樹稱為圖的最小生成樹。求圖的最小生成樹有很多實際應用。例如,通訊線路鋪設造價最優問題就是一個最小生成樹問題。
常見的求最小生成樹的方法有兩種:克魯斯卡爾(Kruskal)演算法和普里姆(Prim)演算法。

2.普里姆(Prim)演算法

1) 演算法的基本思想:

普里姆演算法的基本思想:普里姆演算法是另一種構造最小生成樹的演算法,它是按逐個將頂點連通的方式來構造最小生成樹的。

從連通網路 N = { V, E }中的某一頂點 u0 出發,選擇與它關聯的具有最小權值的邊(u0, v),將其頂點加入到生成樹的頂點集合U中。以後每一步從一個頂點在U中,而另一個頂點不在U中的各條邊中選擇權值最小的邊(u, v),把該邊加入到生成樹的邊集TE中,把它的頂點加入到集合U中。如此重複執行,直到網路中的所有頂點都加入到生成樹頂點集合U中為止。

假設G=(V,E)是一個具有n個頂點的帶權無向連通圖,T(U,TE)是G的最小生成樹,其中U是T的頂點集,TE是T的邊集,則構造G的最小生成樹T的步驟如下:

(1)初始狀態,TE為空,U={v0},v0∈V;

(2)在所有u∈U,v∈V-U的邊(u,v) ∈E中找一條代價最小的邊(u′,v′)併入TE,同時將v′併入U;

重複執行步驟(2)n-1次,直到U=V為止。

在普里姆演算法中,為了便於在集合U和(V-U)之間選取權值最小的邊,需要設定兩個輔助陣列closest和lowcost,分別用於存放頂點的序號和邊的權值。
對於每一個頂點v∈V-U,closest[v]為U中距離v最近的一個鄰接點,即邊 (v,closest[v]) 是在所有與頂點v相鄰、且其另一頂點j∈U的邊中具有最小權值的邊,其最小權值為lowcost[v],即lowcost[v]=cost[v][closest[v]],採用鄰接表作為儲存結構:

設定一個輔助陣列closedge[]:

lowcost域 存放生成樹頂點集合內頂點到生成樹外各頂點的各邊上的當前最小權值;

adjvex域 記錄生成樹頂點集合外各頂點距離集合內哪個頂點最近(即權值最小)。
應用Prim演算法構造最小生成樹的過程:
應用Prim演算法構造最小生成樹的過程

#Prim.py
#王淵
#2015.12.16
#Email:[email protected]

from pylab import *
from mpl_toolkits.mplot3d import Axes3D

#Display the Chinese word
rcParams['font.sans-serif'] = ['SimHei']
rcParams['axes.unicode_minus'] = False

INFINITY = 65535                        #代表無窮大
vexs = array([[0,10,INFINITY,INFINITY,INFINITY,11,INFINITY,INFINITY,INFINITY],#鄰接矩陣
        [10,0,18,INFINITY,INFINITY,INFINITY,16,INFINITY,12],
        [INFINITY,INFINITY,0,22,INFINITY,INFINITY,INFINITY,INFINITY,8],
        [INFINITY,INFINITY,22,0,20,INFINITY,INFINITY,16,21],
        [INFINITY,INFINITY,INFINITY,20,0,26,INFINITY,7,INFINITY],
        [11,INFINITY,INFINITY,INFINITY,26,0,17,INFINITY,INFINITY],
        [INFINITY,16,INFINITY,INFINITY,INFINITY,17,0,19,INFINITY],
        [INFINITY,INFINITY,INFINITY,16,7,INFINITY,19,0,INFINITY],
        [INFINITY,12,8,21,INFINITY,INFINITY,INFINITY,INFINITY,0]])

lengthVex = len(vexs)                   #鄰接矩陣大小
adjvex = zeros(lengthVex)               #連通分量,初始只有第一個頂點,當全部元素為1後,說明連通分量已經包含所有頂點
adjvex[0] = 1;
lowCost = vexs[0,:]                     #記錄與連通分量連線的頂點的最小權值,初始化為與第一個頂點連線的頂點權值
lowCost[0] = 0
count = 0
while (count<9):
    I = (argsort(lowCost))[count]
    print("Vertex   [",count,"]:",I)
    adjvex[I] = lowCost[I]
    print("Edge [",count,"]:",adjvex[I])
    lowCost[I] = 0
    lowCost = array(list(map(lambda x,y:x if x<y else y,lowCost,vexs[I,:])))
    count = count+1
print("The length of the minimum cost spanning tree is: ", sum(adjvex))

執行結果:
Vertex代表依次加入最小生成樹的各頂點,Edge代表依次加入最小生成樹的各條邊,最後給出最小生成樹的總的長度。

Vertex  [ 0 ]: 0
Edge    [ 0 ]: 0.0
Vertex  [ 1 ]: 1
Edge    [ 1 ]: 10.0
Vertex  [ 2 ]: 5
Edge    [ 2 ]: 11.0
Vertex  [ 3 ]: 8
Edge    [ 3 ]: 12.0
Vertex  [ 4 ]: 2
Edge    [ 4 ]: 8.0
Vertex  [ 5 ]: 6
Edge    [ 5 ]: 16.0
Vertex  [ 6 ]: 7
Edge    [ 6 ]: 19.0
Vertex  [ 7 ]: 4
Edge    [ 7 ]: 7.0
Vertex  [ 8 ]: 3
Edge    [ 8 ]: 16.0
The length of the minimum cost spanning tree is:  99.0

相關推薦

小生成樹,演算法Python實現

December 16, 2015 12:01 PM 1.相關概念 1)生成樹 一個連通圖的生成樹是它的極小連通子圖,在n個頂點的情形下,有n-1條邊。生成樹是對連通圖而言的,是連同圖的極小連通子圖,包含圖中的所有頂點,有且僅有n-1條邊。非連通圖的生成

小生成樹---演算法Prim演算法)和克魯斯卡爾演算法Kruskal演算法

      **最小生成樹的性質:MST性質(假設N=(V,{E})是一個連通網,U是頂點集V的一個非空子集,如果(u,v)是一條具有最小權值的邊,其中u屬於U,v屬於V-U,則必定存在一顆包含邊(u,v)的最小生成樹)** # 普里姆演算法(Pri

資料結構圖之二小生成樹--演算法

1 #include <iostream> 2 #include "SeqList.h" 3 #include <iomanip> 4 using namespace std; 5 6 #define INFINITY 65535 7 8 t

小生成樹-----演算法---java版

最小生成樹(自己理解的,不當之處希望有人可以指出) 簡單的說一下最小生成樹: 假設一個圖,它有n個頂點,則只需n-1條邊,就可以將其組成一個連通圖,在各種組合中,所有n-1條邊的權重之和最小的連通圖,就是所謂的最小生成樹.   演算法思想(自己揣摩的,不當之處希

圖->連通性->小生成樹(演算法)

文字描述   用連通網來表示n個城市及n個城市間可能設定的通訊線路,其中網的頂點表示城市,邊表示兩城市之間的線路,賦於邊的權值表示相應的代價。對於n個定點的連通網可以建立許多不同的生成樹,每一棵生成樹都可以是一個通訊網。現在,我們要選擇這樣一個生成樹,使總的耗費最少。這個問題就是構造連通網的最小代價生成樹(

圖->連通性->小生成樹(克魯斯卡爾演算法) 小生成樹(演算法)

文字描述   上一篇部落格介紹了最小生成樹(普里姆演算法),知道了普里姆演算法求最小生成樹的時間複雜度為n^2, 就是說複雜度與頂點數無關,而與弧的數量沒有關係;   而用克魯斯卡爾(Kruskal)演算法求最小生成樹則恰恰相反。它的時間複雜度為eloge (e為網中邊的數目),因此它相對於普里姆演算法而

[Sicily 1090 Highways] 求小生成樹的兩種演算法演算法/克魯斯卡爾演算法

(1)問題描述: 政府建公路把所有城市聯絡起來,使得公路最長的邊最短,輸出這個最長的邊。 (2)基本思路: 使得公路最長的邊最短其實就是要求最小生成樹。 (3)程式碼實現: 普里姆演算法: #

POJ-2421-Constructing Roads小生成樹

connected number this brush first cst 數字 main memory Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26694 Accepted:

資料結構 圖 小子樹C/C++ 演算法Prime

最小子樹有兩個最常用的方法 1、Prime演算法 2、克魯斯卡爾演算法 這裡,小編就先介紹 Prime演算法 思路: 將 圖存入 鄰接表中,這時 建立一個額外空間,是一個結構體陣列 取一個點為樹根,開始,每次找出最小權值 這中演算法是  樹一點點長大,從根,

數據結構之小生成樹(算法)

下一個 iostream 算法 -a mgr height 實例 AI cat 1)普裏姆算法 可取圖中任意一個頂點v作為生成樹的根,之後若要往生成樹上添加頂點w,則在頂點v和頂點w之間必定存在一條邊,並且 該邊的權值在所有連通頂點v和w之間的邊中取值最小。一般情況下,

圖->連通性->小生成樹(算法)

tmp fine 最小 集合 eve list class 一個 數組 文字描述   用連通網來表示n個城市及n個城市間可能設置的通信線路,其中網的頂點表示城市,邊表示兩城市之間的線路,賦於邊的權值表示相應的代價。對於n個定點的連通網可以建立許多不同的生成樹,每一棵生成樹都

小生成樹算法詳解prim+kruskal

span 實現 比較 info 開始 += width map end 最小生成樹概念: 一個有 n 個結點的連通圖的生成樹是原圖的極小連通子圖,且包含原圖中的所有 n 個結點,並且有保持圖連通的最少的邊。 最小生成樹可以用kruskal(克魯斯卡爾)算法或prim(普

大流之Ford-Fulkerson演算法C++實現

本文主要講解最大流問題的Ford-Fulkerson解法。可是說這是一種方法,而不是演算法,因為它包含具有不同執行時間的幾種實現。該方法依賴於三種重要思想:殘留網路,增廣路徑和割。 一、殘留網路 顧名思義,殘留網路是指給定網路和一個流,其對應還可以容納的流組成的網路。具體說來,就是假定一個網

排序演算法python實現

排序演算法一共有2類:    演算法時間fuzh複雜讀與nlogn比較,大為非線性類,小為線性類;         非線性類比較類排序有:交換排序(冒泡,快速),插入排序(簡單插入,shell),歸併排序(2路歸併,多路歸併),選擇排序(簡單選擇,堆排序);      

基於畫素清晰度的影象融合演算法Python實現

# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt import cv2 from math import log from PIL import Image import d

常用查詢資料結構及演算法Python實現

目錄 一、基本概念 二、無序表查詢 三、有序表查詢 3.1 二分查詢(Binary Search) 3.2 插值查詢 3.3 斐波那契查詢 四、線性索引查詢 4.1 稠密索引 4.2 分塊索引 4.3 倒排索引 五、二叉排序樹 六、 平衡二叉樹 七、多路查詢樹(B樹) 7.1 2-3樹 7.2 2-3-4樹

C4.5決策樹演算法Python實現

C4.5演算法使用資訊增益率來代替ID3的資訊增益進行特徵的選擇,克服了資訊增益選擇特徵時偏向於特徵值個數較多的不足。資訊增益率的定義如下: # -*- coding: utf-8 -*- from numpy import * import ma

八皇后問題--遞歸回溯演算法Python實現

前兩天做牛客的時候遇到了一個字串的全排列問題。順便回顧一下八皇后問題。(後附Python程式碼)如何解決八皇后問題?所謂遞歸回溯,本質上是一種列舉法。這種方法從棋盤的第一行開始嘗試擺放第一個皇后,擺放成功後,遞迴一層,再遵循規則在棋盤第二行來擺放第二個皇后。如果當前位置無法擺

對稱加密演算法——DES演算法python實現

一、DES演算法描述         DES演算法總的說來可以兩部分組成: 1、對金鑰的處理。這一部分是把我們用的64位金鑰(實際用的56位,去掉了8個奇偶校驗位)分散成16個48位的子金鑰。 2、對資料的加密。通過第一步生成的子金鑰來加密我們所要加密的資料,最終生成密文。 下面就通過這兩

容易的方式學會單鏈表Python實現

單鏈表與陣列 在本部落格中,我們介紹單鏈表這種資料結構,連結串列結構為基於陣列的序列提供了另一種選擇(例如Python列表)。 基於陣列的序列也會有如下缺點: 一個動態陣列的長度可能超過實際儲存陣列元素所需的長度 在實時系統中對操作的攤銷邊界是不可接受的 在一個數組內部執行插入和刪除操作的代價太高 基於陣