• 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算法

  • 相关阅读:
    Django的filter查询
    第一篇博客
    算法:位运算加减乘除
    ip头、tcp头、udp头详解及定义,结合Wireshark抓包看实际情况
    linux ls -l 详解
    重要常用的Lunix命令
    开博感言(真正第一篇博客园博客)
    校招与内推:软实力的技巧
    最长公共子串——动态规划求解
    最长公共子序列——动态规划求解
  • 原文地址:https://www.cnblogs.com/vvlj/p/12405725.html
Copyright © 2020-2023  润新知