匈牙利算法

[学习笔记] 匈牙利匹配

房东的猫 提交于 2019-11-28 16:52:58
匈牙利匹配算法 摘要 匈牙利匹配算法可以用来做目标跟踪,根据预测算法预测box与上一帧box的iou关系可以确定是否是上一帧的目标。 也是比较常用的二分图匹配算法。 概念 图G的一个 匹配 是由一组没有公共端点的不是圈的边构成的集合。 完美匹配 :考虑部集为X={x1 ,x2, ...}和Y={y1, y2, ...}的二部图,一个完美匹配就是定义从X-Y的一个双射,依次为x1, x2, ... xn找到配对的顶点 交错路:给定图G的一个匹配M,如果一条路径的边交替出现在M中和不出现在M中,我们称之为一条 交错路 增广路:而如果一条M-交错路径,它的两个端点都不与M中的边关联,我们称这条路径叫做 M-增广路 匈牙利算法的实质是寻找增广路,通过找到目标后改变之前匹配的结果完成最终的匹配。 算法 ​ 1.置M为空   2.找出一条增广路径P,通过取反操作获得更大的匹配M’代替M   3.重复2操作直到找不出增广路径为止 说穿了,就是你从二分图中找出一条路径来,让路径的起点和终点都是还没有匹配过的点,并且路径经过的连线是一条没被匹配、一条已经匹配过,再下一条又没匹配这样交替地出现。找到这样的路径后,显然路径里没被匹配的连线比已经匹配了的连线多一条,于是修改匹配图,把路径里所有匹配过的连线去掉匹配关系,把没有匹配的连线变成匹配的,这样匹配数就比原来多1个。不断执行上述操作

【匈牙利算法】

前提是你 提交于 2019-11-28 08:41:04
前置 二分图:二分图又称作二部图,是图论中的一种特殊模型。 设 \(G=(V,E)\) 是一个无向图,如果顶点V可分割为两个互不相交的子集 \((A,B)\) ,并且图中的每条边 \((i,j)\) 所关联的两个顶点i和j分别属于这两个不同的顶点集 \((i\;in A,j\;in B)\) ,则称图G为一个二分图。 简而言之,就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集,两个子集内的顶点不相邻。 无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。 匹配:给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配 极大匹配(Maximal Matching)是指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数。最大匹配(maximum matching)是所有极大匹配当中边数最大的一个匹配。选择这样的边数最大的子集称为图的最大匹配问题。 如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。 求二分图最大匹配可以用最大流(Maximal Flow)或者匈牙利算法(Hungarian Algorithm) 实战 下面好几道 (好像总共也没几道题) 都是网络流的题 因为数据太水可以用匈牙利水过

匈牙利算法

帅比萌擦擦* 提交于 2019-11-26 22:33:33
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈匈牙利模板打的真舒服哇 思路见 博客 洛谷P3386 【模板】二分图匹配 题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 输出格式: 共一行,二分图最大匹配 输入输出样例 输入样例#1:   1 1 1   1 1 输出样例#1:   1 说明 n, m小于等于 1000,u和v分别为小于n、m的正整数。 因为数据有坑,可能会遇到 v>m 的情况。请把 v>m 的数据自觉过滤掉。 代码 #include<cstdio> #include<iostream> #include<cstring> using namespace std; int n, m, p, tot = 0, ans = 0; int a[1001], b[1001], t[1001][1001], vis[1001]; int dfs(int u) { for (int v = 1; v <= m; v++) if (t[u][v] && !vis[v]) { vis[v] = 1; if (!b[v] || dfs(b[v])) { a[u] = v; b[v] = u; return 1; } } return 0; }