【Python資料結構】無向圖的實現及用數學思想相互轉換
PS:此處使用的表示方式只是鄰接矩陣和只存半三角矩陣這兩種。
鄰接矩陣的轉化方法:
- 下三角列表轉化鄰接矩陣(設矩陣的階數為
N
N
N)
對於下三角而言:索引每層都是順序遞增,且第一層只含有一個元素,第二次含有兩個元素,以此類推…故只需確定起點就可由列表轉為矩陣。起點的遞增便可以理解為二階導數是1的一個函式。起點用函式表示即 f ( y + 1 ) = f ( y ) + y + 1 , f ( 0 ) = 0 , 此 處 y 表 示 第 幾 行 . f(y+1)=f(y)+y+1,f(0)=0,此處y表示第幾行. f(y+1)=f(y)+y+1,f(0)=0,此處y表示第幾行.
對於上三角而言:由於是對稱的關係,起點便是變為由該層的對角元素開始,則起點函式便是 g ( x + 1 ) = g ( x ) + x + 2 , x ∈ [ 0 , N − 1 ) , g ( 0 ) = 0 , 此 處 x 表 示 第 幾 行 g(x+1)=g(x)+x+2,x∈[0, N-1),g(0)=0,此處x表示第幾行 g(x+1)=g(x)+x+2,x∈[0,N−1),g(0)=0,此處x表示第幾行,則元素的遞增元素函式為 f ( y + 1 ) = f ( y ) + y + 1 , y ∈ ( x , N − 1 ) , 初 始 狀 態 下 f ( y ) = g ( x ) , 此 處 y 表 示 第 幾 列 , x 表 示 第 幾 行 f(y+1)=f(y)+y+1,y∈(x, N-1),初始狀態下f(y)=g(x),此處y表示第幾列,x表示第幾行 f(y+1)=f(y)+y+1,y∈(x,N−1),初始狀態下f(y)=g(x),此處y表示第幾列,x表示第幾行
時間複雜度是 O ( n ) O(n) O(n)
…- 下三角起點函式: f ( y + 1 ) = f ( y ) + y + 1 , f ( 0 ) = 0 , y ∈ [ 0 , N − 1 ) , 此 處 y 表 示 第 幾 行 f(y+1)=f(y)+y+1,f(0)=0,y∈[0,N-1),此處y表示第幾行 f(y+1)=f(y)+y+1,f(0)=0,y∈[0,N−1),此處y表示第幾行
- 下三角元素函式: g ( x + 1 ) = g ( x ) + 1 , x ∈ [ 0 , y − 1 ) , g ( 0 ) = f ( y ) , 此 處 x 表 示 第 幾 列 , y 表 示 第 幾 行 g(x+1)=g(x)+1, x∈[0, y-1),g(0)=f(y),此處x表示第幾列,y表示第幾行 g(x+1)=g(x)+1,x∈[0,y−1),g(0)=f(y),此處x表示第幾列,y表示第幾行
- 上三角起點函式: g ( x + 1 ) = g ( x ) + x + 2 , x ∈ [ 0 , N − 1 ) , g ( 0 ) = 0 , 此 處 x 表 示 第 幾 行 g(x+1)=g(x)+x+2,x∈[0, N-1),g(0)=0,此處x表示第幾行 g(x+1)=g(x)+x+2,x∈[0,N−1),g(0)=0,此處x表示第幾行
- 上三角元素函式: f ( y + 1 ) = f ( y ) + y + 1 , y ∈ ( x , N − 1 ) , 初 始 狀 態 下 f ( y ) = g ( x ) , 此 處 y 表 示 第 幾 列 , x 表 示 第 幾 行 f(y+1)=f(y)+y+1,y∈(x, N-1),初始狀態下f(y)=g(x),此處y表示第幾列,x表示第幾行 f(y+1)=f(y)+y+1,y∈(x,N−1),初始狀態下f(y)=g(x),此處y表示第幾列,x表示第幾行
- 上三角列表轉化鄰接矩陣(設矩陣的階數為
N
N
N)
對於上三角而言:每層都是順序遞增的,只需確定矩陣的總階數,就可上三角元素和下三角元素進行拼接,完成轉換。由於半三角列表滿足等差數列,故總階數函式是 N = f ( l e n g t h ) = 1 + 8 ∗ l e n g t h − 1 2 N=f(length)=\frac {\sqrt{1+8*length}-1}{2} N=f(length)=21+8∗length−1。有了總階數,就可算出每一層對角元素的值,即起點函式為 g ( x + 1 ) = g ( x ) + ( N − x ) , x ∈ [ 0 , N − 1 ) , g ( 0 ) = 0 , 此 處 x 表 示 第 幾 行 g(x+1) = g(x) + (N-x),x∈[0, N-1),g(0) = 0, 此處x表示第幾行 g(x+1)=g(x)+(N−x),x∈[0,N−1),g(0)=0,此處x表示第幾行。
對於下三角而言:起點函式 f ( y ) = y , y ∈ [ 0 , N ) , 此 處 y 表 示 第 幾 行 f(y)=y, y∈[0, N),此處y表示第幾行 f(y)=y,y∈[0,N),此處y表示第幾行,而該行的元素遞增是一個二階導數為-1的函式,元素函式為 g ( x + 1 ) = g ( x ) + [ N − ( x − 1 ) ] , x ∈ [ 0 , y − 1 ) , 初 始 狀 態 下 g ( x ) = f ( y ) , 此 處 x 表 示 第 幾 列 , y 表 示 第 幾 行 g(x+1) = g(x) + [N-(x-1)], x∈[0, y-1), 初始狀態下g(x)=f(y), 此處x表示第幾列,y表示第幾行 g(x+1)=g(x)+[N−(x−1)],x∈[0,y−1),初始狀態下g(x)=f(y),此處x表示第幾列,y表示第幾行
時間複雜度是 O ( n ) O(n) O(n)
…- 下三角起點函式: f ( y ) = y , y ∈ [ 0 , N ) , 此 處 y 表 示 第 幾 行 f(y)=y, y∈[0, N), 此處y表示第幾行 f(y)=y,y∈[0,N),此處y表示第幾行
- 下三角元素函式: g ( x + 1 ) = g ( x ) + [ N − ( x − 1 ) ] , x ∈ [ 0 , y − 1 ) , 初 始 狀 態 下 g ( x ) = f ( y ) , 此 處 x 表 示 第 幾 列 , y 表 示 第 幾 行 g(x+1) = g(x) + [N-(x-1)], x∈[0, y-1), 初始狀態下g(x)=f(y), 此處x表示第幾列,y表示第幾行 g(x+1)=g(x)+[N−(x−1)],x∈[0,y−1),初始狀態下g(x)=f(y),此處x表示第幾列,y表示第幾行
- 上三角起點函式: g ( x + 1 ) = g ( x ) + ( N − x ) , x ∈ [ 0 , N − 1 ) , g ( 0 ) = 0 , 此 處 x 表 示 第 幾 行 g(x+1) = g(x) + (N-x),x∈[0, N-1),g(0) = 0, 此處x表示第幾行 g(x+1)=g(x)+(N−x),x∈[0,N−1),g(0)=0,此處x表示第幾行
- 上三角元素函式: f ( y + 1 ) = f ( y ) + y + 1 , y ∈ ( x , N − 1 ) , 初 始 狀 態 下 f ( y ) = g ( x ) , 此 處 y 表 示 第 幾 列 , x 表 示 第 幾 行 f(y+1)=f(y)+y+1,y∈(x, N-1),初始狀態下f(y)=g(x),此處y表示第幾列,x表示第幾行 f(y+1)=f(y)+y+1,y∈(x,N−1),初始狀態下f(y)=g(x),此處y表示第幾列,x表示第幾行
- 無論是上三角還是下三角,只需在每一行以對角元素為準,向右輸出
b
b
b個元素,向左輸出
a
a
a個元素,只要滿足
a
+
b
+
1
=
N
a+b+1=N
a+b+1=N即可轉換為鄰接矩陣。
設
r
o
w
=
行
數
,
矩
陣
的
階
數
為
N
設row=行數,矩陣的階數為N
設row=行數,矩陣的階數為N
- a = [ 0 , r o w ] a=[0, row] a=[0,row]
- b = [ N − r o w − 1 , N ) b=[N-row-1, N) b=[N−row−1,N)
簡單程式碼實現:
class SymmetryGraph:
def __init__(self, matrix, shape_type):
"""
初始化圖
:param matrix: 鄰接矩陣、上三角形式或下三角形式
:param shape_type: matrix、list_up、list_down
"""
# 圖
self.data = matrix
# 表示形式
self.type = shape_type
# 節點數
if self.type == 'matrix':
self.n = len(self.data)
else:
spot_num = ((8 * len(self.data) + 1) ** 0.5 - 1) / 2
if spot_num == float(int(spot_num)):
self.n = int(spot_num)
else:
raise TypeError('data is not a symmetry graph')
def info(self):
"""
顯示對稱矩陣
:return:
"""
print('=' * self.n * 3)
if self.type == 'matrix':
for i in self.data:
print(str(i).replace(',', ' '))
elif self.type == 'list_up':
num = 0
for i in range(self.n):
row = self.data[num: num + self.n - i]
print('[' + ' ' * (self.n - len(row)) + str(row)[1:].replace(',', ' '))
num += self.n - i
elif self.type == 'list_down':
num = 0
for i in range(self.n):
row = self.data[num: num + i + 1]
print(str(row)[:-1].replace(',', ' ') + ' ' * (self.n - len(row)) + ']')
num += i + 1
def to_convert(self, mode='list', spilt='up'):
"""
轉化對稱矩陣為上三角或下三角陣列
======================================================================
matrix = [
[0, 0, 0, 0, 1],
[0, 0, 1, 1, 0],
[0, 1, 0, 1, 0],
[0, 1, 1, 0, 1],
[1, 0, 0, 1, 0]
]
m = SymmetryGraph(matrix)
m.to_convert(mode='list', spilt='up') # 將對稱矩陣轉化為上三角陣列
m.to_convert(mode='list', spilt='down') # 將對稱矩陣轉化為下三角陣列
matrix_up = [0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0]
m = SymmetryGraph(matrix_up)
m.to_convert(mode='matrix', spilt='up') # 將上三角陣列轉化為對稱矩陣
matrix_down = [0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0]
m = SymmetryGraph(matrix_down)
m.to_convert(mode='matrix', spilt='down') # 將下三角陣列轉化為對稱矩陣
======================================================================
:param mode: 轉換的目標: list, matrix
:param spilt: 陣列的分割: up, down
:return: None
"""
if not self.data:
raise TypeError('graph is empty')
temp = list()
if mode == 'list' and self.type == 'matrix':
if spilt == 'up':
for row in range(len(self.data)):
temp.extend(self.data[row][row:])
self.data = temp
self.type = 'list_up'
elif spilt == 'down':
for row in range(len(self.data)):
temp.extend(self.data[row][:row + 1])
self.data = temp
self.type = 'list_down'
elif mode == 'matrix' and 'list' in self.type:
if spilt == 'up':
i_0, j_0 = 0, 0
for i in range(self.n):
j_0 = i_0
temp.append(self.data[i_0: i_0 + self.n - i])
i_0 += self.n - i
for j in range(len(temp[i]), self.n):
j_0 = j_0 - j
temp[i].insert(0, self.data[j_0])
self.data = temp
elif spilt == 'down':
i_0, j_0 = 0, 0
for i in range(self.n):
row = list()
i_0 += i
for j1 in range(i_0, i_0 + i + 1):
row.append(self.data[j1])
j_0 = j1
for j2 in range(i + 1, self.n):
j_0 += j2
row.append(self.data[j_0])
temp.append(row)
self.data = temp
self.type = 'matrix'
elif mode == 'list' and 'list' in self.type:
self.to_convert(mode='matrix', spilt=self.type.replace('list_', ''))
self.to_convert(mode='list', spilt=spilt)
def conn_status(self, p1, p2):
if self.type == 'matrix':
return self.data[p1][p2]
elif self.type == 'list_up':
[p1, p2] = sorted([p1, p2])
pos = (p1 * (2 * self.n - p1 - 1)) // 2 + p2
return self.data[pos]
elif self.type == 'list_down':
[p1, p2] = sorted([p1, p2], reverse=True)
pos = (p1 * (p1 + 1)) // 2 + p2
return self.data[pos]
matrix0 = [
[0, 0, 0, 0, 1, 1],
[0, 0, 1, 1, 0, 0],
[0, 1, 0, 1, 0, 1],
[0, 1, 1, 0, 1, 1],
[1, 0, 0, 1, 0, 1],
[1, 0, 1, 1, 1, 0]
]
# matrix_down = [0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0]
# matrix_up = [0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0]
m = SymmetryGraph(matrix=matrix0, shape_type='matrix')
m.info()
m.to_convert(mode='list', spilt='down')
m.info()
m.to_convert(mode='list', spilt='up')
m.info()
status = m.conn_status(4, 0)
print('點4和點0的連通性是:', status)
執行結果
==================
[0 0 0 0 1 1]
[0 0 1 1 0 0]
[0 1 0 1 0 1]
[0 1 1 0 1 1]
[1 0 0 1 0 1]
[1 0 1 1 1 0]
==================
[0 ]
[0 0 ]
[0 1 0 ]
[0 1 1 0 ]
[1 0 0 1 0 ]
[1 0 1 1 1 0]
==================
[0 0 0 0 1 1]
[ 0 1 1 0 0]
[ 0 1 0 1]
[ 0 1 1]
[ 0 1]
[ 0]
點4和點0的連通性是: 1
相關文章
- 資料結構學習(C++)——圖【3】(無向圖)(上) (轉)資料結構C++
- 資料結構學習(C++)——圖【3】(無向圖)(下) (轉)資料結構C++
- python資料結構之圖的實現Python資料結構
- 資料結構-雙向連結串列(Python實現)資料結構Python
- python 資料結構之雙向連結串列的實現Python資料結構
- 【資料結構】棧的應用--數制轉換(c++)資料結構C++
- 資料結構(雙向連結串列的實現)資料結構
- JavaScript資料結構——圖的實現JavaScript資料結構
- 資料結構與演算法——有向無環圖的拓撲排序C++實現資料結構演算法排序C++
- Python 實現Excel XLS和XLSX格式相互轉換PythonExcel
- 使用Anaconda實現Python2和Python3共存及相互轉換Python
- JS實現JSON物件與URL引數的相互轉換JSON物件
- Python資料結構——樹的實現Python資料結構
- 資料結構-2.單向連結串列的實現資料結構
- 【資料結構】ArrayList原理及實現資料結構
- Python資料結構——連結串列的實現Python資料結構
- Python 實現Excel和TXT文字格式之間的相互轉換PythonExcel
- 資料結構與演算法 | 棧的實現及應用資料結構演算法
- C++資料結構和pb資料結構的轉換C++資料結構
- 資料結構之php實現單向連結串列資料結構PHP
- 資料結構學習(C++)——雙向連結串列 (轉)資料結構C++
- 資料結構學習(C++)——圖(總結) (轉)資料結構C++
- 資料結構作業——用鄰接表表示無向網資料結構
- 字串和數字的相互轉換字串
- 資料結構 - 圖之程式碼實現資料結構
- js實現的字串和陣列的相互轉換JS字串陣列
- 用go實現常見的資料結構Go資料結構
- python實現字串轉換整數Python字串
- 基本線性資料結構的Python實現資料結構Python
- python 資料結構之單連結串列的實現Python資料結構
- javascript的資料結構快速學-連結串列的實現JavaScript資料結構
- C++實現任意進位制的相互轉換C++
- javascript數字和字串的相互轉換JavaScript字串
- js實現的陣列和CSV格式的相互轉換JS陣列
- python實用小技之資料結構Python資料結構
- JavaScript資料結構——集合的實現與應用JavaScript資料結構
- 資料結構學習總結--圖資料結構
- python 資料結構之順序列表的實現Python資料結構