我有一个由节点和边组成的数据集。 节点代表人,边代表他们的关系,每个关系都有一个使用欧氏距离计算的成本。
现在我希望通过它们各自的边缘将这些节点匹配在一起,其中只有一个约束:
现在我们知道我正在使用通用图,其中每个节点理论上可以与数据集中的任何节点匹配,只要它们之间有边缘。
我希望做的是找到具有最大匹配率和总体最低成本的解决方案。
Node A
Node B
Node C
Node D
- Edge 1:
Start: End Cost
Node A Node B 0.5
- Edge 2:
Start: End Cost
Node B Node C 1
- Edge 3:
Start: End Cost
Node C Node D 0.5
- Edge 2:
Start: End Cost
Node D Node A 1
此问题的解决方案如下:
分配边缘1和边缘3,因为这是最大匹配量(在这种情况下,显然只有2个解决方案,但是其他节点可能有大量的分支边缘)
分配边缘1和边缘3,因为它是具有最大匹配量和最小总成本的解决方案(1)
我研究了很多算法,包括匈牙利语,开花,最小成本流程,但我不确定哪种算法最适合这种情况。在两部分图中解决这些问题似乎也有很多材料,在这个问题上并非如此。
所以我问你:
在这种情况下哪种算法最适合返回(a)最大匹配量和(b)最低总成本。
您知道任何好的材料(可能是一些易于理解的伪代码),对于您推荐的算法?我不是数学符号中最强的。
答案 0 :(得分:2)
对于(a),最合适的算法(理论上更快的算法,但它们更难以理解)将是Edmonds的Blossom算法。不幸的是它很复杂,但我会尽力解释基础。
基本思想是进行匹配,并通过进行一些局部更改来不断改进(增加匹配节点的数量)。关键概念是交替路径:从不匹配节点到另一个不匹配节点的路径,其边缘在匹配之间交替,并且位于其外部。
如果你有一个交替路径,那么你可以通过翻转交替路径中边缘的状态(无论它们是否在匹配中)来增加匹配的大小。
如果存在交替路径,则匹配不是最大值(因为路径为您提供了增加匹配大小的方法),相反,您可以显示如果没有交替路径,则匹配为最大值。因此,要找到最大匹配,您需要做的就是找到一个交替路径。
在二分图中,这很容易做到(可以使用DFS完成)。在一般图表中,这更复杂,这是Edmonds的Blossom算法的用法。粗略地说:
构建一个新的图形,如果你可以通过首先遍历匹配中的边缘,然后遍历边缘而不是从u到v,在两个顶点之间存在边缘。
在此图中,尝试查找从不匹配的顶点到具有不匹配邻居的匹配顶点的路径(即原始图中的邻居)。
您找到的路径中的每条边都对应于原始图的两条边(即匹配中的边和不匹配的边),因此路径转换为新图中的交替步行,但这不是必然是交替路径(路径和步行之间的区别是路径只使用每个顶点一次,但是步行可以多次使用每个顶点)。
如果步行是路径,则您有一个交替路径并完成。
如果没有,那么walk会多次使用一些顶点。您可以在两次访问此顶点之间移除部分步行,并获得一个新图形(删除部分顶点)。在这个新图表中,您必须再次进行整个搜索,如果在新图表中找到交替路径,则可以将其“提升”到原始图表的交替路径。
详细介绍这个(关键的)最后一步对于stackoverflow答案来说有点太多了,但你可以找到关于Wikipedia的更多细节,也许这个高级概述可以帮助你理解更多数学文章。
从头开始实施这将是非常具有挑战性的。
对于加权版本(具有欧几里德距离),有一种更复杂的埃德蒙兹算法可以处理权重。 Kolmogorov提供了C ++实现和相关论文。这也可以用于未加权的情况,所以使用这个实现可能是一个好主意(即使它不在java中,应该有一些方法与它接口)。
由于您的权重是基于欧几里德距离,因此可能会有针对该情况的专门算法,但我上面提到的更通用的版本也可以使用,并且可以实现它。