Python 请在route planner练习中查找我的代码中的隐形错误

Python 请在route planner练习中查找我的代码中的隐形错误,python,python-3.x,graph,Python,Python 3.x,Graph,我试图解决这个问题: 作为路线规划器的一部分,如果目的地是可到达的,则使用route_exists方法作为快速过滤器,然后再使用计算量更大的程序来寻找最佳路线。 地图上的道路被栅格化,并生成布尔值矩阵-如果道路存在,则为True;如果道路不存在,则为False。矩阵中的道路仅在道路紧靠左侧、右侧、下方或上方时才连接。 完成route_exists方法,以便在目标可到达时返回True,否则返回False。from_行和from_列参数是映射_矩阵中的起始行和列。to_行和to_列是映射_矩阵中的目

我试图解决这个问题:

作为路线规划器的一部分,如果目的地是可到达的,则使用route_exists方法作为快速过滤器,然后再使用计算量更大的程序来寻找最佳路线。 地图上的道路被栅格化,并生成布尔值矩阵-如果道路存在,则为True;如果道路不存在,则为False。矩阵中的道路仅在道路紧靠左侧、右侧、下方或上方时才连接。 完成route_exists方法,以便在目标可到达时返回True,否则返回False。from_行和from_列参数是映射_矩阵中的起始行和列。to_行和to_列是映射_矩阵中的目标行和列。map_矩阵参数是从map生成的上述矩阵。 例如,以下代码应返回True,因为目标是可访问的:

我的递归解决方案:

def route_exists(from_row, from_column, to_row, to_column, map_matrix):
    if route_exists2(from_row, from_column, to_row, to_column, map_matrix):
        return True
    else:
        return False
def route_exists2(from_row, from_column, to_row, to_column, map_matrix):
    if (from_row<0 or from_row>=len(map_matrix) or from_column<0 or from_column>=len(map_matrix[0])):
        return False
    if map_matrix[from_row][from_column]:
        map_matrix[from_row][from_column]=False #traversed
        if (from_row == to_row and from_column ==to_column):
            return True
        return (route_exists2(from_row-1, from_column, to_row, to_column, map_matrix) or
                route_exists2(from_row, from_column-1, to_row, to_column, map_matrix) or
                route_exists2(from_row, from_column+1, to_row, to_column, map_matrix) or
                route_exists2(from_row+1, from_column, to_row, to_column, map_matrix))
        
if __name__ == '__main__':
    map_matrix = [
        [True, False, False],
        [True, True, False],
        [False, True, True]
    ];

    print(route_exists(0, 0, 2, 2, map_matrix))
def route_存在(从_行、从_列、到_行、到_列、映射矩阵):
如果存在路由2(从行、从列、到行、到列、映射矩阵):
返回真值
其他:
返回错误
def route_exists2(从_行、从_列、到_行、到_列、映射矩阵):
如果(从列=len(映射矩阵)或从列=len(映射矩阵[0]):
返回错误
如果映射矩阵[来自\u行][来自\u列]:
映射_矩阵[从_行][从_列]=False#遍历
如果(从_行==到_行和从_列==到_列):
返回真值
返回(路由_exists2(从_行-1、从_列、到_行、到_列、映射矩阵)或
路由_exists2(从_行、从_列-1、到_行、到_列、映射矩阵)或
路由_exists2(从_行、从_列+1、到_行、到_列、映射矩阵)或
路由_exists2(从_行+1、从_列、到_行、到_列、映射矩阵))
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
映射矩阵=[
[真,假,假],
[对,对,错],
[假,真,真]
];
打印(路由_存在(0、0、2、2、地图_矩阵))

我在本练习的4个测试用例中只得到了50%的逻辑错误,我无法从测试用例中重新创建错误。

您需要将结束更改为:

result = (rout_exists2..........)
map_matrix[from_row][from_column] = True
return result
当您进行递归调用,然后返回调用方时,需要撤消对状态所做的任何更改

======扩展我的答案======


想象一下对
route\u exists2()
的外部调用。它要对
route_exists2()
进行四次递归调用,并且它要传递给这四次递归调用中的每一次的矩阵就是它接收到的矩阵,其中一个单元格已更改。但这四个递归调用中的每一个都可能进一步修改矩阵,并且这些更改永远不会撤消。

您需要将结束更改为:

result = (rout_exists2..........)
map_matrix[from_row][from_column] = True
return result
当您进行递归调用,然后返回调用方时,需要撤消对状态所做的任何更改

======扩展我的答案======


想象一下对
route\u exists2()
的外部调用。它要对
route_exists2()
进行四次递归调用,并且它要传递给这四次递归调用中的每一次的矩阵就是它接收到的矩阵,其中一个单元格已更改。但是,这四个递归调用中的每一个都可能进一步修改矩阵,并且这些更改永远不会撤消。

一种可能的方法是在给定起点的情况下映射所有可能的有效目的地,然后检查所需的目的地是否在考虑范围内。我想这就是您在递归调用中试图实现的目标,即尝试将路由_exists()的结尾拆分为几个路由_exists()调用。但问题是,正如Frank Yellin所指出的,当第一个递归调用完全解决时,您正在将该路径的所有路径设置为False,从而避免使用这些路径的其他可能路径。我宁愿尝试存储最后的新路线,并通过它们进行交互

def route_exists(start_x, start_y, end_x, end_y, map_matrix):
    possible_routes = [[[start_x, start_y]]]
        # each route is a list of [x, y] points indicating all the route roads  
    added_routes = 0
    
    while True:
        routes_count = len(possible_routes)
        for route in possible_routes[-added_routes:]:
            # check only the active new rotes and their possible roads
            for x, y in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
                road_x = route[-1][0] + x
                road_y = route[-1][1] + y
                    # the possible road at the route end
                try:
                    if map_matrix[road_x][road_y]: # the road exists
                        if [road_x, road_y] not in route: # not going backwards
                            new_route = route + [[road_x, road_y]]
                            if new_route not in possible_routes:
                                possible_routes.append(new_route)
                except:
                    pass

        added_routes = len(possible_routes) - routes_count
        if added_routes == 0:
            break

    destinations = [r[-1] for r in possible_routes]
    if [end_x, end_y] in destinations:
        return True
    else:
        return False

这种方法检查并存储所有可能的道路,我想这会解决问题,但随着地图矩阵变大,它会消耗内存,因此我鼓励您根据需要进行更改。

一种可能的方法是,在给定起点的情况下,映射所有可能的有效目的地,然后检查是否考虑到所需的目的地。我想这就是您在递归调用中试图实现的目标,即尝试将路由_exists()的结尾拆分为几个路由_exists()调用。但问题是,正如Frank Yellin所指出的,当第一个递归调用完全解决时,您正在将该路径的所有路径设置为False,从而避免使用这些路径的其他可能路径。我宁愿尝试存储最后的新路线,并通过它们进行交互

def route_exists(start_x, start_y, end_x, end_y, map_matrix):
    possible_routes = [[[start_x, start_y]]]
        # each route is a list of [x, y] points indicating all the route roads  
    added_routes = 0
    
    while True:
        routes_count = len(possible_routes)
        for route in possible_routes[-added_routes:]:
            # check only the active new rotes and their possible roads
            for x, y in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
                road_x = route[-1][0] + x
                road_y = route[-1][1] + y
                    # the possible road at the route end
                try:
                    if map_matrix[road_x][road_y]: # the road exists
                        if [road_x, road_y] not in route: # not going backwards
                            new_route = route + [[road_x, road_y]]
                            if new_route not in possible_routes:
                                possible_routes.append(new_route)
                except:
                    pass

        added_routes = len(possible_routes) - routes_count
        if added_routes == 0:
            break

    destinations = [r[-1] for r in possible_routes]
    if [end_x, end_y] in destinations:
        return True
    else:
        return False

这种方法检查并存储所有可能的道路,我想它会解决问题,但随着地图矩阵变大,它会消耗内存,因此我鼓励您根据需要进行更改。

弗兰克·耶林提到的最终解决方案

def route_exists(from_row, from_column, to_row, to_column, map_matrix):
    visited = [[False for i in range(len(map_matrix[0]))] for j in range(len(map_matrix))]
    
    def route_exists2(from_row, from_column, to_row, to_column, map_matrix):
        if (from_row<0 or from_row>=len(map_matrix) or from_column<0 or from_column>=len(map_matrix[0]) or visited[from_row][from_column]==True):
            return False
        if map_matrix[from_row][from_column]:
            visited[from_row][from_column]=True
            #map_matrix[from_row][from_column]=False #traversed
            if (from_row == to_row and from_column ==to_column):
                return True
            return (route_exists2(from_row-1, from_column, to_row, to_column, map_matrix) or
                    route_exists2(from_row, from_column-1, to_row, to_column, map_matrix) or
                    route_exists2(from_row, from_column+1, to_row, to_column, map_matrix) or
                    route_exists2(from_row+1, from_column, to_row, to_column, map_matrix))

    
    if route_exists2(from_row, from_column, to_row, to_column, map_matrix):
        return True
    else:
        return False
    
    
if __name__ == '__main__':
    map_matrix = [
        [True, False, False],
        [True, True, False],
        [False, True, True]
    ];
    

    print(route_exists(0, 0, 2, 2, map_matrix))
def route_存在(从_行、从_列、到_行、到_列、映射矩阵):
visited=[[False for i in range(len(map_矩阵[0]))]for j in range(len(map_矩阵))]
def route_exists2(从_行、从_列、到_行、到_列、映射矩阵):
如果(从列=len(映射矩阵)或从列=len(映射矩阵[0])或访问[从列][从列]==True):
返回错误
如果映射矩阵[来自\u行][来自\u列]:
已访问[从_行][从_列]=True
#映射_矩阵[从_行][从_列]=False#遍历
如果(从_行==到_行和从_列==到_列):
返回真值
返回(路由_exists2(从_行-1、从_列、到_行、到_列、映射矩阵)或
路由_exists2(从_行、从_列-1、到_行、到_列、映射矩阵)或
路由_exists2(从_行、从_列+1、到_行、到_列、映射矩阵)或