一百行Ruby写个A*

A* in Ruby

Ruby quiz的第98题让写一个A*寻路程序。Daniel Martin提供了一个不到两百行的解答。如果简化一下,完全可以在一百行以内实现。

 

 

在Daniel的程序里,do_quiz_solution()是个外壳,它做三件事:找到起止点的坐标(@start和@goal),把puzzle解析成数值矩阵(存在@terrain中),把puzzle转换成没有空格的规范形式存进instr以便后面利用它把路径打印出来。

核心的部分是do_find_path()。这里需要用到优先队列PriorityQueue。优先队列的元素也是一个复合结构:[优先级, [当前考察的点, 到达该点的最佳路径, 目前花费的代价]]。

 

 

下面来看看如何实现优先队列:

优先队列可以看成一个半序的容器,它每次抛出优先级最低(或最高)的元素。优先队列一般是用堆(一种满足特定规则的完全二叉树)来实现的,但这里因为优先队列不是重点,Daniel利用Ruby内置的sort函数实现了一个简单,而且性能不咋地的优先队列。

@list是个数组。每次在add新元素时,会把优先级信息也一并记录下来。另外,为了区分相同优先级的元素,add()还会悄悄把该元素是第几个加入队列的元素也写进去,即

 

然后sort!,保证数组按优先级进行排列。

接着来看看估价函数,它用来评估当前所在的位置到目标点的尽可能大的下界(最好比实际代价小)。在这里,由于允许走斜线,只需考虑当前点与目标点横纵坐标差的最大值即可。

 

还有一个辅助函数spotfrom(),用来生成当前点周围没访问过的邻居。

 

最后,我们来看看它是怎么把杂乱的字符串规整成标准形式的,以及又是如何依据规范字符地图生成二位数值矩阵的。

逐行分析输入的字符串:

  • 遇到由纯空白符构成的行(/^/s*$/)就跳过;
  • 替换掉所有非.@~X*^符号; ;
  • 逐字分析
    • 根据题设在数值矩阵的相应位置写入相应的代价 

题目里有个测试地图。我想把结果用图的形式显示出来,对Ruby 这方面的库又不熟,只好用Python了(需要用到matplotlib)。

 

P.S. 果然不习惯Python的语法。

large test map

红色表示水塘,不能通过。

这是结果:

large test map solution

好丑,还不如ASCII码:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值