爱因斯坦谜题:谁养鱼的回溯算法解决

      前几天看过该题目的文章:http://www.cnblogs.com/yefanqiu/archive/2009/09/27/1575326.html,当时一时兴趣还在纸上画了好一阵子。此问题从常规算法的角度来说至少可以使用穷举法、回溯法和递归三种算法进行解决。正好现在猪流感闹得厉害,出门不太方便,国庆在家没事的时候正好可以用此题练练手。
      当然,上述三种算法实现的难易程度不同,效果也不同。毫无疑问,使用穷举法实现最容易,但效果也最差。递归算法个人觉得太复杂,因此本人在此使用相对比较容易实现的回溯法予以解决。至于题目的内容本人就不再介绍,首先介绍一下本人的算法思想。

算法思想

      其实算法思想很简单,当然要实现还真不是易事,特别在逻辑排错调试上。
1、首先就是把各个类别信息进行分组(例如国籍放在一组,房子颜色放到一组等等)
2、然后依次从各个类别的分组中取出一个元素放到存放最终结果的数组中。其中对应的元素只能根据其所在的分组而存放到指定的某行中(例如国籍只能存放到结果数组的首行,房子颜色只能存放到次行等等)。存放之前需测试其是否满足条件。
3、如果满足条件则把该元素保存到结果数组中,否则取该元素所在分组余下尚未测试的下一个元素进行测试。
4、如果该元素所在分组余下的所有元素都不满足条件则返回到上一个数组单元继续测试,直到满足条件为止,如果都不满足条件则证明此题无解。
      备注:在本人的解决办法中使用的是按先列后行的次序对结果数组进行操作。

具体实现

1、为方便程序的编写,首先定义一些常量和类

Helper
2、然后声明相关的字段并进行初始化,为操作的方便性考虑本人使用了一个队列数组来保存所有尚未分配的元素
初始化
3、数组越界检测方法
数组越界检测
4、队列过标检测方法与设置数组单元所对应的监哨兵的值的方法
队列过标检测
5、当前组中所有未分配的元素都不满足条件时回到前一个数组单元的状态的方法
返回前一数组单元继续测试
6、对绝大部分规则条件进行测试的辅助方法
规则条件辅助测试方法
7、每个组的规则条件测试方法,测试是否满足插入条件
组规则测试
8、体现算法思想核心的方法
核心算法
9、有了上面一系列的方法,对于主程序的实现就相当简单了:
主程序
程序运行结果:
 

结论

      本题的算法思想虽然简单,但真正实现还真不是容易的事,特别要找出某个逻辑上的错误真的很难。同时在本人的实现方法中只要找到一个解后程序就立即退出,如果要找多个解的话还得对本程序进行很少量的修改,不过本题应该只有唯一解(当然也没有测试过)。此题也应该可以用递归算法实现,不过在纠正逻辑错误上可能还会复杂很多,有兴趣的朋友不妨一试。

源代码:TheEinsteinPuzzle

原文地址:https://www.cnblogs.com/gyche/p/1577426.html