最大二部分匹配C++

Maximum Bipartite Matching C++

本文关键字:C++ 二部      更新时间:2023-10-16

我正在用class的两个vectors解决匹配问题

class matching
{
public:
int n;
char match;
};

这是我试图实现的算法:

int augment(vector<matching> &left, vector<matching> &right)
{
while(there's no augmenting path)
if(condition for matching)
<augment>
return "number of matching";
}

对于粗匹配,如果left[i]right[j]匹配,则left[i].n = jleft[i].match ='M'right[j].n = iright[j].match = 'M'以及不匹配的具有成员n = -1match = 'U'

在寻找扩充路径时,如果另一个(i,j)存在一个扩充路径,则我们将不匹配的扩充路径的成员match'M'更改为'U'及其n = -1,并且与扩充路径匹配的两个扩充路径将其成员match更改为"A",而我们根据其索引更改其成员n

我不知道这是否是解决这个问题的正确方法,这是我第一次尝试最大匹配,我在网上读了很多文章和观看了教程,但我无法让我的"代码"正常工作。

我不需要代码,我可以写我的代码。我只是想一步一步地了解这个算法。如果有人能给我一个像我上面尝试的算法,我会很感激。此外,如果我从那以后一直走错了方向,请纠正我。

我不确定您是否正确地找到了扩充路径。我建议采取以下方法。

  1. 以贪婪的方式找到初始匹配。为了获得这一点,我们遍历左侧的每个顶点,并贪婪地尝试将其与右侧的一些自由(不匹配)顶点匹配。

  2. 尝试在图中找到一个扩充路径p。为此,我们需要从左侧的所有自由顶点开始进行广度优先搜索,并在搜索中交替通过匹配和不匹配的边。(即,第二级包含与级别1相邻的所有右侧顶点顶点,第三级包含与第二级顶点匹配,第四级包含所有右侧与第三级顶点相邻的顶点等)。当我们访问任何未来级别的自由顶点并计算扩充路径P使用迄今为止计算的广度优先搜索树。

  3. 如果我们能在上一步中找到一个扩充路径p:将p中的匹配和不匹配边分别更改为不匹配和匹配边,然后转到第2步。

  4. 否则:获得的匹配结果为最大值。

该算法需要对每个预兆进行广度优先搜索,因此最坏情况下的复杂度为O(nm)。尽管Hopcroft-Karp算法可以对每个广度优先搜索执行多次增强,并且在最坏情况下具有更好的复杂性(从维基百科的文章来看)它在实践中似乎并没有更快。