A star算法优化一

A*算法 求最优解

算法一直维护两个表: Open和Close

  • 将起点S加入Open中

  • 将所有S可到达的点(障碍物以及位于Close表中的点均看成不可达)加入到Open中。将起点从Open中删去,并加入到Close中

  • ①从Open中删去F值最小的点Min,并将其加入到Close中

  • ②将Min点所有可到达的点加入Open中,并设这些点的父节点为Min。若某点已经在Open中,则比较其F值,若新路径F值较小,说明从Min走路更短,更新其父节点为Min;否则不更新此点

  • 循环①②,直到Open中出现目的点E 

公式表示为: f(n)=g(n)+h(n),

其中 f(n) 是从初始状态经由状态n到目标状态的代价估计,

g(n) 是在状态空间中从初始状态到状态n的实际代价,

h(n) 是从状态n到目标状态的最佳路径的估计代价。

通俗一点讲:

g(n)代表你从起始点到下一点的实际距离(制定到下一点的距离的规则)

h(n)是自己设计的函数,可以是到目的地大致的距离


可将循环过程封装成函数:

[cpp] view plaincopy
  1.     while (isNotEnd()) {  
  2.         Find_deleteMinFromOpen_AddToClose();  
  3.         putReachableIntoOpen(close.back());  
  4.     }  

举个栗子:

对于以下图:5行15列

000000000000000

0000000x0000000

00s0000x0000e00

0000000x0000000

000000000000000

其中x为墙壁,s为起点,e为终点,建立合适的模型,调用A star算法,找到一条s到e的最短路径。

取直走G值为10,斜走G值为14

这里H值设定为无视障碍到达终点所需的 步数*10

我们看开始的几步:

000000000000000

0000000x0000000

00s0000x0000e00

0000000x0000000

000000000000000

灰色的点G=10,H=9*10 ,其F值最小,加入Close


000000000000000

0000000x0000000

00s0000x0000e00

0000000x0000000

000000000000000

灰色的点G=10+10,H=8*10 ,其F值最小,加入Close


000000000000000

0000000x0000000

00s0000x0000e00

0000000x0000000

000000000000000

灰色的点G=10+10+10,H=7*10 ,其F值最小,加入Close


000000000000000

0000000x0000000

00s0000x0000e00

0000000x0000000

000000000000000

灰色的点G=10+10+10+10,H=6*10 ,其F值最小,加入Close


以此循环,直到e在Open中,此时只需要沿着父节点往回走就可以到达起点了,这条路就是当前情况下最优的解


结果:


000000000000000

0000000x0000000

00s0000x0000e00

0000000x0000000

000000000000000



C++实现:

[cpp] view plaincopy
  1. #include#include#include#includeusing namespace std;  
  2. char square[5][15] = {//待求数据  
  3.     '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',  
  4.     '0','0','0','0','0','0','0','x','0','0','0','0','0','0','0',  
  5.     '0','0','s','0','0','0','0','x','0','0','0','0','e','0','0',  
  6.     '0','0','0','0','0','0','0','x','0','0','0','0','0','0','0',  
  7.     '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'  
  8. };  
  9.   
  10. class point {  
  11.   
  12. public:  
  13.     point(char s) {  
  14.         v = s;  
  15.         G = 0;  
  16.         H = 0;  
  17.         F = 0;  
  18.     }  
  19.     pair ParentPosi;  
  20.     pair posi;  
  21.     char v;//value  
  22.     int F;  
  23.     int G;  
  24.     int H;  
  25.     int UpdateF() {  
  26.         F = G + H;  
  27.         return F;  
  28.     }  
  29.     int UpdateH() {  
  30.         int x = posi.first - 2;  
  31.         int y = posi.second - 12;  
  32.         x *= 10;  
  33.         y *= 10;  
  34.         if (x < 0) {  
  35.             x = -x;  
  36.         }  
  37.         if (y < 0) {  
  38.             y = -y;  
  39.         }  
  40.         H = x + y;  
  41.         return H;  
  42.     }  
  43.     void setPosi(pair x) {  
  44.         posi = x;  
  45.     }  
  46.     void setParentPosi(pair x) {  
  47.         ParentPosi= x;  
  48.     }  
  49.     void setG(int g) {  
  50.         G = g;  
  51.     }  
  52.     void setH(int h) {  
  53.         H = h;  
  54.     }  
  55.     point &operator = (point &s) {  
  56.         (*this).v=(s).v;  
  57.         (*this).ParentPosi = s.ParentPosi;  
  58.         (*this).posi = s.posi;  
  59.         (*this).F = s.F;  
  60.         (*this).G = s.G;  
  61.         (*this).H = s.H;  
  62.         return *this;  
  63.     }  
  64. };  
  65. vector open;  
  66. vector close;  
  67. point squ[5][15] = {  
  68.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
  69.     0,0,0,0,0,0,0,'x',0,0,0,0,0,0,0,  
  70.     0,0,'s',0,0,0,0,'x',0,0,0,0,'e',0,0,  
  71.     0,0,0,0,0,0,0,'x',0,0,0,0,0,0,0,  
  72.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  
  73. };  
  74. bool isInOpenList(pair s) {  
  75.     for (int i = 0;i<open.size();i++) {  
  76.         if (open[i].posi == s) {  
  77.             return true;  
  78.         }  
  79.     }  
  80.     return false;  
  81. }  
  82. bool isInCloseList(pair s) {  
  83.     for (int i = 0;i<close.size();i++) {  
  84.         if (close[i].posi == s) {  
  85.             return true;  
  86.         }  
  87.     }  
  88.     return false;  
  89. }  
  90. void putReachableIntoOpen(point min) {  
  91.     int x = min.posi.first;  
  92.     int y = min.posi.second;  
  93.   
  94.     int direc[8][2] = {  
  95.         0,1,  
  96.         1,1,  
  97.         1,0,  
  98.         1,-1,  
  99.         0,-1,  
  100.         -1,-1,  
  101.         -1,0,  
  102.         -1,1  
  103.     };  
  104.     for (int i = 0;i < 8;i++) {  
  105.         x = x + direc[i][0];  
  106.         y = y + direc[i][1];  
  107.         if (isInOpenList(make_pair(x, y))&&close.size()>0) {  
  108.             int tempi = 0;  
  109.             for (int i = 0;i < open.size();i++) {  
  110.                 if (open[i].posi == make_pair(x, y)) {  
  111.                     tempi = i;  
  112.                 }  
  113.             }  
  114.             if (direc[i][0] * direc[i][1] != 0) {//斜向  
  115.                 int G_now = close.back().G + 14;  
  116.                 if (G_now < open[tempi].G) { //G比较小就更新路径  
  117.                     open[tempi].ParentPosi = make_pair(x, y);  
  118.                     squ[open[tempi].posi.first][open[tempi].posi.second].ParentPosi = make_pair(x, y);  
  119.                 }  
  120.             }  
  121.             else {  
  122.                 int G_now = close.back().G + 10;  
  123.             }  
  124.             continue;  
  125.         }  
  126.         //既不在关闭也不在开启列表中而且可到达 就将其加入开启列表  
  127.         if ((!isInOpenList(make_pair(x, y))) && (!isInCloseList(make_pair(x,y)))&&x >= 0 && x < 5 && square[x][y] != 'x') {  
  128.             squ[x][y].setParentPosi(min.posi);  
  129.             open.push_back(squ[x][y]);  
  130.             if (direc[i][0] * direc[i][1] != 0) {//斜向  
  131.                 squ[x][y].setG(squ[x][y].G+14);  
  132.             }  
  133.             else {  
  134.                 squ[x][y].setG(squ[x][y].G + 10);  
  135.             }  
  136.             //cout << "(" << squ[x][y].posi.first << "," << squ[x][y].posi.second << ")" << endl;  
  137.         }  
  138.         x = x - direc[i][0];  
  139.         y = y - direc[i][1];  
  140.     }  
  141.     //cout << "------------------------" << "(" << x << "," << y << "):" << "------------------------" << endl;  
  142. }  
  143. void Find_deleteMinFromOpen_AddToClose() {  
  144.     point min_= open[0];  
  145.     int tempi = 0;  
  146.     for (int i = 0;i < open.size();i++) {  
  147.         if (open[i].UpdateF() < min_.UpdateF()) {  
  148.             min_ = open[i];  
  149.             tempi = i;  
  150.         }  
  151.     }  
  152.     close.push_back(min_);  
  153.     std::vector::iterator it=open.begin()+tempi;  
  154.     open.erase(it);  
  155.     //cout << "close:           (" << min_.posi.first << "," << min_.posi.second << ")" << endl;  
  156.     //cout << "closeSize()=" << close.size() << endl;  
  157.     //cout << "openSize()=" << open.size() << endl;  
  158. }  
  159. bool isNotEnd() {  
  160.     for (int i=0;i<open.size();i++) {  
  161.         if (open[i].v == 'e') {  
  162.             open[i].ParentPosi=close.back().posi;  
  163.             return false;  
  164.         }  
  165.     }  
  166.     return true;  
  167. }  
  168.   
  169. void findPath(pair begin,pairend) {  
  170.     //将起点放入open  
  171.     open.push_back(squ[2][2]);  
  172.     putReachableIntoOpen(squ[2][2]);  
  173.     int tempi = 0;  
  174.     for (int i = 0;i < open.size();i++) {  
  175.         if (open[i].v == 's') {  
  176.             tempi = i;  
  177.         }  
  178.     }  
  179.     std::vector::iterator it = open.begin()+tempi;//删除起点  
  180.   
  181.       
  182.     while (isNotEnd()) {  
  183.         Find_deleteMinFromOpen_AddToClose();  
  184.         putReachableIntoOpen(close.back());  
  185.     }  
  186. }  
  187. void print_path() {  
  188.     for (int i = 0;i < 5;i++) {  
  189.         for (int j = 0;j < 15;j++) {  
  190.             squ[i][j].posi = make_pair(i, j);  

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

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

相关文章

可怕!CPU暗藏了这些未公开的指令!

我们平时编程写的高级语言&#xff0c;都是经过编译器编译以后&#xff0c;变成了CPU可以执行的机器指令&#xff1a;而CPU能支持的指令&#xff0c;都在它的指令集里面了。很久以来&#xff0c;我都在思考一个问题&#xff1a;CPU有没有未公开的指令&#xff1f;或者说&#x…

在Ubuntu下运行 apt-get update命令后出现错误:

在Ubuntu下运行 apt-get update命令后出现错误: The package lists or status file could not be parsed or opened sudo rm /var/lib/apt/lists/* -vf 然后&#xff1a; sudo apt-get update #&#xff08;更新软件源&#xff09;执行安装操作 sudo apt-get upgrade#&#xff…

mvc filter 的用法

1、建个类在model里面名字随便 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using RHRSP.Web.Controllers.Common;namespace RHRSP.Web.Models {public class DemoActionAttributeFilter : ActionFilterAttr…

Sandy引擎学习笔记:摄影机

第三课程&#xff1a;如何使用摄影机&#xff1f;通过摄影机移动来使摄影的对象产生变化&#xff0c;这样会使动画变得容易。因为你不需要改变观察对象的的属性&#xff0c;只是改变摄影机的变化 package { import flash.display.Sprite; import flash.events.*; impo…

A star算法优化二

本文目的是对A*寻路算法所生成的路径进行一些人性化的调整&#xff0c;使其看起来不至于太机械化。关于A*算法的原理与实现&#xff0c;读者可以阅读其他资料&#xff0c;这里不再详细阐述。 如何写估价函数A*寻路算法本质上是一个有方向性的广度优先搜索算法&#xff0c;它使用…

格式化字符串

Format (.7, “0%”)&#xff1d;70%Format (1140, “$#,##0”)&#xff1d;$1,140Format (114, “$#,##0”)&#xff1d;$1,140字符意义&#xff1a;0 显示一数字&#xff0c;若此位置没有数字则补 0# 显示一数字&#xff0c; 若此位置没有数字则不显示% 数字乘以 100 并在右边…

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;会出现主设备之间短路的情况。所以总线一般会使用开漏输出。为什么要接上…

[转贴]使用jQuery自动缩图片 - [jQuery]

具体思路: 通过具体容器取得容器内所有图片 循环检查所有图片长宽 对超过的图重新定高度. 直接写成一个扩展好了,以后可以直接用. jquery.fn.ImageAutoSize function(width,height){ $("img",this).each(function() { var image $(this); if(i…

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

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

A - Character Encoding HDU - 6397 - 方程整数解-容斥原理

A - Character Encoding HDU - 6397 思路 &#xff1a; 隔板法就是在n个元素间的&#xff08;n-1&#xff09;个空中插入k-1个板&#xff0c;可以把n个元素分成k组的方法 普通隔板法 求方程 xyz10的正整数解的个数。 添元素隔板法 求方程 xyz10的非负整数解的个数。 那么 增加…

读书笔记之何时重构(下)

因为中间看了一本其他的书&#xff0c;差不多一个月未跟新读书笔记了&#xff0c;这段时间要补补课&#xff0c;接着上一章继续说说何时重构&#xff0c;文章中很多重构的方法这里还没有说明&#xff0c;后续章节会详细的介绍这些经常使用到的重构方法&#xff0c;尽请期待&…

SQLite和MySQL数据库的区别与应用

简单来说&#xff0c;SQLITE功能简约&#xff0c;小型化&#xff0c;追求最大磁盘效率&#xff1b;MYSQL功能全面&#xff0c;综合化&#xff0c;追求最大并发效率。如果只是单机上用的&#xff0c;数据量不是很大&#xff0c;需要方便移植或者需要频繁读/写磁盘文件的话&#…

第九章 虚拟内存

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

Safari browser and asp.net Menu control (asp:Menu)

问题&#xff1a; asp:Menu 在Safari浏览器中显示不正常。 解决方法一&#xff1a;&#xff08;App_Browsers&#xff09; Step1: Add App_Browser Folder in application right click on project add ASP.Net Folder - App_Browsers right click on App_Browsers -- Add new…

CentOS常用到的查看系统命令

# uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # hostname # 查看计算机名 # lspci -tv # 列出所有PCI设备 # lsusb -tv # 列出所有USB设备 # lsmod…

Android HandlerThread 总结使用

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

[MathType需要安装新版的MT EXtra字体]解决方法

MathType是一款强大的数学公式编辑器&#xff0c;当安装完成&#xff08;或者使用绿色版&#xff09;打开程序时&#xff0c;常常弹出缺少字体的对话框&#xff0c;如下&#xff1a; MathType需要一个新版的MT Extra&#xff08;TrueType&#xff09;字体。请重新安装MathType&…

Microsoft Lync

转载于:https://blog.51cto.com/dynamicit/874659

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:…