从匈牙利算法到Kuhn-Munkres算法

匈牙利算法要解决的是这样的问题,比如一群男生女生,男生是否有缘可以跟自己喜欢的人在一起。

当然我们简化成集合符号A和B, A和B的大小可以不同,我们只想知道最后按照喜欢的人在一起的话,最多有几对。

匈牙利算法从0开始构建匹配的可能性。如果男生Ai喜欢女生Bj而且女生Bj未匹配,那么她当然可以跟男生Ai在一起了。

但是不要慌,后面的情况还可能变化,Ai可能Bj+1在一起,但是我们保证结果是每次都比原来的成功数要大的。

匈牙利算法当然是解决图论的问题,这里不用A,B了——X和Y两个

从X开始,每次找到一个未配对的点u

抽象的说,是我们在X这边保存了已经访问过的点S,在Y这边类似有T,从u点开始S和T都不断增大,每次只增大1,增大

的规则是u的邻接点y如果已经匹配z,就把y加到T,z加到S,下一步的操作,是换个u, 再将T中没有访问过的点再次考查

一遍。如果y没有匹配,那正好,根据你的访问规则,这个时候u和y肯定可以配对的,这样就可以增加配对了。

我们的工作是为了让配对的个数越来越多,直到最后不能再配对。不能配对的判定就是Hall定理,S的邻接点刚好是T。

由于这个问题实在太过常见,以至于很多人还是像我10分钟前想的例子一样老掉牙。我们还是想个其他的抽象吧。

可能有人会希望说我们可以改成公司面试应聘者,多个公司跟多个应聘者匹配啊。对哦,前提是你们不要拿了offer就跑掉了。

 对了你有没有想到前面说的是男生喜欢女生?如果是这样的话说明什么?我们忽略了方向。所以这个也是一厢情愿的说。

 好了另外一个例子,如果东南亚n国希望出口椰子岛中国各y省,但是一个省只能跟一国签约(现实中没有的)。这个也是

一种问题。那好的,我们现在定个价格,让总的价格最大(喂喂喂),这不是对我们来说的,是对东南亚各国来说的。

 这个就是可以抽象成Kuhn-Munkres算法了。

 对我来说这个问题比较好理解,但是算法比较难证明。看起来就是一个算法的问题。

 我们要设计一个给X,Y标号的函数l,比如 l(x) = 1,然后根据这个函数再多次应用匈牙利算法——多次是感觉得多大?

 当然,这个函数前人已经设计好了。在每次迭代的时候,我们要根据w(xy)跟l(x)+l(y)的关系得到一个生成子图G(就是满足条件的x和y和这些边),然后找最大匹配。当我们经过很多次的匈牙利算法就可以得到最终的结果了。

 文章需要配图吗?我随便写的。先这样吧。

关于匈牙利算法,维基百科有很好的解释,离散数学的课本一般也有介绍。另外Byvoid也有说过。

时间: 2024-11-03 05:38:41

从匈牙利算法到Kuhn-Munkres算法的相关文章

8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来探讨一下非递归方案 实验结果令人还是有些失望,原来非递归方案的性能并不比递归方案性能高 代码如下: package com.newflypig.eightqueen; import java.util.Date; /** * 使用循环控制来实现回溯,解决N皇后 * @author [email pr

操作系统: 最佳适配算法和邻近适配算法的模拟实现(内存分配算法)

实现动态分区的分配算法. (1) 最佳适配算法:选择内存空闲块中最适合进程大小的块分配. (2) 邻近适配算法:从上一次分配的地址开始查找符合要求的块,所查找到的第一个满足要求的空闲块就分配给进程. 模拟添加进程的时候,假定内存是一块完整的空闲区,对于算法(1)来说,分配的时候遍历所有的空闲内存块,找出其中最适合的一块,注意此时内存分区的总块数可能已经发生了变化: 对于算法(2)来说,则需要从上次分配的内存块(使用变量记录即可)接着向下找到第一个满足条件的块即可,内存分区的总块可能也已经发生了变

算法导论——lec 13 贪心算法与图上算法

之前我们介绍了用动态规划的方法来解决一些最优化的问题.但对于有些最优化问题来说,用动态规划就是"高射炮打蚊子",采用一些更加简单有效的方法就可以解决.贪心算法就是其中之一.贪心算法是使所做的选择看起来是当前最佳的,期望通过所做的局部最优选择来产生一个全局最优解. 一. 活动选择问题 [问题]对几个互相竞争的活动进行调度:活动集合S = {a1, a2, ..., an},它们都要求以独占的方式使用某一公共资源(如教室),每个活动ai有一个开始时间si和结束时间fi ,且0 ≤ si &

Breaseman算法绘制圆形|中点算法绘制圆形_程序片段

Breaseman算法绘制圆形|中点算法绘制圆形_程序片段 1. Breaseman算法绘制圆形程序 由于算法的特殊性,限制绘制第一象限部分,其他部分通过旋转绘制. 1 void CCGProjectWorkView::bresenHam_1P4Circle(int radium, const float lineColor[]) 2 { 3 int pointX, pointY, deltD, deltHD, deltDV, direction; 4 pointX = 0; 5 pointY

最小生成树(普利姆算法、克鲁斯卡尔算法)

给定一个加权无向连通图,如何选择一个生成树,使权利的最小总和的边缘所有树,叫最小生成树. 求最小生成树算法 (1) 克鲁斯卡尔算法 图的存贮结构採用边集数组,且权值相等的边在数组中排列次序能够是随意的.该方法对于边相对照较多的不是非常有用,浪费时间. (2) p=1313">普里姆算法 图的存贮结构採用邻接矩阵.此方法是按各个顶点连通的步骤进行,须要用一个顶点集合,開始为空集,以后将以连通的顶点陆续增加到集合中,所有顶点增加集合后就得到所需的最小生成树 . 以下来详细讲下: 克鲁斯卡尔算法

[迷宫中的算法实践]迷宫生成算法——Prim算法

       普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小.该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现:并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现:1959年,艾兹格·迪科斯彻再次发现了该算法.因此,在某些场合,普里姆

CGA填充算法之种子填充算法

CGA填充算法之种子填充算法 平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界 (也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜色(也可能是图案填充).区域填充中最常用的是多边形填色,本文讨论种子填充算法(Seed Filling)   如果要填充的区域是以图像元数据方式给出的,通常使用种子填充算法(Seed Filling)进行区域填充.种子填充算法需要给出图像数据的区域,以及区域内的一个点,这种算法比较适合人机交互方式进

HDU 2544 最短路(我的dijkstra算法模板、SPAFA算法模板)

思路:这道题是基础的最短路径算法,可以拿来试一下自己对3种方法的理解 dijkstra主要是从第一个点开始枚举,每次枚举出当当前最小的路径,然后再以那最小的路径点为起点,求出它到其它未标记点的最短距离 bellman-ford 算法则是假设有向网中有n 个顶点.且不存在负权值回路,从顶点v1 和到顶点v2 如果存在最短路径,则此路径最多有n-1 条边.这是因为如果路径上的边数超过了n-1 条时,必然会重复经过一个顶点,形成回路:而如果这个回路的权值总和为非负时,完全可以去掉这个回路,使得v1到v

算法总结之欧几里德算法

算法总结之欧几里德算法 1.欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个正整数a,b的最大公约数. 其计算原理依赖于下面的定理: gcd(a,b) = gcd(b,a mod b) (a>b 且a mod b 不为0) 代码实现: 1 int gcd(int a,int b) 2 { 3 return b==0?a:gcd(b,a%b); 4 } 2.扩展欧几里德算法 基本算法: 对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y,

底层算法系列:Paxos算法

关于算法,面太广.本系列只研究实际应用中遇到的核心算法.了解这些算法和应用,对java码农进阶是很有必要的. 对于Paxos学习论证过程中,证实一句话:有史以来学习paxos最好的地方wiki:Paxos (computer science) 目录 1.背景 2.Paxos算法 3.Muti-Paxos算法 4.Muti-Paxos在google chubby中的应用 ===============正文分割线============================ 一.背景 Paxos 协议是一