首页 > 编程语言 > 详细

匈牙利算法

时间:2020-08-16 13:28:11      阅读:66      评论:0      收藏:0      [点我收藏+]

匈牙利算法

1 先看一些基础概念:

最大匹配

给定一个二分图G,在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点,则称M是一个匹配。选择这样的边数最大的子集称为图的最大匹配问题,如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。

增广路(增广轨):

若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径(举例来说,有A、B集合,增广路由A中一个点通向B中一个点,再由B中这个点通向A中一个点……交替进行)。

匈牙利算法虽然根本上是最大流算法,但是它不需要建网络模型,所以图中不再需要源点和汇点,仅仅是一个二分图。每条边也不需要有方向。

图1技术分享图片图2技术分享图片
图1是给出的二分图中的一个匹配:[1,5]和[2,6]。图2就是在这个匹配的基础上找到的一条增广路径:3->6->2->5->1->4。

2 回到匈牙利算法:

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。

白话描述具体参考https://blog.csdn.net/dark_scope/article/details/8880547

算法实现参考https://www.cnblogs.com/walter-xh/p/10698834.html

#include <iostream>
#include <array>

using namespace std;

bool line[4][4] = {{true, true, false, false}, {false, true, true, false}, {true, true, false,false}, {false, false, true, false}};
array<bool, 4> used = {false, false, false, false};
array<int, 4> girl = {-1, -1, -1, -1};

bool find(int x){
    for(int i = 0; i < 4; ++i){
        if(line[x][i] == true && used[i] == false){
            used[i] = true;
            if(girl[i] == -1 || find(girl[i])){
                girl[i] = x;
                return true;
            }
        }
    }
    return false;
}

int main(){
    for(int i = 0; i < 4; ++i){
        used.fill(false);
        find(i);
    }
    for(int i = 0; i < 4; ++i){
        cout << "girl: " << i << " <----> " << girl[i] << endl;
    }
    return 0;
}

匈牙利算法

原文:https://www.cnblogs.com/waynew/p/13512092.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!