数据结构实践二:项目准备与设计

一. 实践内容

隐式图的搜索问题
(1)实践任务
  • 对九宫重排问题,建立图的启发式搜索求解方法;
  • 用A*算法求解九宫重排问题。
(2)实践要求
  • 3х3九宫棋盘,放置数码为1~8的8个棋子,棋盘中留有一个空格,空格周围的棋子可以移动到空格中,从而改变棋盘的布局。根据给定初始布局和目标布局,移动棋子从初始布局到达目标布局,求解移动步骤并输出。请设计算法,使用合适的搜索策略,在较少的空间和时间代价下找到最短路径。
    在这里插入图片描述

二. 开发环境

  • 实现语言:Java
  • 开发平台:IntelliJ IDEA

三. 项目设计

(1)A*算法

这是一种在静态路网中求解最短路径的有效算法,通俗地讲,它不是像深度优先搜索算法和广度优先搜索算法一样的傻瓜式的埋头搜索,它是先对当前的情况进行分析,得到最有可能的一个分支,然后在该分支上进行扩展,然后将扩展的结果放在之前的大环境中进行比较,再选取最有可能的分支进行扩展,直到找到最终状态。
A*算法的核心是估价函数的选取(通俗的说就是对当前情况的评价方式的选取,通过什么方式选取的分支才是最有可能离最终状态最近的分支)。
公式表示为: f(n)=g(n)+h(n),
其中 f(n) 是从初始点经由节点n到目标点的估价函数,
g(n) 是在状态空间中从初始节点到n节点的实际代价,
h(n) 是从n到目标节点最佳路径的估计代价。

最佳路径查找步骤:
1,从起始状态A开始,并且把它作为待处理点存入一个“open list”。open list就像一张购物清单。尽管现在列表里只有一个元素,但以后就会多起来。你的路径可能会通过它包含的其他状态,也可能不会。基本上,这是一个待检查方格的列表。
2,寻找起点周围通过上下左右移动所有可到达的状态。也把他们加入open list。为所有这些状态保存状态A作为“父方格”。当我们想描述路径的时候,父方格的资料是十分重要的。后面会解释它的具体用途。
3,从open list中删除状态A,把它加入到一个“close list”。
4,取出open list中 f(n)最低的状态,判断该状态性质
(1) 如果在open list中出现,那么判断该状态的 g(n) 通过当前节点(从open list中取出,扩展出该节点的节点)作为父节点带来的 g(n) 是否小于原先的父节点,若小于则需要更改它的父节点以及 g(n) .
(2) 如果在close list中出现,那么判断该状态的 g(n) 通过当前节点(从open list中取出,扩展出该节点的节点)作为父节点带来的 g(n) 是否小于原先的父节点,若小于则需要从close list中删除该节点,并且将其加入open list,并更改其父节点为当前节点。
(3) 既不在open list,也不在close list,这样就很简单,直接加入open list中就行(保持open list升序排列)
(4) 如果取出的节点为目标节点,则成功退出

A*算法的伪代码

创建两个表,open表保存所有已生成而未考察的节点,close表中记录已访问过的节点。 
算起点的估价值;
将起点放入open表;
   while(open!=NULL)
 {
    从open表中取估价值f最小的节点n;
         if(n节点==目标节点){
         break;
          }
         for(当前节点n 的每个子节点X)
       {
          算X的估价值;
              if(X in open)
            {
                if( X的估价值小于open表的X估价值 ){
                把n设置为X的父亲;
               更新open表中的估价值; //取最小路径的估价值 
                     }
          }
        if(X in close) {
                if( X的估价值小于close表的X估价值 )
                把n设置为X的父亲;  
                 将该节点从close表中除去
             把X节点放入open //取最小路径的估价值 
                       }
              }
         if(X not in both){
           把n设置为X的父亲;
           求X的估价值;
           并将X插入open表中; //升序排列open
         }
    }//end for
  将n节点插入close表中;
  按照估价值将open表中的节点排序; //实际上是比较open表内节点f的大小,从最小路径的节点向下进行。
  } //end while(open!=NULL)
 保存路径,即从终点开始,每个节点沿着父节点移动直至起点,这就是你的路径;
(2)A*算法解决九宫格重排问题

算法计算公式 f(n) = g(n)+h(n)
其中 g(n) 为从起始状态到当前状态所消耗的步数,h(n)为估算从当前状态到目标状态所需的步数,一般h(n)小于等于实际需要步数为好,这样不会将最优解忽略,因为h(n)和解空间有一些关系,如果h(n)设置的比实际需要的步数多,那么解空间就有可能将最优解忽略。举个例子,宽度优先搜索就是h(n)=0带来的效果,深度优先搜索就是g(n)=0带来的效果,不过h(n)距离h*(n)[实际需要的步数]的程度不能过大,否则h(x)就没有过强的区分能力,算法效率并不会很高。对一个好的h(n)的评价是:h(n)在h*(n)的下界之下,并且尽量接近h*(n)。
那么八数码问题 g(n) 为经过上下左右移动空格附近的数字来得到新状态所需步数,h(n) 为当前状态与目标状态的距离,就是所有不在目标位置的数字总和,必然小于h*(n)。

对于八数码问题,每个结点有8个数字和一个空格,可以将空格看成0,那么一共有9个数字,可以用一个整数表示一个结点对应的信息。
我们令g(n)为从开始节点到当前节点所经过的实际步数(即深度),h(n)为从该节点到最终节点必须至少要的步数的估计(在估算h(n)时,我们忽略其他的数字对该数字到其最终位置的影响,所以h(n)只是其最小步数的下限),f(n)=h(n)+g(n)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当编制数据结构教学计划时,可以考虑以下几个方面的内容: 1. 教学目标:明确教学的目标和重点,例如学生应该掌握的基本概念、算法和数据结构的应用等。 2. 教学内容:确定教学内容的范围和深度,包括但不限于线性表、栈、队列、树、图等数据结构的基本知识和相关算法。 3. 教学方法:选择适合的教学方法,例如讲授、实践、案例分析、小组讨论等,以提高学生的理解和应用能力。 4. 教学资源:准备教学所需的资源,包括教材、课件、实验室设备等,以支持教学过程中的实践和演示。 5. 教学评估:设计合适的评估方式,例如作业、考试、项目等,以检验学生对数据结构的理解和应用能力。 编制代码方面,可以考虑以下几个步骤: 1. 确定代码实现语言:选择一种适合教学的编程语言,例如C++、Java等。 2. 设计数据结构类:根据教学内容,设计相应的数据结构类,例如链表、栈、队列等。 3. 实现基本操作:在每个数据结构类中,实现基本的操作方法,例如插入、删除、查找等。 4. 编写示例代码:编写一些示例代码,演示如何使用数据结构类进行操作和解决问题。 5. 提供注释和说明:在代码中添加注释和说明,解释每个方法的功能和使用方法,以便学生理解和学习。 6. 整理代码文档:将代码整理成文档形式,包括教学目标、代码实现、示例代码和注释说明等内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值