记录_A*搜索算法之C#

A*搜索就是在BFS的基础上给出到终点更多的信息,约搜索点到终点地信息,使得一个搜索点到终点的距离最短。而且A*算法又有dijkstra的优点他能保持一个点到起始点的距离也是最短,这就能保证能在条件内得出最短距离。而A*中的估算函数对运行时间很重要,对于估算函数有很多种算法,一个点到终点的距离H(u)中的信息越多保证到终点的距离也就越短,但相对的运算时间也就要增加。而一个点到起始点的距离G(u)是确定的,所以函数也是可以确定的。而一个搜索点到起始点的距离加上一个搜索点到终点的距离F(u)=G(u)+H(u)的距离只要最短就能得出最短路径。所以只要在F(u)集中不断找对小权值点就能得到最短路径了。
    下面贴代码:

 public class Point_ai//存储各个搜索点的信息

    {

        public Point loc;

        public Point_ai father;

        int G;

        int H;

        public int F;

        public void min_path(Point start, Point end)

        {
            //到起点的估计值 

            this.G = (int)Math.Sqrt(Math.Abs(start.X - loc.X) * Math.Abs(start.X - loc.X) + Math.Abs(start.Y - loc.Y) * Math.Abs(start.Y - loc.Y));
            //到终点的估计值 

            this.H = (int)Math.Sqrt(Math.Abs(end.X - loc.X) * Math.Abs(end.X - loc.X) + Math.Abs(end.Y - loc.Y) * Math.Abs(end.Y - loc.Y));

            this.F = this.G + this.H;

        }

        public Point_ai(Point lo)

        {

            this.loc = lo;

        }

        public Point_ai()

        {

 

        }

    }

    public partial class A_star

    {

        //A*搜索

        public List<Point_ai> openlist=new List<Point_ai>();

        public List<Point_ai> closelist=new List<Point_ai>();

 

       /* public bool is_colli(Point po)//障碍检测A*搜索中障碍检测要重写这只是贪吃蛇的写法

        {

            for (int i = 1; i < snakeLen_ai -1; ++i)

            {

                if (po.X == snakeArr_ai[i].X && po.Y == snakeArr_ai[i].Y)

                {

                    return true;

                }

            }

            if (po.X < 0 || po.X > ClientRectangle.Width || po.Y < 0 || po.Y > ClientRectangle.Height)

            {

                return true;

            }

            return false;

        }*/

 

        public bool is_inclose(Point lo)//是否在关闭列表 如果关闭列表就说明这个点已经测试过了不需要进行重复测试

        {

            foreach (Point_ai loc in closelist)

            {

                if (lo == loc.loc)

                {

                    return true;

                }

            }

            return false;

        }

 

        public void add_open(Point_ai loc, Point start, Point end)//加入开启列表

        {
            /* 这些就是H(u) 的信息 信息越多 得到的距离也就越短 */ 
            /* 这里搜索的就四个方向 如果将搜索的方向增加到8个 也就是全方位搜索那么得出的距离会越短 */ 
            /*在这个贪吃蛇中我们以 15的边长的正方形做搜索的点 */ 

            Point temp = new Point();

            temp.X = loc.loc.X + 15;//右

            temp.Y = loc.loc.Y;

            if (!is_inclose(temp) && !is_colli(temp))

            {

                Point_ai lo = new Point_ai(temp);

                lo.min_path(start, end);

                lo.father = loc;//连接父节点 以便得出路劲

                openlist.Add(lo);

            }

            temp.X = loc.loc.X - 15;//左

            temp.Y = loc.loc.Y;

            if (!is_inclose(temp) && !is_colli(temp))

            {

                Point_ai lo = new Point_ai(temp);

                lo.min_path(start, end);

                lo.father = loc;//连接父节点 以便得出路劲

                openlist.Add(lo);

            }

            temp.X = loc.loc.X;     //下

            temp.Y = loc.loc.Y + 15;

            if (!is_inclose(temp) && !is_colli(temp))

            {

                Point_ai lo = new Point_ai(temp);

                lo.min_path(start, end);

                lo.father = loc;//连接父节点 以便得出路劲

                openlist.Add(lo);

            }

            temp.X = loc.loc.X;     //上

            temp.Y = loc.loc.Y - 15;

            if (!is_inclose(temp) && !is_colli(temp))

            {

                Point_ai lo = new Point_ai(temp);

                lo.min_path(start, end);

                lo.father = loc;//连接父节点 以便得出路劲

                openlist.Add(lo);

            }

        }

 

        public Point_ai search_min()//找开启列表里的最小权

        {

            int min = 9999999;

            Point_ai re = new Point_ai();

            for (int i = 0; i < openlist.Count;++i )//搜索开启列表

            {

                if (!is_inclose(openlist[i].loc))//如果不在关闭列表

                {

                    if (openlist[i].F < min)//找F(u)值最小的点

                    {

                        min = openlist[i].F;//更新最小权

                        re = openlist[i];//更新最小权点

                    }

                }

                else

                {

                    openlist.Remove(openlist[i]);//如果已经在关闭列表就移出开启列表

                }

            }

            openlist.Remove(re);//移除已检测点

            closelist.Add(re);//加入到关闭列表以防再次搜索

            return re;//返回最小权值点

        }

 

        public Point A(Point_ai start, Point_ai end)//A*搜索

        {

            Point_ai min = new Point_ai();

            closelist.Add(start);//移除起始点

            add_open(start, start.loc, end.loc);//加搜索区域

            while (openlist.Count != 0)//如果开启列表不为空

            {

                min = search_min();//获取开启列表最小F(u)

                add_open(min, start.loc, end.loc);//加搜索区域

                if (min.loc == end.loc)//如果检测到最小点已经是终点 退出

                {

                    break;

                }

            }

            while (min.father.loc != start.loc)//寻找路径的第一个节点

            {

                min = min.father;//因为在C#中一切对象皆是引用 所以直接写 如果在C++中要用指针 否则无法赋值

            }

            openlist.Clear();//清空开启列表

            closelist.Clear();//清空关闭列表

            return min.loc;//返回第一个节点

        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值