为什么我的 DFS 不能解决这个 8 个难题?

问题描述 投票:0回答:1

我正在尝试在这个 8 谜题求解器上运行 DFS。初始状态是这样的:

1 4 2
3 _ 5
6 7 8

其中“_”代表空格。 目标状态是这样的(在我的代码中格式化为_12345678):

_ 1 2
3 4 5
6 7 8

我们给出了预期输出:7U,8L,5D,2D,4R,7U,8U,5L,2D,4D,7R,8U,5U,2L,4D,7D,8R,5U,2U,4L,7D ,8D,5R,2U,4U,7L,8D,5D,2R,1R (向上移动图块 7,向左移动图块 8,等等)

当我运行代码时,它会正确开始并按预期经历大部分状态。然而,接近尾声时,它表现得很奇怪,这就是接近尾声时发生的事情......

探索状态:这里,8D刚刚发生,只剩下几个简短的动作来完成它

1 2 5
3 4 _
6 7 8

探索状态:这是5D

1 2 _
3 4 5
6 7 8

探索状态:这里应该先发生2R,然后发生1R,但空方块只是随机跳到中间,同时调整了4和5。我不确定为什么会发生这种情况,特别是因为到目前为止它都正确通过 DFS

1 2 5
3 _ 4
6 7 8

探索状态:然后继续循环

1 2 5
3 7 4
6 _ 8

我有两个主要函数,get_neighbor 和 dfs。 get_neighbor 通过沿有效方向移动空图块 ('_') 来获取邻居。我不确定这些函数或其他地方是否存在逻辑问题,但这确实难倒了我。

如果您想自己运行它,这是完整的代码。警告,准备好 control+c 因为它会继续下去:

import sys

state = "1423_5678"

# check if the current state matches the goal state
def is_goal(state):
    return state == "_12345678"  

# get neighbors by moving the empty tile ('_') in valid directions
def get_neighbors(state):
    neighbors = []
    state_list = list(state)  
    idx = state.index('_')  # find the index of the empty tile

    # Get the coordinates of the empty tile
    row, col = divmod(idx, 3)

    # possible moves
    moves = [('U', 1, 0), ('L', 0, 1), ('D', -1, 0), ('R', 0, -1)]

    # go over possible moves and check if they are valid
    for move_desc, row_delta, col_delta in moves:
        new_row, new_col = row + row_delta, col + col_delta
        if 0 <= new_row < 3 and 0 <= new_col < 3:  # check if new position is within bounds
            new_idx = new_row * 3 + new_col  # calculate the new index after the move
            # Swap the empty space with the neighboring tile
            new_state_list = state_list[:]  # create a copy of the state list
            tile_moved = new_state_list[new_idx]  # get the tile that's going to move
            new_state_list[idx], new_state_list[new_idx] = new_state_list[new_idx], new_state_list[idx]
            new_state = ''.join(new_state_list)  # join the list back into a string
            # Append the new state and the move (with the tile that moved) to neighbors
            neighbors.append((new_state, f"{tile_moved}{move_desc}"))

    return neighbors

# Depth-First Search (DFS)
def dfs(initial_state):
    stack = [(initial_state, [])]  # stack stores (current_state, path_to_current_state)
    visited = set([initial_state])  # mark initial state as visited

    while stack:
        current_state, path = stack.pop()  # pop the last state added (DFS)
        print(f"Exploring state:\n{format_state(current_state)}")  # Print the current state

        if is_goal(current_state):
            return path  # return the path leading to the goal when found

        # Explore neighbors in the natural order (ULDR), but reversed when appending to stack
        neighbors = get_neighbors(current_state)
        for neighbor, move in neighbors[::-1]:  # reverse the list to explore ULDR
            if neighbor not in visited:  # only explore unvisited states
                visited.add(neighbor)  # mark the neighbor as visited
                stack.append((neighbor, path + [move]))  # add the neighbor to the stack with updated path

    return None  # return None if no solution is found



# Helper function to format the state as a 3x3 grid (for better visualization in debugging)
def format_state(state):
    return '\n'.join([state[i:i+3] for i in range(0, len(state), 3)])

# Main function to execute the DFS
if __name__ == '__main__':
    #initial_state = read_initial_state()  # read initial puzzle state from file
    initial_state = state
    solution_path = dfs(initial_state)  # execute DFS to find the solution path

    if solution_path:
        print("The solution of Q1.1.a (DFS) is:")
        print(','.join(solution_path))  # print the solution as a comma-separated list of moves
    else:
        print("No solution found.")  # in case no solution is found
python depth-first-search sliding-tile-puzzle
1个回答
0
投票

moves
中的
get_neighbors
不正确:

  • 向上和向左应该减少行/列索引,您正在增加它
  • 向下和向右应该增加它们,但你正在减少索引

所以,应该是这样的:

moves = [('U', -1, 0), ('L', 0, -1), ('D', 1, 0), ('R', 0, 1)]

更改后的结果:

Exploring state:
142
3_5
678
Exploring state:
1_2
345
678
Exploring state:
_12
345
678
The solution of Q1.1.a (DFS) is:
4U,1L
© www.soinside.com 2019 - 2024. All rights reserved.