1. 程式人生 > 其它 >python3回溯找最大團

python3回溯找最大團

技術標籤:python圖論

最近學習圖論的一串小結之三

數學概念見上上篇:最大完全子圖和極大連通子圖

最大團問題分析可以移步這篇博文:回溯、圖論——最大團問題(求最大完全子圖)

程式碼一部分參考了這篇博文: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

執行結果