Reference
算法流程圖
注意:基本原理方法在文章中有詳細介紹
使用該文章的方法,實現一個圖形相似度的計算,完成模式識別
import numpy as np
class Cycle(object):
def __init__(self, N, E, S):
self.N = N # 元素數量
# [['類型', '連接方式', '尺寸約束'], ['類型', '連接方式', '尺寸約束'], ['類型', '連接方式', '尺寸約束']...]
self.E = E
self.S = S # 對稱性
def __str__(self):
return 'N={}\nE={}\nS={}\n'.format(self.N, self.E, self.S)
__repr__ = __str__
# 幾何元素類型的相似係數
def type_coeff(o1, o2):
if o1 == o2:
return 1
return 0.25
# 幾何元素的連接方式的相似係數
def method_coeff(o1, o2):
if o1 == o2:
return 1
if o1 in (0,6) and o2 in (0,6):
return 0.75
if o1 in (0,6) and o2 in (1,2,5) or o2 in (0,6) and o1 in (1,2,5):
return 0.5
return 0
# if o1 in [0,1,2,6] and o2 in [3,4] or o2 in [0,1,2,6] and o1 in [3,4]:
# return 0
# return 0
# a = method_coeff(1, 1)
# print(a)
# 幾何元素的尺寸約束狀況的相似係數
def size_coeff(o1, o2):
if o1 == o2:
return 1
if o1 in (2,3) and o2 in (2,3):
return 0.75
return 0
# if o1 in (2,3) and o2 in (1,4,5) or o2 in (2,3) and o1 in (1,4,5):
# return 0
# 對稱性的相似係數
def symmtry_coeff(o1, o2):
if o1 == o2:
return 1
return 0
def calculate_Qt(ca, cb):
N = ca.N
qt = 0
for i in range(N):
o1_type = ca.E[i][0] # C1元素類型
o2_type = cb.E[i][0] #
o1_state = ca.E[(i+1) % N][0] # C1連接狀態
o2_state = cb.E[(i+1) % N][0]
qt += type_coeff(o1_type, o2_type) + type_coeff(o1_state, o2_state)
# gt /= (2*N)
return qt/(2*N)
def calculate_Qg(ca, cb):
N = ca.N
qg = 0
for i in range(N):
o1_type = ca.E[i][0] # C1元素類型
o2_type = cb.E[i][0] #
o1_state = ca.E[(i + 1) % N][0] # C1連接狀態
o2_state = cb.E[(i + 1) % N][0]
o1_method = ca.E[i][1] # C3連接方式
o2_method = cb.E[i][1] #
qg += type_coeff(o1_type, o2_type) + type_coeff(o1_state, o2_state) + method_coeff(o1_method, o2_method)
o1_sym = ca.S # C4對稱性
o2_sym = cb.S
qg += symmtry_coeff(o1_sym, o2_sym)
return qg / (3 * N + 1)
def calculate_Qd(ca, cb):
N = ca.N
qd = 0
for i in range(N):
o1_type = ca.E[i][0] # C1元素類型
o2_type = cb.E[i][0] #
o1_state = ca.E[(i + 1) % N][0] # C1連接狀態
o2_state = cb.E[(i + 1) % N][0]
o1_method = ca.E[i][1] # C3連接方式
o2_method = cb.E[i][1] #
o1_size = ca.E[i][2] # C5尺寸約束
o2_size = cb.E[i][2]
qd += type_coeff(o1_type, o2_type) + type_coeff(o1_state, o2_state) \
+ method_coeff(o1_method, o2_method) + size_coeff(o1_size, o2_size)
o1_sym = ca.S # C4對稱性
o2_sym = cb.S
qd += symmtry_coeff(o1_sym, o2_sym)
return qd / (4 * N + 1)
def core(graph, re_graph):
# -1 代表確定性相似 -2 表示模糊性相似 -3 表示完成不相似
graph_similar = []
jude_similar = []
for i in range(len(graph)): # 檢查圖的每一個環
s = ''
qt = 0
qg = 0
qd = 0
qt = calculate_Qt(graph[i], re_graph[i])
if qt == 1:
qg = calculate_Qg(graph[i], re_graph[i])
if qg == 1:
qd = calculate_Qd(graph[i], re_graph[i])
# t = qd
if qd == 1:
s = '確定性相似'
elif qd == 0:
s = '完全不相似'
else:
s = '模糊性相似'
elif qg == 0:
s = '完全不相似'
else:
s = '模糊性相似'
elif qt == 0:
s = '完全不相似'
else:
s = '模糊性相似'
similar = qt + qg + qd
graph_similar.append(similar)
jude_similar.append(s)
return graph_similar, jude_similar
"""
元素類型:
直線:0
圓弧:1
圓:2
樣條曲線:3
鄰接狀態:
連接方式:
垂直連接:0
銳連接:1
鈍連接A:2
鈍連接B:3
相切連接:4
相割連接:5
其它連接:6
尺寸約束狀況:
無尺寸約束:0
線性尺寸:1
直徑類尺寸:2
半徑類尺寸:3
球徑類尺寸:4
螺紋類尺寸:5
對稱性:
不對稱:0
對稱:1
"""
if __name__ == '__main__':
c1 = Cycle(4, [[1, 4, 0], [0, 1, 0], [0, 1, 0], [0, 4, 0]], 1)
c2 = Cycle(1, [[2, -1, 4]], 1)
c3 = Cycle(4, [[1, 5, 0], [0, 0, 0], [0, 1, 0], [0, 5, 0]], 0)
c4 = Cycle(4, [[1, 5, 0], [0, 1, 0], [0, 0, 0], [0, 5, 0]], 0)
Graph = [c1, c2, c3, c4]
c1 = Cycle(4, [[1, 4, 0], [0, 1, 0], [0, 1, 0], [0, 4, 0]], 1)
c2 = Cycle(1, [[2, -1, 4]], 1)
c3 = Cycle(4, [[1, 5, 0], [0, 0, 0], [0, 1, 0], [0, 5, 0]], 0)
c4 = Cycle(4, [[1, 5, 0], [0, 1, 0], [0, 0, 0], [0, 5, 0]], 0)
Graph_re0 = [c1, c2, c3, c4]
c1 = Cycle(4, [[1, 4, 0], [0, 1, 1], [0, 1, 1], [0, 4, 1]], 0)
c2 = Cycle(1, [[2, -1, 3]], 1)
c3 = Cycle(4, [[1, 5, 0], [0, 0, 1], [0, 1, 1], [0, 5, 1]], 0)
c4 = Cycle(4, [[1, 5, 0], [0, 1, 1], [0, 0, 1], [0, 5, 1]], 0)
Graph_re1 = [c1, c2, c3, c4]
c1 = Cycle(4, [[1, 4, 0], [0, 1, 0], [0, 1, 0], [0, 4, 0]], 1)
c2 = Cycle(1, [[2, -1, 4]], 1)
c3 = Cycle(4, [[1, 5, 0], [0, 0, 0], [0, 1, 0], [0, 5, 0]], 0)
c4 = Cycle(4, [[1, 5, 0], [0, 1, 0], [0, 0, 0], [0, 5, 0]], 0)
Graph_re2 = [c1, c2, c3, c4]
c1 = Cycle(4, [[1, 4, 0], [0, 1, 0], [0, 1, 0], [0, 4, 0]], 1)
c2 = Cycle(1, [[2, -1, 2]], 1)
c3 = Cycle(4, [[1, 5, 0], [1, 0, 0], [0, 1, 0], [0, 5, 0]], 0)
c4 = Cycle(4, [[1, 5, 0], [2, 1, 0], [0, 0, 0], [0, 5, 0]], 0)
Graph_re3 = [c1, c2, c3, c4]
c1 = Cycle(4, [[1, 4, 0], [0, 1, 1], [0, 1, 1], [0, 4, 1]], 0)
c2 = Cycle(1, [[2, -1, 3]], 1)
c3 = Cycle(4, [[1, 5, 0], [0, 0, 0], [2, 1, 0], [0, 5, 0]], 0)
c4 = Cycle(4, [[1, 5, 0], [0, 1, 0], [1, 0, 0], [0, 5, 0]], 0)
Graph_re4 = [c1, c2, c3, c4]
# Graph_list = [Graph_re0, Graph_re1, Graph_re2, Graph_re3, Graph_re4]
graph_similar, jude_similar = core(Graph,Graph_re0)
print(graph_similar)
print(jude_similar)
與Graph_re0識別(每條弧的相似性):
與Graph_re1識別(每條弧的相似性):
與Graph_re2識別(每條弧的相似性):
與Graph_re3識別(每條弧的相似性):
與Graph_re4識別(每條弧的相似性):