Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 最小成本算法&x2B;一般图的最大匹配_Java_C#_Algorithm_Graph_Graph Theory - Fatal编程技术网

Java 最小成本算法&x2B;一般图的最大匹配

Java 最小成本算法&x2B;一般图的最大匹配,java,c#,algorithm,graph,graph-theory,Java,C#,Algorithm,Graph,Graph Theory,我有一个由节点和边组成的数据集。 节点代表人,边代表人与人之间的关系,每个节点都有一个使用欧几里德距离计算的代价 现在,我希望通过它们各自的边将这些节点匹配在一起,其中只有一个约束: 任何节点只能与单个其他节点匹配 现在我们知道我在一个普通的图中工作,理论上每个节点都可以与数据集中的任何节点匹配,只要它们之间有一条边 我想做的是找到最大匹配和总成本最低的解决方案 Node A Node B Node C Node D - Edge 1: Start: End Cost

我有一个由节点和边组成的数据集。 节点代表人,边代表人与人之间的关系,每个节点都有一个使用欧几里德距离计算的代价

现在,我希望通过它们各自的边将这些节点匹配在一起,其中只有一个约束:

  • 任何节点只能与单个其他节点匹配
现在我们知道我在一个普通的图中工作,理论上每个节点都可以与数据集中的任何节点匹配,只要它们之间有一条边

我想做的是找到最大匹配和总成本最低的解决方案

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)的解决方案

我研究了很多算法,包括匈牙利算法、Blossom算法、最小成本流算法,但我不确定哪种算法最适合这种情况。另外,在二部图中,似乎有很多材料可以用来解决这类问题,但在这个问题上,情况并非如此

所以我问你:

  • 在这种情况下,哪种算法最适合返回(a)最大匹配量和(b)最低总体成本

  • 你知道你推荐的算法有什么好材料(可能是一些容易理解的伪代码)吗?我不是数学符号学最强的

  • 对于(a),最合适的算法(理论上有更快的算法,但更难理解)是Edmonds的Blossom算法。不幸的是,这很复杂,但我会尽我所能解释其基础

    基本思想是进行匹配,并通过进行一些局部更改来不断改进(增加匹配节点的数量)。关键概念是一个交替路径:从一个不匹配节点到另一个不匹配节点的路径,其特性是边在匹配内和匹配外交替

    如果有交替路径,则可以通过翻转交替路径中边的状态(无论它们是否处于匹配状态)将匹配的大小增加1

    如果存在交替路径,则匹配不是最大的(因为该路径为您提供了增加匹配大小的方法),相反,您可以显示,如果没有交替路径,则匹配是最大的。所以,要找到一个最大匹配,你需要做的就是找到一条交替的路径

    在二部图中,这是非常容易做到的(可以通过DFS做到)。一般来说,这更为复杂,这是Edmonds的Blossom算法。粗略地说:

    • 构建一个新的图,其中两个顶点之间有一条边,如果您可以通过首先遍历匹配中的边,然后遍历不匹配的边,从u到v

    • 在此图中,尝试查找从未匹配顶点到具有未匹配邻居(即原始图中的邻居)的匹配顶点的路径

    找到的路径中的每条边对应于原始图形的两条边(即匹配中的一条边和不匹配中的一条边),因此该路径在新图形中转换为交替行走,但这不一定是交替路径(路径和漫游之间的区别在于,路径仅使用每个顶点一次,但漫游可以多次使用每个顶点)

    • 如果行走是一条路径,则您有一条交替的路径,并且已完成

    • 如果没有,则行走不止一次地使用某个顶点。您可以删除两次访问该顶点之间的行走部分,然后获得一个新图形(删除部分顶点)。在这个新图形中,您必须再次执行整个搜索,如果您在新图形中找到一条交替路径,则可以“提升”将其转换为原始图形的交替路径

    对于stackoverflow的答案来说,深入了解这(关键)最后一步的细节有点太多了,但是您可以找到更多细节,也许有了这个高级概述可以帮助您理解更多数学文章

    从零开始实现这一点将是相当具有挑战性的

    加权版本(欧氏距离),EDMONDS算法可以处理更复杂的权重,提供了C++实现和伴随的文件,这也可以用于未加权的情况,所以使用这个实现可能是个好主意。(即使它不在java中,也应该有某种方式与之交互)


    因为你的权重是基于欧几里德距离的,所以这种情况下可能会有一个专门的算法,但是我上面提到的更通用的版本也可以工作,并且可以实现它。

    你所说的最大匹配是什么意思?答案很好。你知道加权版本是建立在现有最大匹配之上的吗ing,还是必须直接在现有算法中实现?您是否愿意在最适合您的平台上通过IM讨论这一问题?