CPU上0.0022S的九宫算法,GPU能更快么?

欢迎大家下载我上传的资源: (内附源码、详细代码注释、测试数据)

源码1:普通IDA*算法实现八数码

源码2:变相IDA*算法实现八数码,这个我得好好说道说道。

 

一大清早地,跟电脑前发愣,突然想知道8/15数码的GPU速度会怎样,毕竟这可是搜索界的极品问题了。先跟网上狂搜一把,“2005年百度之星”的决赛题目,就这个九宫问题,且看冠军得主楼大牛如何在0.0022s的时间内搞定它(请参看源码)。我用了一天的时间来“破译”这段代码,真的实现了零注释哇,总算呕血看完,也添加了详细注释供后来人参考。

 

不得不赞,有几处用地非常巧妙:

1. 在判断九宫问题有无解情况的时候方法巧妙 (countP – disp[b1][b2])%2 = = 0则无解;

2. 楼大牛是这么用地A* + ID思想:死表就是那个hash表,活动表用地好,head[]使得按预估值从小到大迭代加深(ID式)地进行,expand[]按depth深度从小到大BFS进行考查。而不走常规按DFS进行考查,这里BFS深度不超maxp.

3. 从代码中看地出来,楼天成数学功底很强悍,对整数的那些个计算看地我都然了,他在赛场上那么短的时间还…,百度之星当之无愧! 这个比赛为什么叫A星赛,就这个名堂!

 

顺带科普一下A*/ID/IDA*,以下是我的理解,供初学者参考:

普通的A*算法是这么做地:一个活动表,一个死表(均可用Queue/list/heap/hashtable实现),分别用来记录待扩展结点和已经扩展过的结点。在活动表中的结点按预估函数值f(f=g+h)值从小到大排列,取出最小的,放进死表并把其扩展出的结点进行考查,如果扩展出的结点在活动表、死表中均未出现,说明它是新结点,加入活动表;如果在死表中出现,那么不管了;如果在活动表中出现,看它的f值是不是更小,谁小就用谁(毕竟A*是按预估值小的进行启发式搜索地)。上面的过程重复进行直到找到目标。所以总地来说,活动表要支持查找、删除、更新、排序功能;死表要支持查找、插入功能。

 

ID算法将深度设置为dep,对于一个树做深度优先的遍历(节制条件:所有节点的深度不大于dep),如果没有找到目标,那么将dep++,重复上面的过程直到找到目标。

 

IDA*(迭代深度优先)算法在是A*与ID算法的结合物,用了A*算法的预估方法和预估值(f=g+h),用了ID算法的迭代深入(最初从Manhatton距离开始)。较之A*算法,IDA*算法不需要Open表和Closed表,大大节省了内存空间,而且IDA*算法可以不采用递归式程序设计方法,这样也可以节约堆栈空间。 IDA*在进行搜索时,使用耗散值(f=g+h)替代ID中的深度值,在那些不超过给定值的结点中进行DFS,当深度超过一给定阈值时,去掉相应的分支并进行回溯。如果搜索不成功,那么返回头节点,并且使耗散值变大(具体为所有超过上次限定值节点中的最小耗散,在迭代过程中需要纪录那些已经探知的,超过限定的节点的耗散函数值,然后挑选其中的最小值,再次进行搜索)。

 

 下一步就该CUDA大显身手啦。预知效率如何,且听下次分解啦!毕竟GPU实现+优化也是需要点时间的嘛!

你可能感兴趣的:(算法,优化,活动,CUDA,百度,扩展)