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

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace AStarOne
{
class AStar
{
public const int OBLIQUE = ;//sqrt(2.0) is 1.414; they have been amplified.
public const int STEP = ;
public int[,] AStarArray { get; private set; }
List<Point> CloseList; // Close List
List<Point> OpenList; // Open List public AStar(int [,] aStar)
{
this.AStarArray = aStar;
OpenList = new List<Point>(AStarArray.Length);// Impossible to be bigger than the number of all data
CloseList = new List<Point>(AStarArray.Length);
} /// <summary>
/// Find an achievable path from start to end
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
/// <param name="IsIgnoreCorner">If ignore diagonal spot</param>
/// <returns></returns>
public Point FindPath(Point start, Point end, bool IsIgnoreCorner)
{
OpenList.Add(start);
while ( != OpenList.Count)
{
var tempStart = OpenList.MinPoint();// get the minimum F
OpenList.RemoveAt();
CloseList.Add(tempStart); var surroundPoints = GetSurroundPoints(tempStart, IsIgnoreCorner);// Get surrounding points
foreach (var point in surroundPoints)
{
if (OpenList.Exists(point))// If existing in the open list, choose the minimum G between tempStart and point; Update
{
FoundPoint(tempStart, point);
}
else
{
NotFoundPoint(tempStart, end, point);
}
} if (OpenList.Get(end) != null)
return OpenList.Get(end);
} return OpenList.Get(end);
} private void FoundPoint(Point tempStart, Point point)
{
var G = CalcG(tempStart, point);
if (G < point.G)// the minimum one
{
point.ParentPoint = tempStart;
point.G = G;
point.CalcF();
}
} private void NotFoundPoint(Point tempPoint, Point end, Point point)
{
point.ParentPoint = tempPoint;
point.G = CalcG(tempPoint, point);
point.H = CalcH(end, point);
point.CalcF();
OpenList.Add(point);// This is quite important
} private int CalcG(Point start, Point point)// Calc the cost from start to point
{
int G = (Math.Abs(point.X - start.X) + Math.Abs(point.Y - start.Y)) == ? STEP : OBLIQUE;// Should be 1
int parentG = point.ParentPoint != null ? point.ParentPoint.G : ;
return G + parentG;
} private int CalcH(Point end, Point point)// Estimate the cost to reach the target
{
int step = Math.Abs(point.X - end.X) + Math.Abs(point.Y - end.Y);
return step * STEP;
} public List<Point> GetSurroundPoints(Point point, bool IsIgnoreCorner)
{
var surroundPoints = new List<Point>(); for (int x = point.X - ; x <= point.X + ; x++)
{
for (int y = point.Y - ; y <= point.Y + ; y++)
{
if (CanReach(point, x, y, IsIgnoreCorner))
surroundPoints.Add(x, y);
}
} return surroundPoints;
} private bool CanReach(int x, int y)
{
return AStarArray[x, y] == ;
} public bool CanReach(Point start, int x, int y, bool IsIgnoreCorner)
{
if (!CanReach(x, y) || CloseList.Exists(x, y))// Cannot reach or has been handled
{
return false;
}
else
{
if (Math.Abs(x - start.X) + Math.Abs(y - start.Y) == )// Adjacent but not diagonal
{
return true;
}
else
{
if (CanReach(Math.Abs(x - ), y) && CanReach(x, Math.Abs(y - )))// Make sure diagnonal but not necessary
{
return IsIgnoreCorner;
}
else
{
return false;
}
}
}
}
} public class Point
{
public Point ParentPoint { get; set; }
public int F { get; set; } // F = G + H
public int G { get; set; }
public int H { get; set; }
public int X { get; set; }
public int Y { get; set; } public Point(int x, int y)
{
this.X = x;
this.Y = y;
} public void CalcF()
{
this.F = this.G + this.H;
}
} public static class ListHelper
{
public static bool Exists(this List<Point> points, Point point)
{
foreach (var p in points)
if ((p.X == point.X) && (p.Y == point.Y))
return true; return false;
} public static bool Exists(this List<Point> points, int x, int y)
{
foreach (var p in points)
if ((p.X == x) && (p.Y == y))
return true; return false;
} public static Point MinPoint(this List<Point> points)
{
points = points.OrderBy(p => p.F).ToList();
return points[];
} public static void Add(this List<Point> points, int x, int y)
{
points.Add(new Point(x, y));
} public static Point Get(this List<Point> points, Point point)
{
foreach (Point p in points)
if ((p.X == point.X) && (p.Y == point.Y))
return p; return null;
} public static void Remove(this List<Point> points, int x, int y)
{
foreach (var point in points)
if ((point.X == x) && (point.Y == y))
points.Remove(point);
}
}
}

测试代码如下:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace AStarOne
{
class Program
{
static void Main(string[] args)
{
int[,] array = {
{ , , , , , , , , , , , },
{ , , , , , , , , , , , },
{ , , , , , , , , , , , },
{ , , , , , , , , , , , },
{ , , , , , , , , , , , },
{ , , , , , , , , , , , },
{ , , , , , , , , , , , },
{ , , , , , , , , , , , }
}; AStar astar = new AStar(array); Point start = new Point(, );
Point end = new Point(, );
var parent = astar.FindPath(start, end, false); Console.WriteLine("Print path:");
while (parent != null)
{
//Console.WriteLine(parent.X + ", " + parent.Y);
array[parent.X, parent.Y] = ;
parent = parent.ParentPoint;
} for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
Console.Write(array[i,j] + " ");
}
Console.WriteLine();
}
}
}
}

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

A Star算法笔记的更多相关文章

  1. 学习Java 以及对几大基本排序算法(对算法笔记书的研究)的一些学习总结(Java对算法的实现持续更新中)

    Java排序一,冒泡排序! 刚刚开始学习Java,但是比较有兴趣研究算法.最近看了一本算法笔记,刚开始只是打算随便看看,但是发现这本书非常不错,尤其是对排序算法,以及哈希函数的一些解释,让我非常的感兴 ...

  2. 算法笔记--数位dp

    算法笔记 这个博客写的不错:http://blog.csdn.net/wust_zzwh/article/details/52100392 数位dp的精髓是不同情况下sta变量的设置. 模板: ]; ...

  3. 算法笔记--lca倍增算法

    算法笔记 模板: vector<int>g[N]; vector<int>edge[N]; ][N]; int deep[N]; int h[N]; void dfs(int ...

  4. 算法笔记--STL中的各种遍历及查找(待增)

    算法笔记 map: map<string,int> m; map<string,int>::iterator it;//auto it it = m.begin(); whil ...

  5. 算法笔记--priority_queue

    算法笔记 priority_queue<int>que;//默认大顶堆 或者写作:priority_queue<int,vector<int>,less<int&g ...

  6. 算法笔记--sg函数详解及其模板

    算法笔记 参考资料:https://wenku.baidu.com/view/25540742a8956bec0975e3a8.html sg函数大神详解:http://blog.csdn.net/l ...

  7. 算法笔记——C/C++语言基础篇(已完结)

    开始系统学习算法,希望自己能够坚持下去,期间会把常用到的算法写进此博客,便于以后复习,同时希望能够给初学者提供一定的帮助,手敲难免存在错误,欢迎评论指正,共同学习.博客也可能会引用别人写的代码,如有引 ...

  8. 算法笔记_067:蓝桥杯练习 算法训练 安慰奶牛(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 Farmer John变得非常懒,他不想再继续维护供奶牛之间供通行的道路.道路被用来连接N个牧场,牧场被连续地编号为1到N.每一个牧场都是 ...

  9. 算法笔记(c++)--回文

    算法笔记(c++)--回文 #include<iostream> #include<algorithm> #include<vector> using namesp ...

随机推荐

  1. JS实现复制网页内容自动加入版权内容代码和原文链接

    JS实现复制网页内容自动加入版权内容代码和原文链接 实现代码:在body内放入如下代码即可: <script type="text/javascript"> var S ...

  2. IBatisNet Demo (升级from 1.1)

    sqlMap.config, 要修改provider的设置 <providers resource="providers.config"/> <database& ...

  3. oracle 日期格式

    oracle 日期格式 to_date("要转换的字符串","转换的格式")   两个参数的格式必须匹配,否则会报错. 即按照第二个参数的格式解释第一个参数. ...

  4. POSIX字符类

    POSIX字符类需要用引号,或双括号[[]]括起来: [:alnum:]:匹配字面和数字字符.等同于A~Z,a~z,0~9 [:alpha:]:匹配字母字符.等同于A~Z,a~z [:blank:]: ...

  5. visio 由于形状保护和/或图层属性设置不能进行编辑

    方式一.菜单栏 --> 格式 --> 保护 方式二.用鼠标右键单击组件, 格式 --> 保护 . 转自:http://blog.163.com/chen_dawn/blog/stat ...

  6. RAC例子

    我个人非常推崇ReactiveCocoa,它就像中国的太极,太极生两仪,两仪生四象,四象生八卦,八卦生万物.ReactiveCocoa是一个高度抽象的编程框架,它真的很抽象,初看你不知道它是要干嘛的, ...

  7. C#:WiFi

    写的一个简单启动关闭WiFi的类:具体如下 using System; using System.Collections.Generic; using System.Text; using Syste ...

  8. 不定参数的传递VA_LIST的用法

    VA_LIST的用法:(1)首先在函数里定义一具VA_LIST型的变量,这个变量是指向参数的指针: (2)然后用VA_START宏初始化变量刚定义的VA_LIST变量,使其指向第一个可 变参数的地址: ...

  9. android5.x以上 状态栏透明的问题

    1.先在style中把 statusBarColor 设置为透明  如下 <item name="android:statusBarColor">@android:co ...

  10. python :列表 字典 集合 类 ----局部变量可以改全局变量

    #列表 字典 集合 类 ----局部变量可以改全局变量,除了整数和字符串 names=["alex","jack","luck"] def ...