用 heapq 解最小生成樹 貪心演算法

2021-09-23 23:48:02 字數 2679 閱讀 5213

【問題描述】prim演算法解決的是帶權重的無向圖上連線所有頂點的耗費最小的生成樹。

【輸入形式】在螢幕上輸入頂點個數和連線頂點間的邊的權矩陣。

【輸出形式】從源到各個頂點的最短距離及路徑。

【樣例輸入】

0 15 7 0 0 0 0 10

15 0 0 0 0  0 0 0

7 0 0 9 12 5 0 0 

0 0 9 0 0 0 0 0

0 0 12 0 0 6 0 0

0 0 5 0 6 0 14 8

0 0 0 0 0 14 0 3

10 0 0 0 0 8 3 0

【樣例輸出】

15: 1<-2

7: 1<-3

9: 1<-3<-4

6: 1<-3<-6<-5

5: 1<-3<-6

3: 1<-3<-6<-8<-7

8: 1<-3<-6<-8

【樣例說明】

輸入:頂點個數為8。連線頂點間邊的權矩陣大小為8行8列,位置[i,j]上元素值表示第i個頂點到第j個頂點的距離,0表示兩個頂點間沒有邊連線。

輸出:每行表示其餘各頂點的值及其到起始點1的路徑。

import numpy as np

import heapq

import sys

# v 結點下標

# d 結點到父節點距離

# p 父節點

class node:

def __init__(self, v=none, d=none, p=none):

self.v = v

self.d = d

self.p = p

# 重寫類的比較函式用於優先佇列中節點的優先順序

def __lt__(self, other):

return self.d < other.d

# 使用包裝類對 heapq 進行包裝

# 使 heapq 優先佇列中的元素可以為物件

class heap:

def __init__(self):

self._queue =

# 插入時 tuple 的第乙個元素為結點距父節點的距離

# 即根據結點距離父節點的距離來確定節點的優先順序

def push(self, priority, item):

def pop(self):

if self._queue:

else:

return none

def heapify(self):

heapq.heapify(self._queue)

@property

def queue(self):

return self._queue

# 遞迴列印每個節點的路徑

def traceback(root):

if root is not none:

traceback(root.p)

print(root.v+1, end=" ")

# 列印節點路徑

def print_res(v):

for v in v:

print(v.d, end=": ")

traceback(v)

print()

def prim(w, v):

q = heap()

# 將初始化好的節點放入優先佇列中

for v in v:

q.push(v.d, v)

while q.queue:

# 取出優先佇列中的最小節點

u = q.pop()

# 在優先佇列中查詢

for q in q.queue:

v = q[-1]

# 查詢的條件為當前節點到最小節點之間有路徑

# 且路徑的長度小於當前節點所儲存的其距離父節點的最小路徑路徑長度

if 0 < w[u.v, v.v] < v.d:

# 更新當前節點距離其父節點的最短路徑

v.d = w[u.v, v.v]

# 更新當前節點的父節點為剛剛彈出最小節點

v.p = u

# 對優先佇列進行重新排序

q.heapify()

# 列印最後結果

print_res(v)

def main():

n = int(input())

w = np.zeros((n, n))

v =

for i in range(n):

input_line = input()

input_arr = list(map(int, input_line.split()))

w[i, :] = input_arr

node = node(0, 0, none)

for i in range(1, n):

node = node(i, sys.maxsize, none)

prim(w, v)

if __name__ == '__main__':

main()

0: 1 

15.0: 1 2 

7.0: 1 3 

9.0: 1 3 4 

6.0: 1 3 6 5 

5.0: 1 3 6 

3.0: 1 3 6 8 7 

8.0: 1 3 6 8 

貪心演算法 最小生成樹 Prim演算法

乙個無向帶權圖g v,e 其中n個頂點vertex,以及連線各個頂點之間的邊edge,可能有些頂點之間沒有邊,每條邊上的權值都是非負值。生成樹 g的乙個子圖,包含了所有的vertex,和部分的edge。最小生成樹 所有的生成樹中,各條edge上的權值總和最小的乙個。例子 設計通訊網路時,各個城市之間...

貪心演算法之Prim最小生成樹

滿足貪心演算法的條件是都滿足動態規劃的,只是貪心演算法的條件更強,不僅前乙個步驟的解可以用到後一步,而且前一步的解是子問題的最優解,最後能夠得到全域性的最優解。prim演算法是乙個求最小生成樹的演算法。表示圖g 有鄰接表 用於稀疏矩陣 和鄰接矩陣 用於稠密矩陣 下面我給的例項適合用稀疏矩陣。聽了大概...

貪心演算法之最小生成樹(Prim)

最小生成樹 prim 網路的生成樹中的邊帶權值,將生成樹各邊的權值加起來稱為生成樹的權,權值最小的生成樹稱為為最小生成樹。設g v,e 是連通帶權圖,v prim演算法基本思想 首先置s 然後,只要s是v的真子集,就進行如下貪心選擇 選取滿足條件i s,j v s,且c i j 最小的邊,將頂點j新...