我正在用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 = j
,left[i].match ='M'
,right[j].n = i
和right[j].match = 'M'
以及不匹配的匹配有成员n = -1
和match = 'U'
在找到扩充路径时,如果另一个路径(i,j)存在,那么我们会将match
与'M'
之间不匹配的成员'U'
及其{ {1}}和与扩充路径匹配的两个人将其成员n = -1
更改为“A”,同时根据他们的索引更改其成员match
。
我不知道这是否是解决这个问题的正确方法,这是我第一次尝试最大化匹配,我已经阅读了大量文章并在线观看了教程,我无法获得我的“代码”功能恰当。
我不需要代码,我可以编写代码。我只是想逐步理解这个算法。如果有人可以给我一个像我上面尝试的算法,我会很感激。此外,如果我从那时起一直走错了方向,请纠正我。
答案 0 :(得分:4)
我不确定您是否正确找到了增强路径。我建议采用以下方法。
以贪婪的方式找到初始匹配。为了获得这个,我们穿过左侧的每个顶点并贪婪地尝试将它与右侧的一些自由(不匹配)顶点匹配。
尝试在图表中找到扩充路径P.为此,我们需要从左侧的所有自由顶点开始进行广度优先搜索,并在搜索中通过匹配和不匹配的边交替。 (即第二级包含与级别1相邻的所有右侧顶点 顶点,第三级包含所有左侧顶点 与第2级顶点匹配,第四级包含所有右侧 与3级顶点相邻的顶点等)。我们停止搜索 访问任何未来级别的自由顶点并计算增强路径P. 使用到目前为止计算的广度优先搜索树。
如果我们可以在上一步中找到扩充路径P:将P中的匹配和不匹配边分别更改为不匹配和匹配的边,并转到步骤2.
否则:获得的匹配结果最大。
此算法需要对每次扩充进行广度优先搜索,因此最坏情况下的复杂度为O(nm)
。虽然Hopcroft-Karp algorithm可以为每个广度优先搜索执行多次扩充,但具有更好的最坏情况复杂度
似乎(来自维基百科的文章)它在实践中并不快。