【运筹优化】最大二分匹配问题及两种算法详解 + Python代码实现


本篇文章基于 Python 实现,另一篇文章基于 Java 实现:【运筹优化】最大二分匹配问题及两种算法详解 + Java代码实现

一、最大二分匹配问题

1.1 二分图

二分图,又称二部图,英文名叫 Bipartite graph。

二分图是什么?节点由两个集合组成,且两个集合内部没有边的图。

换言之,存在一种方案,将节点划分成满足以上性质的两个集合。

下图展示了一个二分图的示例:

在这里插入图片描述

1.2 最大二分匹配问题介绍

在最大二分匹配(MBM)问题中,给定一个二分图 G,即分左右两部分,两个部分内部的点没有边连接,要求选出一些边,使得这些边没有公共顶点,且边的数量最大。

上面的描述可能比较抽象,我们可以假想成男女配对。如下图所示,男女之间的连线代表他们互相之间有好感,假设你现在是一个媒婆,你的目标是在不违反男女双方自由意志的前提下,尽可能撮合出最多对的情侣。这就是最大二分匹配问题!

在这里插入图片描述


二、匈牙利算法

2.1 算法介绍

关于匈牙利算法的图解可以参考这篇博客:匈牙利算法-看这篇绝对就够了!

2.1 代码实现

def hungarian(graph):
    # 初始化匈牙利树
    tree = {
    
    'V': set(), 'E': set()}
    # 寻找增广路径
    while True:
        # 找到一条增广路径
        path = find_augmenting_path(graph, tree)
        if len(path['E']) == 0:
            break
        # 更新匈牙利树
        tree['V'].update(path['V'])
        tree['E'].update(path['E'])
    # 返回最大匹配
    return tree


def find_augmenting_path(graph, tree):
    # 初始化增广路径
    path = {
    
    'V': set(), 'E': set()}
    # 寻找增广路径
    for v in graph['V']:
        if v not in tree['V']:
            # 寻找从v出发的增广路径
            path = find_augmenting_path_from(graph, tree, v)
            if len(path['E']) > 0:
                break
    # 返回增广路径
    return path


def find_augmenting_path_from(graph, tree, v):
    # 初始化增广路径
    path = {
    
    'V': set(), 'E': set()}
    # 寻找增广路径
    for e in graph['E']:
        if e[0] == v and e[1] not in tree['V']:
            # 找到一条增广路径
            path['V'].add(v)
            path['V'].add(e[1])
            path['E'].add(e)
            break
    # 返回增广路径
    return path


if __name__ == '__main__':
    graph = {
    
    
        'V': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],
        'E': [
            ('A', 'E'), ('A', 'I'), ('B', 'E'), ('B', 'F'), ('C', 'E'), ('C', 'H'), ('D', 'I'),
            ('E', 'A'), ('I', 'A'), ('E', 'B'), ('F', 'B'), ('E', 'C'), ('H', 'C'), ('I', 'D')
        ]
    }
    res = hungarian(graph)
    print(res)

测试案例

在这里插入图片描述

输出

{
    
    'V': {
    
    'E', 'F', 'B', 'A', 'H', 'C', 'I', 'D'}, 'E': {
    
    ('D', 'I'), ('C', 'H'), ('B', 'F'), ('A', 'E')}}

最大匹配可视化

在这里插入图片描述


三、Hopcroft-karp 算法

暂未完成。

可以参考博客:二分图最大匹配之Hopcroft-Karp算法

猜你喜欢

转载自blog.csdn.net/weixin_51545953/article/details/129024686