匈牙利算法python实现

匈牙利算法理解参考
https://blog.csdn.net/dark_scope/article/details/8880547
https://www.jianshu.com/p/cb685445e8b1

例题及解答

匈牙利算法python实现_第1张图片

左边是题,右边是解答(红色线是算法最终得到的最大匹配)

python实现



"""
N和M分别代表左右边节点的个数,
edges代表节点之间的连线
graph是N*M矩阵, 记录左右节点之间是否存在连线
"""
N = 4
M = 4
edges = [(0,0), (0,1), (1,1), (1,2), (2,0), (2,1), (3,2)]
graph = []
for i in range(N):
    graph.append([])
    for j in range(M):
        if (i, j) in edges:
            graph[i].append(1)
        else:
            graph[i].append(0)
print("初始图: ")
for i in range(N):
    print(graph[i])
print("")



def find(x, graph, match, used):
    """
    x (int): 当前尝试配对的左节点索引
    graph (list[list]): [N[M]], 是N*M矩阵, 记录左右节点之间是否存在连线
    match (list[int]): [M], 记录右节点被分配给坐标哪个节点
    used (list[int]): [M], 记录在本轮配对中某个右节点是否已经被访问过,
        因为每一轮每个右节点只能被访问一次, 否则会被重复配对
    """
    for j in range(M):
        # x和j是存在连线 and (j在本轮还没被访问过)
        if graph[x][j] == 1 and not used[j]:
            used[j] = True
            # j还没被分配 or 成功把j腾出来(通过递归, 给j之前分配的左节点成功分配了另外1个右节点)
            if match[j] == -1 or find(match[j], graph, match, used):
                match[j] = x
                return True
    return False



# match记录左边节点最终与左边哪个节点匹配
match = [-1 for _ in range(M)]
# count记录最终的匹配数
count = 0
## 遍历左节点, 依次尝试配对左边每个节点,
# 对于每次尝试配对的左节点, 
# 如果能在右边找到与之匹配的右节点
# 则匹配数+1
for i in range(N):
    # 每一轮是一次全新的查找, 所以used要重置,
    # 但是是基于前面几轮找到的最优匹配, 所以match是复用的
    used = [False for _ in range(M)]
    if find(i, graph, match, used):
        count += 1

print("最大匹配个数: ", count)
print("右节点匹配到的左节点序号: ", match)




 

你可能感兴趣的:(其他,python,python,算法,数据结构)