マトリックスの各ポイントをチェックして、隣接するポイントに基づいて質量を計算すると思います。ポイントの質量は、たとえば距離の2乗になります。次に、互いに最小の距離で上位4つのポイントを選択できます。
これは、各ポイントの質量を見つけるためのアプローチを説明するために一緒に作成したPythonコードです。サンプルマトリックスを使用したセットアップ:
matrix = [[1.0 if x == "X" else 0.0 for x in y] for y in """.XX......
.XXX..X..
.....XXX.
......X..
.XX......
.X.......
.X.......
....XX...
....XX...""".split("\n")]
HEIGHT = len(matrix)
WIDTH = len(matrix[0])
Y_RADIUS = HEIGHT / 2
X_RADIUS = WIDTH / 2
特定の点の質量を計算するには:
def distance(x1, y1, x2, y2):
'Manhattan distance http://en.wikipedia.org/wiki/Manhattan_distance'
return abs(y1 - y2) + abs(x1 - x2)
def mass(m, x, y):
_mass = m[y][x]
for _y in range(max(0, y - Y_RADIUS), min(HEIGHT, y + Y_RADIUS)):
for _x in range(max(0, x - X_RADIUS), min(WIDTH, x + X_RADIUS)):
d = max(1, distance(x, y, _x, _y))
_mass += m[_y][_x] / (d * d)
return _mass
注:ここではマンハッタン距離(別名Cityblock、別名Taxicab Geometry)を使用しています。これは、ユークリッド距離を使用して追加された精度がsqrt()を呼び出すコストに見合うとは思わないためです。
マトリックスを反復処理し、(x、y、mass(x、y))のようなタプルのリストを作成します。
point_mass = []
for y in range(0, HEIGHT):
for x in range(0, WIDTH):
point_mass.append((x, y, mass(matrix, x, y)))
各ポイントの質量でリストを並べ替えます。
from operator import itemgetter
point_mass.sort(key=itemgetter(2), reverse=True)
そのソートされたリストの上位9ポイントを見てください。
(6, 2, 6.1580555555555554)
(2, 1, 5.4861111111111107)
(1, 1, 4.6736111111111107)
(1, 4, 4.5938888888888885)
(2, 0, 4.54)
(4, 7, 4.4480555555555554)
(1, 5, 4.4480555555555554)
(5, 7, 4.4059637188208614)
(4, 8, 4.3659637188208613)
最高から最低まで作業し、すでに表示されているポイントに近すぎるポイントを除外すると、取得できます(コードで実行する時間がなくなったため、手動で実行しています...):
(6, 2, 6.1580555555555554)
(2, 1, 5.4861111111111107)
(1, 4, 4.5938888888888885)
(4, 7, 4.4480555555555554)
これは、マトリックスを見るだけで非常に直感的な結果です(例と比較すると、座標はゼロに基づいていることに注意してください)。