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 ...
随机推荐
- javaWeb 使用jsp开发 html过滤标签
1.jsp调用代码 <t:htmlFilter> <a href="${pageContext.request.contextPath }/index.jsp"& ...
- [转]JEXUS的高级配置
转自:http://www.cnblogs.com/xiaodiejinghong/archive/2013/04/14/3019660.html 前一回合,我们对服务器软件Jexus作了简单的介绍, ...
- Centos7下使用ELK(Elasticsearch + Logstash + Kibana)搭建日志集中分析平台
日志监控和分析在保障业务稳定运行时,起到了很重要的作用,不过一般情况下日志都分散在各个生产服务器,且开发人员无法登陆生产服务器,这时候就需要一个集中式的日志收集装置,对日志中的关键字进行监控,触发异常 ...
- 解决HP服务器安装Centos7 x64无法识别硬盘
公司有一台老旧的HP服务器——HP BL460c G7 SmartArray P410i.由于种种原因,需要重新安装操作系统Centos7.但是经过各种努力,Centos7的安装程序就是无法识别服务器 ...
- 27、oracle(三)
1)掌握增.删.改数据和事务操作 2)掌握[视图]和同义词 3)掌握[序列]和索引 4)了解有关用户和权限的控制 ------------------------------------------- ...
- java 面试每日一题7
题目:判断101-200之间有多少个素数,并输出所有素数. 1.程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除, 则表明此数不是素数,反之是素数. public cla ...
- React.js入门小案例
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
- Python基本概念及零碎知识点
1.python面向对象 类和对象是面向对象编程的两个主要方面.类创建一个新类型,而对象这个类的实例:这类似于你有一个int类型的变量,这存储整数的变量是int类的实例(对象)把握一点:在python ...
- hdu4933 Miaomiao's Function
水水的计数题,关键在细节. import java.math.BigInteger; import java.util.Scanner; import java.io.*; public class ...
- 第十二届浙江省大学生程序设计大赛-Demacia of the Ancients 分类: 比赛 2015-06-26 14:39 30人阅读 评论(0) 收藏
Demacia of the Ancients Time Limit: 2 Seconds Memory Limit: 65536 KB There is a popular multiplayer ...