繁体   English   中英

需要帮助理解这个python深度优先搜索代码

[英]Need help understanding this python depth first search code

我对 Python 编码很陌生,很难理解下面的代码。 它是基于图论使用 DFS 来找到所有岛屿区域中最大的区域。 1代表一个岛,0代表网格中的水。

def maxAreaOfIsland(grid):
    row, col = len(grid), len(grid[0])
    def dfs(i, j):
        if 0 <= i <= row - 1 and 0 <= j <= col - 1 and grid[i][j]:
            grid[i][j] = 0

#scans through all rows & cols and 
#turns number in the grid into 0 if all conditions are true?

            return  1 + dfs(i - 1, j) + dfs(i + 1, j) + dfs(i, j - 1) + dfs(i, j + 1)
        return 0  

# recursive function that checks up, down, left, right in the grid. 
# when does it return 1?

    return max(dfs(i, j) for i in range(row) for j in range(col))

maxAreaOfIsland([[1,0,1,1,1],
                 [0,0,0,1,1],
                 [1,1,1,0,1]]) 
Out: 6

我已经包含了评论,这些评论反映了我迄今为止的理解,但不确定它是否正确。 从第 4 行开始,我很困惑,尤其是递归部分。 有人能详细解释一下吗? 通常这些类型的代码往往有一个队列/出队来记录是否有人访问过该岛,但我认为这段代码没有?

我想这个问题实际上是关于理解算法而不是 Python。 提供的 Python 代码非常简单。

该代码包含函数maxAreaOfIsland ,该函数又包含递归函数dfs 这 2 个函数形成了 2 层计算。 让我们分别看一下这些层。

# outer layer
def maxAreaOfIsland(grid):
    row, col = len(grid), len(grid[0])
    # function dfs() definition
    return max(dfs(i, j) for i in range(row) for j in range(col))

所以外层非常简单 - 为所有可能的ij计算dfs(i, j)然后选择最大的计算值。

# inner layer - slightly modified
def dfs(i, j):
    # recursive case
    if (0 <= i <= row - 1 and 0 <= j <= col - 1) and grid[i][j] == 1:
        grid[i][j] = 0  # this is how we remember visited cells since we don't count zeros
        # optional prints to look at the grid during computation
        # print(i, j)
        # print(*grid, sep='\n', end='\n\n')
        count_current = 1
        count_neighbors = dfs(i - 1, j) + dfs(i + 1, j) + dfs(i, j - 1) + dfs(i, j + 1)
        return  count_current + count_neighbors
    # trivial case and out-of-borders case
    else:
        return 0

内层稍微复杂一点。 它能做什么? (1) 它得到ij (2) 如果单元格包含0则它是微不足道的情况(水)或者我们不在网格中 - 只需返回0 (3)如果单元格包含1那么它的递归情况下(陆地) -功能开始计数所有的量的1邻近于给定小区每1计计数变成0以避免重复计算。

您的示例网格有 3 行(0、1、2)和 5 列(0、1、2、3、4)。 假设我们在i = 0, j = 2 它是1 我们对其进行计数(当前结果为 1),将其变为0并一一查看其邻居 - 上邻居不在网格中,底部邻居为0 ,左邻居为0 ,右邻居为1 我们不返回当前结果,而是继续处理右边的邻居i = 0, j = 3 我们计算它(当前结果是 2),将其变成0并查看邻居。 上邻居在网格之外,下邻居是1 我们停在这里,我们不返回当前结果,我们记得还有 2 个邻居,我们继续到底部邻居i = 1, j = 3 我们对其进行计数(当前结果为 3),将其变为0并查看邻居。 上邻居是1 我们停在这里,我们不返回当前结果,我们记得还有 3 个邻居,我们继续上层邻居i = 0, j = 3 等等。

我的建议是绘制简单的样本网格(用笔在纸上)并手动对其应用 dfs 算法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM