zoukankan      html  css  js  c++  java
  • python 实现匈牙利算法求解二分图最大匹配

    ​ 重点:理解增广路和取反

    1. 匈牙利算法

    • 求解目标:找到二分图的最大匹配
    • 整体思路:每一步寻找一条增广路径,取反

    2. 关键步骤

    二分图的顶点分为左边点集X和右边点集Y,假定遍历的点集是X。对于每一次迭代的点x_i,

    1. 搜索增广路径:遍历x_i的邻接节点y_j
      1. 如果y_j未匹配,则找到增广路
      2. 如果y_j已匹配,则寻找y_j的匹配节点的增广路径(深搜或者广搜)
    2. 取反:把增广路径中的已经匹配边改成未匹配;未匹配的改成匹配

    3. python代码

    ​ 算法输入为字典形式的特殊邻接表。特殊之处在于字典的键和值的顶点分别属于二分图的左右点集合。

    ​ 深度搜索增广路径函数的参数中的visited_set的作用是避免重复访问。

    # 匈牙利算法(dfs)
    class Hungarian:
    
        def search_extend_path(self, l_node, adjoin_map, l_match, r_match, visited_set):
            '''深度搜索增广路径'''
            for r_node in adjoin_map[l_node]:  # 邻接节点
                if r_node not in r_match.keys():  # 情况1: 未匹配, 则找到增广路径,取反
                    l_match[l_node] = r_node
                    r_match[r_node] = l_node
                    return True
                else:  # 情况2: 已匹配
                    next_l_node = r_match[r_node]
                    if next_l_node not in visited_set:
                        visited_set.add(next_l_node)
                        if self.search_extend_path(next_l_node, adjoin_map, l_match, r_match, visited_set):  # 找到增广路径,取反
                            l_match[l_node] = r_node
                            r_match[r_node] = l_node
                            return True
                        return False
    
        def run(self, adjoin_map):
            '''
            :param adjoin_map: {x_i: [y_j, y_k]}
            :return:
            '''
            l_match, r_match = {}, {}  # 存放匹配
            for lNode in adjoin_map.keys():
                self.search_extend_path(lNode, adjoin_map, l_match, r_match, set())
            return l_match
    
    

    二分图匹配——匈牙利算法和KM算法

  • 相关阅读:
    如何用cmd命令加密文件夹
    C++异常处理
    STRTOK
    如何生成Detours.lib——Detours的使用准备
    学习C++心得与值得一看的书
    工作两年后的感悟
    MFC十八个简单问题转载
    程序员的五种非技术错误 转载
    用VC写DLL中"error LNK2005: _DllMain@12 already defined"的错误
    CxImage
  • 原文地址:https://www.cnblogs.com/vvlj/p/12405725.html
Copyright © 2011-2022 走看看