A star算法优化二

       本文目的是对A*寻路算法所生成的路径进行一些人性化的调整,使其看起来不至于太机械化。关于A*算法的原理与实现,读者可以阅读其他资料,这里不再详细阐述。

如何写估价函数

        A*寻路算法本质上是一个有方向性的广度优先搜索算法,它使用一个估价函数,来估测可能的最短路径,在每一次搜索迭代完成后,选取其邻接点中最优的一个(即,距离终点最近的一个点),作为下一次迭代的起点。如此反复,直到找到终点。下面先列出估价函数的常规写法:

        设i点到起点的价值为S,到终点的估价为E,i点的总估价G等于S+E。S的值是确定的:

[cpp] view plain copy
  1. S = parent.S + 1(i点是其父节点的水平或垂直方向上的邻接点)  
  2. 或  
  3. S = parent.S + sqrt(2))(i点是其父节点斜方向上的邻接点)  

E点的值需要估算。精确一点的写法:

[cpp] view plain copy
  1. 水平距离:dx = abs(ix - ex)  
  2. 垂直距离:dy = abs(iy - ey)  
  3. 需要斜着走过的距离:v1 = min(dx, dy) * sqrt(2)  
  4. 需要直线走过的距离:v2 = max(dx, dy) - min(dx, dy)  
  5. E =  v1 + v2  

粗略的写法:

[cpp] view plain copy
  1. E = abs(ix - ex) + abs(iy - ey)  

如何避免转向抖动

        A*寻路得到的结果是最优的,但不是唯一的,这源于两点之间最近的路线可能不只一条。那么问题就产生了,两条最佳路线距离都相等的情况下,哪一条会更好?

    

(红色是障碍,白色可通行,黑色是搜索路径)

        如上图所示,是A* 8方向搜索得到的两条距离相等的路线,但是左图的路线在中间位置发生了“拐弯”,要比右图的路线多一个“拐弯”。如果路线上拐弯太多,人物行走的过程中,会出现频繁转向,从而出现“抖动”现象。所以,我们判定右图路线优于左图路线。针对这一问题,我们可以通过修改估价函数,来选择“拐弯”更少的路线。

        拐弯的问题,可以简化成先尽可能的向一个方向走,然后再考虑转向。进一步简化成,点越接近起点或是终点,越优先考虑。我们给E加上一个干扰值factor,

[cpp] view plain copy
  1. factor = min(abs(ix - sx), abs(ix - ex)) + min(abs(iy - sy), abs(iy - ey))  
  2. factor *= 0.01  

factor的值不能过大,否则会造成搜索结果不是最短距离,因此适当的给factor乘上一个缩放系数。

如何远离障碍物

        A*寻路的效果是抄近道,走捷径。但对于游戏体验来说,这并不完全是件好事,放着宽阔的马路不走,非得走悬崖峭壁,一不小心就跌落万丈深渊,或者卡在岩石边上。那么,我们该如何避免这些现象呢?同样,我们可以通过修改估计函数做到。

        我们给每一块可走区域都加上一个干扰值,越靠近障碍的可走区域,其干扰值越大。干扰值计算方法:

[cpp] view plain copy
  1. factor = 0  
  2. for(x = -n; x <= n; ++x)  
  3. {  
  4.       for(y = -n; y <= n; ++y)  
  5.      {  
  6.         if(isObstacle(ix + x, iy + y))  
  7.         {  
  8.             factor += n - min(abs(x), abs(y))  
  9.         }  
  10.      }  
  11. }  

        我们甚至可以根据地表的材质来增加干扰值,比如山路和沼泽地带明显比马路的干扰值大。

后记

        总之,我们可以调节估价函数来达到不同的效果。但是,也不能随意修改,不良的估价函数,会增加搜索成本。

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

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

相关文章

CentOS下python-mysqldb安装

CentOS下python-mysqldb安装日期&#xff1a;2011-04-17 &#xff5c; 来源&#xff1a;未知 &#xff5c; 作者&#xff1a;redice &#xff5c; 869 人围观 &#xff5c; 1 人鼓掌了&#xff01;鲲鹏Web数据抓取 - 专业Web数据采集服务提供者&#xff08;1&#xff09;py…

I2C总线接上拉电阻的原因

I2C为什么要接上拉电阻&#xff1f;因为它是开漏输出。为什么是开漏输出&#xff1f;I2C协议支持多个主设备与多个从设备在一条总线上&#xff0c;如果不用开漏输出&#xff0c;而用推挽输出&#xff0c;会出现主设备之间短路的情况。所以总线一般会使用开漏输出。为什么要接上…

解决循环引用--弱引用weak_ptr

循环引用&#xff1a; 引用计数是一种便利的内存管理机制&#xff0c;但它有一个很大的缺点&#xff0c;那就是不能管理循环引用的对象。一个简单的例子如下&#xff1a; class parent; class children;typedef shared_ptr<parent> parent_ptr; typedef shared_ptr<ch…

第九章 虚拟内存

物理地址和虚拟地址&#xff1a; 计算机的主存被组织成一个由M个连续的字节大小的单元组成的数组。每个字节都有一个唯一的物理地址&#xff08;PA&#xff09;。第一个字节地址为0&#xff0c;接下来为1&#xff0c;再接下来为2&#xff0c;依次类推。CPU访问内存的最自然方式…

Android HandlerThread 总结使用

Android HandlerThread 总结使用转载请标明出处&#xff1a;http://www.cnblogs.com/zhaoyanjun/p/6062880.html本文出自【赵彦军的博客】前言以前我在 【Android Handler、Loop 的简单使用】 介绍了子线程和子线程之间的通信。很明显的一点就是&#xff0c;我们要在子线程中调…

python 文件操作练习

1. 文件a.txt内容&#xff1a;每一行内容分别为商品名字&#xff0c;价钱&#xff0c;个数。 apple 10 3 tesla 100000 1 mac 3000 2 lenovo 30000 3 chicken 10 3 通过代码&#xff0c;将其构建成这种数据类型&#xff1a;[{name:apple,price:10,amount:3},{name:tesla,price:…

微软发布Enterprise Library 4.1和Unity 1.2

说明 微软模式与实践团队今天发布了Enterprise Library 4.1和Unity 1.2版本&#xff0c;这次发布的主要新特性如下&#xff1a; 1. 支持Visual Studio 2008 SP1 2. Unity应用程序块中加入了拦截机制 3. 性能提升 4. 配置工具的可用性提升 5. Bugs修复。 在Unity 1.2中有如下几点…

简易的波形折叠电路

01 波形折叠一、背景介绍今天在 Youtube 上看到 UP 主 Neukolln 展示了一款非常简单波形折叠电路。那么什么是波形折叠电路&#xff1f;它有什么用处&#xff1f;1、什么是波形折叠&#xff1f;通常情况下&#xff0c;信号在放大中会产生“饱和失真”&#xff0c;这是由于放大器…

STL 容器和迭代器连载6_顺序容器的操作3

2019独角兽企业重金招聘Python工程师标准>>> /*- * 文件名 &#xff1a;STL_con_ite_6.cpp * 开发人员&#xff1a;袁培荣 * 当前版本&#xff1a;1.0.0.2595 * 创建时间&#xff1a;2012-05-24 * 修改时间&#xff1a;2012-05-24 * 功能…

vector的内存释放

1. vector容器的内存自增长 与其他容器不同&#xff0c;其内存空间只会增长&#xff0c;不会减小。先来看看"C Primer"中怎么说&#xff1a;为了支持快速的随机访问&#xff0c;vector容器的元素以连续方式存放&#xff0c;每一个元素都紧挨着前一个元素存储。设想一…

poj 2096 , zoj 3329 , hdu 4035 —— 期望DP

题目&#xff1a;http://poj.org/problem?id2096 题目好长...意思就是每次出现 x 和 y&#xff0c;问期望几次 x 集齐 n 种&#xff0c;y 集齐 s 种&#xff1b; 所以设 f[i][j] 表示已经有几种&#xff0c;转移一下即可。 代码如下&#xff1a; #include<cstdio> #incl…

[C++]MySQL数据库操作实例

由于课程大实验需要使用c操作MySQL数据库&#xff0c;经过一番研究终于成功实现VS2008中与MySQL的连接。环境设置&#xff1a;安装完MySQL之后&#xff0c;将安装目录中的include目录下的libmysql.lib文件拷到VS2008安装目录中的VC\lib\下&#xff0c;然后在项目-选项-c/c-常规…

MapInfo开发心得——控件篇

前阵做一个项目过程中&#xff0c;需要结合MapInfo进行地方展示开发&#xff0c;积累一点点心得与大家共享以下所有基于MapXtreme 6.6MapInfo提供了足够强大的WinForm地图空间&#xff0c;可以很方便地在VS中拖拉摆放。但如此强大的控件也带来了封闭性太强的问题。现在我们都接…

89个嵌入式相关概念,你懂了几个?

嵌入式、计算机的学习&#xff0c;最基础的就是弄清一些概念。嵌入式、计算机相关的概念很多&#xff0c;这次汇总整理一些&#xff1a;1. 操作系统&#xff08;Operating System&#xff0c;OS&#xff09;&#xff1a;是管理计算机硬件与软件资源的系统软件&#xff0c;同时也…

使用VLC转码,在HTML5页面播放实时监控

首先要获取摄像机品牌的RTSP地址&#xff1a; 如大华的是rtsp://user:pwdip:port/cam/ realmonitor?channel1&subtype0 海康的是rtsp://user:pwdip:port/MPEG-4/ch1/main/av_stream Html5 <video>并不支持rtsp,所以使用vlc进行转码,将rtsp转http流,这样<video&g…

聊聊Linux中线程和进程的联系与区别!

大家好&#xff0c;推荐飞哥的一篇文章&#xff01;关于进程和线程&#xff0c;在 Linux 中是一对儿很核心的概念。但是进程和线程到底有啥联系&#xff0c;又有啥区别&#xff0c;很多人还都没有搞清楚。在网上对进程和线程的讨论中&#xff0c;很多都是聚集在这二位有啥不同。…

Docker swarm 实战-部署wordpress

Docker swarm 实战-部署wordpress 创建一个overlay的网络 docker network create -d overlay demo6imq8da3vcwvj2n499k4bwdlt docker network ls NETWORK ID NAME DRIVER SCOPE feea5ba8507b bridge bridge …

比GDB方便n倍的调试工具——CGDB

CGDB 是GDB的前端&#xff0c;在终端窗口中意图形化的形式来调试代码(基于ncurse)&#xff0c;非常方便。相对于GDB来说&#xff0c;可以很大的提高效率。这篇文章就来分享一下CGDB的最基本使用方法&#xff0c;如果是第一次听说&#xff0c;强烈建议您体验一下&#xff0c;一定…

WCF Security userName/Password

1. Transfer SecurityTransfer Security 主要包括三个方面&#xff1a; "消息完整性(Message Integrity)"、"消息机密性 (Message Confidentiality)" 和 "交互验证(Mutual Authentication)"。消息完整性必须确保消息在传输过程中没有被篡改&…

保护视力,我写的一个定时提醒的小玩意。

做程序员2年了&#xff0c;感觉视力越来越差。有时候常常工作到忘记休息。于是就想写一个能够定时提醒的小东西(公司不让从网络下载别的程序)。 功能: 1.能够每隔一段时间提醒我休息&#xff0c;做做眼保健操。 2.能够自己设定时间间隔. 运行环境&#xff1a;.ne…