繁体   English   中英

在2D平面上找到n个点的几何中心-曼哈顿距离

[英]Finding the geometric center of n points on a 2D plane - Manhattan distance

假设我们在M-by-M网格上有p随机点。 我们想在网格上找到一个点,该点的曼哈顿距离到所有p个点的总和最低。

我的想法:我认为也许将所有x和y取平均值,然后尝试所有接近该点的9个点,我们可能会找到所需的点。 但是似乎这种方法不起作用:

static void find_center(int p , int M){
    int[][] point = new int[p][2]; // initializing p points as random
    Random r = new Random();
    for (int i = 0 ; i < p ; i++){
        point[i][0] = r.nextInt(M);
        point[i][1] = r.nextInt(M);
    }
    //the naive brute force approach to find the real closest point on the grid
    int min_distance = Integer.MAX_VALUE;
    int[] result = new int[2];
    for (int i = 0 ; i < M ; i++){
        for (int j = 0 ; j < M ; j++){
            int d = 0;
            for (int k = 0 ; k < point.length ; k++){
                d += Math.abs(i - point[k][0]);
                d += Math.abs(j - point[k][1]);
            }
            if (d < min_distance){
                min_distance = d;
                result[0] = i;
                result[1] = j;
            }
        }
    }
    System.out.println(min_distance);
    System.out.println(result[0] + " : " + result[1]);
    //the other proposed approach
    System.out.println("---------");
    int x = 0;
    int y = 0;
    for (int i = 0 ; i < point.length ; i++){
        x += point[i][0];
        y += point[i][1];
    }
    x /= point.length;
    y /= point.length;
    min_distance = Integer.MAX_VALUE;
    for (int a : new int[] {-1,0,1}){
        for (int b : new int[] {-1,0,1}){
            int d = 0;
            for (int k = 0 ; k < point.length ; k++){
                d += Math.abs(x + a - point[k][0]);
                d += Math.abs(y + b - point[k][1]);
            }
            if (d < min_distance){
                min_distance = d;
                result[0] = x + a;
                result[1] = y + b;
            }
        }
    }
    System.out.println(min_distance);
    System.out.println(result[0] + " : " + result[1]);
    return;
}

我认为您要寻找的点是中位数X和中位数Y:X和Y在它们之前(在X和Y维度上)和在它们之后的点都一样多。

那时,向左或向右移动不会减少总距离,因为左和右的连接数相同。 Y上下也一样。

这是由于曼哈顿距离的定义有点特殊,实际上您可以分别在X和Y中计算出曼哈顿距离的总和,然后相加。

编辑:中位数很容易计算,只需列出X的所有值,对它进行排序,然后在列表中间选择一个即可。 与Y相同。

最小生成树可以计算到所有其他点的最短距离树。

正如jdv-Jan de Vaan所说,以下代码有效:

    Arrays.sort(point , new Comparator<int[]>(){
        @Override
        public int compare(int[] arg0, int[] arg1) {
            return Double.compare(arg0[0], arg1[0]);
        }
    });
    int median_x = point[point.length/2][0];
    Arrays.sort(point , new Comparator<int[]>(){
        @Override
        public int compare(int[] arg0, int[] arg1) {
            return Double.compare(arg0[1], arg1[1]);
        }
    });
    int median_y = point[point.length/2][1];
    int min_distance = 0;
    for (int i = 0 ; i < point.length ; i++){
        min_distance += Math.abs(point[i][0] - median_x) + Math.abs(point[i][1] - median_y);
    }
    System.out.println(min_distance);
    System.out.println(median_x + " : " + median_y);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM