python - 使用坐标 python 列表的广度优先搜索

标签 python algorithm breadth-first-search

我正在为“蜘蛛游戏”构建一个简单的人工智能(与贪吃蛇游戏的概念几乎相同,但移动逻辑略有不同)。我正在尝试实现 BFS 算法,以便蜘蛛找到将它引向 Ant 的路径。该算法似乎适用于多次迭代,但是当我在调试器之外运行它时,它在 node_list 中得到一个 None 值,这使得其他方法失败(因为你不能得到任何下一步行动)。

这是 BFS 算法:

def BFS(spider_state, ant_state):
    goal = False
    count = 0
    initial_node = Node(spider_state, None, 0)
    node_list = [initial_node]
    initial_ant_state = ant_state

    while goal == False or len(node_list) == 0:
        e = node_list.pop(0)
        future_ant_state = initial_ant_state
        for i in range(0, e.depth):
            future_ant_state = get_next_ant_move(border_choice, initial_ant_state)
        for move in POSSIBLE_MOVES:
            count += 1
            next_node = Node(None, None, None)
            next_node.state = get_next_spider_move(deepcopy(e.state), move)
            next_node.parent = e
            next_node.depth = e.depth + 1
            if next_node.state == future_ant_state:
                goal = True
                break
            else:
                node_list.append(next_node)
    return node_list

节点:

class Node():
    def __init__(self, state, parent, depth):
        self.state = state
        self.parent = parent
        self.depth = depth

蜘蛛和 Ant 表示为 xy 位置的简单列表:

spider = [15, 35]
ant = [20, 10]

get next move 方法如下所示:

def get_next_spider_move(spidy, move):
    if spidy:
        # check the bounds and assign the new value to spidy
        spidy = spider_bounds(spidy)
        # farthest right
        if move == 0:
            spidy[1] += 2
            spidy[0] -= 1
        # furhter up and right
        if move == 1:
            spidy[1] += 1
            spidy[0] -= 2
        # backwords
        if move == 2:
            spidy[0] += 1
        # farthest left
        if move == 3:
            spidy[1] -= 2
            spidy[0] -= 1
        # furhter up and to the left
        if move == 4:
            spidy[1] += 1
            spidy[0] -= 2
        # one left
        if move == 5:
            spidy[1] -= 1
        # one right
        if move == 6:
            spidy[1] -= 1
        # side right
        if move == 7:
            spidy[1] += 1
            spidy[0] += 1
        # side left
        if move == 8:
            spidy[1] -= 1
            spidy[0] -= 1
        else:
            # if no valid direction was given
            return spidy
    else:
        raise ValueError('spidy must contain an x and y position. %s',  spidy, ' was found')

运行时出现的错误:

    File "spider_game_bfs.py", line 141, in <module>
    path = BFS(spider, ant)
  File "spider_game_bfs.py", line 130, in BFS
    next_node.state = get_next_spider_move(deepcopy(e.state), move)
  File "spider_game_bfs.py", line 100, in get_next_spider_move
    raise ValueError('spidy must contain an x and y position. %s',  spidy, ' was found')
ValueError: ('spidy must contain an x and y position. %s', None, ' was found')

最佳答案

您的移动函数底部存在逻辑错误。最后一个完整的语句是

    if move == 8:
        spidy[1] -= 1
        spidy[0] -= 1
    else:
        # if no valid direction was given
        return spidy

您的评论不正确:else 子句由 8 以外的任何移动 执行。如果移动 8,则您返回None,因为您跳过了返回 spidy 的语句。

如第一条评论所述,使用 if ... elif ... else 作为您的逻辑结构会做得更好。比这更好的是,遵循许多移动项目的在线示例:制作移动列表或字典,如下所示:

move_dir = [
    (-1, +2),  # move 0
    (-2, +1),  # move 1
    (+1,  0),  # move 2
    ...        # fill in the rest
]

if move in range(len(move_dir)):
    spidy[0] += move_dir[move[0]]
    spidy[1] += move_dir[move[1]]
    return spidy
else:
    raise ValueError ...

关于python - 使用坐标 python 列表的广度优先搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54889501/

相关文章:

python - jython 杀死生成子进程的父进程会破坏子进程标准输出到文件吗?

python - 根据时间分割推文

python - 名称错误 : name 'X' is not defined sklearn

查找总和为特定值的第一个整数序列的算法

algorithm - DFS 和 BFS 的实际用途是什么?

python - 确保列表的所有元素都不同的最 pythonic 方法是什么?

最小化路径之间切换的算法

algorithm - 这种素性测试算法的时间复杂度?

c++ - 生成直到给定数字 N 的步进数字

algorithm - O(E+V) 算法计算给定图上 2 个节点之间的最短路径数