Creo que verificaría cada punto de la matriz y descubriría su masa en función de sus vecinos. La masa de los puntos caería con decir el cuadrado de la distancia. A continuación, puede elegir los cuatro puntos superiores con una distancia mínima el uno del otro.
Aquí hay un código de Python que mezclé para intentar ilustrar el enfoque para descubrir la masa de cada punto. Algunos de configuración usando el ejemplo de la matriz:
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
para calcular la masa de un punto dado:
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
Nota: Estoy usando Manhattan distancias (aka Cityblock, también conocido como Taxi geometría) aquí porque Don No creo que la precisión añadida usando distancias Euclidianas valga el costo de llamar a sqrt().
Iterar a través de nuestra matriz y la construcción de una lista de tuplas como (x, y, la masa (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)))
Clasificación de la lista de la masa para cada punto:
from operator import itemgetter
point_mass.sort(key=itemgetter(2), reverse=True)
en cuanto a los 9 puntos superiores en esa lista ordenada:
(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)
Si hemos de trabajar de mayor a menor y filtrante r distancia puntos que están demasiado cerca de los puntos de visto ya vamos a llegar (lo estoy haciendo manualmente desde que he quedado sin tiempo ahora para hacerlo en código ...):
(6, 2, 6.1580555555555554)
(2, 1, 5.4861111111111107)
(1, 4, 4.5938888888888885)
(4, 7, 4.4480555555555554)
que es un resultado bastante intuitivo al solo mirar su matriz (tenga en cuenta que las coordenadas son cero cuando se compara con su ejemplo).