问题背景

给定一个x与y对应的连接图,要求每个xi与yi最多只能匹配一次,求最大的匹配次数

求解思路

(1)将x与y的连接转换成矩阵,可相互连接标记为1,其余为0

y1 y2 y3 y4 y5 y6 y7
x1 1 1 0 1 0 0 0
x2 0 1 0 0 1 0 0
x3 1 0 0 1 0 0 1
x4 0 0 1 1 0 1 0
x5 0 0 0 1 0 0 0
x6 0 0 0 1 0 0 0

(2)最外层循环x1到x6,即第一行到第六行,每一行分别从y1到y7遍历

(3)其中used_b = [0, 0, 0, 0, 0, 0, 0]为某一行中被使用的y1

(4)conection_b = [-1,-1,-1,-1,-1,-1,-1]其中每个元素的取值范围为0-5,代表了y对应的第几行x

(5)从第一行开始,选中了y1,conection_b发生变化[0, -1, -1, -1, -1, -1, -1]

i: 0
find: 0
_index: 0
_used_b: [1, 0, 0, 0, 0, 0, 0]
_conection_b: [-1, -1, -1, -1, -1, -1, -1]
index: 0
conection_b: [0, -1, -1, -1, -1, -1, -1]
count
y1 y2 y3 y4 y5 y6 y7
x1 1 1 0 1 0 0 0

(6)第二行,选中了y2,conection_b发生变化[0, 1, -1, -1, -1, -1, -1]

i: 1
find: 1
_index: 1
_used_b: [0, 1, 0, 0, 0, 0, 0]
_conection_b: [0, -1, -1, -1, -1, -1, -1]
index: 1
conection_b: [0, 1, -1, -1, -1, -1, -1]
count
y1 y2 y3 y4 y5 y6 y7
x1 1 1 0 1 0 0 0
x2 0 1 0 0 1 0 0

(7)第三行,选中了y1,由于第一行也选中了y1,因此进入递归

i: 2
find: 2
_index: 0
_used_b: [1, 0, 0, 0, 0, 0, 0]
_conection_b: [0, 1, -1, -1, -1, -1, -1]
find: 0
_index: 1
_used_b: [1, 1, 0, 0, 0, 0, 0]
_conection_b: [0, 1, -1, -1, -1, -1, -1]
find: 1
_index: 4
_used_b: [1, 1, 0, 0, 1, 0, 0]
_conection_b: [0, 1, -1, -1, -1, -1, -1]
index: 4
conection_b: [0, 1, -1, -1, 1, -1, -1]
index: 1
conection_b: [0, 0, -1, -1, 1, -1, -1]
index: 0
conection_b: [2, 0, -1, -1, 1, -1, -1]
count
y1 y2 y3 y4 y5 y6 y7
x1 1 1 0 1 0 0 0
x2 0 1 0 0 1 0 0
x3 1 0 0 1 0 0 1

(8)得到冲突行的index为0,因此开始find(0),发现y2也被使用,因此继续递归find(1)

y1 y2 y3 y4 y5 y6 y7
x1 1 1 0 1 0 0 0
x2 0 1 0 0 1 0 0
x3 1 0 0 1 0 0 1

(9)最后x2找到了y5,因此递归结束,conection_b: [2, 0, -1, -1, 1, -1, -1]

y1 y2 y3 y4 y5 y6 y7
x1 1 1 0 1 0 0 0
x2 0 1 0 0 1 0 0
x3 1 0 0 1 0 0 1

(10)第四行,选中了y3,由于没有冲突,所以conection_b: [2, 0, 3, -1, 1, -1, -1]

i: 3
find: 3
_index: 2
_used_b: [0, 0, 1, 0, 0, 0, 0]
_conection_b: [2, 0, -1, -1, 1, -1, -1]
index: 2
conection_b: [2, 0, 3, -1, 1, -1, -1]
count
y1 y2 y3 y4 y5 y6 y7
x1 1 1 0 1 0 0 0
x2 0 1 0 0 1 0 0
x3 1 0 0 1 0 0 1
x4 0 0 1 1 0 1 0

(11)第五行,选中了y4,由于没有冲突,所以conection_b: [2, 0, 3, 4, 1, -1, -1]

i: 4
find: 4
_index: 3
_used_b: [0, 0, 0, 1, 0, 0, 0]
_conection_b: [2, 0, 3, -1, 1, -1, -1]
index: 3
conection_b: [2, 0, 3, 4, 1, -1, -1]
count
y1 y2 y3 y4 y5 y6 y7
x1 1 1 0 1 0 0 0
x2 0 1 0 0 1 0 0
x3 1 0 0 1 0 0 1
x4 0 0 1 1 0 1 0
x5 0 0 0 1 0 0 0

(12)第六行,选中了y4,由于与第五行发生了冲突,所以进入递归find(4)

y1 y2 y3 y4 y5 y6 y7
x1 1 1 0 1 0 0 0
x2 0 1 0 0 1 0 0
x3 1 0 0 1 0 0 1
x4 0 0 1 1 0 1 0
x5 0 0 0 1 0 0 0
x6 0 0 0 1 0 0 0
i: 5
find: 5
_index: 3
_used_b: [0, 0, 0, 1, 0, 0, 0]
_conection_b: [2, 0, 3, 4, 1, -1, -1]
find: 4
used_b: [0, 0, 0, 1, 0, 0, 0]
conection_b: [2, 0, 3, 4, 1, -1, -1]
5

(13)由于第五行中除了y4,没有其他可选线项,因此 find(4) = 0,conection_b没有被改变,因此:conection_b: [2, 0, 3, 4, 1, -1, -1]

y1 y2 y3 y4 y5 y6 y7
x1 1 1 0 1 0 0 0
x2 0 1 0 0 1 0 0
x3 1 0 0 1 0 0 1
x4 0 0 1 1 0 1 0
x5 0 0 0 1 0 0 0
x6 0 0 0 1 0 0 0

代码

>>>def find(x):
...    print("find:", x)
...    for index in range(7):
...        if matrix[x][index] == 1 and used_b[index] == 0:
...            used_b[index] = 1
...            print("_index:", index)
...            print("_used_b:", str(used_b))
...            print("_conection_b:", str(conection_b))
...            if conection_b[index] == -1 or find(conection_b[index]) != 0:
...                print("index:", index)
...                conection_b[index] = x
...                print("conection_b:", str(conection_b))
...                return 1
...    return 0
>>>matrix = [
...    [1,1,0,1,0,0,0],
...    [0,1,0,0,1,0,0],
...    [1,0,0,1,0,0,1],
...    [0,0,1,1,0,1,0],
...    [0,0,0,1,0,0,0],
...    [0,0,0,1,0,0,0]
...    ]
>>>conection_b = [-1 for _ in range(7)]
>>>count = 0
>>>for i in range(6):
...    used_b = [0 for _ in range(7)]
...    print("i:",i)
...    if find(i):
...        print("count")
...        count += 1
>>>print("used_b:", str(used_b))
>>>print("conection_b:", str(conection_b))
>>>print(count)
i: 0
find: 0
_index: 0
_used_b: [1, 0, 0, 0, 0, 0, 0]
_conection_b: [-1, -1, -1, -1, -1, -1, -1]
index: 0
conection_b: [0, -1, -1, -1, -1, -1, -1]
count
i: 1
find: 1
_index: 1
_used_b: [0, 1, 0, 0, 0, 0, 0]
_conection_b: [0, -1, -1, -1, -1, -1, -1]
index: 1
conection_b: [0, 1, -1, -1, -1, -1, -1]
count
i: 2
find: 2
_index: 0
_used_b: [1, 0, 0, 0, 0, 0, 0]
_conection_b: [0, 1, -1, -1, -1, -1, -1]
find: 0
_index: 1
_used_b: [1, 1, 0, 0, 0, 0, 0]
_conection_b: [0, 1, -1, -1, -1, -1, -1]
find: 1
_index: 4
_used_b: [1, 1, 0, 0, 1, 0, 0]
_conection_b: [0, 1, -1, -1, -1, -1, -1]
index: 4
conection_b: [0, 1, -1, -1, 1, -1, -1]
index: 1
conection_b: [0, 0, -1, -1, 1, -1, -1]
index: 0
conection_b: [2, 0, -1, -1, 1, -1, -1]
count
i: 3
find: 3
_index: 2
_used_b: [0, 0, 1, 0, 0, 0, 0]
_conection_b: [2, 0, -1, -1, 1, -1, -1]
index: 2
conection_b: [2, 0, 3, -1, 1, -1, -1]
count
i: 4
find: 4
_index: 3
_used_b: [0, 0, 0, 1, 0, 0, 0]
_conection_b: [2, 0, 3, -1, 1, -1, -1]
index: 3
conection_b: [2, 0, 3, 4, 1, -1, -1]
count
i: 5
find: 5
_index: 3
_used_b: [0, 0, 0, 1, 0, 0, 0]
_conection_b: [2, 0, 3, 4, 1, -1, -1]
find: 4
used_b: [0, 0, 0, 1, 0, 0, 0]
conection_b: [2, 0, 3, 4, 1, -1, -1]
5

总结

匈牙利算法的核心思想为:优先考虑最后一行,如果发生冲突,则寻找冲突行可替代项,如果没有可替代项,丢弃最后一行,如果有可替代项,则使用其替代,如果替代之后发生冲突则进入递归,发现冲突不可解除,则丢弃最后一行,冲突可以解除,则使用该方案。

find递归函数的意义在于回溯上一阶段方案能否找到可替代项,使得整个匹配方案之间两两不发生冲突。

匈牙利算法寻找最大匹配相关推荐

  1. nyoj239 月老的难题 (匈牙利算法,最大匹配,邻接表)

    题目239 题目信息 运行结果 本题排行 讨论区 月老的难题 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. ...

  2. hdu 4160 Dolls 匈牙利算法求最大匹配

    Dolls                                                                               Time Limit: 2000 ...

  3. 【模板】匈牙利算法 二分图最大匹配题模板

    [任务] 给定一个二分图,用匈牙利算法求这个二分图的最大匹配数. [说明] 求最大匹配,那么我们希望每一个在左边的点都尽量找到右边的一个点和它匹配. 我们一次枚举左边的点x的所有出边指向的点y, 若y ...

  4. 浅谈匈牙利算法(二分图最大匹配)

    前置知识 一张图是二分图,当且仅当它的点可以被分成两部分,而这张图上的所有边的两个端点,都分属不同的部分.我们称这两个点集,一个叫左部,一个叫右部.左部中的点叫左部点:右部中的点叫右部点. 一张图的一 ...

  5. POJ-3041 匈牙利算法 二分图最大匹配

    踢以 给出多个点的坐标 有一种攻击 可以把一次干掉同一列的 或者干掉同一行的 求最少的攻击次数 肥西 由于问题是问选取最少的行和列干掉所有的陨石 可以把输入的r和c看成r和c之间有一条连边因为要实现干 ...

  6. 【HDU - 2444】The Accomodation of Students(二分图判断 + 匈牙利算法求最大匹配)

    题干: There are a group of students. Some of them may know each other, while others don't. For example ...

  7. 二分图最大匹配——匈牙利算法

    二分图最大匹配 (一).二分图的介绍 1.定义 2.充要条件 (二).二分图的匹配 1.二分图的最大匹配 2.增广路径 3.匈牙利算法 (1).复杂度 (2).算法思路 (3).代码实现 (一).二分 ...

  8. 二分图匹配--匈牙利算法

    文章目录 二分图: 匹配 匈牙利算法 代码: 二分图: 二分图是一个无向图,点集分成子集X和Y,图中每一条边都是一边在X一边在Y 当且仅当无向图G的每一个回路次数都是偶数时(包括0),G就是一个二分图 ...

  9. 图论二分图问题讲解-染色法和匈牙利算法

    二分图 概述: 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两 ...

  10. 匈牙利算法Hungarian algorithm

    匈牙利算法是解决寻找二分图最大匹配的. 匈牙利算法(Hungarian Algorithm)是一种组合优化算法(combinatorial optimization algorithm),换句话说就是 ...

最新文章

  1. 数据蒋堂 | JOIN提速 - 外键指针化
  2. Data source rejected establishment of connection, message from server: Too many connections解决办法...
  3. 技术除了工作,还有什么可以提升的?
  4. 狄利克雷卷积_一些狄利克雷卷积性质的证明
  5. 信息系统项目管理师为什么不建议自学
  6. 基本Socket通信流程
  7. 如何在工作中更好的学习
  8. [2019.05.09]Linux 学习笔记(3)
  9. openwrt安装aliddns使用阿里云ddns
  10. caj转pdf python_caj2pdf gui程序: 转换 CAJ 为 PDF。佛系转换,成功与否,皆是玄学。...
  11. 日本房地产泡沫破裂后的平民生活
  12. Vista下最好用输入法 - 搜狗拼音输入法4.0正式版闪亮登场!
  13. C/C++在线餐馆预订管理系统
  14. 哈佛架构 VS 冯·诺依曼架构
  15. vrchat合并账号
  16. HyperLPR3车牌识别-Linux/MacOS使用:C/C++库编译
  17. python学习,共同成长,招集python+odoo共同创业合伙人
  18. htt的缺点有哪些?这里列举的几点,欢迎留言
  19. 南方科大计算机学院院长,新闻详情 - 计算机科学与工程系 - 南方科技大学
  20. 抖音死亡计算机背景音乐,抖音死亡计算器app

热门文章

  1. android自定义速度仪表盘,自定义View实战:汽车速度仪表盘
  2. 本地词库翻译php,有道词典词库(您也可以轻松翻译离线的有道词典词库)
  3. 多渠道门店如何进行会员管理和会员营销
  4. 15-Mixly模拟输出 | Mixly技巧系列
  5. 【回波损耗(dB)和电压驻波比(VSWR)之间的关系】
  6. 冷热分离和直接使用大数据库_【TBase开源版测评】深度测评TBase的shard分片和冷热分离存储特性...
  7. pspice计算机仿真实验,基于OrCAD_PSpice二阶动态电路的计算机仿真分析
  8. 2021年下半年软考真题软件设计师真题答案(下午题)
  9. voms下的反射大师_VOMS虚拟大师
  10. FAT文件系统解析(一) 引导扇区、FAT表及根目录区分析