a星算法c++实现_递归算法理解

a星算法c++实现_递归算法理解翻了翻别人写的博客,我看到一个A星算法,只怪自己见识太少,竟然没听过这个算法。网上查了好些资料,自己对这算法理解了些,并用C#实现出来。           A星算法,也叫A*算法。这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法。如在一张dota地图上,英雄从一个地方走动到地图上另一个点,它选择最优路线的算法。       如上图,绿点是

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

         翻了翻别人写的博客,我看到一个A星算法,只怪自己见识太少,竟然没听过这个算法。网上查了好些资料,自己对这算法理解了些,并用C#实现出来。

     a星算法c++实现_递归算法理解

               A星算法,也叫A*算法。这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法。 如在一张dota地图上,英雄从一个地方走动到地图上另一个点,它选择最优路线的算法。

             如上图,绿点是开始点,红点是目的地,黑色区域是不可通过区域。 通过A*算法,黄色线段就是找到的最优路线。

        我想了想,其实用漫水算法也能找这路线啊。这A星算法优点在于处理速度快,并不是像漫水一样,各个方向都在寻找。

         A*算法原理。就以上面那种情况说明吧, 从绿色点开始,你想去红色点,你下一步有八个方向选择。

a星算法c++实现_递归算法理解

     八个方向选择,你肯定想往右边走,这样才能离目的地近。横竖走,还是斜着走,更倾向横竖走,距离短。

    用G表示你从起始点走的距离。横或竖一格G=10,斜着G=14。

    用H表示你离目的地的距离,这里就是个估算,就像你老远看下,在那个方向,估算下距离。用曼哈顿距离表示就可以了。 比如你在(1,1),要去(5,5).距离就当你竖着走4格,横着走4个,八格就到了。估算,别管障碍物。八格那么,H=80.变大十倍(因为G变大10倍了)。

    那么用F=G+H表示你周围的格子,你要去目的地花的代价。 越小越好。

     然后你建两个表,存放一些东西。你要探索的格子存在OpenList里去,你找到最好的存到CloseList去。你存的不仅仅是这个格子的F值,还有它指向的方向,不然你的G有什么意义。


      然后你就有F的值了,你周围的八个格子F都有了,加入到你的OpenList里去。选个F最小的格子,移出OpenList,存到CloseList去。走到这个格子,探索这个格子周围的格子忽略障碍物和边界,忽略CloseList里的格子,其他统统加入到Openlist里。如果有格子在OpenList里,看看他们原来的G值和你走过去的G值大小比较下,如果你的G大,就让那个格子以前那样,你的G小,更新它。

      然后在OpenList找最小F那个格子,移出OpenList,加入CloseList,走到这个格子,打开周围格子,循环下去,直到你哪天一不小心打开了目的地的格子。就停止吧。

   最后,从目的地这个格子的指向,一路指向你开始的格子!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyAXing
{
    class MyPoint      //定义了MyPoint这种数据结构  就是我说的上面那种格子
    {
        public int x;
        public int y;
        public int G;
        public int H;
        public MyPoint father;
        public MyPoint()
        {
        }
        public MyPoint(int x0, int y0, int G0, int H0,MyPoint F)
        {
            x = x0;
            y = y0;
            G = G0;
            H = H0;
            father = F;
        }
    }
}

按照上面的思路,写出来就是了。定义两个List<MyPoint>来存Mypoint。

        List<MyPoint> Open_List = new List<MyPoint>();
        List<MyPoint> Close_List = new List<MyPoint>();

更新下,贴上源码//

Form1

  public partial class Form1 : Form
    {

        enum mycc
        {
            wall,
            start,
            des
        }

        mycc mychoose = mycc.wall;

        byte[,] R = new byte[10, 10] { 
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
            
            };

        mybutton[,] mybut = new mybutton[20, 20];

        byte[,] myR = new byte[20, 20];


        MyPoint pa = new MyPoint();
        MyPoint pb = new MyPoint();

        void init()
        {
            for (int i = 0; i < 20; i++)
            {
                for (int j = 0; j < 20; j++)
                {
                    myR[i, j] = 1;
                    mybut[i, j].BackColor = Color.Transparent;
                }
            }
        }



        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            AxingTest ax = new AxingTest(R);

            //定义起始位置
            MyPoint pa = new MyPoint();
            pa.x = 1;
            pa.y = 1;

            //定义目的地
            MyPoint pb = new MyPoint();
            pb.x = 8;
            pb.y = 8;

            List<MyPoint> myp = new List<MyPoint>();
           myp= ax.FindeWay(pa, pb);
           foreach (MyPoint p in myp)
           {
            //   textBox1.AppendText(p.ToString() + " ");
           }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 20; i++)
            {
                for (int j = 0; j < 20; j++)
                {
                    mybut[i, j] = new mybutton();
                    mybut[i, j].X = i;
                    mybut[i, j].Y = j;
                    mybut[i, j].Size = new Size(20, 20);
                    mybut[i, j].Location = new Point(i * 20, j * 20);
                    this.Controls.Add(mybut[i, j]);
                    mybut[i, j].MouseDown += Form1_MouseDown;
                }
            }
        }

        void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            mybutton myb = (mybutton)sender;
            int x = myb.X;
            int y = myb.Y;
            if (mychoose == mycc.wall)
            {
                mybut[x, y].BackColor = Color.Black;
                myR[y, x] = 0;
            }

            if (mychoose == mycc.start)
            {
                mybut[x, y].BackColor = Color.Green;
              //  myR[x, y] = 1;
                pa.x = x;
                pa.y = y;
            }

            if (mychoose == mycc.des)
            {
                mybut[x, y].BackColor = Color.Red;
              //  myR[x, y] = 1;
                pb.x = x;
                pb.y = y;
            }

        }

        private void button6_Click(object sender, EventArgs e)
        {
            init();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            mychoose = mycc.wall;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            mychoose = mycc.start;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            mychoose = mycc.des;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            AxingTest ax = new AxingTest(myR);
            List<MyPoint> myp = new List<MyPoint>();
            myp = ax.FindeWay(pa, pb);

            foreach (MyPoint p in myp)
            {
                mybut[p.x, p.y].BackColor = Color.Yellow;
            }
            mybut[pb.x, pb.y].BackColor = Color.Red;
        }
    }


    public class mybutton : Button
    {
        int x;
        int y;
        public int X
        {
            set { x = value; }
            get { return x; }
        }

        public int Y
        {
            set { y = value; }
            get { return y; }
        }
    }


AXingTest

    class AxingTest
    {
        List<MyPoint> Open_List = new List<MyPoint>();
        List<MyPoint> Close_List = new List<MyPoint>();
        byte[,] R;

        //byte[,] R = new byte[10, 10] { 
        //    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        //    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        //    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        //    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        //    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        //    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        //    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        //    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        //    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        //    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
            
        //    };

        public AxingTest(byte[,] R)
        {
            this.R = R;
        }


        //从开启列表查找F值最小的节点
        private MyPoint GetMinFFromOpenList()
        {
            MyPoint Pmin = null;
            foreach (MyPoint p in Open_List)
                if (Pmin == null || Pmin.G + Pmin.H > p.G + p.H)
                    Pmin = p;
            return Pmin;
        }

        //判断一个点是否为障碍物
        private bool IsBar(MyPoint p, byte[,] map)
        {
            if (map[p.y, p.x] == 0) return true;
            return false;
        }

        //判断关闭列表是否包含一个坐标的点
        private bool IsInCloseList(int x, int y)
        {
            foreach (MyPoint p in Close_List)
                if (p.x == x && p.y == y)
                    return true;
            return false;
        }

        //从关闭列表返回对应坐标的点
        private MyPoint GetPointFromCloseList(int x, int y)
        {
            foreach (MyPoint p in Close_List)
                if (p.x == x && p.y == y)
                    return p;
            return null;
        }

        private bool IsInOpenList(int x, int y)
        {
            foreach (MyPoint p in Open_List)
                if (p.x == x && p.y == y)
                    return true;
            return false;
        }

        private MyPoint GetPointFromeOpenList(int x, int y)
        {
            foreach (MyPoint p in Open_List)
                if (p.x == x && p.y == y)
                    return p;
            return null;
        }

        private int GetG(MyPoint p)
        {
            if (p.father == null) return 0;
            if (p.x == p.father.x || p.y == p.father.y)
                return p.father.G + 10;
            else
                return p.father.G + 14;
        }

        private int GetH(MyPoint p, MyPoint pb)
        {
            return Math.Abs(p.x - pb.x)*10 + Math.Abs(p.y - pb.y)*10;
        }

        private void CheckP8(MyPoint p0, byte[,] map, MyPoint pa, ref MyPoint pb)
        {
            for (int xt = p0.x - 1; xt <= p0.x + 1; xt++)
            {
                for (int yt = p0.y - 1; yt <= p0.y + 1; yt++)
                {
                    //排除超过边界和关闭自身的点
                    if((xt>=0&&xt<R.GetLength(0)&&yt>=0&&yt<R.GetLength(1))&&!(xt==p0.x&&yt==p0.y))
                    {
                        //排除障碍点和关闭列表中的点
                        if(map[yt,xt]!=0&&!IsInCloseList(xt,yt))
                        {
                            if (IsInOpenList(xt, yt))
                            {
                                MyPoint pt = GetPointFromeOpenList(xt, yt);
                                int G_new = 0;
                                if (p0.x == pt.x || p0.y == pt.y)
                                    G_new = p0.G + 10;
                                else
                                    G_new = p0.G + 14;

                                if (G_new < pt.G)
                                {
                                    Open_List.Remove(pt);
                                    pt.father = p0;
                                    pt.G = G_new;
                                    Open_List.Add(pt);
                                }


                            }
                            else
                            {
                                //不在开启列表中
                                MyPoint pt = new MyPoint();
                                pt.x = xt;
                                pt.y = yt;
                                pt.father = p0;
                                pt.G = GetG(pt);
                                pt.H = GetH(pt, pb);
                                Open_List.Add(pt);
                            }
                        }
                    }
                }
            }
        }

        public List<MyPoint> FindeWay(MyPoint pa, MyPoint pb)
        {
            List<MyPoint> myp = new List<MyPoint>();
            Open_List.Add(pa);
            while (!(IsInOpenList(pb.x, pb.y) || Open_List.Count == 0))
            {
                MyPoint p0 = GetMinFFromOpenList();
                if (p0 == null) return null;
                Open_List.Remove(p0);
                Close_List.Add(p0);
                CheckP8(p0, R, pa, ref pb);
            }

            MyPoint p = GetPointFromeOpenList(pb.x, pb.y);
            while (p.father != null)
            {
                myp.Add(p);
                p = p.father;
               // R[p.y, p.x] = 3;
            }
            return myp;
        }


    }

MyPoint

    class MyPoint
    {
        public int x;
        public int y;
        public int G;
        public int H;
        public MyPoint father;
        public MyPoint()
        {
        }
        public MyPoint(int x0, int y0, int G0, int H0,MyPoint F)
        {
            x = x0;
            y = y0;
            G = G0;
            H = H0;
            father = F;
        }

        public override string ToString()
        {
            return "{"+x.ToString() + "," + y.ToString()+"}";
        }
    }

       

       

            

               

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/185196.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • latex 公式如何换行

    latex 公式如何换行1、如图所示,我们先写个长公式。2、可以看到,公式没有自动换行,而是跨过了一栏。3、如图所示,在公式上下两端加上split。同时使用\\指明换行的位置。4、如图所示,公式实现了自动换行。5、大家选择换行的位置也很重要。如图所示,选择该处换行6、得到的效果就非常糟糕。承接Matlab、Python和C++的编程,机器学习、计算机视觉的理论实现及辅导,本科和硕士的均可,咸鱼交易,专业回答请走知乎,详谈请联系QQ号757160542,非诚勿扰。…

    2022年5月4日
    317
  • SQL之CASE WHEN用法详解

    SQL之CASE WHEN用法详解简单CASEWHEN函数:CASESCOREWHEN’A’THEN’优’ELSE’不及格’ENDCASESCOREWHEN’B’THEN’良’ELSE’不及格’ENDCASESCOREWHEN’C’THEN’中’ELSE’不及格’END等同于,使用CASEWHEN条件表达式函数实现:CASEWHENSCORE=’A’……

    2022年6月21日
    28
  • 非主流文字生成_非主流文字转换器

    非主流文字生成_非主流文字转换器这是米奥的第01篇笔记作者|米奥来源|米奥笔记ID|miaobiji01为什么要重视排版回想一下,你一般都是在什么场景下来阅读公众号的推文?可能是窝在被窝时、坐公交地铁时、排队吃饭时、工作学习开小差时,甚至是厕所蹲坑时……在这么“将就”的环境下,我们很难高度集中我们的注意力来阅读一篇文章。所以,高颜值的排版要让用户看起来舒服、轻松,而不是花枝招展;另外,在这样的…

    2022年9月25日
    5
  • 《树先生》影评_hello树先生影评分析

    《树先生》影评_hello树先生影评分析1.树先生的母亲对树说:你看二猪都把咱家的地给占了,你也不去说说。这一个情节对应高鹏结婚的时候树先生借着酒劲向二猪说出来那句话:占了俺家的地,也不提前说声。这个会给树带来心理上的压力,就好像作为家

    2022年8月5日
    9
  • HttpClient4模拟表单提交[通俗易懂]

    HttpClient4模拟表单提交[通俗易懂]这里用httpclient4.3模拟一个表单普通文本提交的方法建一个servlet接受表单数据,只传递2个参数,name和password//servlet的访问地址是:http://localhost:80/testjs/servlet/FormServletpublicclassFormServletextendsHttpServlet{publicvoidd

    2022年7月22日
    12
  • 5个常用的MySQL数据库管理工具_SQL工具

    5个常用的MySQL数据库管理工具_SQL工具原文:http://www.techxue.com/techxue-11898-1.html如今,Web应用程序的响应速度是成功的关键法宝之一。它与用户互动,用户对网站的看法,甚至谷歌网站排名情况都有着密不可分的关系。数据库性能是响应速度最重要的因素之一,一旦出错,所有程序都将会宕机。工欲善其事,必先利其器。几乎每一个Web开发人员都有一个最钟爱的MySQL管理工具,它帮助开发人员在许

    2022年8月22日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号