图的深度优先搜索和广度优先搜索(Common Lisp实现)

news/2023/10/4 2:28:25

为了便于描述,本文中的图指的是下图所示的无向图。

 

 

搜索指:搜索从S到F的一条路径。若存在,则以表的形式返回路径;若不存在,则返回nil。

定义属性设置函数putProp

;将物体obj的名为name的属性的值设置为value

(defun putProp (obj name value )

 (setf (get obj name) value)

)

;测试函数putProp的代码

(putprop 'James 'son '(robert albert) )

(get 'James 'son)

图的表示

使用原子和特性表来表示上图中各结点之间的邻接关系。代码如下:

(putProp 'S 'neighbors '(L O))   ;设置S结点的邻接点为L和O

(putProp 'L 'neighbors '(S M F))   ;设置L结点的邻接点为S, M和F

(putProp 'M 'neighbors '(L N))    ;设置M结点的邻接点为L, N

(putProp 'N 'neighbors '(M F))    ;设置N结点的邻接点为M, F

(putProp 'O 'neighbors '(S P Q))   ;设置O结点的邻接点为S, P和Q

(putProp 'P 'neighbors '(O F))    ;设置P结点的邻接点为O, F

(putProp 'Q 'neighbors '(O F))    ;设置Q结点的邻接点为O, F

(putProp 'F 'neighbors '(N L P Q))   ;设置F结点的邻接点为N, L, P, Q

定义路径扩展函数expand

路径扩展函数,将路径X的第一个元素(即图中的某个结点)的邻接点集合E加入到X中(若E已经在X中,则不加入;这样是为了消除闭合路径)。代码如下:

;expand扩展路径X

(defun expand (X)

(mapcan

(lambda (E)  ;匿名函数定义

(cond

((member E X) nil) ;若E在X存在, 则返回nil

(T (list (cons E X))) ;否则, 将E添加到表X的第一个位置

)

)

(get (car X) 'neighbors) ;匿名函数的参数, 即路径X的第一个元素的邻接点集合

)

)

上述的cond子句中,如果路径是闭合路径,则返回nil,append抛弃nil项;将非nil项收集到一张表中,作为expand的返回值。

深度优先搜索函数depth_first

函数代码如下

;深度优先搜索函数depth_first,找到从S到F的路径

(defun depth_first (start finish)

(prog (queue expansion)

(setq queue (list (list start))) ;初始化

(print queue) ;测试代码. 显示队列内容

tryagain ;循环开始

(cond ;分情况处理

((null queue) (return nil)) ;队列为空, 表示不存在路径,返回nil

((equal finish (caar queue))

(return (reverse (car queue))) ;返回找到的路径

) ;找到, 返回T

)

(setq expansion (expand (car queue))) ;扩展队列第一个元素

(setq queue (cdr queue)) ;删除队列中的第一个元素

(setq queue (append expansion queue))   ;扩展队列. 新结点在前,实现深度优先搜索

(print queue) ;测试代码. 显示队列内容

(go tryagain)

)

)

函数的运行及结果:

(depth_first 's 'f)  ;lisp不区分符号的大小写

运行结果为输出(S L M N F)

 

广度优先搜索函数width_first

广度优先与深度优先的代码基本一致,只有代码“(setq queue (append queue expansion))”不同,广度优先将expansion放在队尾,深度优先将expansion放在队首。函数代码如下:

;广度优先搜索函数width_first,找到从S到F的路径

(defun width_first (start finish)

(prog (queue expansion)

(setq queue (list (list start))) ;初始化

(print queue) ;测试代码. 显示队列内容

tryagain ;循环开始

(cond ;分情况处理

((null queue) (return nil)) ;队列为空, 表示不存在路径,返回nil

((equal finish (caar queue))

(return (reverse (car queue))) ;返回找到的路径

) ;找到, 返回T

)

(setq expansion (expand (car queue))) ;扩展队列第一个元素

(setq queue (cdr queue)) ;删除队列中的第一个元素

(setq queue (append queue expansion))   ;扩展队列. 新结点在后,实现广度优先搜索

(print queue) ;测试代码. 显示队列内容

(go tryagain)

)

)

函数的运行及结果:

(width_first 's 'f)  ;lisp不区分符号的大小写

运行结果为输出(S L F)

在本例中,广度优先搜索的结果优于深度优先搜索的结果。 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

线性代数学习笔记11-2:总复习Part2(相似对角化、对称矩阵、奇异值分解SVD)

下面的一系列分解,涉及了线性代数中的各个重要知识点: 关于求解方程组的分解: Ch1[矩阵乘法角度] 矩阵A\mathbf AA列向量矩阵C\mathbf CC和行向量矩阵R\mathbf RR的乘积Ch2[消元解方程组] LU分解Ch3[施密特正交化] QR分解:将列向…

Centos7安装mysql(只需六步)

Centos7 安装 mysql 的详细过程,我会通过 “环境准备”、“安装步骤”、“过程遇到的问题” 来告诉你如何操作~ 1. 环境准备 阿里云ECS云服务器CentOS 7.5 64位MySQL(因 MySQL8 和 MySQL8以下 版本的安装方式有些微差别,故本文会讲解两种版本…

汇总了30余场面试,4-6月Java面经笔记及详解,通用性极强

最近感慨面试难的人越来越多了,一方面是市场环境,更重要的一方面是企业对 Java 的人才要求越来越高了。‍ 基本上这样感慨的分为两类人,第一,虽然挂着 3、5 年经验,但肚子里货少,也没啥拿得出手的项目&…

对象创建过程

概述 通常情况下,我们创建一个对象,只需要使用new关键字即可。而对于java虚拟机来说,需要经历一系列过程。 首先,需要找到对应的类是哪个,这个类是否已经加载,没有加载还需要将它先加载进来,然后给将要创建的对象分配内存,然后对对象进行初始化设置,我们才能使用一个完…

Linux文本三剑客

Linux下文本三剑客正则表达式文本三剑客Grep文本三剑客Sed文本三剑客Awkawk、grep、sed是linux操作文本的三大利器,合称文本三剑客,也是必须掌握的linux命令之一。三者的功能都是处理文本,但侧重点各不相同,其中属awk功能最强大&a…

全站最简单 “数据滚动可视化大屏” 【JS基础拿来即用】

源码获取方式: 数据滚动大屏源码,原生js实现超级简单-Javascript文档类资源-CSDN下载原生js实现的数据滚动大屏案例,实现应该是全网最简单的,拿来直接使用即可,没有会员的小伙伴去我文章主更多下载资源、学习资料请访问…

MyBatis-Plus——查询和删除(逻辑删除)

MyBatis-Plus的查询和删除 MyBatis-Plus的查询和删除1 查询1.1 多个id的批量查询1.2 简单多条件查询2. 删除2.1 根据id删除2.2 批量删除2.3 简单多条件删除3. 逻辑删除3.1 在数据库中添加deleted字段3.2 在实体类中添加对应属性3.3 默认配置(可修改)3.4 …

相机标定基础--相关坐标系

目录 1. 相机标定的四个坐标系 1.1 世界坐标系 1.2 相机坐标系 1.3 图像平面坐标系 1.4 像素坐标系 2. 坐标系之间的转换关系 2.1 世界坐标系与相机坐标系的变换 2.2 相机坐标系与图像平面坐标系的变换 2.3 图像平面坐标系与像素坐标系的变换 1. 相机标定的四个坐标系 …

MyBatis-Plus——实现乐观锁

MyBatis-Plus——实现乐观锁乐观锁——MyBatis-Plus实现1. 主要适用场景:2. 乐观锁实现方式:3. 乐观锁实现流程3.1 修改实体类属性3.2 注册乐观锁插件3.3 测试乐观锁——MyBatis-Plus实现 针对于某一问题的解决方案,多线程或并发操作中产生的一些问题——丢失更新 …

C++多态

📋 个人简介 💖 作者简介:大家好,我是菀枯😜 🎉 支持我:点赞👍收藏⭐️留言📝 💬格言:不要在低谷沉沦自己,不要在高峰上放弃努力&am…

简单几步,爬取网页图片

简单几步,爬取网页图片 目录简单几步,爬取网页图片前言1 爬取原理讲解1.1 查看网页源代码1.2 分析网页源码并制定对应的爬取方案1.3 完善爬取流程和细节2 实战演练2.1 PyCharm下载安装2.2 安装相应依赖包(类库)2.3 编写代码2.4 补充细节和优化2.5 运行测…

linux shell 编程之变量总结

一、什么是Shell 变量 变量用于存储和管理临时的数据, 这些数据都是在运行内存中的; 二、变量的分类 shell中变量大致可以分为下面几类: 系统环境变量自定义变量特殊符号变量系统环境变量 是由系统提供的共享变量。是linux系统加载Shell的配置文件中定…

slam 14讲笔记

中秋抽时间混囵吞枣看了slam 14讲的前一半,稍微记录下. slam的框架 视觉里程计, 估计相邻两帧图像之间的位姿(特帧匹配)以及局部地图(又称为前端)后端优化, 主要利用前端返回的一些稀疏点,相机初步位姿, 传感器等信息, 回环检测,使用非线性优化来估计全局的位姿和地图. 数学知…

【手把手带你学JavaSE系列】String类(上篇)

目录一、字符串的构造方法二、String对象的比较1.比较是否引用同一个对象。2. boolean equals(Object anObject) 方法:按照字典序比较。3. int compareTo(String s) 方法4.int compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是…

django项目实战基于Python实现的衣物捐赠系统

💖💖更多项目资源,最下方联系我们✨✨✨✨✨✨ 目录 Python项目介绍 资料获取 Python项目介绍 计算机毕业设计python毕设项目(pythonmysql) 旧衣物捐赠系统-IT实战课堂_哔哩哔哩_bilibili计算机毕业设计python毕设项目(pythonmysql) 旧衣…

刘二大人 PyTorch深度学习实践 笔记 P10 卷积神经网络(基础篇)

刘二大人 PyTorch深度学习实践 笔记 P10 卷积神经网络(基础篇)1、基本概念2、卷积I 卷积运算过程II paddingIII stride2 步长为2,有效降低图像的W HIV 下采样 max pooling layer 最大池化层,没有w,2 * 2的max pooling&…

【小月电子】安路国产FPGA开发板系统学习教程-LESSON7串口通信

串口通信例程讲解若要观看该博客配套的视频教程,可点击此链接根据多年工作经验,总结出的FPGA的设计流程,概括起来总共有以上12步,其中根据项目难易度可省去其中一些步骤。比如非常简单的项目,我们可以省去虚线框里面的…

使用 SwiftUI 的 Eager Grids

介绍 早在 2020 年,我们就拥有了在 SwiftUI(LazyVGrid 和 LazyHGrid)中绘制网格的新视图控件。两年后,我们又获得了另一种在网格(Grid)中显示视图的视图控件。但是,这些新增功能非常不同&#…

深入源码!详解MultipartFile

MultipartFile大家想必不陌生,在SpringMVC的控制器方法中,我们可以通过MultipartFile自动注入上传的文件。我们从一个小案例引入,深入了解下MultipartFile 1、一个小问题 此问题来自真实案例,大家可以先想想当我们通过生产者端 …

【JAVA】线程不安全问题以及相关解决方案

1.造成线程不安全的常见5点因素 2.如何解决线程不安全 线程不安全,就是在多线程运行的结束后,结果或者过程并不按照我们预期的那样执行,则为线程不安全,即产生了BUG 出现以下5种情况,一般都会造成线程不安全 1.抢占式…
最新文章