匈牙利算法学习资料(转载)
2013-04-23 09:23
141 查看
原文地址:匈牙利算法学习资料(转载)作者:依然二分图最大匹配的匈牙利算法:
二分图是这样一个图,它的顶点可以分类两个集合X和Y,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。
最大匹配: 图中包含边数最多的匹配称为图的最大匹配。
完美匹配: 如果所有点都在匹配边上,称这个最大匹配是完美匹配。
最小覆盖:在一个二分图上用最少的点(x 或 y
集合的都行),让每条连接两个点集的边都至少和其中一个点关联。根据konig定理:二分图的最小顶点覆盖数等于最大匹配数。
最小路径覆盖:用尽量少的不相交简单路径(连着n条边)覆盖有向无环图G的所有结点,且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次);解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的i和Y结点集中的i',如果有边i->j,则在二分图中引入边i->j',设二分图最大匹配为m,则结果就是n-m。
最大独立集问题:在N个点的图G中选出m个点,使这m个点两两之间没有边(没有某种关系).求m最大值.如果图G满足二分图条件,则可以用二分图匹配来做.最大独立集点数 = N
- 最大匹配数
二分图最大匹配问题的匈牙利算法:
#include<iostream>
using namespace std;
const int Max = 405;
int n,
m;
// 二分图中x和y中点的数目
int
link[Max];
//
link[x]记录当前与y节点相连的x的节点。
bool map[Max][Max],
vis[Max];
// map[i][j]记录连接x和y的边,如果i和j之间有边则为1,否则为0。
bool dfs(int
u){
//
dfs实现,u表示现在在寻求匹配y的点x。
for(int i = 1; i <= m; i ++)
if(!vis[i] && map[u][i]){
vis[i] = true;
if(link[i] == -1 ||
dfs(link[i])){
//
条件:点i还没匹配,或者link[i]找到新的匹配。
link[i] = u;
return true;
}
}
return false;
}
int MaxMatch(){
int i,num
= 0;
memset(link, -1, sizeof(link));
for(i =
1;i <= n; i ++){
memset(vis, 0, sizeof(vis));
if(bfs(i)) num++;
}
return
num;
}
算法思想:
算法的思路是不停的找增广轨,并增加匹配的个数,增广轨顾名思义是指一条可以使匹配数变多的路径,在匹配问题中,增广轨的表现形式是一条"交错轨",也就是说这条由图的边组成的路径,它的第一条边是目前还没有参与匹配的,第二条边参与了匹配,第三条边没有..最后一条边没有参与匹配,并且始点和终点还没有被选择过.这样交错进行,显然他有奇数条边.那么对于这样一条路径,我们可以将第一条边改为已匹配,第二条边改为未匹配...以此类推.也就是将所有的边进行"反色",容易发现这样修改以后,匹配仍然是合法的,但是匹配数增加了一对.另外,单独的一条连接两个未匹配点的边显然也是交错轨.可以证明,当不能再找到增广轨时,就得到了一个最大匹配.这也就是匈牙利算法的思路.
二分图是这样一个图,它的顶点可以分类两个集合X和Y,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。
最大匹配: 图中包含边数最多的匹配称为图的最大匹配。
完美匹配: 如果所有点都在匹配边上,称这个最大匹配是完美匹配。
最小覆盖:在一个二分图上用最少的点(x 或 y
集合的都行),让每条连接两个点集的边都至少和其中一个点关联。根据konig定理:二分图的最小顶点覆盖数等于最大匹配数。
最小路径覆盖:用尽量少的不相交简单路径(连着n条边)覆盖有向无环图G的所有结点,且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次);解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的i和Y结点集中的i',如果有边i->j,则在二分图中引入边i->j',设二分图最大匹配为m,则结果就是n-m。
最大独立集问题:在N个点的图G中选出m个点,使这m个点两两之间没有边(没有某种关系).求m最大值.如果图G满足二分图条件,则可以用二分图匹配来做.最大独立集点数 = N
- 最大匹配数
二分图最大匹配问题的匈牙利算法:
#include<iostream>
using namespace std;
const int Max = 405;
int n,
m;
// 二分图中x和y中点的数目
int
link[Max];
//
link[x]记录当前与y节点相连的x的节点。
bool map[Max][Max],
vis[Max];
// map[i][j]记录连接x和y的边,如果i和j之间有边则为1,否则为0。
bool dfs(int
u){
//
dfs实现,u表示现在在寻求匹配y的点x。
for(int i = 1; i <= m; i ++)
if(!vis[i] && map[u][i]){
vis[i] = true;
if(link[i] == -1 ||
dfs(link[i])){
//
条件:点i还没匹配,或者link[i]找到新的匹配。
link[i] = u;
return true;
}
}
return false;
}
int MaxMatch(){
int i,num
= 0;
memset(link, -1, sizeof(link));
for(i =
1;i <= n; i ++){
memset(vis, 0, sizeof(vis));
if(bfs(i)) num++;
}
return
num;
}
算法思想:
算法的思路是不停的找增广轨,并增加匹配的个数,增广轨顾名思义是指一条可以使匹配数变多的路径,在匹配问题中,增广轨的表现形式是一条"交错轨",也就是说这条由图的边组成的路径,它的第一条边是目前还没有参与匹配的,第二条边参与了匹配,第三条边没有..最后一条边没有参与匹配,并且始点和终点还没有被选择过.这样交错进行,显然他有奇数条边.那么对于这样一条路径,我们可以将第一条边改为已匹配,第二条边改为未匹配...以此类推.也就是将所有的边进行"反色",容易发现这样修改以后,匹配仍然是合法的,但是匹配数增加了一对.另外,单独的一条连接两个未匹配点的边显然也是交错轨.可以证明,当不能再找到增广轨时,就得到了一个最大匹配.这也就是匈牙利算法的思路.
相关文章推荐
- 匈牙利算法学习资料
- 匈牙利算法学习资料
- [转载] 架构领域学习资料
- ecos 学习资料(转载)
- ACM基本算法分类、推荐学习资料和配套pku习题
- 学习笔记-二分图匹配(匈牙利算法)
- 如何学习小波分析?——小波分析学习方法及学习资料(原创,若转载请标明出处)
- 前端学习资料汇总(转载)
- C语言的学习要从基础,100个经典的算法 (转载)
- 防止程序假死,Application.DoEvents()学习(资料收集、转载)
- 算法与数据结构学习资料及面试
- 学习笔记-二分图匹配(匈牙利算法)
- 【转载】数据结构和算法学习之路
- 【匈牙利算法】【二分图匹配】【转载】趣写算法系列之--匈牙利算法
- 转载 一个游戏程序员的学习资料
- 一个游戏程序员的学习资料【转载】
- 用匈牙利算法求二分图的最大匹配(转载)
- JDBC Batch 学习资料--转载
- 【转载】WF学习资料汇总
- SLAM学习资料整理(转载)