Python 在二维二进制矩阵中求孤岛数
我试图计算2D二进制矩阵中的孤岛数(一组相连的1形成一个孤岛) 例如:Python 在二维二进制矩阵中求孤岛数,python,algorithm,matrix,graph,Python,Algorithm,Matrix,Graph,我试图计算2D二进制矩阵中的孤岛数(一组相连的1形成一个孤岛) 例如: [ [1, 1, 0, 0, 0], [0, 1, 0, 0, 1], [1, 0, 0, 1, 1], [0, 0, 0, 0, 0], [1, 0, 1, 0, 1] ] 在上述矩阵中,有5个岛屿,分别为: First: (0,0), (0,1), (1,1), (2,0) Second: (1,4), (2,3), (2,4) Third: (4,0) Fourth: (4,2) Fifth: (4,4) 为了计算
[
[1, 1, 0, 0, 0],
[0, 1, 0, 0, 1],
[1, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[1, 0, 1, 0, 1]
]
在上述矩阵中,有5个岛屿,分别为:
First: (0,0), (0,1), (1,1), (2,0)
Second: (1,4), (2,3), (2,4)
Third: (4,0)
Fourth: (4,2)
Fifth: (4,4)
为了计算2D矩阵中的孤岛数,我假设矩阵是一个图,然后使用DFS算法来计算孤岛数
我一直在跟踪DFS(递归函数)调用的数量,因为图中有很多组件
下面是我为此编写的代码:
# count the 1's in the island
def count_houses(mat, visited, i, j):
# base case
if i < 0 or i >= len(mat) or j < 0 or j >= len(mat[0]) or\
visited[i][j] is True or mat[i][j] == 0:
return 0
# marking visited at i, j
visited[i][j] = True
# cnt is initialized to 1 coz 1 is found
cnt = 1
# now go in all possible directions (i.e. form 8 branches)
# starting from the left upper corner of i,j and going down to right bottom
# corner of i,j
for r in xrange(i-1, i+2, 1):
for c in xrange(j-1, j+2, 1):
# print 'r:', r
# print 'c:', c
# don't call for i, j
if r != i and c != j:
cnt += count_houses(mat, visited, r, c)
return cnt
def island_count(mat):
houses = list()
clusters = 0
row = len(mat)
col = len(mat[0])
# initialize the visited matrix
visited = [[False for i in xrange(col)] for j in xrange(row)]
# run over matrix, search for 1 and then do dfs when found 1
for i in xrange(row):
for j in xrange(col):
# see if value at i, j is 1 in mat and val at i, j is False in
# visited
if mat[i][j] == 1 and visited[i][j] is False:
clusters += 1
h = count_houses(mat, visited, i, j)
houses.append(h)
print 'clusters:', clusters
return houses
if __name__ == '__main__':
mat = [
[1, 1, 0, 0, 0],
[0, 1, 0, 0, 1],
[1, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[1, 0, 1, 0, 1]
]
houses = island_count(mat)
print houses
# print 'maximum houses:', max(houses)
#数一数岛上的1
def计数室(mat、参观、i、j):
#基本情况
如果i<0或i>=len(mat)或j<0或j>=len(mat[0]),或\
访问[i][j]为真或mat[i][j]==0:
返回0
#在i,j
访问[i][j]=正确
#cnt被初始化为1,因为找到了1
cnt=1
#现在向所有可能的方向前进(即表格8分支)
#从i,j的左上角开始,向下到右下角
#i,j角
对于X范围内的r(i-1,i+2,1):
对于X范围内的c(j-1,j+2,1):
#打印“r:”,r
#打印“c:”,c
#不要叫我,j
如果r!=i和c!=j:
cnt+=计数房屋(mat、参观、r、c)
返回cnt
def岛_计数(mat):
房屋=名单()
集群=0
行=长(垫)
col=len(mat[0])
#初始化访问矩阵
visited=[[xrange中的i为假(列)]xrange中的j为假(行)]
#运行矩阵,搜索1,然后在找到1时执行dfs
对于X范围内的i(行):
对于X范围内的j(列):
#查看在mat中i,j处的值是否为1,在mat中i,j处的值是否为False
#拜访
如果mat[i][j]==1且访问[i][j]为假:
集群+=1
h=计数房屋(mat、参观、i、j)
房屋.附加(h)
打印“群集:”,群集
返回房屋
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
mat=[
[1, 1, 0, 0, 0],
[0, 1, 0, 0, 1],
[1, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[1, 0, 1, 0, 1]
]
房屋=岛屿数量(垫)
印刷厂
#打印“最大房屋数:”,最大(房屋数)
我在参数中传递的矩阵的输出错误。我得到了7个
,但有5个
集群
我试着调试代码是否有任何逻辑错误。但我找不出问题出在哪里。大锤法,供参考 必须添加
结构
参数np.one((3,3))
以添加对角连接
import numpy as np
from scipy import ndimage
ary = np.array([
[1, 1, 0, 0, 0],
[0, 1, 0, 0, 1],
[1, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[1, 0, 1, 0, 1]
])
labeled_array, num_features = ndimage.label(ary, np.ones((3,3)))
labeled_array, num_features
Out[183]:
(array([[1, 1, 0, 0, 0],
[0, 1, 0, 0, 2],
[1, 0, 0, 2, 2],
[0, 0, 0, 0, 0],
[3, 0, 4, 0, 5]]), 5)
除了第21行之外,您的算法几乎是正确的:
if r != i and c != j:
cnt += count_houses(mat, visited, r, c)
相反,如果至少有一个坐标与中心不相同,则要使用或
继续计数
if r != i or c != j:
cnt += count_houses(mat, visited, r, c)
另一种更直观的书写方法是
if (r, c) != (i, j):
cnt += count_houses(mat, visited, r, c)
看起来有一个库,函数@f5r5e5d我不想使用预定义的函数/lib。但是,我认为您上面提到的函数执行不同的任务。此解决方案如何帮助解决上述问题?可以作为测试的参考