深度优先查找和广度优先查找

2023-11-11

深度优先查找和广度优先查找

在人工智能和运筹学的领域中求解与图有关的许多应用中,这两个算法被
证明是非常有用的。并且,如需高效地研究图的基本性质,例如图的连通性以及图是否存
在环,这些算法也是必不可少的。

深度优先查找

深度优先查找可以从任意顶点开始访问图的项点,然后把该顶点标记为已访问。在每次迭代的时候,该算法紧接着处理与当前顶点邻接的未访问顶点。(如果有若干个这样的顶点,可以任意选择一个顶点。但在实际应用中,选择哪一个邻接的未访问候选顶点主要是由表示图的数据结构决定的。在我们的例子中,我们总是根据顶点的字母顺序来选择顶点。)
这个过程一直持续,直到遇到一个终点——该顶点的所有邻接顶点都已被访问过。在该终点上,该算法沿着来路后退一条边,并试着继续从那里访问未访问的顶点。在后退到起始顶点,并且起始顶点也是一个终点时,该算法最终停了下来。这样,起始顶点所在的连通分量的所有顶点都被访问过了。如果未访问过的顶点仍然存在,该算法必须从其中任一顶点开始,重复上述过程。

分解步骤

  1. 任选一顶点进行访问,访问后标记该顶点为已访问,进入步骤2
  2. 紧接着处理与当前顶点邻接的未访问顶点(如果有多个,任选一个),访问后标记该顶点为已访问,接下来:
    如果当前顶点所有邻接顶点均被访问,进入步骤3,否则进入步骤2
  3. 沿着来路后退一条边,并试着继续从那里访问未访问的顶点
    如果当前顶点所有邻接顶点均被访问,进入步骤3,否则进入步骤2
  4. 最后将回退到最初选定的点。如果图中没有离散的顶点,即每一个顶点至少有一条边,那么查找结束。否则,从所有未被访问的任选一个,进行访问并标记,之后进入步骤2。直至所有顶点均被访问后,查找结束

深度优先查找森林

在深度优先查找遍历的时候构造一个所谓的深度优先查找森林(depth-first search forest)也是非常有用的。

  • 遍历的初始顶点可以作为这样一个森林中第一棵树的根
  • 无论何时,如果第一次遇到一个新的未访问顶点,它是从哪个顶点被访问到的,就把它附加为哪个顶点的子女。连接这样两个顶点的边称为树向边,因为所有这种边的集合构成了一个森林。
  • 该算法也可能会遇到一条指向已访问顶点的边,并且这个顶点不是它的直接前趋(即它在树中的父母),我们把这种边称为回边(back edge),因为这条边在一个深度优先查找森林中,把一个顶点和它的非父母祖先连在了一起
  • 如果从图中移走一个节点和所有它附带的边之后,图被分为若干个不相交的部分,我们说这样的节点是图的关节点

伪代码

DFS(G)
	//实现给定图的深度优先查找遍历
	//输入:图G=<V,E>
	//输出:图G的顶点,按照被DFS第一次访问到的先后次序,用连续的整数标记将V中的每个顶点标记为0,表示还”未访问“
	count <- 0
	for each vertex v in V do
		if v is marked with 0
			dfs(v)
	
dfs(v)
	//递归访问所有和v相连接的未访问顶点,然后按照全局变量count的值
	//根据遇到它们的先后次序,给它们附上相应的值
	count <- count+1;mark v with count
	for each vertex in V adjacent to do
		if w is marked with 0
			dfs(w)

Java代码实现

package com.算法;

import java.util.LinkedList;
import java.util.List;

/**
 * @Author Lanh
 **/
public class DFSDemo {
    public static void main(String[] args) {
        List<Vertex> Graph = new LinkedList<>();
        Vertex A = new Vertex('A',new LinkedList<>());
        Vertex B = new Vertex('B',new LinkedList<>());
        Vertex C = new Vertex('C',new LinkedList<>());
        Vertex D = new Vertex('D',new LinkedList<>());
        Graph.add(A);Graph.add(B);Graph.add(C);Graph.add(D);

        //添加边
        A.list.add(B);
        A.list.add(C);
        B.list.add(D);
        C.list.add(B);
        C.list.add(D);

        DFS(Graph);
        Graph.forEach(V -> {
            System.out.println(V.mark+":"+V.v);
        });
    }

    static int count = 0;

    public static void DFS(List<Vertex> Graph){
        Graph.forEach(V -> {
            if (V.mark==0) dfs(V);
        });
    }

    private static void dfs(Vertex vertex){
        count++;
        vertex.mark = count;
        if (vertex.list != null && vertex.list.size() >0){
            vertex.list.forEach(V -> {
                if (V.mark==0) dfs(V);
            });
        }
    }

    static class Vertex{
        char v;
        List<Vertex> list = null;
        int mark = 0;

        public Vertex(char v,List<Vertex> list){
            this.v = v;
            this.list = list;
        }
    }
}


测试用例:

在这里插入图片描述

结果如下:
在这里插入图片描述

广度优先查找

如果说深度优先查找遍历表现出来的是一种勇气(该算法尽可能地离“家”远些),广度优先查找遍历表现出来的则是一种谨慎。它按照一种同心圆的方式,首先访问所有和初始顶点邻接的顶点,然后是离它两条边的所有未访问顶点,以此类推,直到所有与初始顶点同在一个连通分量中的顶点都访问过了为止。如果仍然存在未被访问的顶点,该算法必须从图的其他连通分量中的任意顶点重新开始。
使用队列(注意它和深度优先查找的区别!)来跟踪广度优先查找的操作是比较方便的。该队列先从遍历的初始顶点开始,将该顶点标记为已访问。在每次迭代的时候,该算法找出所有和队头顶点邻接的未访问顶点,把它们标记为已访问,再把它们入队。然后,将队头顶点从队列中移去。

广度优先查找森林

  • 遍历的初始顶点可以作为这样一个森林中第一棵树的根。
  • 无论何时,只要第一次遇到一个新的未访问顶点,它是从哪个顶点被访问到的,就把它附加为哪个顶点的子女。连接这样两个顶点的边称为树向边
  • 如果一条边指向的是一个曾经访问过的顶点,并且这个顶点不是它的直接前趋(即它在树中的父母),这种边被称为交叉边

伪代码

BFS(G)
	//实现给定图的广度优先查找遍历
	//输入:图G=<V,E>
	//输出:图G的顶点,按照被BFS遍历访问到的先后次序,用连续的整数标记将V中的每个顶点标记为0,表示还”未访问“
	count <- 0
	for each vertex v in V do
		if v is marked with 0
			bfs(v)
	
bfs(v)
	//递归访问所有和v相连接的未访问顶点,然后按照全局变量count的值
	//根据遇到它们的先后次序,给它们附上相应的值
	count <- count+1;mark v with count;initalize a queue with v
	while the queue is not empty do
		for each vertex in V adjacent to do
			if w is marked with 0
				count++;mark w with count
				add w to the queue
		remove the front vertex from the queue

Java代码实现

package com.算法;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * @Author Lanh
 **/
public class BFSDemo {
    public static void main(String[] args) {
        List<Vertex> Graph = new LinkedList<>();
        Vertex A = new Vertex('A',new LinkedList<>());
        Vertex B = new Vertex('B',new LinkedList<>());
        Vertex C = new Vertex('C',new LinkedList<>());
        Vertex D = new Vertex('D',new LinkedList<>());
        Graph.add(A);Graph.add(B);Graph.add(C);Graph.add(D);

        //添加边
        A.list.add(B);
        A.list.add(C);
        B.list.add(D);
        C.list.add(B);
        C.list.add(D);

        BFS(Graph);
        Graph.forEach(V -> {
            System.out.println(V.mark+":"+V.v);
        });
    }

    static int count = 0;

    public static void BFS(List<Vertex> Graph){
        Graph.forEach(V -> {
            if (V.mark==0) bfs(V);
        });
    }

    private static void bfs(Vertex vertex) {
        count++;
        vertex.mark = count;
        Queue<Vertex> queue = new LinkedList<>();
        queue.offer(vertex);
        while (!queue.isEmpty()){
            vertex = queue.poll();
            if (vertex.list!=null && vertex.list.size() > 0){
                vertex.list.forEach(v -> {
                    if (v.mark==0){
                        count++;
                        v.mark = count;
                        queue.offer(v);
                    }
                });
            }
        }
    }

    static class Vertex{
        char v;
        List<Vertex> list = null;
        int mark = 0;

        public Vertex(char v,List<Vertex> list){
            this.v = v;
            this.list = list;
        }
    }
}

测试用例:

在这里插入图片描述

结果如下:
在这里插入图片描述

深度优先查找(DFS)和广度优先查找(BFS)的主要性质在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深度优先查找和广度优先查找 的相关文章

  • Ansible安装部署

    Ansible安装部署 Ansible概述 Ansible的作用 Ansible工作原理 Ansible的特点 Ansible安装部署 环境准备 管理端安装ansible 配置主机清单 ansible 命令行模块 1 command 模块
  • 基于时间序列的短期数据预测--ARMA模型的设计与实现(每个步骤附实现源码)

    本文demo源码 实验数据 传送门 引言 前面我有分享两篇关于时间序列模型的文章 一篇是 Holt Winters模型原理分析及代码实现 python 一篇是 LSTM模型分析及对时序数据预测的具体实现 python实现 holt wint
  • win32api.sendmessage模拟鼠标点击_安卓模拟器一键宏设置教程

    一 什么是一键宏 一键宏是指宏指令 主要作用是一键触发多个点击事件 游戏玩家可以用来设置一键连招 一键发言等功能 因此成为一键宏 二 如何设置一键宏 打开雷电模拟器 点击右侧栏按键按钮 找到 一键宏 按钮 点击拖拉到模拟器窗口你想摆放的位置

随机推荐

  • 【Spring Cloud】分布式必学springcloud(五)——Ribbon自定义负载均衡策略

    一 前言 在上一篇博客中 小编向大家介绍了负载均衡工具Ribbon 是不是很颠覆呀 是不是很好用呀 从中大家有没有感觉到他的负载均衡策略呀 对的 Ribbon内置的默认策略是轮询 在这篇博客中 小编就带大家领略一下Ribbon自定义策略 二
  • 计算机信息单位换算中的t是,算力单位换算(算力单位t)

    算力每隔千位划为一个单位 最小单位 H 1次 1000H 1K 1000K 1G 1000G 1T 1000T 1P 1000P 1E 1公斤力等于多磅力 n牛 顿 是力的国际单位 kg千克 是质量的国际单位 这两个单位可以通过加速度计算
  • 腾讯自选股任务 青龙脚本

    有python环境可以运行 青龙也可以运行 添加脚本自己定时规则 修改环境变量位自己的 加入进去即可 更新时间 2022 6 2 有python环境可以运行 青龙也可以运行 添加脚本自己定时规则 修改环境变量位自己的 加入进去即可 更新时间
  • Android的Context详解 - 揭开Context的神秘面纱

    这篇文章是基于我四年前的一篇文章进行更正和深入探究 背景是 2019年4月份我在找工作 看到一个问题 问this getBaseContext getApplication getApplicationContext 的区别 当时我写了简单
  • dn什么意思_钢管中的DN表示什么意思?

    展开全部 DN是一种工程通径 不是实际的数值 由于各国标准不同 所以相对应的实际数值就不一样 扩展资e69da5e6ba903231313335323631343130323136353331333365666137料 DN既不是外径 也不
  • Java中int(Integer)类型与long(Long)类型数据的相互转化

    新手开车 先上代码 后边解析 能看懂代码就不要看解析 PS 命名规范 i代指int类型 l代指long类型 I代指Integer类型 L代指Long类型 2 transferTo 首先创建四个基本操作对象 Long L0 123456l i
  • java浮点数转二进制_浮点数转换成二进制

    因为要参加软考了 当然也只有考试有这种魅力 我得了概浮点数转化为二进制表示这个最难的知识点 个人认为最难 俺结合大量的从网上收集而来的资料现整理如下 希望对此知识点感兴趣的pfan有所帮助 基础知识 十进制转十六进制 十六进制转二进制 IE
  • Git恢复本地误删文件

    转 https www cnblogs com yangshifu p 9680993 html Step 1 git status Step 2 git reset HEAD 被删除的文件或文件夹 Step 3 git checkout
  • vuex 是什么? 有哪几种属性?

    Vuex 是一个专为 Vue js 应用程序开发的状态管理模式 简单点说 方便父子组件及组件之间的数据传递 有 5 种 分别是 state getter mutation action module vuex 的 store 是什么 vue
  • MIDP对应的设备特性(转)

    由于MID这类设备 在屏幕 内存 处理器等问题上有诸多限制 在手机或是PDA等MID上开发应用程序必须要考虑一些技术上的特殊点 下面给出一些MID设备的特性 显示 display 96x54 最小屏幕尺寸 1bit 最小色深 单色 输入设备
  • 工具网页收藏

    腾讯文档 百度脑图 墨者写书 语雀文档 阿里图标库 百度图说 腾讯智图 百度Suger数据可视化 腾讯设计导航 135设计 极速app 小程序开发 墨刀 processon visio axure mockplus sketchcn 其他i
  • 子序列(组合数学)

    子序列 题目描述 给出一个长度为 n n n的序列 你需要计算出所有长度为 k k k的子序列中 除最大最小数之外所有数的乘积相乘的结果 输入描述 第一行一个整数
  • maven学习笔记(五)maven全局配置文件settings.xml详解

    目录 setting文件简介 settings xml的作用 settings xml文件位置 配置的优先级 settings xml元素详解 顶级元素概览 LocalRepository InteractiveMode UsePlugin
  • Shiro权限框架-Springboot集成Shiro(5)

    1 技术栈 主框架 springboot 响应层 springMVC 持久层 mybatis 事务控制 jta 前端技术 easyui 2 数据库设计 1 数据库图解 sh user 用户表 一个用户可以有多个角色 sh role 角色表
  • python arima predict end无效_样本外预测的ARMA.predict不适用于浮点?

    在我开发了用于样本分析的小ARMAX预测模型之后 我想预测一些样本外的数据 我用于预测计算的时间序列从2013 01 01开始 到2013 12 31结束 以下是我正在处理的数据 hr np loadtxt Data 2013 17 txt
  • 《深入浅出数据分析》R语言实用教程

    深入浅出数据分析 R语言实用教程 1年前的R语言笔记 跟着 深浅 学习 当时用的版本是R i386 4 0 3 因为先学了MySQL再学的R 所以会夹带一些在借助MySQL来理解 1 基本处理 先加载程序包 程序包 加载程序包 加载xlsx
  • (二)、edtFTPj FileTransferClient

    edtFTPj的FileTransferClient类简单易用 而且下载的组件包中文档丰富 参考使用 完全能满足自己需要 下载地址为 http www enterprisedt com index html 废话不多说 上代码 Java代码
  • 监督学习,无监督学习,半监督学习,主动学习的概念

    1 监督学习 supervised learning 训练数据既有特征 feature 又有标签 label 通过训练 让机器可以自己找到特征和标签之间的联系 在面对只有特征没有标签的数据时 可以判断出标签 即生成合适的函数将输入映射到输出
  • 高斯噪声与高斯滤波

    噪声 噪声表现形式 噪声在图像上常表现为一引起较强视觉效果的孤立像素点或像素块 一般 噪声信号与要研究的对象不相关 它以无用的信息形式出现 扰乱图像的可观测信息 通俗的说就是噪声让图像不清楚 噪声对数字图像的影响 对于数字图像信号 噪声表为
  • 深度优先查找和广度优先查找

    深度优先查找和广度优先查找 在人工智能和运筹学的领域中求解与图有关的许多应用中 这两个算法被 证明是非常有用的 并且 如需高效地研究图的基本性质 例如图的连通性以及图是否存 在环 这些算法也是必不可少的 深度优先查找 深度优先查找可以从任意