匈牙利算法python实现

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

例题及解答

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

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)




 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值