启发式搜索(A*、IDDFS、IDA*)

我们在解决图问题的时候,通常需要使用DFS和BFS搜索,可是这两种搜索方式的效率较低,我们会遍历到很多空白节点,有没有办法可以优化这种低效问题呢?今天要推出我们的主角:启发式搜索。

一、A*

什么是A*算法?

A* 算法是一种路径搜索算法,用于在图形(如地图)中寻找最短路径。A* 算法基于启发式搜索和贪心搜索的思想,通过估计从起始点到目标点的距离来选择下一步移动。它综合考虑了已走过的路径长度(即实际代价)和估计的剩余路径长度(即启发代价),找到从起始点到目标点的最佳路径。

A*算法使用一个开放列表和一个关闭列表来追踪已探索的节点。它通过计算每个节点的“f值”来确定下一步移动。f值等于从起始点到当前节点的实际代价(即已走过的路径长度)加上从当前节点到目标点的估计代价(即剩余路径长度)。

A*算法在每一步中选择f值最小的节点来移动。当找到目标点或遍历完所有可能的节点时,算法停止。如果找到目标点,路径会被重构,即从目标点沿父节点指针一直回溯到起始点。这样就找到了从起始点到目标点的最短路径。

A*算法在寻找路径问题中被广泛应用,例如在游戏中的AI路径规划、地图导航和机器人路径规划等。它具有较高的效率和准确性,并且可以根据需要进行优化和改进。

在A* 算法中,我们需要构建一个估价函数,简单来说,A*算法就是BFS+优先队列+估价函数

估价函数:
f ( i ) = g ( i ) + h ( i ) \ f(i) = g(i) + h(i)  f(i)=g(i)+h(i)
其中g(i)是Dijkstra算法计算的当前i点离起点的最短路径,h(i)是用贪心算法预估当前i点到达终点需要的最短路径,但这里的预测不一定准确,在寻路时碰壁可以回溯到之前节点,重新寻找其他节点

如何设计h函数?
(1)曼哈顿距离:只能在四个方向(上下左右)移动
h ( i ) = a b s ( i . x − t . x ) + a b s ( i . y − t . y ) h(i) = abs(i.x - t.x) + abs(i.y - t.y) h(i)=abs(i.xt.x)+abs(i.yt.y)
(2)对角线距离:只能在八个方向移动
h ( i ) = m a x ( a b s ( i . x − t . x ) , a b s ( i . y − t . y ) ) h(i) = max(abs(i.x - t.x),abs(i.y - t.y)) h(i)=max(abs(i.xt.x),abs(i.yt.y))
(3)欧几里得距离:可以向任何方向移动
h ( i ) = s q r t ( ( i . x − t . x ) 2 + ( i . y − t . y ) 2 ) h(i) = sqrt((i.x - t.x)^2 + (i.y - t.y)^2) h(i)=sqrt((i.xt.x)2+(i.yt.y)2)

二、IDDFS

IDDFS(Iterative Deepening Depth-First Search)是一种启发式搜索算法,可用于在图或树上进行深度优先搜索(DFS)。

IDDFS结合了迭代深化和深度优先搜索的特点。它的基本思想是进行一系列深度限制的DFS,从深度为1开始,逐渐增加深度直到找到目标节点或遍历完整个图或树。

IDDFS的过程如下:

  1. 以深度为1开始,执行DFS搜索,探索从起始节点出发的深度为1的路径。
  2. 如果在深度为1的搜索中找到目标节点,搜索结束,返回结果。
  3. 如果在深度为1的搜索中没有找到目标节点,增加深度限制,将深度限制设为2,然后重复步骤1和2。
  4. 不断增加深度限制并重复步骤1和2,直到找到目标节点或遍历完整个图或树。

IDDFS的优点是可以控制搜索深度,避免无限循环或过度搜索的问题。它对于搜索空间较大且没有完整的启发式信息时非常有用。然而,IDDFS的时间复杂度较高,可能需要重复许多次深度受限的DFS搜索。

总结起来,IDDFS是一种可以在深度优先搜索中控制搜索深度的算法,适用于在没有完整启发式信息的情况下搜索图或树结构。

三、IDA*

IDA* 是结合A*与IDDFS的算法,即有估价函数的IDDFS,效率很高

下面给出一道IDA*的例题
在这里插入图片描述

#include <stdio.h>
#include <string.h>
const int N = 100;//设置最大层次
int num[N];//记录某一条路径上的数字,num[i]即该路径的第i个节点
int n, depth;
bool dfs(int now,int d){//now为当前路径走到的数字,d为now所在的层数if(d > depth)return false;if(now == n)return true;if(now << (depth - d) < n)//预估函数,如果最乐观的倍增法都无法在剩余可走层数到达最后结果,直接剪枝return false;num[d] = now;for (int i = 0; i <= d; i++){//继续下一层if(dfs(now + num[i], d + 1))return true;//加else if(dfs(now - num[i],d + 1))return true;}return false;
}int main(){while(~scanf("%d",&n) && n != 0){for (depth = 0;; depth++){//IDDFSmemset(num, 0, sizeof(num));if(dfs(1,0)){break;}}printf("%d\n", depth);}return 0;
}

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

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

相关文章

MySQL索引原理以及SQL优化

案例 struct index_failure_t{int id;string name;int cid;int score;string phonenumber;}Map<int,index_failure>; 熟悉C的同学知道&#xff0c;上述案例中&#xff0c;我们map底层是一颗红黑树&#xff0c;一个节点存储了一对kv&#xff08;键值对&#xff09;&…

go-zero 非k8s单体服务上线流程

1、安装mysql 镜像 docker pull mysql:5.7 2、创建mysql容器(主机目录要先存在 不然启动不起来。/opt/mysqlGo) docker run --name mysql-go -e MYSQL_ROOT_PASSWORD数据库密码 -p 8888:3306 -v /opt/mysqlGo:/var/lib/mysql -d 镜像id 3、可以通过navicat连接数据库&#…

【微服务】概述

微服务架构技术栈梳理 【注】本文旨在对微服务架构从整体上有一个简单的认识和了解&#xff0c;每一块都可能涉及较多的解决方案与实现框架&#xff0c;这里不做更深入的介绍。 1.背景&#xff08;Why&#xff09; 相关背景&#xff0c;也是推动单体服务走向微服务架构的原因…

seata 分布式

一、下载安装seata 已经下载好的朋友可以跳过这个步骤。这里下载的是seata1.6.1这个版本。 1、进入seata官网 地址&#xff1a; https://seata.io/zh-cn/index.html 2、进入下载 3、点击下载地址 下载地址&#xff1a; https://github.com/seata/seata 二、配置seata 进入c…

git仓库批量备份

git的mirror参数 在git中&#xff0c;--mirror是一个用于克隆和推送操作的参数。它用于创建一个镜像仓库&#xff0c;包含了源仓库的所有分支、标签和提交历史记录。 当使用git clone --mirror <source-repo>命令时&#xff0c;会创建一个完全相同的镜像仓库&#xff0…

虚拟机设置静态ip

有时候搭环境需要局域网&#xff0c;设置一下虚拟机静态ip&#xff0c;这里做个记录&#xff1a; 这里我用的是ubuntu18.04的虚拟机&#xff0c;安装完成之后&#xff0c;点击进入设置 这里设置一下桥接模式 这个时候输入ifconfig&#xff0c;就是和主机一个网段了&#xff…

Android 8.1 相关修改

一些常用修改&#xff0c;做个记录&#xff0c;为了节约时间和防止踩坑。 一、修改默认中文 修改位置&#xff1a; build\make\target\product\full_base.mk 修改内容&#xff1a; # Put en_US first in the list, so make it default. PRODUCT_LOCALES : zh_…

跟着cherno手搓游戏引擎【14】封装opengl

本节先把代码粘上&#xff0c;后续会慢慢把注释都给加上&#xff0c;先看代码了解个大概&#xff08;待更新&#xff09; 前置&#xff1a; RendererAPI.h: #pragma once namespace YOTO {enum class RendererAPI {None 0,OpenGL1};class Renderer {public:inline static R…

JavaWeb后端登录校验功能(JWT令牌技术,Cookie技术,Session,拦截技术,过滤器)

目录 一.登录校验功能&#xff08;解决直接通过路径访问&#xff09; 1.实现思路 二.会话技术 ​编辑 1.Cookie技术 2.Session 3.令牌技术 1.简介 2.如何生成和解析 3.令牌的使用 三.Filter过滤器 1.什么是过滤器 2.实现步骤&#xff1a; 3.过滤器执行流程 4.拦截路径 5.过…

[C++历练之路]C++中的继承小学问

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; &#x1f354;前言&#xff1a; C中&#xff0c;继承是一种面向对象编程的重要概念&#xff0c;它允许一个类&#xff08;子类/派生类&#xff09;从另一个类&#xff08;父类/基类&#xff09;继承属性和方法。继承是…

免费MySQL数据库客户端推荐

1. Navicat Lite Navicat Lite是一款功能强大的数据库管理工具&#xff0c;提供了免费版本供个人开发者使用。它支持MySQL等多种数据库系统&#xff0c;具有直观的用户界面和丰富的功能&#xff0c;包括数据编辑、导入导出、备份恢复等。 2. Toad Edge Toad Edge是一款针对开…

Hadoop-MapReduce-YarnChild启动篇

一、源码下载 下面是hadoop官方源码下载地址&#xff0c;我下载的是hadoop-3.2.4&#xff0c;那就一起来看下吧 Index of /dist/hadoop/core 二、上下文 在上一篇<Hadoop-MapReduce-MRAppMaster启动篇>中已经将到&#xff1a;MRAppMaster的启动&#xff0c;那么运行M…

(刷题记录)移除元素

我的代码&#xff1a; class Solution {public int removeElement(int[] nums, int val) {int j0;for(int i0;i<nums.length;i){if(nums[i]!val){nums[j]nums[i];j;}}return j;} }思路&#xff1a;双指针&#xff0c;右指针指向当前要处理的元素&#xff0c;有不等的数就赋…

Docker私有仓库搭建

registry私有仓库 步骤一&#xff1a;先拉取registry的镜像 [rootlocalhost ~]#docker pull registry 步骤二&#xff1a;修改docker的配置文件重启 [rootlocalhost ~]#vim /etc/docker/daemon.json {"insecure-registries": ["192.168.66.66:5000"] }[r…

第二十天| 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

Leetcode 654.最大二叉树 题目链接&#xff1a;654 最大二叉树 题干&#xff1a;给定一个不重复的整数数组nums。最大二叉树可以用下面的算法从nums递归地构建: 创建一个根节点&#xff0c;其值为nums中的最大值。递归地在最大值左边的子数组前缀上构建左子树。递归地在最大…

浅谈隔离放大器

浅谈隔离放大器 定义&#xff1a;隔离放大器是将输入的电量信号或物理量信号通过一种技术手段处理后,隔离输出一组模拟量信号,这组模拟量信号是以标准的4-20mA/0-20mA/0-10mA/0-10V/0-5V/1-5V/2-10V/0-2.5V/0-20mA/0-10mA/0-10V/0-100mV/0-5V等信号,以便控制系统及仪器仪表设备…

PGsql 解析json及json数组

创建测试数据 drop table if exists json_test; create table json_test as select 111 as id, {"nodes":{"1692328028076":{"nodeId":"1692328028076","nodeName":"测试表1","nodeType":"DATACO…

单片机学习笔记---定时器计数器(含寄存器)工作原理介绍(详解篇2)

目录 T1工作在方式2时 T0工作在方式3时 四种工作方式的总结 定时计数器对输入信号的要求 定时计数器对的编程的一个要求 关于初值计算的问题 4种工作方式的最大定时时间的大小 关于编程方式的问题 实例分析 实例1 实例2 T1工作在方式2时 51单片机&#xff0c;有两个…

vue实践:构建高效的电子签名功能

前言 在现代数字化时代&#xff0c;电子签名成为了一种方便、高效且安全的签署文件的方式。本文将介绍电子签名的原理和实现方法&#xff0c;帮助你快速掌握这一重要的工具。 电子签名是什么&#xff1f; 电子签名是一种数字化的签名方式&#xff0c;用于验证和确认电子文档、…

matlab appdesigner系列-app程序打包成可执行exe程序

提供了3种打包方式&#xff1a; 1&#xff09;Matlab App &#xff0c;这种方式是生成Matlab内部使用的小程序&#xff0c;可添加到matlab app菜单栏中的常用程序中&#xff0c;也就是应用该程序之前&#xff0c;你必须安装了matlab&#xff1b; 2&#xff09;Web app 3&…