Несмотря на то, что я нашел решение, я использовал эту команду:
sudo chmod 666 /dev/ttyS6
Я думаю, что проверил бы каждую точку в матрицу и выяснил бы, что это - масса на основе, он - соседи. Масса для точек упала бы с, говорят что квадрат расстояния. Вы могли затем выбрать лучшие четыре точки с минимальным расстоянием друг от друга.
Вот некоторый код 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, также известный как Геометрия Такси) здесь, потому что я не думаю, что добавленная точность с помощью Евклидовых расстояний стоит стоимости вызова sqrt ().
Выполняя итерации через нашу матрицу и создание списка кортежей как (x, y, масса (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)
Который является довольно интуитивным результатом просто смотрящий на Вашу матрицу (обратите внимание, что координаты являются нулем, базирующимся при сравнении примеру).
Вам нужен кластеризирующийся алгоритм, это легко, так как у Вас просто есть 2 размерных сетки, и записи ограничивают друг друга. Можно просто использовать floodfill алгоритм. После того как у Вас есть каждый кластер, можно найти центр как в 2D центре массовой статьи..
Моя первая мысль состояла бы в том, чтобы сначала найти любую ячейку с ненулевым значением. Оттуда сделайте некоторый алгоритм заливки и вычислите центр массы найденных ячеек. Затем обнулите найденные ячейки от матрицы и начните с вершины.
Это, конечно, не масштабировалось бы, а также метод от Google, который связанный tuinstoel, но будет легче реализовать для меньших матриц.
Править:
Непересекающиеся наборы (использующий сжатие пути и объединение разрядом) могли быть полезными здесь. У них есть O (α (n)) временная сложность для объединения и установленный на находку, где
α (n) = минута {k: Ak (1) ≥ n}.
Ak (n) является функцией Ackerman, таким образом, α (n) по существу будет O (1) для любой рыночной стоимости. Единственная проблема состоит в том, что непересекающиеся наборы являются односторонним отображением объекта для установки, но это не будет иметь значения, идете ли Вы канавка все объекты.
Вот простой сценарий Python для демонстрации:
from collections import defaultdict
class DisjointSets(object):
def __init__(self):
self.item_map = defaultdict(DisjointNode)
def add(self,item):
"""Add item to the forest."""
# It's gets initialized to a new node when
# trying to access a non-existant item.
return self.item_map[item]
def __contains__(self,item):
return (item in self.item_map)
def __getitem__(self,item):
if item not in self:
raise KeyError
return self.item_map[item]
def __delitem__(self,item):
del self.item_map[item]
def __iter__(self):
# sort all items into real sets
all_sets = defaultdict(set)
for item,node in self.item_map.iteritems():
all_sets[node.find_set()].add(item)
return all_sets.itervalues()
class DisjointNode(object):
def __init__(self,parent=None,rank=0):
if parent is None:
self.parent = self
else:
self.parent = parent
self.rank = rank
def union(self,other):
"""Join two sets."""
node1 = self.find_set()
node2 = other.find_set()
# union by rank
if node1.rank > node2.rank:
node2.parent = node1
else:
node1.parent = node2
if node1.rank == node2.rank:
node2.rank += 1
return node1
def find_set(self):
"""Finds the root node of this set."""
node = self
while node is not node.parent:
node = node.parent
# path compression
root, node = node, self
while node is not node.parent:
node, node.parent = node.parent, root
return root
def find_clusters(grid):
disj = DisjointSets()
for y,row in enumerate(grid):
for x,cell in enumerate(row):
if cell:
node = disj.add((x,y))
for dx,dy in ((-1,0),(-1,-1),(0,-1),(1,-1)):
if (x+dx,y+dy) in disj:
node.union(disj[x+dx,y+dy])
for index,set_ in enumerate(disj):
sum_x, sum_y, count = 0, 0, 0
for x,y in set_:
sum_x += x
sum_y += y
count += 1
yield 1.0 * sum_x / count, 1.0 * sum_y / count
def main():
grid = [[('.' != cell) for cell in row if not cell.isspace()] for row in (
". X X . . . . . .",
". X X X . . X . .",
". . . . . X X X .",
". . . . . . X . .",
". X X . . . . . .",
". X . . . . . . .",
". X . . . . . . .",
". . . . X X . . .",
". . . . X X . . .",
)]
coordinates = list(find_clusters(grid))
centers = dict(((round(x),round(y)),i) for i,(x,y) in enumerate(coordinates))
for y,row in enumerate(grid):
for x,cell in enumerate(row):
if (x,y) in centers:
print centers[x,y]+1,
elif cell:
print 'X',
else:
print '.',
print
print
print '%4s | %7s %7s' % ('i','x','y')
print '-'*22
for i,(x,y) in enumerate(coordinates):
print '%4d | %7.4f %7.4f' % (i+1,x,y)
if __name__ == '__main__':
main()
Вывод:
. X X . . . . . .
. X 3 X . . X . .
. . . . . X 4 X .
. . . . . . X . .
. X X . . . . . .
. 2 . . . . . . .
. X . . . . . . .
. . . . X X . . .
. . . . X 1 . . .
i | x y
----------------------
1 | 4.5000 7.5000
2 | 1.2500 4.7500
3 | 1.8000 0.6000
4 | 6.0000 2.0000
Точка этого должна была продемонстрировать непересекающиеся наборы. Фактический алгоритм в find_clusters()
мог быть обновлен до чего-то более устойчивого.
Ссылки