QQ超市最佳路径寻路算法改进尝试3
今天是个可喜的日子!
经过一系列的改进,1店5口计算时间从之前的近20分钟减少至99秒……
改进内容如下
1.取消链表搜索:
搜索过程和计算过程中,都需要判断目标节点是否在路径链表中,用的是LinkedList的Contains方法。
这个方法在每次递归循环中调用了0~8次,在面数计算方法中也要调用0~4次。花费的时间绝对不少。
原本先是用List去代替LinkedList,结果花费时间不减反增。
后来才想到应该直接在地图数据上做标记。地图标记原本很复杂,空地、起点、终点,都是不同标记。
干脆把地图数据取出来重新建立一个标记表,不可行走的都是0,可行走都是1,而路径标记为2.
每次入栈做标记,出栈取消标记。
//二次循环,遍历四周可走格子,递归
for (int x = 0; x <= j; x++)//遍历四周可走格子-pach和空位
{
paths.AddLast(dir[x]);//入栈
mapIsTile[dir[x].X, dir[x].Y]=2;//设置标记
searchAll(dir[x]);//递归
paths.RemoveLast();//出栈
mapIsTile[dir[x].X, dir[x].Y] = 1;//改回标记
}
判断节点是否是路径,只需判断该节点标记是否为2即可。
于是,原本20分钟的计算时间缩短为了2分钟。
2.边界节点的方向剪裁:
先看下图
红线部分是什么呢?是边界。
QQ超市大多图都是入口在上边界,出口在左边界上方。这里可以很容易判断出,
如果路径走到右边界,再往上就是死路,左边界往下是死路,下边界往右是死路。
加上这几个判断能否提高速度?虽说心理是有一定把握的,但是提高的幅度还是超出了想象。
120秒提高到99秒。
3.尽量不要调用递归外部的方法:
原本判断边界什么的为了方便都单独写了方法。后面都把它合并到了递归里面。
很多没必要分开的判断都写在了一起。
4.尽量不要在递归里面使用局部变量:
每次递归都会新建变量,出栈后施放变量,一定程度上影响了效率。
没必要的变量都应该放到递归外面声明。
第3~4点都是网上查到的,改善后虽然没具体测试过,不过应该会有点作用。
下面该思考2格货架的面数计算问题了,目前还没什么头绪。