首页 > 编程语言 >搜索算法练习——拼图问题

搜索算法练习——拼图问题

时间:2024-04-01 15:02:21浏览次数:26  
标签:状态 ni 拼图 练习 搜索算法 empty board 方块

拼图问题是一个经典的搜索问题,其中目标是将一个拼图板恢复到初始状态,或者找到一个初始状态到目标状态的最短路径。

我们可以使用广度优先搜索(BFS)来解决这个问题,将每个状态作为节点,并尝试所有可能的移动。

from collections import deque

def swap(board, i, j, ni, nj):
    """
    交换拼图板上两个方块的位置。
    
    Parameters:
        board (list): 当前拼图板状态。
        i (int): 第一个方块的行号。
        j (int): 第一个方块的列号。
        ni (int): 第二个方块的行号。
        nj (int): 第二个方块的列号。
    """
    board[i][j], board[ni][nj] = board[ni][nj], board[i][j]

def get_neighbors(board):
    """
    获取当前拼图板状态的所有可能邻居状态。
    
    Parameters:
        board (list): 当前拼图板状态。
    
    Returns:
        list: 所有可能的邻居状态列表。
    """
    neighbors = []
    empty_row, empty_col = find_empty_square(board)
    moves = [(1, 0), (-1, 0), (0, 1), (0, -1)]  # 可以向上、下、左、右移动的方向
    for dr, dc in moves:
        nr, nc = empty_row + dr, empty_col + dc
        if 0 <= nr < len(board) and 0 <= nc < len(board[0]):
            new_board = [row[:] for row in board]  # 创建当前拼图板的副本
            swap(new_board, empty_row, empty_col, nr, nc)  # 移动空方块
            neighbors.append(new_board)
    return neighbors

def find_empty_square(board):
    """
    在拼图板上找到空方块的位置。
    
    Parameters:
        board (list): 拼图板状态。
    
    Returns:
        tuple: 空方块的行号和列号。
    """
    for i in range(len(board)):
        for j in range(len(board[0])):
            if board[i][j] == 0:
                return i, j

def is_goal_state(board, target):
    """
    检查当前拼图板状态是否为目标状态。
    
    Parameters:
        board (list): 当前拼图板状态。
        target (list): 目标拼图板状态。
    
    Returns:
        bool: 如果当前状态与目标状态相同,则返回True,否则返回False。
    """
    return board == target

def bfs_puzzle(initial, target):
    """
    使用广度优先搜索(BFS)解决拼图问题。
    
    Parameters:
        initial (list): 初始拼图板状态。
        target (list): 目标拼图板状态。
    
    Returns:
        list: 到达目标状态的最短路径,如果不存在路径则返回空列表。
    """
    queue = deque([(initial, [])])  # 使用队列存储当前拼图板状态和到达该状态的路径
    visited = set([tuple(map(tuple, initial))])  # 使用集合记录已经访问过的拼图板状态
    
    while queue:
        board, path = queue.popleft()
        if is_goal_state(board, target):
            return path
        for neighbor in get_neighbors(board):
            if tuple(map(tuple, neighbor)) not in visited:
                visited.add(tuple(map(tuple, neighbor)))
                queue.append((neighbor, path + [neighbor]))
    
    return []

# 示例初始拼图板状态和目标拼图板状态
initial_board = [
    [1, 2, 3],
    [0, 4, 5],
    [6, 7, 8]
]
target_board = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 0]
]

# 使用广度优先搜索解决拼图问题
shortest_path = bfs_puzzle(initial_board, target_board)
if shortest_path:
    print("到达目标状态的最短路径:")
    for step in shortest_path:
        for row in step:
            print(row)
        print()
else:
    print("未找到到达目标状态的路径。")

在上述代码中,我们首先定义了几个辅助函数:

  • swap(board, i, j, ni, nj):用于交换拼图板上两个方块的位置。
  • get_neighbors(board):用于获取当前拼图板状态的所有可能邻居状态。
  • find_empty_square(board):用于找到拼图板上空方块的位置。
  • is_goal_state(board, target):用于检查当前拼图板状态是否为目标状态。

然后,我们使用广度优先搜索(BFS)来解决拼图问题。在每一步中,我们从队列中取出当前拼图板状态,然后尝试移动空方块,并将新的拼图板状态加入队列中。最终,如果找到到达目标状态的路径,则打印该路径;否则,打印未找到路径的消息。

标签:状态,ni,拼图,练习,搜索算法,empty,board,方块
From: https://blog.csdn.net/SmiledrinkCat/article/details/137023086

相关文章

  • 搜索算法练习——八皇后问题
    八皇后问题是一个经典的回溯算法问题,其目标是在8×8的棋盘上放置八个皇后,使得它们彼此之间不会相互攻击,即任意两个皇后都不在同一行、同一列或同一斜线上。我们可以使用回溯算法来解决这个问题,其中深度优先搜索(DFS)用于尝试每个可能的放置位置。defis_safe(board,row,co......
  • 递归例题+练习
    例题2斐波那契数列时间限制:1s内存限制:128M 题目描述斐波那契数列是一个有特殊规律的数列,它的前两项都是1,从第3项开始,该项等于前两项数字之和。现在请你输出斐波那契的第n项。【输入格式】输入共1行:第1行,1个正整数n。【输出格式】输出共1行:第1行,输出......
  • 2024年春季学期《算法分析与设计》练习5
    问题A:随机数题目描述有一个rand(n)的函数,它的作用是产生一个在[0,n)的随机整数。现在有另外一个函数,它的代码如下:intrandom(intn,intm){        returnrand(n)+m;}显而易见的是函数random(n,m)可以产生任意范围的随机数。现在问题来了,如果我想要......
  • 练习3-2 计算符号函数的值
    对于任一整数n,符号函数sign(n)的定义如下:请编写程序计算该函数对任一输入整数的值。输入格式:输入在一行中给出整数n。输出格式:在一行中按照格式“sign(n)=函数值”输出该整数n对应的函数值。输入样例1:10输出样例1:sign(10)=1输入样例2:0输出样例2......
  • 20240331_搜索练习
    目录P3206DungeonMasterP3207LakeCountingP3208TheCastleP896仙岛求药P429【基础】走迷宫P2465迷宫问题P952【入门】算24点P3206DungeonMaster这题是一个三维迷宫,其中用‘.’表示空地,‘#’表示障碍物,‘S’表示起点,‘E’表示终点,求从起点到终点的最小移动次......
  • 00342第四章 结构化程序设计 思考题和练习题(C语言)
    一、单项选择题1.若从键盘输入字符串"HOWAREYOU?",可以直接使用库函数【】。        A.scanf    B.getstr    C.gets    D.都不能直接使用2.C语言的库函数中,可以输出double型变量值的是【】。        A.getchar   ......
  • 算法---动态规划练习-9(粉刷房子)
    题目1.题目解析2.讲解算法原理3.编写代码1.题目解析题目地址:点这里2.讲解算法原理创建dp表:vector<vector>dp(n,vector(3))。这里创建了一个二维向量dp,其中dp[i][j]表示第i天选择颜色j的最小成本。初始化第一天的成本:for(inti=0;i<3;i++)......
  • 【2024年5月备考新增】《软考真题分章练习(含答案解析) - 14 组织级项目管理(高项)》
    1题目1、办公软件开发公司A非常重视软件过程管理,按照CMMI(能力成熟度模型)逐步进行过程改进,刚刚实现了组织级过程性能、定量项目管理,按照CMMI(能力成熟度模型),A公司达到了()级别。A.CMMI2B.CMMI3C.CMMI4D.CMMI52、CMMI的连续式表示法与阶段式表示法分别表示:()。A.项......
  • 8.C语言的一些练习题坑整理
    总结没有顺序之分想起一个算一个逗号表达式https://blog.csdn.net/qq_43539854/article/details/105757536(参考)设f是实型变量,下列表达式中不是逗号表达式的是_________A.f=3.2,1.0B.f>0,f<10C.f=2.0,f>0D.f=(3.2,1.0)逗号表达式即执行第......
  • L2-046 天梯赛的赛场安排 团体程序设计天梯赛-练习集 c++ 易懂 模拟
    天梯赛使用OMS监考系统,需要将参赛队员安排到系统中的虚拟赛场里,并为每个赛场分配一位监考老师。每位监考老师需要联系自己赛场内队员对应的教练们,以便发放比赛账号。为了尽可能减少教练和监考的沟通负担,我们要求赛场的安排满足以下条件:每位监考老师负责的赛场里,队员人数不得......