Python深度优先解决八数码问题

宽度优先解决八数码问题基础上对节点类增加深度属性

import copy
import numpy as np
from datetime import datetime


# 字符串列表化
def string_to_ls(str):
    return [i.split(' ') for i in str.split(',')]


# 获取位置
def get_loacl(arr, target):
    # r, c = np.where(arr == target)
    # return r, c
    for i in arr:
        for j in i:
            if j == target:
                return arr.index(i), i.index(j)


# 获取可以和0交换位置的元素
def get_elements(arr):
    r, c = get_loacl(arr, '0')
    elements = []
    if r > 0:
        elements.append(arr[r - 1][c])  # 上面的元素
    if r < 2:
        elements.append(arr[r + 1][c])  # 下边的元素
    if c > 0:
        elements.append(arr[r][c - 1])  # 左面的元素
    if c < 2:
        elements.append(arr[r][c + 1])  # 右面的元素
    return elements


def get_child(arr, e):
    # 深拷贝与浅拷贝!!
    arr_new = copy.deepcopy(arr)
    r, c = get_loacl(arr_new, '0')
    r1, c1 = get_loacl(arr_new, e)
    arr_new[r][c], arr_new[r1][c1] = arr_new[r1][c1], arr_new[r][c]
    return arr_new


def is_goal(arr, goal):
    return arr == goal


class state:
    def __init__(self, state, deep, parent):
        # state是一个3x3的ls矩阵
        self.state = state
        self.deep = deep
        self.parent = parent

    def chidren(self):
        chidren = []
        for i in get_elements(self.state):
            child = state(state=get_child(self.state, i), deep=self.deep + 1, parent=self)
            chidren.append(child)
        return chidren


# 打印求解路径
def print_path(n):
    if n.parent == None:
        return
    else:
        print('↑')
        print(np.array(n.parent.state))
        print_path(n.parent)


if __name__ == '__main__':
    # initial = '0 1 3,4 2 5,7 8 6'
    # goal = '4 1 3,7 0 5,8 2 6'
    # initial = '0 7 8,2 5 4,3 6 1'
    # goal = '7 5 8,2 4 1,3 6 0'
    initial = '4 0 1,6 8 5,7 3 2'
    goal = '5 8 2,1 0 4,6 3 7'
    initial_arr = state(string_to_ls(initial), deep=0, parent=None)
    goal_arr = string_to_ls(goal)
    start = datetime.now()
    open = [initial_arr]
    close = []
    # limit = eval(input('请输入要搜索的深度:'))
    limit = 20
    while len(open) > 0:
        open_tb = [i.state for i in open]
        close_tb = [i.state for i in close]
        n = open.pop(0)
        close.append(n)
        if is_goal(n.state, goal_arr):
            print(np.array(n.state))
            print_path(n)
            print('求解过程如上')
            break
        else:
            if n.deep < limit:
                for i in n.chidren():
                    if i.state not in open_tb:
                        if i not in close_tb:
                            open.insert(0, i)
    else:
        print('该深度下无解')

    end = datetime.now()
    print('深度为{}下的搜索步数为:{}'.format(close[-1].deep, len(close) - 2))
    print('共耗时:', end - start)

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值