A*算法解八数码拼图问题(搜索算法)

这段代码实现了一个基于优先队列的搜索算法来解决经典的八数码拼图问题。首先定义了VertexNode类表示节点,包含状态、关键值、空间位置和步数。然后创建了Heap类作为优先队列。dn_num函数计算不在正确位置的数字数量,dn_state检查新状态是否已遍历过。heap_search函数进行实际的搜索,通过移动空白格子尝试所有可能的下一步,并根据汉明距离更新节点的关键值。最后,main函数读取输入并输出所需的步数来达到目标状态。
部署运行你感兴趣的模型镜像

题目

通过优先队列搜索算法求解八数码拼图问题

 

 

代码:

import numpy as np
import heapq
import copy


class VertexNode(object):
    def __init__(self, state=None, key=0, space=0, num=0):
        self.key = key
        self.state = state
        self.space = space
        self.num = num

    def __lt__(self, other):
        return self.key < other.key


class Heap(object):
    def __init__(self):
        self._queue = []

    def push(self, item):
        heapq.heappush(self._queue, item)

    def pop(self):
        if self._queue:
            return heapq.heappop(self._queue)
        else:
            return None

    def heapify(self):
        heapq.heapify(self._queue)

    @property
    def queue(self):
        return self._queue


def dn_num(state, goal):  # 不在位将牌数
    num = 0
    for i in range(9):
        if state[i] != goal[i]:
            num += 1
    return num


def dn_state(all_state, new_state):  # 判断新状态是否走过
    k = 0
    for i in all_state:
        if i == new_state:
            k = k + 1
    if k > 0:
        return False
    else:
        return True

    # if new_state in all_state:
    #     return False
    # else:
    #     return True


def heap_search(start, goal, space):
    start_node = VertexNode(state=copy.deepcopy(start), key=0, space=space, num=0)
    open = Heap()
    open.push(start_node)
    all_state = []
    count = 0
    x = [-3, 3, -1, 1]
    all_state.append(list(start_node.state))

    while open.queue:
        cur_node = open.pop()
        if cur_node.state == goal:  # 到目标状态结束
            count = cur_node.num
            break

        # 四个条件,判断上下左右移动
        if cur_node.space not in [0, 1, 2]:
            new_list = copy.deepcopy(cur_node.state)
            new_list[cur_node.space + x[0]], new_list[cur_node.space] = new_list[cur_node.space], new_list[cur_node.space + x[0]]
            new_key = cur_node.num + dn_num(new_list, goal)
            new_node = VertexNode(state=copy.deepcopy(new_list), key=new_key, space=cur_node.space + x[0], num=cur_node.num + 1)
            if dn_state(all_state, new_node.state):
                all_state.append(list(new_node.state))
                open.push(new_node)
        if cur_node.space not in [6, 7, 8]:
            new_list = copy.deepcopy(cur_node.state)
            new_list[cur_node.space + x[1]], new_list[cur_node.space] = new_list[cur_node.space], new_list[cur_node.space + x[1]]
            new_key = cur_node.num + dn_num(new_list, goal)
            new_node = VertexNode(state=copy.deepcopy(new_list), key=new_key, space=cur_node.space + x[1], num=cur_node.num + 1)
            if dn_state(all_state, new_node.state):
                all_state.append(list(new_node.state))
                open.push(new_node)
        if cur_node.space not in [0, 3, 6]:
            new_list = copy.deepcopy(cur_node.state)
            new_list[cur_node.space + x[2]], new_list[cur_node.space] = new_list[cur_node.space], new_list[cur_node.space + x[2]]
            new_key = cur_node.num + dn_num(new_list, goal)
            new_node = VertexNode(state=copy.deepcopy(new_list), key=new_key, space=cur_node.space + x[2], num=cur_node.num + 1)
            if dn_state(all_state, new_node.state):
                all_state.append(list(new_node.state))
                open.push(new_node)
        if cur_node.space not in [2, 5, 8]:
            new_list = copy.deepcopy(cur_node.state)
            new_list[cur_node.space + x[3]], new_list[cur_node.space] = new_list[cur_node.space], new_list[cur_node.space + x[3]]
            new_key = cur_node.num + dn_num(new_list, goal)
            new_node = VertexNode(state=copy.deepcopy(new_list), key=new_key, space=cur_node.space + x[3], num=cur_node.num + 1)
            if dn_state(all_state, new_node.state):
                all_state.append(list(new_node.state))
                open.push(new_node)

        # for i in range(4):
        #     a = cur_node.space + x[i]
        #     if a > 8 or a < 0:
        #         continue
        #     else:
        #         new_list = copy.deepcopy(cur_node.state)
        #         new_list[cur_node.space+x[i]], new_list[cur_node.space] = new_list[cur_node.space], new_list[cur_node.space+x[i]]
        #         new_key = cur_node.num + dn_num(new_list, goal)
        #         new_node = VertexNode(state=copy.deepcopy(new_list), key=new_key, space=cur_node.space+x[i], num=cur_node.num+1)
        #         if dn_state(all_state, new_node.state):
        #             all_state.append(list(new_node.state))
        #             open.push(new_node)
    return count


def main():
    m, n = map(int, input().split())
    m = m
    n = n
    a = []
    for i in range(3):
        a.append(list(map(int, input().rstrip().split())))
    b = np.array(a).reshape(3, 3)
    start = list(b.flatten())  # 压成一维数组

    goal = [0, 1, 2, 3, 4, 5, 6, 7, 8]
    goal[3*m+n] = -1
    for i in range(9):
        if start[i] == -1:
            space = i

    dis = heap_search(start, goal, space)
    print(dis)


if __name__ == '__main__':
    main()

"""
2 2
0 1 2
3 -1 4
6 7 5
"""
"""
1 1
-1 0 2
3 1 5
6 7 8
"""
"""
1 1
2 5 -1
1 3 7
6 0 8
"""

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值