python3回溯找最大团

最近学习图论的一串小结之三

数学概念见上上篇:最大完全子图和极大连通子图

最大团问题分析可以移步这篇博文:回溯、图论——最大团问题(求最大完全子图)

代码一部分参考了这篇博文:python最大团问题

本篇博文的问题描述:对于无向图graph,循环删除最大团所包含的节点和边,直到剩余各节点独立

python3回溯找最大团_第1张图片图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

运行结果

python3回溯找最大团_第2张图片

你可能感兴趣的:(图,python,python,图论)