1.算法介绍

a*算法是一种寻路算法,类似于图的广度优先遍历搜索.

2.基本概念

设计先两个集合CloseList和OpenList,CloseList表示已经走过的节点,OpenList中的节点表示所有我们可以选择的下一步节点.

3.计算步骤:

1.将起点设为当前节点,并创建OpenList和CloseList.

2.将当前节点从OpenList中删除,并加入到CloseList中.

3.遍历当前节点的可到达节点,不包括CloseList中的节点,记录为AroundList,

4.然后对每个AroundList中的节点进行估值,f(x)=g(x)+h(x)

  ①.计算g(x).g(x)是消耗记录值,表示走过的路程所需要消耗的值,为当前节点的g值加上与当前节点的距离值.同时需将估值节点的加入OpenList并将估值节点的父节点设为当前节点.

    在计算g(x),需要注意此节点已存在于OpenList中,而且新g(x)小于原g(x),则更改g(x)的值,并更改当此节点的父节点为当前节点,否则不做修改.

  ②h(x)其中,g(x)表示估值算法,计算其与目标位置距离的估值.

    h(x)就是启发式搜索的估值函数,此函数写的越好,算法的效率就越高

5.若未到达目标节点,执行6,若到达目标节点,执行7

6.选择OpenList当中f(x)最小的点,设为当前节点,重复以上步骤2,3,4,5..

7.通过当前节点的父节点属性一直往上遍历,则得到目标路径节点的倒序排列.

4.代码实现

  1 using System.Collections.Generic;
  2
  3 namespace 动态规划
  4 {
  5     internal class Program
  6     {
  7         readonly List<Node> OpenList = new List<Node>();
  8         readonly List<Node> CloseList = new List<Node>();
  9
 10         List<Node> FindWayByAStart(Node startNode, Node endNode)
 11         {
 12             //1.将当前节点加入到CloseList中,并从OpenList中删除
 13             CloseList.Add(startNode);
 14             if (OpenList.Contains(startNode))
 15                 OpenList.Remove(startNode);
 16             //2.寻找当前节点所有可以到达的节点
 17             //且可到达的节点并不再CloseList中,则加入AroundList
 18             //TODO
 19             var aroundList = new List<Node>();
 20
 21             //3.对AroundList中的每个节点计算f(x)=g(x)+h(x)的值
 22             foreach (Node curNode in aroundList)
 23             {
 24                 if (!OpenList.Contains(curNode))
 25                 {
 26                     //如果此节点不在OpenList中,正常估值
 27                     //将此节点加入到OpenList中,并将其父节点设为当前节点
 28                     curNode.G = GetGValue(curNode, startNode) + startNode.G;
 29                     curNode.H = GetHValue(curNode, endNode);
 30                     curNode.Parent = startNode;
 31                     OpenList.Add(curNode);
 32                 }
 33                 else
 34                 {
 35                     //此节点在OpenList中
 36                     //若此节点的新估值g(x)小于之前的g(x),则更改g(x)的值,并重新赋值父节点
 37                     int newg = GetGValue(curNode, startNode)+startNode.G;
 38                     if (newg < curNode.G)
 39                     {
 40                         curNode.G = newg;
 41                         curNode.Parent = startNode;
 42                     }
 43                     //否则,不做操作
 44                 }
 45             }
 46
 47             //4.若当前节点为目标节点则执行操作6
 48             if (startNode != endNode)
 49             {
 50                 //没有可走点却没找到终点,寻路失败
 51                 if (OpenList.Count == 0)
 52                 {
 53                     return new List<Node>();
 54                 }
 55
 56                 Node nextNode = null;
 57                 //6.重复以上步骤
 58                 foreach (Node curNode in OpenList)
 59                 {
 60                     if (nextNode == null)
 61                     {
 62                         nextNode = curNode;
 63                     }
 64                     else if (nextNode.F >= curNode.F)
 65                     {
 66                         nextNode = curNode;
 67                     }
 68                 }
 69                 return FindWayByAStart(nextNode, endNode);
 70             }
 71             else
 72             {
 73                 //7.通过当前节点的父节点一层层往上遍历,得到目标路径节点的倒序排列.
 74                 List<Node> way = new List<Node>();
 75                 List<Node> backWay = new List<Node>();
 76                 Node curNode = startNode;
 77                 while (true)
 78                 {
 79                     backWay.Add(curNode);
 80
 81                     if (curNode.Parent == null)
 82                     {
 83                         backWay.Remove(curNode);
 84                         backWay.Remove(startNode);
 85                         break;
 86                     }
 87                     else
 88                     {
 89                         curNode = curNode.Parent;
 90                     }
 91                 }
 92
 93                 Node[] nodes = backWay.ToArray();
 94
 95                 for (int i = nodes.Length - 1; i >= 0; i--)
 96                 {
 97                     way.Add(nodes[i]);
 98                 }
 99                 return way;
100             }
101
102         }
103
104         internal class Node
105         {
106             public int F {
107                 get { return G + H; }
108             }
109
110             public int G;
111             public int H;
112
113             public Node Parent;
114         }
115
116         int GetGValue(Node a, Node b)
117         {
118             //TODO
119             return 0;
120         }
121
122         int GetHValue(Node a, Node b)
123         {
124             //TODO
125             return 0;
126         }
127     }
128 }

View Code

转载于:https://www.cnblogs.com/WongSiuming/p/5044670.html

[小明学算法]3.启发式搜索算法----A*算法之我见相关推荐

  1. 小明学PostgreSQL : 自旋锁浅析

    <小明学PostgreSQL : 自旋锁浅析> Table of Contents 什么是自旋锁 自旋锁的伪码 TAS VS CAS PostgreSQL的自旋锁 什么是自旋锁 自从小明学 ...

  2. 你必须会的启发式搜索算法--A*算法

    一.算法原理 A* 算法,就是解决在一个平面 grid地图中寻找起点到终点的最短路径问题的算法,类似于Dijkstra算法和BFS算法一样,属于广度优先搜索.实际上它还是一个启发式搜索算法,什么叫启发 ...

  3. 分支限界算法 之 A*算法(启发式搜索算法)---九宫重排游戏(也称八数码问题)

    3*3的棋盘中摆放了0~8这9个数字,每次只能允许0与其上下左右相邻的4个位置进行交换, 使得棋盘最终达到一种目标状态,要求输出最少交换次数的过程.例如 起始状态 目标状态1 2 3 1 2 3 6 ...

  4. [小明学Shader]1.Diffuse

    写在前面 本系列随笔是看化石大大的Unity Shader编程做的图书笔记,原课程地址:Unity Shader编程 Shader简介 Shader直译的话意思是"着色器",是在可 ...

  5. [小明学Shader]14.热扭曲效果

    1.代码 Shader "AAAA/HeatIsland" { Properties {_MainTex ("Base (RGB)", 2D) = " ...

  6. 小明学java基础系列——Java 类加载

    Java类加载学习笔记 一.基本概念 1.1 基本文件类型和概念 1.2 idea程序示例 1.2.1 idea-java源文件 1.2.2 idea-java字节码 1.2.3 idea-类加载 1 ...

  7. [小明学Shader]10.百叶窗

    1.代码 1 Shader "Custom/百叶窗" { 2 Properties { 3 [PerRendererData]_MainTex ("Base (RGB)& ...

  8. 载波恢复算法 Blind Phase Search 算法(盲相位搜索算法 BPS算法)

    背景 载波恢复算法通常分为两部分,频偏估计算法和相位恢复算法.在实际通信中,收发端光载波的频率存在偏差,百MHz-GHz,会对光信号引入较大的相位旋转.同时光通信系统通常是长距离传输,随着时间的延长激 ...

  9. 算法笔记 --- 记忆搜索算法 --- 动态规划算法

    to be continued 转载于:https://www.cnblogs.com/zhongzhiqiang/p/5811201.html

最新文章

  1. 操作系统编写之引导扇区
  2. Dubbo入门介绍---搭建一个最简单的Demo框架
  3. 2021考研数一李正元400题、张宇4套卷题目整理
  4. 苹果Mac 3D 数字绘画工具:Substance 3D Painter
  5. 用ASP.NET向Javascript传递变量
  6. 部署Ansible与常用模块
  7. 3点15分夹角多少度
  8. TQ210 —— LCD
  9. 如何划分安全域及网络如何改造
  10. JAVA设计模式总结之23种设计模式(重点!!!)
  11. 桌面计算机未响应怎么办,电脑桌面假死(点击无反应)怎么解决?试试这三种处理方法吧...
  12. [转]AJAX基础教程
  13. 同源策略、跨域以及跨域的三种解决方案详解
  14. Pytorch中dim的理解
  15. c语言程序设计(微课版),C语言程序设计教程(微课版)
  16. 神经网络与深度学习 作业3:分别使用numpy和pytorch实现FNN例题
  17. 在Linux中卸载Refind
  18. 程序员学习能力提升三要素
  19. 基于QT的界面框架qcanpool使用教程(废弃)
  20. 域名更换为itwxe.com

热门文章

  1. linux主辅DNS的搭配
  2. Spring Cloud之Hystrix
  3. 浅谈script标签中的async和defer
  4. hihocoder #1333 : 平衡树·Splay2
  5. nvm 解决nodejs无法全局/usr/bin/node问题
  6. 源码安装apache及配置转发
  7. struts2 从 action 到 jsp 页面
  8. Android开发之Navigationdrawer导航抽屉功能的实现(源代码分享)
  9. requestLayout 无效
  10. 第十六周程序阅读(8)