寻路算法和逻辑算法之间异同点都有哪些

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了寻路算法和逻辑算法之间异同点都有哪些相关的知识,希望对你有一定的参考价值。

寻路算法和逻辑算法之间异同点: 
寻路算法也可以通过深度优先遍历 dfs 实现,寻找图 graph 从起始 s 点到其他点的路径,在上一小节的实现类中添加全局变量 from数组记录路径,from[i] 表示查找的路径上i的上一个节点。
 逻辑算法又称布尔运算,通常用来测试真假值,由于布尔在符号逻辑运算中的特殊贡献,很多计算机语言中将逻辑运算称为布尔运算,用来判断是否该离开循环或继续执行循环内的指令,并由二维逻辑运算发展到三维图形的逻辑运算。
参考技术A 关于寻路算法和逻辑算法之间异同点有哪些相关资料如下
算法=逻辑+控制 (来源这里)

算法可以被视为由逻辑和控制组成,逻辑指用于解决问题的知识;控制组件则确定解决问题的策略,也就是说,应该使用哪个知识。

逻辑能确定算法的含义,而控制仅能影响其效率,通过改进控制组件而不改变算法的逻辑,通常可以提高算法的效率。

小白学游戏常用算法一随机迷宫算法

  现在的很多游戏中的地图一般采用格子的方式,虽然在表面地图上无法看到实际的格子,但是在地图的结构中专门有一个逻辑层,这个层和地图大小相等,划出很多小的格子,然后在可以通过的地方使用0表示,在有障碍的且不能通过的地方用1或者其他数字表示(如图所示)。有了这个逻辑层之后,实际上自动寻路就转换成了如何在一个二维数组中找出一条从逻辑值为0的地点移动到目标的路径。在寻路之前,我们首先要随机生成这些地图。

                                                                               

                             游戏中地图      二维数组逻辑层

  本质上,地图的障碍逻辑层是由一个二维数组保存的。障碍标记在二维数组中的数据值以0或者1表示,我们首先需要做的就是随机产生这样的二维数组。当然,最简单的办法就是循环这个二维数组,然后在每一个位置随机地产生0或者1,但是这种算法产生的图形比较难看,并且不一定保证图中的任意两点可以相连通。

  在随机生成的迷宫中要求任意两点,都可以找到一条路径相通,所以在图论中可以认为迷宫就是一个连通图。产生连通图的常见方法有克鲁斯卡尔和普利姆算法,这里我们以普利姆算法为例实现一下,使用普利姆算法产生的迷宫比较自然和随机。

                           

  (1)如上图所示为一个6x6的迷宫,先假设迷宫中所有的通路都是完全封闭的,黄色的格子表示可以通过,黑色的格子表示墙壁或者障碍不能通过。

  (2)随机选择一个黄色的格子作为当前正在访问的格子,同时把该格子放入一个已经访问的列表中。

  (3)循环以下操作,直到所有的格子都被访问到。

     1.得到当前访问格子的四周(上下左右)的格子,在这些格子中随机选择一个没有在访问列表中的格子,如果找到,则把该格子和当前访问的格子中间的墙打通(置为0),把该格子作为当前访问的格子,并放入访问列表。

     2.如果周围所有的格子都已经访问过,则从已访问的列表中,随机选取一个作为当前访问的格子。

   通过以上的迷宫生成算法,可以生成一个自然随机的迷宫、

  下面使用代码实现一个R行N列大小的随机迷宫,R行表示的是刚开始空白格子的行数,而格子之间还有墙壁和障碍物,所以最终产生的二维数组大小实际为2R+1 * 2N+1

 1 //产生随机迷宫
 2 primMaze:function(r,c)
 3 {
 4          //初始化数组
 5          function init(r,c)
 6          {
 7              var a = new Array(2*r+1);
 8             //全部置1
 9             for(var i=0,len=a.length;i<len;i++)
10             {
11                 var cols = 2*c+1;
12                 a[i]= new Array(cols);
13                 ArrayUtil.fillWith(a[i],1);
14             }
15             //中间格子为0
16             for(var i=0;i<r;i++)
17                 for(var j=0;j<c;j++)
18                 {
19                     a[2*i+1][2*j+1] = 0;
20                 }
21                 return a;
22         }
23          //处理数组,产生最终的数组
24          function process(arr)
25          {
26            //acc存放已访问队列,noacc存放没有访问队列
27            var acc = [],noacc = [];
28            var r = arr.length>>1,c=arr[0].length>>1;
29            var count = r*c;
30            for(var i=0;i<count;i++){noacc[i]=0;}
31            //定义空单元上下左右偏移
32            var offs=[-c,c,-1,1],offR=[-1,1,0,0],offC=[0,0,-1,1];      
33            //随机从noacc取出一个位置
34            var pos = MathUtil.randInt(count);
35            noacc[pos]=1;
36            acc.push(pos);       
37            while(acc.length<count)
38            {        
39                var ls = -1,offPos = -1;
40                offPos = -1;
41              //找出pos位置在二维数组中的坐标
42              var pr = pos/c|0,pc=pos%c,co=0,o=0;
43              //随机取上下左右四个单元
44              while(++co<5)
45              {
46                  o = MathUtil.randInt(0,5);
47                  ls =offs[o]+pos;
48                  var tpr = pr+offR[o];
49                  var tpc = pc+offC[o];           
50                  if(tpr>=0&&tpc>=0&&tpr<=r-1&&tpc<=c-1&&noacc[ls]==0){ offPos = o;break;}           
51              }                 
52              if(offPos<0)
53              {
54 
55                  pos = acc[MathUtil.randInt(acc.length)];
56              }
57              else
58              {
59                  pr = 2*pr+1;
60                  pc = 2*pc+1;
61                 //相邻空单元中间的位置置0
62                 arr[pr+offR[offPos]][pc+offC[offPos]]=0;
63                 pos = ls;  
64                 noacc[pos] = 1;
65                 acc.push(pos);
66             }        
67         }
68     }
69     var a = init(r,c);
70     process(a);
71     return a;
72 }

利用上面的算法我们就可以实现一个类似于下面的随机迷宫了。

有了随机迷宫就得开始寻路了,下一篇的博客中我们将一起学习一下最常见的A*寻路算法。

 

 

   

以上是关于寻路算法和逻辑算法之间异同点都有哪些的主要内容,如果未能解决你的问题,请参考以下文章

教程翻译-理解基于矢量场寻路算法

迷宫寻路系列常用算法逻辑探究

js寻路算法

PHP树生成迷宫及A*自己主动寻路算法

动态BGP与静态BGP相比的优势都有哪些

A*寻路算法的实现