A star算法笔记

回顾A*算法,偶得一源代码,略有瑕疵,改正之,并置于下。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6
  7 namespace AStarOne
  8 {
  9     class AStar
 10     {
 11         public const int OBLIQUE = 14;//sqrt(2.0) is 1.414; they have been amplified.
 12         public const int STEP = 10;
 13         public int[,] AStarArray { get; private set; }
 14         List<Point> CloseList; // Close List
 15         List<Point> OpenList; // Open List
 16
 17         public AStar(int [,] aStar)
 18         {
 19             this.AStarArray = aStar;
 20             OpenList = new List<Point>(AStarArray.Length);// Impossible to be bigger than the number of all data
 21             CloseList = new List<Point>(AStarArray.Length);
 22         }
 23
 24         /// <summary>
 25         /// Find an achievable path from start to end
 26         /// </summary>
 27         /// <param name="start"></param>
 28         /// <param name="end"></param>
 29         /// <param name="IsIgnoreCorner">If ignore diagonal spot</param>
 30         /// <returns></returns>
 31         public Point FindPath(Point start, Point end, bool IsIgnoreCorner)
 32         {
 33             OpenList.Add(start);
 34             while (0 != OpenList.Count)
 35             {
 36                 var tempStart = OpenList.MinPoint();// get the minimum F
 37                 OpenList.RemoveAt(0);
 38                 CloseList.Add(tempStart);
 39
 40                 var surroundPoints = GetSurroundPoints(tempStart, IsIgnoreCorner);// Get surrounding points
 41                 foreach (var point in surroundPoints)
 42                 {
 43                     if (OpenList.Exists(point))// If existing in the open list, choose the minimum G between tempStart and point; Update
 44                     {
 45                         FoundPoint(tempStart, point);
 46                     }
 47                     else
 48                     {
 49                         NotFoundPoint(tempStart, end, point);
 50                     }
 51                 }
 52
 53                 if (OpenList.Get(end) != null)
 54                     return OpenList.Get(end);
 55             }
 56
 57             return OpenList.Get(end);
 58         }
 59
 60         private void FoundPoint(Point tempStart, Point point)
 61         {
 62             var G = CalcG(tempStart, point);
 63             if (G < point.G)// the minimum one
 64             {
 65                 point.ParentPoint = tempStart;
 66                 point.G = G;
 67                 point.CalcF();
 68             }
 69         }
 70
 71         private void NotFoundPoint(Point tempPoint, Point end, Point point)
 72         {
 73             point.ParentPoint = tempPoint;
 74             point.G = CalcG(tempPoint, point);
 75             point.H = CalcH(end, point);
 76             point.CalcF();
 77             OpenList.Add(point);// This is quite important
 78         }
 79
 80         private int CalcG(Point start, Point point)// Calc the cost from start to point
 81         {
 82             int G = (Math.Abs(point.X - start.X) + Math.Abs(point.Y - start.Y)) == 1 ? STEP : OBLIQUE;// Should be 1
 83             int parentG = point.ParentPoint != null ? point.ParentPoint.G : 0;
 84             return G + parentG;
 85         }
 86
 87         private int CalcH(Point end, Point point)// Estimate the cost to reach the target
 88         {
 89             int step = Math.Abs(point.X - end.X) + Math.Abs(point.Y - end.Y);
 90             return step * STEP;
 91         }
 92
 93         public List<Point> GetSurroundPoints(Point point, bool IsIgnoreCorner)
 94         {
 95             var surroundPoints = new List<Point>(9);
 96
 97             for (int x = point.X - 1; x <= point.X + 1; x++)
 98             {
 99                 for (int y = point.Y - 1; y <= point.Y + 1; y++)
100                 {
101                     if (CanReach(point, x, y, IsIgnoreCorner))
102                         surroundPoints.Add(x, y);
103                 }
104             }
105
106             return surroundPoints;
107         }
108
109         private bool CanReach(int x, int y)
110         {
111             return AStarArray[x, y] == 0;
112         }
113
114         public bool CanReach(Point start, int x, int y, bool IsIgnoreCorner)
115         {
116             if (!CanReach(x, y) || CloseList.Exists(x, y))// Cannot reach or has been handled
117             {
118                 return false;
119             }
120             else
121             {
122                 if (Math.Abs(x - start.X) + Math.Abs(y - start.Y) == 1)// Adjacent but not diagonal
123                 {
124                     return true;
125                 }
126                 else
127                 {
128                     if (CanReach(Math.Abs(x - 1), y) && CanReach(x, Math.Abs(y - 1)))// Make sure diagnonal but not necessary
129                     {
130                         return IsIgnoreCorner;
131                     }
132                     else
133                     {
134                         return false;
135                     }
136                 }
137             }
138         }
139     }
140
141     public class Point
142     {
143         public Point ParentPoint { get; set; }
144         public int F { get; set; } // F = G + H
145         public int G { get; set; }
146         public int H { get; set; }
147         public int X { get; set; }
148         public int Y { get; set; }
149
150         public Point(int x, int y)
151         {
152             this.X = x;
153             this.Y = y;
154         }
155
156         public void CalcF()
157         {
158             this.F = this.G + this.H;
159         }
160     }
161
162     public static class ListHelper
163     {
164         public static bool Exists(this List<Point> points, Point point)
165         {
166             foreach (var p in points)
167                 if ((p.X == point.X) && (p.Y == point.Y))
168                     return true;
169
170              return false;
171         }
172
173         public static bool Exists(this List<Point> points, int x, int y)
174         {
175             foreach (var p in points)
176                 if ((p.X == x) && (p.Y == y))
177                     return true;
178
179             return false;
180         }
181
182         public static Point MinPoint(this List<Point> points)
183         {
184             points = points.OrderBy(p => p.F).ToList();
185             return points[0];
186         }
187
188         public static void Add(this List<Point> points, int x, int y)
189         {
190             points.Add(new Point(x, y));
191         }
192
193         public static Point Get(this List<Point> points, Point point)
194         {
195             foreach (Point p in points)
196                 if ((p.X == point.X) && (p.Y == point.Y))
197                     return p;
198
199             return null;
200         }
201
202         public static void Remove(this List<Point> points, int x, int y)
203         {
204             foreach (var point in points)
205                 if ((point.X == x) && (point.Y == y))
206                     points.Remove(point);
207         }
208     }
209 }

测试代码如下:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6
 7 namespace AStarOne
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             int[,] array = {
14                                { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
15                                { 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1},
16                                { 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
17                                { 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1},
18                                { 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1},
19                                { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1},
20                                { 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1},
21                                { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
22                            };
23
24             AStar astar = new AStar(array);
25
26             Point start = new Point(1, 1);
27             Point end = new Point(6, 10);
28             var parent = astar.FindPath(start, end, false);
29
30             Console.WriteLine("Print path:");
31             while (parent != null)
32             {
33                 //Console.WriteLine(parent.X + ", " + parent.Y);
34                 array[parent.X, parent.Y] = 8;
35                 parent = parent.ParentPoint;
36             }
37
38             for (int i = 0; i < 8; i++)
39             {
40                 for (int j = 0; j < 12; j++)
41                 {
42                     Console.Write(array[i,j] + " ");
43                 }
44                 Console.WriteLine();
45             }
46         }
47     }
48 }

运行结果如下(注意‘8’的位置即是路径):

时间: 2024-08-26 08:47:54

A star算法笔记的相关文章

算法笔记-DTW动态时间规整

算法笔记-DTW动态时间规整 简介 简单的例子 定义 讨论 约束条件 步模式 标准化 点与点的距离函数 具体应用场景 分类 点到点匹配 算法笔记-DTW动态时间规整 动态时间规整/规划(Dynamic Time Warping, DTW)是一个比较老的算法,大概在1970年左右被提出来,最早用于处理语音方面识别分类的问题. 1.简介 简单来说,给定两个离散的序列(实际上不一定要与时间有关),DTW能够衡量这两个序列的相似程度,或者说两个序列的距离.同时DTW能够对两个序列的延展或者压缩能够有一定

小算法笔记

素数: 除 1 外只能被 1 和自身整除的数. 方法一: #include <stdio.h> #define N 1000 int num = 0; int prime(int n) { int i; if(n % 2 == 0) return (n == 2); if(n % 3 == 0) return (n == 3); if(n % 5 == 0) return (n == 5); for(i = 7; i*i <= n; ++i) if(n % i == 0) return

算法笔记之堆排序

一.对堆排序的相关了解 1.堆排序的运行时间是 O(nlogn) : 2.定义: 堆heap是一棵具有以下属性的二叉树-- (1)它是一棵完全二叉树: (2)每个结点大于或等于它的任意一个孩子. 备注:完全二叉树的定义--除了最后一层没填满以及最后一层的叶子都是偏左放置的,其他层都是满的二叉树! 3.二叉堆有两种:最大堆和最小堆.在堆排序中我们使用的是最大堆,最小堆常常在构造优先队列时使用. 4.一条路径的深度指的是这条路径的边数,一个结点的深度是指从根结点到该结点的路径的长度. 二.对堆进行排

算法笔记_023:拓扑排序(Java)

目录 1 问题描述 2 解决方案 2.1 基于减治法实现 2.2 基于深度优先查找实现 1 问题描述 给定一个有向图,求取此图的拓扑排序序列. 那么,何为拓扑排序? 定义:将有向图中的顶点以线性方式进行排序.即对于任何连接自顶点u到顶点v的有向边uv,在最后的排序结果中,顶点u总是在顶点v的前面. 2 解决方案 2.1 基于减治法实现 实现原理:不断地做这样一件事,在余下的有向图中求取一个源(source)(PS:定义入度为0的顶点为有向图的源),它是一个没有输入边的顶点,然后把它和所有从它出发

算法笔记_018:旅行商问题(Java)

目录 1 问题描述 2 解决方案 2.1 蛮力法   1 问题描述 何为旅行商问题?按照非专业的说法,这个问题要求找出一条n个给定的城市间的最短路径,使我们在回到触发的城市之前,对每个城市都只访问一次.这样该问题就可以表述为求一个图的最短哈密顿回路的问题.(哈密顿回路:定义为一个对图的每个顶点都只穿越一次的回路) 很容易看出来,哈密顿回路也可以定义为n+1个相邻顶点v1,v2,v3,...,vn,v1的一个序列.其中,序列的第一个顶点和最后一个顶点是相同的,而其它n-1个顶点都是互不相同的.并且

算法笔记1-最大子序列和问题的求解

问题-- 给定N个整数(有可能是负数)A1,A2,A3,A4...An,求最大子序列和. (子序列必须是连续的):比如,对于输入,-2,11,-4,13,-5,-2:这个序列, 答案是20,即从A2到A4. 对于这个问题,你怎么想的呢?下面有四种解法,看看你的解法是不是其中之一. 解法一.穷举 解题思路-- 既然是求某一个连续的子序列的最大和,那么我们把所有的子序列的和都加一遍,然后用一个变量来存储最大的和值,当遍历一遍所有子序列,即可得到最大的和.由于这个子序列长度可以是1,也可以是N,因此需

[数据结构和算法]折半插入排序算法笔记

/// <summary> /// 步骤: /// 1.记录当前待排元素 /// 2.标记顺序表有序查找区域下界和上界 /// 3.在顺序表有序查找区域中折半查找等待排序元素的位置 /// 4.把顺序表有序查找区域的某些元素后移一位,以空出位置给等待排序的元素 /// 5.在空出的位置填写当前排序元素 /// </summary> /// <param name="elements"></param> static void SqList

算法笔记2-优先队列(堆)(上)

一.什么是优先队列? 看一情景:我们去KTV唱歌,点歌的时候,可以发现所点的歌就是一个队列. 这时候,一个MM突然不玩手机了想唱歌,于是她来点歌,并且想尽早轮到她. 于是她可以选择"插歌"这个功能插到前排队列里. 这种具备可以插入优先权元素的队列,就叫优先队列.但是,这个定义不是严谨的. 优先队列的基本模型是这样的-- 具备两个功能: insert插入: deleteMin 删除最小者. 它的工作就是-- 它很有用哦,具体可以用在操作系统,外部排序和贪婪算法中等. 二.怎么实现优先队列

算法笔记_071:SPFA算法简单介绍(Java)

目录 1 问题描述 2 解决方案 2.1 具体编码   1 问题描述 何为spfa(Shortest Path Faster Algorithm)算法? spfa算法功能:给定一个加权连通图,选取一个顶点,称为起点,求取起点到其它所有顶点之间的最短距离,其显著特点是可以求含负权图的单源最短路径,且效率较高.(PS:引用自百度百科:spfa是求单源最短路径的一种算法,它还有一个重要的功能是判负环(在差分约束系统中会得以体现),在Bellman-ford算法的基础上加上一个队列优化,减少了冗余的松弛