匈牙利算法

本贴最后更新于 258 天前,其中的信息可能已经渤澥桑田

二分图最大匹配算法(Hungarian Algorithm)

这个算法的操作与原理及其数学证明都很繁与困难,理解如何应用以及应用场景即可


一、概论介绍

  • 最大匹配:在二分图中最多能找到多少条没有公共端点的边(配对)

示例
image

不难发现,这个二分图的最大匹配是如下(不唯一)

但是最大匹配数为 4

image

  • 下面我们严谨的表述一遍最大匹配

在 G 的一个子图 M 中,M 的边集中的任意两条边都不依附于同一个顶点,则称 M 是一个匹配

选择这样的边数最大的子集称为图的最大匹配问题,最大匹配的边数称为最大匹配数

如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。

  • 下面介绍两个基本概念(交替路与增广路)

交替路: 从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边...形成的路径叫交替路

增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路(agumenting path)

二、算法原理

原理:增广路的性质,增广路中的匹配边总是比未匹配边多一条,所以如果我们放弃一条增广路中的匹配边,选取未匹配边作为匹配边,则匹配的数量就会增加

匈牙利算法就是在不断寻找增广路,如果找不到增广路,就说明达到了最大匹配

可以数学证明这种算法得到的解即为最大匹配数

这个算法的严谨数学证明是比较难的,这里就不加以赘述了,感兴趣可以结合上学期离散数学的图论知识证明,不需要使用任何定理

举例使用:

起始状态尚未匹配,全部都是非匹配边和非匹配点

image

任意选中 x1 与任意其中一个点 y1 匹配

image

选中第二个点 x2,x1 没有已霸占 x2 的任何一个对象,故 x2 与任意一个 y2 匹配即可

image

选中 x3,发现 x3 的第一对象 y1 已经被 x1 占了,于是找出 x3 出发的的交错路径 x3-y1-x1-y4,把交错路中已在匹配上的边 x1-y1 从匹配中去掉,反而匹配剩余的边 x3-y1,x1-y4,这就是增广路技巧

具体操作中将使用 DFS 深度优先搜索

接着选择 x4,发现没有增广路,于是只好选择 y3

image

接着选择 x5,发现有增广路:x5-y4-x1-y1-x3-y7,于是变成如下

image

最后选择 x6,x6 无对象可选,而且没有增广路,于是 x6 没法匹配

此结果即为最大匹配

Code-hxw

typedef struct tagMaxMatch{ int edge[COUNT][COUNT]; bool on_path[COUNT]; int path[COUNT]; int max_match; }GRAPH_MATCH; void outputRes(int *path){ for (int i = 0 ; i<COUNT; i++) { printf("%d****%d\n",i,*(path+i)); } } void clearOnPathSign(GRAPH_MATCH *match){ for (int j = 0 ; j < COUNT ; j++) { match->on_path[j] = false; } } //dfs算法 bool FindAugPath(GRAPH_MATCH *match , int xi){ for (int yj = 0 ; yj < COUNT; yj++) { if ( match->edge[xi][yj] == 1 && !match->on_path[yj]) { match->on_path[yj] = true; if (match->path[yj] == -1 || FindAugPath(match,match->path[yj])) { match->path[yj] = xi; return true; } } } return false; } void Hungary_match(GRAPH_MATCH *match){ for (int xi = 0; xi<COUNT ; xi++) { FindAugPath(match, xi); clearOnPathSign(match); } outputRes(match->path); } int main() { GRAPH_MATCH *graph = (GRAPH_MATCH *)malloc(sizeof(GRAPH_MATCH)); for (int i = 0 ; i < COUNT ; i++) { for (int j = 0 ; j < COUNT ; j++) { graph->edge[i][j] = 0; } } graph->edge[0][1] = 1; graph->edge[0][0] = 1; graph->edge[1][1] = 1; graph->edge[1][2] = 1; graph->edge[2][1] = 1; graph->edge[2][0] = 1; graph->edge[3][2] = 1; //举例 for (int j = 0 ; j < COUNT ; j++) { graph->path[j] = -1; graph->on_path[j] = false; } Hungary_match(graph); }

参考学习资料:

**[1]**​匈牙利算法(二分图) - 神犇(shenben) - 博客园 (cnblogs.com)

  • 算法
    424 引用 • 254 回帖 • 24 关注
1 操作
XiaoweiH 在 2024-10-10 00:26:33 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用 • 9 关注
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 735 关注
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 59 关注
  • Office

    Office 现已更名为 Microsoft 365. Microsoft 365 将高级 Office 应用(如 Word、Excel 和 PowerPoint)与 1 TB 的 OneDrive 云存储空间、高级安全性等结合在一起,可帮助你在任何设备上完成操作。

    5 引用 • 34 回帖
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    12 引用 • 5 回帖 • 635 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1251 回帖 • 395 关注
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    554 引用 • 675 回帖
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    134 引用 • 1127 回帖 • 109 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 4 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖 • 1 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    167 引用 • 408 回帖 • 491 关注
  • GraphQL

    GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

    4 引用 • 3 回帖 • 10 关注
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    115 引用 • 318 回帖
  • OneDrive
    2 引用 • 4 关注
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 27 关注
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    336 引用 • 324 回帖 • 1 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    76 引用 • 258 回帖 • 627 关注
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖 • 1 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 820 关注
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    10 引用 • 77 回帖
  • danl
    173 关注
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1443 引用 • 10082 回帖 • 497 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 52 关注
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    500 引用 • 1395 回帖 • 243 关注
  • JSON

    JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。易于人类阅读和编写。同时也易于机器解析和生成。

    53 引用 • 190 回帖 • 1 关注
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    413 引用 • 3590 回帖
  • Hibernate

    Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

    39 引用 • 103 回帖 • 729 关注