爱因斯坦谜语的编程解法思路

转    自: http://blog.donews.com/grammerliu/archive/2006/05/04/856488.aspx
作    者:程序牛
发表于:2006年05月04日 10:31 PM
 
 
 
爱因斯坦谜语的编程解法思路
在首页上看到 爱因斯坦20世纪初出的谜语 98%人答不出 ,想了一下,发现用图论的思路有希望编程解决。
原体如下:

        1、在一条街上,有5座房子,喷了5种颜色。
  2、每个房里住着不同国籍的人
  3、每个人喝不同的饮料,抽不同品牌的香烟,养不同的宠物
  问题是:谁养鱼?

  提示:
  1、英国人住红色房子
  2、瑞典人养狗
  3、丹麦人喝茶
  4、绿色房子在白色房子左面
  5、绿色房子主人喝咖啡
  6、抽Pall Mall 香烟的人养鸟
  7、黄色房子主人抽Dunhill 香烟
  8、住在中间房子的人喝牛奶
  9、 挪威人住第一间房
  10、抽Blends香烟的人住在养猫的人隔壁
  11、养马的人住抽Dunhill 香烟的人隔壁
  12、抽Blue Master的人喝啤酒
  13、德国人抽Prince香烟
  14、挪威人住蓝色房子隔壁
  15、抽Blends香烟的人有一个喝水的邻居

        五个房子、五种颜色、五个人、五种饮料、五种香烟、五种宠物
        一共是30个节点,每个节点都可以和不属于自己同类的另外25个点建立连接。两点间的连接就代表了两个事物间建立了从属的关系。那么,15个提示就是15个条件,其中1、2、3、5、6、7、8、9、12、13这些条件指名哪些边是确实存在的,而10、11、14、15则隐式的给出哪些边是不存在的,第4条提示不能直接给出有用信息,可以作为验证条件。
        于是,可以先建立一个30*25的矩阵,每个点代表一个边,初值设为UNKNOWN,然后输入条件,第一类条件使得对应的边的值改变为TRUE,第二类条件使得对应边的值变为FALSE。之后,就是在这个矩阵基础之上寻找算法使得30个点恰可以分为5个线性表,并且包含值为TRUE的边,不含值为FALSE的边,找到一组后用第三组条件来验证,如果通过验证则为一组解。
        所以接下来关键就是怎样找出五个线性表了。首先应该找出值为TRUE的点组成的森林中的最长路,从这条路出发,用穷举的方法补全它的顶点。流程大概是:1 找出最长路-〉2 在这条路上增加一个节点,如果成功则进行3,如果失败,则取消最后建立连接的那条边,重复2-〉3 如果路的长度达到最大(6),则将这条路的顶点从顶点集中去除,重复步骤1~3;如果长度小于最大值(6),则重复2、3-〉直道找到五条线性表,输出成功退出;若穷举找不到结果,则输出失败标志返回。

       这个算法基本上和人脑算的思路是一样的,效率很低,不知道有没有什么更高效的算法。我的这个算是抛砖引玉了,等待高手的指导。

你可能感兴趣的:(结构与算法)