python3回溯找最大團
阿新 • • 發佈:2020-12-12
最近學習圖論的一串小結之三
數學概念見上上篇:最大完全子圖和極大連通子圖
最大團問題分析可以移步這篇博文:回溯、圖論——最大團問題(求最大完全子圖)
程式碼一部分參考了這篇博文:python最大團問題
本篇博文的問題描述:對於無向圖graph,迴圈刪除最大團所包含的節點和邊,直到剩餘各節點獨立
圖graph
主函式:
if __name__ == '__main__': global v, e, graph # nodes為頂點數,edges為邊數,graph為鄰接矩陣 global cn, bestn # cn當前團的頂點數,bestn最大團的頂點數 global corder, bestorder # corder已選的頂點集,bestorder最大團的頂點集 global ori_nodes, delnodes # ori_nodes原始節點列表,delnodes被刪除的節點列表 global nodes, r_nodes ori_nodes = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] delnodes = [] nodes = {} for i, item in enumerate(ori_nodes): nodes[item] = i edges = [['a', 'b', 1], ['a', 'e', 1], ['a', 'd', 1], ['b', 'a', 1], ['b', 'd', 1], ['b', 'e', 1], ['e', 'a', 1], ['e', 'b', 1], ['e', 'd', 1], ['d', 'a', 1], ['d', 'b', 1], ['d', 'e', 1], ['c', 'f', 1], ['c', 'g', 1], ['f', 'c', 1], ['f', 'g', 1], ['g', 'c', 1], ['g', 'f', 1], ['c', 'e', 1], ['h', 'i', 1], ['i', 'h' ,1]] bestorder = [0 for i in range(len(ori_nodes))] while(len(bestorder)>2): load_data(edges) backtrack(0) delnodes = delnodes + bestorder.copy() print('maximum clique:',bestorder) edges = del_clique(edges) print('delete nodes:',delnodes) print('remain nodes:',ori_nodes)
核心回溯找最大團
def backtrack(cur): global v, cn, bestn, corder, bestorder, r_nodes if (cur > v):#最後一個點納入計算 if (cn > bestn): bestn = cn for i in range(v + 1): if corder[i] != 0: bestorder.append(r_nodes[i]) return if (istuan(cur)):#點i與裝入的節點滿足構成完全圖 cn += 1#個數加1 corder[cur] = 1#標記1 backtrack(cur + 1)#向下遞推 cn -= 1#向上回溯 corder[cur] = 0 # 回溯到i if ((cn + v - cur) > bestn): # 界限條件,進入右子樹,不能加入團 backtrack(cur + 1) def istuan(cur): global corder, graph for i in range(cur): if ((corder[i] == 1) and (graph[i][cur] == 0)): return 0 return 1
刪除最大團
#刪除最大團 def del_clique(edges): global bestorder, ori_nodes, nodes, r_nodes for item in bestorder: ori_nodes.remove(item) nodes = {} for i, item in enumerate(ori_nodes): nodes[item] = i r_nodes = {i: k for k, i in nodes.items()} newedges = [] for line in edges: if line[0] not in bestorder and line[1] not in bestorder: newedges.append(line) return newedges
重新整理全域性變數
def load_data(edges):
global v, e, graph
global cn, bestn
global corder, bestorder
global nodes, r_nodes
r_nodes = {i: k for k, i in nodes.items()}
v = len(nodes)
e = len(edges)
graph = [[0 for i in range(v + 1)] for i in range(v + 1)]
cn = 0
bestn = 0
corder = [0 for i in range(v + 1)]
bestorder = []
for line in edges:
graph[nodes[line[0]]][nodes[line[1]]] = 1
graph[nodes[line[1]]][nodes[line[0]]] = 1
return
執行結果