Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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
Algorithm 最小化配对点的距离_Algorithm_Matrix_Hungarian Algorithm - Fatal编程技术网

Algorithm 最小化配对点的距离

Algorithm 最小化配对点的距离,algorithm,matrix,hungarian-algorithm,Algorithm,Matrix,Hungarian Algorithm,我的问题如下: Given a number of 2n points, I can calculate the distance between all points and get a symmetrical matrix. Can you create n pairs of points, so that the sum of the distance of all pairs is minimal? EDIT: Every point has to be in one of th

我的问题如下:

Given a number of 2n points, I can calculate the distance between all points 
and get a symmetrical matrix.

Can you create n pairs of points, so that the sum of the distance of all pairs is 
minimal?

EDIT: Every point has to be in one of the pairs. Which means that
every point is only allowed to be in one pair.
我天真地尝试使用匈牙利算法,希望它能给我一个赋值,这样赋值是对称的。但这显然不起作用,因为我没有二部图

搜索之后,我找到了,这似乎与我的问题相似,但区别在于,它只是试图找到匹配项,而不是试图最小化某种距离


有人知道类似的问题或解决方案吗?我错过什么了吗?这个问题实际上看起来并没有那么难,但我就是找不出一个最优的解决方案。

有一个原始-对偶算法是由Edmonds(Blossom算法)引起的,如果可能的话,你真的不想自己实现它。Vladimir Kolmogorov有一个可能适合您使用的网络流量。max flow是要创建的对数。并计算出它的最小成本

现在这不是保证,只是一种预感

您可以找到最短的一对,匹配它们,然后将其从集合中删除

并递归,直到没有对为止


这显然是次优的。但是我有一个预感,这个次优解与绝对最优解的比例是有界的。希望是使用一些子模块化参数,并将其绑定到全局最优值的(1-1/e)分数,但我没能做到。也许有人可以试试看。

< P>竞争编程3中有一个C++记忆化实现(注记最大N为8):

#包括
#包括
#包括
#包括
使用名称空间std;
int N,目标;

双距离[20][20],备注[1如果我理解正确,您有一个对称矩阵,包含每个点之间的距离?为什么不将该矩阵转换为按距离[起点、终点、距离]排序的集合然后选择前n对?每个点只允许在一对中。如果我只按距离排序,这是不能保证的。我应该将这一点添加到问题描述中。嗯,这确实使问题变得更加困难。但是,你确定匈牙利算法不会起作用吗?与其将其视为一个完整的无向图,不如将每个点分成两个点(源和目标),并将其视为完整的二部有向图。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>

using namespace std;

int N, target;
double dist[20][20], memo[1<<16];

double matching(int bitmask)
{
    if (memo[bitmask] > -0.5)    // Already computed? Then return the result if yes
        return memo[bitmask];
    if (bitmask == target)       // If all students are already matched then cost is zero
        return memo[bitmask] = 0;

    double ans = 2000000000.0;        // Infinity could also work
    int p1, p2;

    for (p1 = 0; p1 < 2*N; ++p1)      // Find first non-matched point
        if (!(bitmask & (1 << p1)))
            break;
    for (p2 = p1 + 1; p2 < 2*N; ++p2) // and pair it with another non-matched point
        if (!(bitmask & (1 << p2)))
            ans = min(ans, dist[p1][p2]+matching(bitmask| (1 << p1) | (1 << p2)));

    return memo[bitmask] = ans;

}
int main()
{
    int i,j, caseNo = 1, x[20], y[20];

    while(scanf("%d", &N), N){
         for (i = 0; i < 2 * N; ++i)
             scanf("%d %d", &x[i], &y[i]);
         for (i = 0; i < 2*N - 1; ++i)
             for (j = i + 1; j < 2*N; ++j)
                  dist[i][j] = dist[j][i] = hypot(x[i]-x[j], y[i]-y[j]);

         // use DP to solve min weighted perfect matching on small general graph
         for (i = 0; i < (1 << 16); ++i) memo[i] = -1;
         target = (1 << (2 * N)) - 1;
         printf("Case %d: %.2lf", caseNo++, matching(0));

    }
    return 0;

}