A Star算法笔记
回顾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算法笔记的更多相关文章
- 学习Java 以及对几大基本排序算法(对算法笔记书的研究)的一些学习总结(Java对算法的实现持续更新中)
Java排序一,冒泡排序! 刚刚开始学习Java,但是比较有兴趣研究算法.最近看了一本算法笔记,刚开始只是打算随便看看,但是发现这本书非常不错,尤其是对排序算法,以及哈希函数的一些解释,让我非常的感兴 ...
- 算法笔记--数位dp
算法笔记 这个博客写的不错:http://blog.csdn.net/wust_zzwh/article/details/52100392 数位dp的精髓是不同情况下sta变量的设置. 模板: ]; ...
- 算法笔记--lca倍增算法
算法笔记 模板: vector<int>g[N]; vector<int>edge[N]; ][N]; int deep[N]; int h[N]; void dfs(int ...
- 算法笔记--STL中的各种遍历及查找(待增)
算法笔记 map: map<string,int> m; map<string,int>::iterator it;//auto it it = m.begin(); whil ...
- 算法笔记--priority_queue
算法笔记 priority_queue<int>que;//默认大顶堆 或者写作:priority_queue<int,vector<int>,less<int&g ...
- 算法笔记--sg函数详解及其模板
算法笔记 参考资料:https://wenku.baidu.com/view/25540742a8956bec0975e3a8.html sg函数大神详解:http://blog.csdn.net/l ...
- 算法笔记——C/C++语言基础篇(已完结)
开始系统学习算法,希望自己能够坚持下去,期间会把常用到的算法写进此博客,便于以后复习,同时希望能够给初学者提供一定的帮助,手敲难免存在错误,欢迎评论指正,共同学习.博客也可能会引用别人写的代码,如有引 ...
- 算法笔记_067:蓝桥杯练习 算法训练 安慰奶牛(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 Farmer John变得非常懒,他不想再继续维护供奶牛之间供通行的道路.道路被用来连接N个牧场,牧场被连续地编号为1到N.每一个牧场都是 ...
- 算法笔记(c++)--回文
算法笔记(c++)--回文 #include<iostream> #include<algorithm> #include<vector> using namesp ...
随机推荐
- MySQL OnlineDDL
参考资料: http://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html http://www.mysqlperfo ...
- MAC常用快捷键
1.F11 用于当前界面与桌面进行切换,Command-M 最小化窗口,Option-Command-M 最小化所有窗口,Command-数字 切换数字指定的网页列表 Shift-Command-D ...
- PHP多表取数据的代码优化
<?php header("Content-type: text/html; charset=utf-8"); //假设这里的$goods_arr 和 $shop_arr ...
- 如何修改ECSHOP后台管理中心的Title信息
下图中红色圈定的部分就是本次修改要改的地方 修改方法其实很简单的:打开语言包文件 /languages/zh_cn/admin/common.php 将 $_LANG['app_name'] = ' ...
- css写法优化
写css关于id,class等的命名,文件的结构,共同模块的提取,代码的复用性,可读性,扩展性,维护性都要考虑,不然后期可以会需要花大力气去进行维护修改.考虑写出足够科学的css,需要考虑下面几个方面 ...
- [转]iOS应用程序生命周期(前后台切换,应用的各种状态)详解
转载地址:http://blog.csdn.net/totogo2010/article/details/8048652 iOS的应用程序的生命周期,还有程序是运行在前台还是后台,应用程序各个状态的变 ...
- 20150612_Andriod contextual action mode 菜单
参考地址:http://www.xuebuyuan.com/1114028.html http://www.cnblogs.com/mengdd/p/3564782.html ...
- 迷之节约 分类: sdutOJ 最小生成树 2015-06-24 19:10 10人阅读 评论(0) 收藏
迷之节约 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 FF超级有钱,最近又买了n个(1 <= n <= 300)小岛,为 ...
- Android 内存分析工具 - LogCat GC
一.GC_Reason 触发垃圾回收的回收的集中原因: 类型 描述 GC_CONCURRENT 内存使用将满时,并发的进行垃圾回收. GC_FOR_MALLOC 当内存已满应用尝试分配内存时会出触发垃 ...
- log4j---------学习总结(一)
一.log4j框架 log4j可靠的,快速的,可扩展的(灵活的)日志框架 log4j具有高可配置性,可以通过外部配置文件来控制 log4j可以根据日志不同级别来过滤日志, log4j可以将日志记录直接 ...