用MATLAB结合四种方法搜寻罗马尼亚度假问题

选修了cs的AI课,开始有点不适应,只能用matlab硬着头皮上了,不过matlab代码全网仅此一份,倒有点小自豪。

一、练习题目

分别用宽度优先、深度优先、贪婪算法和 A*算法求解“罗马利亚度假问题”。具体地图我这里不给出了,有兴趣的可以去搜索。即找到从初始地点 Arad到 目的地点 Bucharest 的一条路径。

要求:分别用文件存储地图和启发函数表,用生成节点数比较以上四种算法在同一问题求解时的效率,列表给出结果。

附:罗马尼亚度假问题图(图1.1)

 

图1.1 罗马尼亚度假问题

1.2 题目分析

本题要求分别用宽度优先、深度优先、贪婪算法和 A*算法求解“罗马利亚度假问题”。罗马尼亚度假问题本质上属于“图类”问题,该地图上共有20个地点,要求从Arad出发,到达Bucharest,从图中搜索到达路径,并比较四种方法的优缺点。因此主要的数据结构可以采用图存储的方法,搜索方法题目已经给出。

二、数据结构

2.1 图结构

图:由有穷、非空点集和边集合组成,简写成G(V,E),其中,G表示一个图,V表示图中的顶点,E表示图中的边。在本题,顶点为20个罗马尼亚城市,边则为相邻城市之间的距离。边之间有方向,图为有向图,无方向的图为无向图。本题所用的图为无向图。

尽管二维数组比较占用内存,但是由于MATLAB对矩阵运算非常方便,运算速度也很快,我采用二维数组的方法存储邻接矩阵。对20个地点编号1-20,其中Arad为3号地点,对边采用数值的方法,例如3号到4号距离为75,则令矩阵中点(3,4)的值为75。并令自身距离为0,不相邻的点之间也设为0。

2.2 队列结构

队列(Queue):是只允许在一端进行插入操作,在另一端进行删除操作的线性表。队列也是一种特殊的线性表,是一种先进先出的线性表。允许插入的一端称为表尾,允许删除的一端称为表头。我们将在广度优先搜索中使用到这个结构存储已搜索过的节点。其结构如图2.2所示。

 

图2.2 队列结构图

2.3 栈结构

栈(Stack):也是一种线性存储结构,栈中的数据元素遵守“先进后出”(First In Last Out)的原则,简称FILO结构。只能在栈顶进行插入和删除操作。我们将在深度优先搜索中使用到这个结构存储已搜索过的节点。其结构如图2.3所示。

 

图2.3 栈结构图

三、算法思想

3.1 宽度优先

宽度优先搜索算法(又称广度优先搜索)其别名又叫BFS( Breadth First Search)。属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。算法采用队列的数据结构,所有因为展开节点而得到的子节点都会被加进一个先进先出的队列中。其邻居节点尚未被检验过的节点会被放置在一个被称为 open 的队列,而被检验过的节点则被放置在被称为 closed 的容器中(open-closed表)算法自始至终一直通过已找到和未找到顶点之间的边界向外扩展,首先搜索和s距离为k的所有顶点,然后再去搜索和S距离为k+l的其他顶点。算法流程图如图3.1所示。

 

图3.1 DFS算法流程图

3.2 深度优先

深度优先搜索方法,又称DFS(Depth First Search),和树的先序遍历比较类似。假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。算法流程图如图3.2所示。

 

图3.2 BFS算法流程图

3.3 贪婪方法

贪婪算法(又称贪心算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。为了解决问题,需要寻找一个构成解的候选对象集合,起初,算法选出的候选对象的集合为空。接下来的每一步中,根据选择函数,算法从剩余候选对象中选出最有希望构成解的对象。如果集合中加上该对象后不可行,那么该对象就被丢弃并不再考虑;否则就加到集合里。每一次都扩充集合,并检查该集合是否构成解。

本题中具体实现方法为,先进行深度搜索,但是不急进入堆栈操作,而是存储当前所有搜索到的点的距离,选择距离最短的点,并放弃搜索其他同一深度的点,进入堆栈操作。算法流程图如图3.3所示。

 

图3.3 贪婪算法流程图

3.4 A*方法

A*搜寻算法俗称A星算法。A*算法是比较流行的启发式搜索算法之一,被广泛应用于路径优化领域。它的独特之处是检查最短路径中每个可能的节点时引入了全局信息,对当前节点距终点的距离做出估计,并作为评价该节点处于最短路线上的可能性的量度。

本题中的实现方法为,同贪婪类似,A*就相当于有一个智慧的老人为搜寻的对象打分,搜索过程中将距离和打分值相加,作为新的距离即可。其算法流程图如3.4所示。

 

图3.3 A*算法流程图

四、关键代码

4.1 BFS方法

while tail~=head              %判断
i=queue(tail);               %取点for j=1:20              %搜索所有适合的节点if A(i,j)>=1 && isempty(find(flag==j,1))queue(head)=j;                        head=head+1;                  %数数         flag=[flag j];                %扩容        result=[result;i,j,A(i,j)];                  %记录endendtail=tail+1;                 %队列增加
end

  

 

4.2 DFS方法

while top~=0            %判断
pre_len=length(stack);    %记录栈长度i=stack(top);             %取栈顶for j=1:20if A(i,j)>=1 && isempty(find(flag==j,1))   top=top+1;                         stack(top)=j;                      flag=[flag j];                     re=[re;i,j,A(i,j)];                             %记录           
       break; endend if length(stack)==pre_len %如果栈未增加,则出栈stack(top)=[];top=top-1;end end

4.3 贪婪方法

while top~=0           pre_len=length(stack);   i=stack(top);          record=[];                for j=1:20if A(i,j)>=1 && isempty(find(flag==j,1))    %记录所有相邻节点record=[record;i,j,A(i,j)]    endendif isempty(record)breakend[s,k]= min(record(:,3,:))              %取距离最小节点i=record(k,1,:);j=record(k,2,:);     if isempty(find(flag==j,1))top=top+1;                        stack(top)=j;                      flag=[flag j];                     re=[re;i,j,A(i,j)];                            endif length(stack)==pre_len  stack(top)=[];top=top-1;end   
end

  

4.4 A*方法

绝大部分与贪婪算法相同,只是更新了距离值。

for j=1:20if A(i,j)>=1 && isempty(find(flag==j,1))     F(i,j)=A(i,j)+H(j);record=[record;i,j,F(i,j)];    %启发值endendif isempty(record)break
end

  

4.5 反向寻址

所有的算法均采用相同的反向寻址方法。

while (1)x=find(re(:,2,:)==m)       %找到到达目的地所有的经过地m=re(x,1,:)                  %迭代法反向寻找来的路径if  1-isempty(x)lujin=[city{re(x,1,:)},lujin];juli=juli+re(x,3,:)elsebreak
end
end    

  

4.6 读取EXCEL

city={'Oradea','Zerind','Arad','Timisonra','Lugoj','Mehadia','Dobreta','Craiova','Rimmicu Vikea','Sibiu',...'Fagaras','Pitesti','Bucharest','Giurglu','Uiziceni','Hirsova','Eforie','Vaslui','Lasi','Neamt'};         %存储城市名
filename = 'mymap.xlsx';
sheet = 1;
xlRange = 'C3:V22';
map = xlsread(filename,sheet,xlRange);       %读取excel
map(isnan(map)) = 0;                   %将不相邻的点之间也设为0

  

五、运行结果

BFS方法的运行结果显示路径为:{'Arad'    'Sibiu'    'Fagaras'    'Bucharest'}

DFS方法的运行结果显示路径为:{ 'Arad'    'Zerind'    'Oradea'    'Sibiu'    'Rimmicu Vikea'    'Craiova'    'Pitesti'    'Bucharest'}

贪婪方法的运行结果显示路径为:{ 'Arad'    'Zerind'    'Oradea'    'Sibiu'    'Rimmicu Vikea'    'Pitesti'    'Bucharest'}

A*方法的运行结果显示路径为:{ 'Arad'    'Sibiu'    'Rimmicu Vikea'    'Pitesti'    'Bucharest'}

比较见表5.1

表5.1 四种算法的运行结果

算法

生成节点数

求解时间

距离

BFS方法

11

3.725s

450

DFS方法

12

3.057s

762

贪婪方法

7

3.606s

575

A*方法

7

3.049s

418

注:求解时间包括计时函数自用时间

六、比较结论

得益于MATLAB高速的矩阵运算能力,四种方法均在3-4秒之间完成,速度相差不大,但是在生成节点数上,DFS方法搜索了12个节点最多,贪婪方法和A*方法均为7最少。比较四种搜索方法得到的搜索路径,有启发值的A*方法搜索到的路径距离最短,为418,其次是宽度优先搜索,距离为450,距离最长的路径是由DFS方法产生,为762,贪婪方法为575。通过比较我们可以得出如下结论:

  1. 四种搜索方法在处理小型网络的搜索问题时,速度相差不大。
  2. 贪婪方法和A*方法生成节点数较少,理论上能够更快搜索出到达路径,在处理大型图的问题时,会表现得比较明显。
  3. 贪婪方法每一步都是选择当前状态下的最优解进行搜索,很容易陷入局部最优,从而使得搜索时间延长。
  4. 尽管BFS方法和DFS方法都一定可以找到路径,但是BFS方法搜索到的路径距离要明显优于DFS方法。

 

---恢复内容结束---

转载于:https://www.cnblogs.com/Hangingter/p/7784042.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540372.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[转]Paul Adams:为社交设计

为社交设计 Strong, Weak, and Temporary Ties by Paul Adams on 2010/04/09 PS:作者Paul Adams Facebook全球品牌体验总监 电话和手机聚集十亿用户用了15年的时间,而Facebook只用了9个月。我们看到越来越多的人开始用在线社交网络,这种网络好…

Android Framework中的Application Framework层介绍

Android的四层架构相比大家都很清楚,老生常谈的说一下分别为: Linux2.6内核层,核心库层,应用框架层,应用层。我今天重点介绍一下应用框架层Framework。 Framework层为我们开发应用程序提供了非常多的API,我…

ORACLE中创建如何创建表,并设置结构和默认值

使用select语句查看EMP表,根据COMM排序 默认情况下,空值会自动排列在尾部。 利用nulls last排序时将空值置底 利用nulls first排序时将空值置顶 例 创建一张出版社表 使用语句 create table 表名(列名1 类型,列名2 类型&#xff0…

暴风TV请来中国人工智能first lady冯雁教授任首席科学家

今日下午,暴风AI无屏电视发布会现场,暴风TV宣布邀请号称“中国人工智能first lady”、于香港科技大学任教的冯雁教授,担任暴风TV人工智能首席科学顾问。 冯雁教授于现场表示,选择暴风TV合作的重要原因,一方面在于其个人…

gulp之gulp.watch报错

gulpfile.js如下: 问题: 第一次改动文件,监听正常。再次改动,报错,如下: 解决: 总结: 意思,gulpsequence这玩意儿返回的thunk只能执行一次 转载于:https://www.cnblogs.c…

.NET深入学习笔记(4):深拷贝与浅拷贝(Deep Copy and Shallow Copy)

今天继续利用准备WSE安全开发文章的空闲时间,完善《.NET深入学习笔记》系列(基本都是.Net重要的知识点,我都做了详细的总结,是什么、为什么、和怎么实现)。想必很多人也接触过这两个概念。做过C的人对深浅拷贝的概念一…

VIM一般模式操作

2019独角兽企业重金招聘Python工程师标准>>> vim介绍 vim和vi几乎是一样的,唯一的区别就是当编辑一个文本时,使用vi不会显示颜色,而使用vim会显示颜色。 vim有三个模式:一般模式,编辑模式,命令模…

stateful set 学习笔记

2019独角兽企业重金招聘Python工程师标准>>> 1、创建pv # cat pv.yaml kind: PersistentVolume apiVersion: v1 metadata:name: task-pv-volumelabels:type: local spec:capacity:storage: 3GiaccessModes:- ReadWriteOncehostPath:path: "/tmp/data" 2、…

自定义控件---重写Listbox实现item图标变换和item点击事件

博客开通有一阵了,就是没有时间写,遗憾啊。! 这几天做了个排序的自定义控件,在listbox item里放是button 并支持图标的交替变换 效果如下: 把代码贴上:1using System; 2using System.Collections.…

MySQL初识-架构-安装-初始化-连接-管理工具-数据文件

MySQL架构和结构分析 官方架构图 内部组件结构图 MySQL安装方式 MySQL初始化 MySQL工作模式及常用命令 交互式模式:mysql> 1234567891011121314# 交互式模式下的客户端命令mysql> help # 获取命令帮助 mysql> \? # 同上 mysql> \c # 取消命令执行 mysq…

mdm.Dialogs.promptModal()使用

这是prompt的扩展,提供了更多的功能,比如可以添加其他按钮和图标import mdm.*;mdm.Application.init(this, onInit);function onInit():void {// 启动程序...}quit.addEventListener(MouseEvent.CLICK,quitProgram);function quitProgram(evt:MouseEvent…

Gson的使用,对于不需要html escape的情况的处理

引入: 虽然是小问题,但是我还是需要记录下,我们知道,Google提供了一个Gson框架让我们高效的吧普通对象(一般VO为佳) 和json字符串之间进行互转。因为转换多数是和浏览器打交道的,所以一般默认的…

SpringBoot安装和创建简单的Web应用

SpringBoot安装 方式一: Eclipese->Help->Eclipse Marketplace ->Finde STS -> Install 注意:安装过程中挺慢,而且可能会报错,报错时需要重复以上步骤(重新安装STS后,安装进度接之前的继续进行…

ASP.NET Session 详解

[ASP.NET] Session 详解 开发者在线 Builder.com.cn 更新时间:2008-03-23作者:黑暗凝聚力量,堕落方能自由 来源:CSDN 本文关键词: Web开发 ASP session 详解 本文仅代表作者个人观点,正确与否请读者自行研究!阅读本文…

hadoop namenode管理元数据机制

一、简要namenode管理元数据机制: 二、详细namenode管理元数据机制: 三、secondary namenode 合并edits和fsimage: 四、namenode存储元数据细节: 五、checkpoint触发点: 本文转自lzf0530377451CTO博客,原文…

BABOK - 企业分析(Enterprise Analysis)概要

描述 企业分析描述我们如何捕捉、提炼并明晰业务需要,并定义一个可能实现这些业务需要的一个方案范围,它包括问题定义和分析,业务案例开发,可行性研究和方案范围定义 目的 明确业务战略需要和目标,并建议方案范围 任务…

6、EIGRP配置实验之负载均衡

1、实验拓扑 2、负载均衡原理 等价负载均衡:默认情况下EIGRP只支持等价负载均衡,默认支持4条线路的等价负载均衡,可以通过show ip protocols 查看,最大可以支持16条线路的等价负载均衡,可以在EIGRP路由进程下通过maxim…

haproxy+keepalived实现负载均衡及高可用

HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高性能性、负载均衡,以及基于TCP和HTTP的应用程序代理。相较与 Nginx,HAProxy 更专注与反向代理,因此它可以支持更多的选项,更精细的控制,更多的健…

iOS技术博客:App备案指南

📝 摘要 本文介绍了移动应用程序(App)备案的重要性和流程。备案是规范App开发和运营的必要手段,有助于保护用户权益、维护网络安全和社会秩序。为了帮助开发者更好地了解备案流程,本文提供了一份最新、最全、最详的备…

Perl文件读写操作

本文转自 tiger506 51CTO博客,原文链接:http://blog.51cto.com/tiger506/830771,如需转载请自行联系原作者