【问题标题】:python depth-first search recursionpython深度优先搜索递归
【发布时间】:2017-09-26 02:09:21
【问题描述】:

我正在尝试用递归创建一个 python dfs 连接岛......

程序运行良好,但在某些情况下会出现输出不正确的逻辑错误

例如

o o o

o x x

o o o the output is 1 which is correct.

但是,在其他情况下

o x o

o x o

o o o the output is 2 which is incorrect.

这是我的完整代码,包括 dfs 函数

row = int(input("Enter Row : "))
col = int(input("Enter Col : "))

# declare array baru namanya peta
peta = []

# array 2 dimensi
# Masukkin smua input ke array petas
for i in range(0,row):
    line = input()
    peta.append(line)


store = []
# declare array baru nama visited
visited = []
for i in range(0,row):
    visited.append([])

    # buat column di row i false smua
    for j in range(0,col):
        visited[i].append(False)

def dfs(i,j):
    visited[i][j] = True
    a = row-1
    b = col-1
    #peta[i][j] = store[a][b]
    for i in range(i,row):
        for j in range(j,col):
            if(visited[i][j] == True):
                return 1
            else:
                if(peta[i][j] == 'x' and visited[i][j] == False ):                  
                    #top left array
                    if(i == 0 or j == 0):
                        dfs(i+1,j+1)
                        dfs(i+1,j)
                        dfs(i,j+1)                  

                    #bottom left array
                    elif(i == a and j == 0):
                        dfs(i-1,j)
                        dfs(i-1,j+1)
                        dfs(i,j+1)

                    #top right array
                    elif(i == 0 and j == b):
                        dfs(i,j-1)
                        dfs(i+1,j-1)
                        dfs(i+1,j)

                    #bottom right array
                    elif(i == a and j == b):
                        dfs(i,j-1)
                        dfs(i-1,j-1)
                        dfs(i-1,j)

                    #west array
                    elif(i >= 1 and j == 0):
                        dfs(i-1,j)
                        dfs(i-1,j+1)
                        dfs(i+1,j)
                        dfs(i,j+1)
                        dfs(i+1,j+1)

                    #north array
                    elif(i==0 and j>=1):
                        dfs(i,j-1)
                        dfs(i+1,j-1)
                        dfs(i+1,j)
                        dfs(i,j+1)
                        dfs(i+1,j+1)

                    #east array
                    elif(i>=1 and j==b):
                        dfs(i-1,j)
                        dfs(i-1,j-1)
                        dfs(i,j-1)
                        dfs(i+1,j-1)
                        dfs(i+1,j)

                    #south array
                    elif(i==a and j>=1):
                        dfs(i,j-1)
                        dfs(i-1,j-1)
                        dfs(i-1,j)
                        dfs(i-1,j+1)
                        dfs(i,j+1)

                    #middle array
                    else:
                        dfs(i-1,j-1)
                        dfs(i-1,j)
                        dfs(i-1,j+1)
                        dfs(i,j-1)
                        dfs(i,j+1)
                        dfs(i+1,j-1)
                        dfs(i+1,j)
                        dfs(i+1,j+1)

                else:
                    #peta[i][j] = 0
                    return 0

numberofisland = 0
for i in range(0,row):
    for j in range(0,col):
        if((peta[i][j] == 'x' and visited[i][j] == False)):
            dfs(i,j)
            numberofisland+=1





print(numberofisland)

在我看来,我的逻辑错误是我两次访问访问的节点,但是我的数组中似乎没有错误。你能就我的错误在哪里提出一些建议吗?

非常感谢您的宝贵时间,干杯

编辑:我已根据社区要求更新为完整代码版本(如何调用函数、全局变量等)

【问题讨论】:

  • 你在程序中是怎么调用的?
  • 你在哪里使用了DFS函数的返回值?
  • 它在主程序if((peta[i][j] == 'x' and visited[i][j] == False)): dfs(i,j) numberofisland+=1
  • 由于整个函数中只有两个return语句,即“return 0”和“return 1”,所以你的函数只能返回0或1,这可能是错误的,所以请确保你没有犯任何复制粘贴错误。此外,如果您将整个脚本包含在您的问题中,这将很有帮助,以便人们可以自己运行它。
  • 另外,更清楚你的函数应该做什么:在图中找到connected components 的数量?并且对角相邻的 X 是否被认为是同一组件(岛)的一部分,还是只有直接位于左侧、右侧、顶部或底部的 X?

标签: python recursion microsoft-distributed-file-system


【解决方案1】:

您的代码中的某些内容没有意义:

1) 如果你想从dfs函数返回一个值,这个值应该有一定的意义,应该使用它。如果你只调用一个函数来获得它的副作用,那么你可以只使用return 而没有任何价值。在这种情况下,在我看来,dfs 函数的目的是更新 visited 数组,因此您不需要返回 10 或任何东西。

2) 当您在图中进行深度优先搜索时,您从一个节点开始,然后递归地访问其连接的节点。如果您在 dfs 函数中有一个 for 循环,它访问图表的很大一部分,而忽略了连接,那么您就没有进行 DFS。一般只需要在连接的节点上递归调用dfs函数即可。

3) 你的函数现在看起来的样子,它似乎总是在进行任何递归调用之前返回1

还要注意以下 Python 代码的良好做法:

1) 避免像if expression == True: 这样的结构。而是使用if expression:。也不要使用if expression == False,而是使用if not expression

2) 避免在ifelif 子句中的条件表达式周围使用括号,与C 或Java 不同,这不是必需的。例如,不要使用elif (a == b):,而是使用elif a == b

3) 在函数顶部添加docstring,以描述函数的作用(示例见我的代码)。

据我了解,您希望每次调用 dfs 函数都访问形成一个岛的所有连接的 xs。您可以使用以下代码执行此操作:

def dfs(i,j):
    '''
    This function starts from the square with coordinates (i,j).

    The square (i,j) should be an 'x', and also unvisited.

    This function will keep visiting all adjacent 'x' squares, using a
    depth first traversal, and marking these squares as visited in the
    @visited array.

    The squares considered adjacent are the 8 surrounding squares:
    (up, up-right, right, down-right, down, down-left, left, up-left).
    '''

    # The range checks have been moved to the beginning of the function, after each call.
    # This makes the code much shorter.
    if i < 0 or j < 0 or i >= row or j >= col:
        return

    # If we reached a non-x square, or an already visited square, stop the recursion.
    if peta[i][j] != 'x' or visited[i][j]:
        # Notice that since we don't do something with the return value,
        # there is no point in returning a value here.
        return

    # Mark this square as visited.
    visited[i][j] = True

    # Visit all adjacent squares (up to 8 squares).
    # Don't worry about some index falling out of range,
    # this will be checked right after the function call.
    dfs(i-1,j-1)
    dfs(i-1,j)
    dfs(i-1,j+1)
    dfs(i,j-1)
    dfs(i,j+1)
    dfs(i+1,j-1)
    dfs(i+1,j)
    dfs(i+1,j+1)

【讨论】:

  • 非常感谢您的反馈。我认为遍历整个数组需要一个循环。但似乎递归会做得很好。再次感谢你,干杯:)
  • @darkknight 如果您发现我的回答帮助您解决了您的问题,请继续接受它(或点赞)。这就是 StackOverflow recommends
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-12
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
相关资源
最近更新 更多