文章目录
A星算法的一些关键点
基本原理
C#代码
internal abstract class AStarData
{
public int FSum => _gSum + _hSum;
private int _gSum;
private int _hSum;
public int Direction; // 路径的方向
/// <summary>
/// 计算估算的距离,有很多选择,比如曼哈顿距离, 对角线距离, 欧几里得距离, 平方后的欧几里得距离
/// </summary>
/// <returns></returns>
public abstract int CalcH();
}
class AStar<T> where T: AStarData
{
private List<T> _closeList = new List<T>();
private List<T> _openList = new List<T>();
private T _start;
private T _end;
public List<T> MainAStar()
{
var path = new List<T>();
var currentLocation = this._start;
while (currentLocation != this._end)
{
currentLocation = this.ValidLocations(currentLocation)[0];
this._openList.RemoveAt(0);
this._closeList.Add(currentLocation);
}
var nextLocation = this._end;
while (nextLocation != this._start)
{
nextLocation = this.CalcLocationReverse(nextLocation.Direction);
}
return path;
}
/// <summary>
/// 根据寻找的时候的方向,计算找到的路径
/// </summary>
/// <param name="direction"></param>
/// <returns></returns>
private T CalcLocationReverse(int direction)
{
throw new NotImplementedException();
}
/// <summary>
/// 根据当前位置,找到所有可能的位置(需要考虑封闭的路径)
/// 需要提供要给一个方向值
/// 需要提供已经走过的距离长度
/// </summary>
/// <param name="start"></param>
/// <returns></returns>
private List<T> CalcLocation(T start)
{
throw new NotImplementedException();
}
private List<T> ValidLocations(T current)
{
var currentLocations = this.CalcLocation(current);
this._openList.AddRange(currentLocations);
this._openList.Sort((x, y) =>
{
// 从小到大排列
if (x.FSum < y.FSum) { return -1; }
if (x.FSum == y.FSum) { return 0; }
return x.FSum > y.FSum ? 1 : 0;
});
return _openList;
}
}
- 路径的距离计算根据业务场景不同,自己实现
- 路径的方向也要具体定义
- 估算距离也要选择合适的实现
- 所有可到达的方格都要加入到OpenList
- 找到终点后,还要进行回溯来确定路径