最大二分匹配C ++

时间:2012-10-10 00:00:01

标签: c++ algorithm graph matching bipartite

我正在用vectors

的两个class解决匹配问题
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'及其{ {1}}和与扩充路径匹配的两个人将其成员n = -1更改为“A”,同时根据他们的索引更改其成员match

我不知道这是否是解决这个问题的正确方法,这是我第一次尝试最大化匹配,我已经阅读了大量文章并在线观看了教程,我无法获得我的“代码”功能恰当。

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

1 个答案:

答案 0 :(得分:4)

我不确定您是否正确找到了增强路径。我建议采用以下方法。

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

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

  3. 如果我们可以在上一步中找到扩充路径P:将P中的匹配和不匹配边分别更改为不匹配和匹配的边,并转到步骤2.

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

  5. 此算法需要对每次扩充进行广度优先搜索,因此最坏情况下的复杂度为O(nm)。虽然Hopcroft-Karp algorithm可以为每个广度优先搜索执行多次扩充,但具有更好的最坏情况复杂度 似乎(来自维基百科的文章)它在实践中并不快。