グリッドp
上にランダムな点があるとしましょう。M-by-M
すべてのポイントへのマンハッタン距離の合計が最小になるグリッド上のポイントを見つけたいと考えています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;
}