我有一个0和1的矩阵:
1 0 0 0 0
0 0 1 1 0
a = 0 0 1 1 0
1 0 0 0 0
1 1 0 0 0
我希望使用python将其分解为连接组件的总和,其中“连接”是指矩阵,其中每个“1”至少具有上/下/左/右的另一个“1”。否则必须隔离“1”:
1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
a = 0 0 1 1 0 = 0 0 0 0 0 + 0 0 1 1 0 + 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0
可能有趣的是,在这个问题(Largest rectangle of 1's in 2d binary matrix)中,Guy Adini建议使用BFS分解来分解连接组件中的矩阵。但是我找不到它的python实现,也没有找到如何使用BFS来解决我的问题。
答案 0 :(得分:1)
有效的算法如下:
对于算法访问的元素,保留一个大小相同的visited
矩阵(或者等效地,访问元素的一组坐标)。
您逐个浏览矩阵的所有元素:
答案 1 :(得分:1)
这是一个自定义实现。如果你愿意,我允许你修改它以删除重复项。
import itertools
class Matrix():
def __init__(self, matrix):
self.matrix = matrix
def computeConnectedComponents(self):
rows_id = list(range(len(self.matrix)))
cols_id = list(range(len(self.matrix[0])))
#here are the position of every 1 in the grid. ( row number, column number) indexes start at 0
positions = [couple for couple in self.generate_pairs(rows_id, cols_id) if self.matrix[couple[0]][couple[1]]==1]
#here we store all the connected component finded
allConnectedComponents = []
#while there is position not affected to any connected component
while positions != [] :
#the first element is taken as start of the connected component
to_explore = [positions.pop(0)]
currentConnectedComponent = set()
#while there is node connected to a node connected to the component
while list(to_explore) != []:
currentNode = to_explore.pop()
currentConnectedComponent.add(currentNode)
to_explore += [coord for coord in self.node_neighbourhood(currentNode) if (self.matrix[coord[0]][coord[1]]==1 and (coord not in to_explore) and (coord not in currentConnectedComponent))]
allConnectedComponents.append(currentConnectedComponent)
positions = [position for position in positions if position not in currentConnectedComponent]
return allConnectedComponents
#http://stackoverflow.com/questions/16135833/generate-combinations-of-elements-from-multiple-lists
def generate_pairs(self, *args):
for i, l in enumerate(args, 1):
for x, y in itertools.product(l, itertools.chain(*args[i:])):
yield (x, y)
def node_neighbourhood(self, coordinates):
row, column = coordinates[0], coordinates[1]
result = []
if (row - 1) >= 0 :
result.append((row-1, column))
if (row + 1) < len(self.matrix):
result.append((row+1, column))
if (column - 1) >= 0:
result.append((row, column-1))
if (column + 1) < len(self.matrix[0]):
result.append((row, column+1))
return result
if __name__ == "__main__":
data = [[1,0,0,0,0],
[0,0,1,1,0],
[0,0,1,1,0],
[1,0,0,0,0],
[1,1,0,0,0]]
matrix = Matrix(data)
for connectedComponent in matrix.computeConnectedComponents():
print(connectedComponent)