AI 八数码A_star算法问题-实验报告

简介: AI 八数码A_star算法问题-实验报告

一 题目要求:


       八数码问题的A星搜索算法实现

       要求:设计估价函数,并采用c或python编程实现,以八数码为例演示A星算法的搜索过程,争取做到直观、清晰地演示算法,代码要适当加注释。

       八数码难题:在3×3方格棋盘上,分别放置了标有数字1,2,3,4,5,6,7,8的八张牌,初始状态S0可自己随机设定,使用的操作有:空格上移,空格左移,空格右移,空格下移。试采用A*算法编一程序实现这一搜索过程.

二 构造状态空间:


       这个题目的状态空间描述为一组整数对(r,s,t,u,v,w,x,y,z)。

       每个字母分别对应八数码的每个位置,如下表所示。

r s t
u v w
x y z

表1-八数码状态空间对应关系

三 对题目的理解:


       这个题目也应该采用树形结构来解,我觉得难点有二:

  1. 如何建立每个节点的数据结构;
  2. 因为是A*算法,所以公式f=g+h启发信息,如何在编程中体现。
    这里我是用Python写的算法,结点的数据结构如下:
class Point:
    def __init__(self, r, s, t, u, v, w, x, y, z):
        self.r = r
        self.s = s
        self.t = t
        self.u = u
        self.v = v
        self.w = w
        self.x = x
        self.y = y
        self.z = z
        self.g = 0
        self.f = 0  # f = g+h
        self.father = None
        self.node = [r, s, t, u, v, w, x, y, z] 

首先定义了八数码问题的9个位置的值。比较重要的是Point结点的father属性,指明了子节点与父节点的关系,保证了树形结构的准确性。然后定义了g属性,来保存节点的深度,f属性为g+h的和,这样就保证了启发信息。


后来遇到个Python特有的bug,就是def了一个函数,然后传参,就算我用=号复制了一个list,原来的参数也会被改变,因为他们的指针都是一样的。解决方法是用copy.copy(list),这样复制就不是同一个指针了。

四 算法代码:


见报告最后。

五 代码解释:


首先定义了open表、closed表,声明了Point类,定义了初始节点init(2, 0, 3, 1, 8, 4, 7, 6, 5)和目的节点(1, 2, 3, 8, 4, 5, 0, 7, 6)。

在开始进行A_star(A*)算法之前,先定义几个函数:

1) getKey:找出Point节点中0(即空格)的位置索引;

2) up:空格上移函数。把某节点的空格和上方位置的值交换(考虑了溢出问题,即第一行不能up);

3) down:空格下移函数。同上;

4) left:空格左移函数。同上;

5) right:空格右移函数。同上;

6) h:启发函数。将某个节点与目的节点比较,返回位置不同的数目;

7) equal:判断两个节点是否相同;

8) open_sort:把open表里面的节点,按照属性f的值,排序;

9) in_list:判断节点是否在open表或者closed表已经存在。

开始编写A*算法:

1) 首先,先把初始节点init放入到OPEN表中,然后遍历OPEN表;

2) 如果OPEN中取出的节点是目的节点goal,那么结束遍历;否则把这个节点从OPEN表取出,放入CLOUSED表;

3) 然后根据此节点,来得到它的子节点,通过上、下、左、右四个方向来获取四个新节点,然后对四个节点遍历;

4) 把该节点的f属性、father属性、g属性指定好。判断该new节点是否已经出现在open表中,如果已经出现了而且它的f属性值更好,说明它更优,那么把之前的移除,把这个插入。Open表同理。如果该new节点在open表和closed表都没有,那么把它直接插入到open表。最后根据f属性的值,对open表的节点排序。

4 最后打印一下路径,就可显示出解。

六 算法输出分析:


如图1是以初始节点init(2, 0, 3, 1, 8, 4, 7, 6, 5)和目的节点(1, 2, 3, 8, 4, 5, 0, 7, 6)运行的程序输出。根据OPEN表画出树形图如图2。

image.png

图1-程序输出

2020042412423519.jpg

图2-分析过程

附:Python算法


import copy
import operator
OPEN = []  # open表
CLOSED = []  # closed表
class Point:
    def __init__(self, r, s, t, u, v, w, x, y, z):
        self.r = r
        self.s = s
        self.t = t
        self.u = u
        self.v = v
        self.w = w
        self.x = x
        self.y = y
        self.z = z
        self.g = 0
        self.f = 0  # f = g+h
        self.father = None
        self.node = [r, s, t, u, v, w, x, y, z]
init = Point(2, 0, 3, 1, 8, 4, 7, 6, 5)  # 初始节点
goal = Point(1, 2, 3, 8, 0, 4, 7, 6, 5)  # 目标
# 返回空位的index值
def getKey(s):
    return s.node.index(0)
def up(s, key):
    if key - 3 >= 0:
        arr = copy.copy(s.node)
        arr[key], arr[key - 3] = arr[key - 3], arr[key]
        return Point(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8])
    else:
        return None
def down(s, key):
    if key + 3 <= 8:
        arr = copy.copy(s.node)
        arr[key], arr[key + 3] = arr[key + 3], arr[key]
        return Point(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8])
    else:
        return None
def left(s, key):
    if key != 0 and key != 3 and key != 6:
        arr = copy.copy(s.node)
        arr[key], arr[key - 1] = arr[key - 1], arr[key]
        return Point(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8])
    else:
        return None
def right(s, key):
    if key != 2 and key != 5 and key != 8:
        arr = copy.copy(s.node)
        arr[key], arr[key + 1] = arr[key + 1], arr[key]
        return Point(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8])
    else:
        return None
# 启发函数
def h(s, p=goal):
    flag = 0
    for i in range(0, 9):
        if s.node[i] != p.node[i]:
            flag += 1
    return flag
def equal(a, b):
    if a.node == b.node:
        return True
# 将open_list以f值进行排序
def open_sort(l):
    the_key = operator.attrgetter('f')  # 指定属性排序的key
    l.sort(key=the_key)
# 扩展节点时在open表和closed表中找原来是否存在相同属性的节点
def in_list(new, l):
    for item in l:
        if new.node == item.node:
            return True, item
    return False, None
def A_star(s):
    global OPEN, CLOSED
    OPEN = [s]
    CLOSED = []
    while OPEN:  # open表非空
        get = OPEN[0]  # 取出open表第一个元素get
        if get.node == goal.node:  # 判断是否为目标节点
            return get
        OPEN.remove(get)  # 将get从open表移出
        CLOSED.append(get)  # 将get加入closed表
        # 以下得到一个get的新子节点new并考虑是否放入OPEN
        key = getKey(get)
        for i in range(0, 4):  # 四个方向
            if i == 0:
                new = up(get, key)
            elif i == 1:
                new = down(get, key)
            elif i == 2:
                new = left(get, key)
            elif i == 3:
                new = right(get, key)
            if new == None:  # 状态非法或new折返了
                pass
            # 如果要拓展的节点满足以上情况,将它的父亲设为当前节点,计算f,并对open_list排序
            else:
                new.father = get
                new.g = get.g + 1  # 与起点的距离
                new.f = get.g + h(new)  # f = g + h
                # 如果new在open表中(只关注m,c,b的值)
                if in_list(new, OPEN)[0]:
                    old = in_list(new, OPEN)[1]
                    if new.f < old.f:  # new的f<open表相同状态的f
                        OPEN.remove(old)
                        OPEN.append(new)
                        open_sort(OPEN)
                    else:
                        pass
                # 继续,如果new在closed表中
                elif in_list(new, CLOSED)[0]:
                    old = in_list(new, CLOSED)[1]
                    if new.f < old.f:
                        # 将old从closed删除,并重新加入open
                        CLOSED.remove(old)
                        OPEN.append(new)
                        open_sort(OPEN)
                    else:
                        pass
                else:
                    OPEN.append(new)
                    open_sort(OPEN)
        print('OPEN:')
        for o in OPEN:
            print(o.node,o.f,o.g)
# 递归打印路径
def printPath(f):
    if f is None:
        return
    printPath(f.father)
    print(f.node)
if __name__ == '__main__':
    final = A_star(init)
    if final:
        print('有解,解为:')
        printPath(final)
    else:
        print('无解!')
相关文章
|
5天前
|
传感器 人工智能 监控
智慧电厂AI算法方案
智慧电厂AI算法方案通过深度学习和机器学习技术,实现设备故障预测、发电运行优化、安全监控和环保管理。方案涵盖平台层、展现层、应用层和基础层,具备精准诊断、智能优化、全方位监控等优势,助力电厂提升效率、降低成本、保障安全和环保合规。
智慧电厂AI算法方案
|
6天前
|
机器学习/深度学习 人工智能 监控
智慧交通AI算法解决方案
智慧交通AI算法方案针对交通拥堵、违法取证难等问题,通过AI技术实现交通管理的智能化。平台层整合多种AI能力,提供实时监控、违法识别等功能;展现层与应用层则通过一张图、路口态势研判等工具,提升交通管理效率。方案优势包括先进的算法、系统集成性和数据融合性,应用场景涵盖车辆检测、道路环境检测和道路行人检测等。
|
6天前
|
传感器 人工智能 监控
智慧化工厂AI算法方案
智慧化工厂AI算法方案针对化工行业生产过程中的安全风险、效率瓶颈、环保压力和数据管理不足等问题,通过深度学习、大数据分析等技术,实现生产过程的实时监控与优化、设备故障预测与维护、安全预警与应急响应、环保监测与治理优化,全面提升工厂的智能化水平和管理效能。
智慧化工厂AI算法方案
|
29天前
|
人工智能 安全 决策智能
OpenAI推出实验性“Swarm”框架,引发关于AI驱动自动化的争论
OpenAI推出实验性“Swarm”框架,引发关于AI驱动自动化的争论
|
1月前
|
机器学习/深度学习 人工智能 算法
"拥抱AI规模化浪潮:从数据到算法,解锁未来无限可能,你准备好迎接这场技术革命了吗?"
【10月更文挑战第14天】本文探讨了AI规模化的重要性和挑战,涵盖数据、算法、算力和应用场景等方面。通过使用Python和TensorFlow的示例代码,展示了如何训练并应用一个基本的AI模型进行图像分类,强调了AI规模化在各行业的广泛应用前景。
31 5
|
1月前
|
人工智能 算法 前端开发
无界批发零售定义及无界AI算法,打破传统壁垒,累积数据流量
“无界批发与零售”是一种结合了批发与零售的商业模式,通过后端逻辑、数据库设计和前端用户界面实现。该模式支持用户注册、登录、商品管理、订单处理、批发与零售功能,并根据用户行为计算信用等级,确保交易安全与高效。
|
1月前
|
人工智能 算法 JavaScript
无界SaaS与AI算力算法,链接裂变万企万商万物互联
本文介绍了一种基于无界SaaS与AI算力算法的商业模式的技术实现方案,涵盖前端、后端、数据库及AI算法等关键部分。通过React.js构建用户界面,Node.js与Express搭建后端服务,MongoDB存储数据,TensorFlow实现AI功能。提供了项目结构、代码示例及部署建议,强调了安全性、可扩展性和性能优化的重要性。
|
6天前
|
机器学习/深度学习 人工智能 自然语言处理
当前AI大模型在软件开发中的创新应用与挑战
2024年,AI大模型在软件开发领域的应用正重塑传统流程,从自动化编码、智能协作到代码审查和测试,显著提升了开发效率和代码质量。然而,技术挑战、伦理安全及模型可解释性等问题仍需解决。未来,AI将继续推动软件开发向更高效、智能化方向发展。
|
11天前
|
机器学习/深度学习 人工智能 自然语言处理
AI在医疗领域的应用及其挑战
【10月更文挑战第34天】本文将探讨人工智能(AI)在医疗领域的应用及其面临的挑战。我们将从AI技术的基本概念入手,然后详细介绍其在医疗领域的各种应用,如疾病诊断、药物研发、患者护理等。最后,我们将讨论AI在医疗领域面临的主要挑战,包括数据隐私、算法偏见、法规合规等问题。
30 1
|
8天前
|
机器学习/深度学习 人工智能 算法
AI在医疗领域的应用与挑战
本文探讨了人工智能(AI)在医疗领域的应用,包括其在疾病诊断、治疗方案制定、患者管理等方面的优势和潜力。同时,也分析了AI在医疗领域面临的挑战,如数据隐私、伦理问题以及技术局限性等。通过对这些内容的深入分析,旨在为读者提供一个全面了解AI在医疗领域现状和未来发展的视角。
40 10

热门文章

最新文章