谁养鱼

Smile_Tiger 2015-12-28 12:46:54
1. 有5栋5种颜色的房子
  2. 每一位房子的主人国籍都不同
  3. 这五个人每人只喝一个牌子的饮料,只抽一个牌子的香烟,只养一种宠物
  4. 没有人有相同的宠物,抽相同牌子的烟,喝相同牌子的饮料
  已知条件:
  1. 英国人住在红房子里
  2. 瑞典人养了一条狗
  3. 丹麦人喝茶
  4. 绿房子在白房子的左边
  5. 绿房子主人喝咖啡
  6. 抽PALL MALL 烟的人养了一只鸟
  7. 黄房子主人抽DUNHILL烟
  8. 住在中间房子的人喝牛奶
  9. 挪威人住在第一间房子
  10. 抽混合烟的人住在养猫人的旁边
  11. 养马人住在抽DUNHILL烟人的旁边
  12. 抽BLUE MASTER烟的人喝啤酒
  13. 德国人抽PRINCE烟
  14. 挪威人住在蓝房子旁边
  15. 抽混合烟的人的邻居喝矿泉水
  问题:谁养鱼?


我的问题是:如何编程实现?如果用prolog,也请说一下思路,说一下用到的数学方面的知识。

我初步感觉要用到笛卡尔积方面的知识,请高人指点
...全文
567 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
我所讨论的一贯思路,既可以给人工使用也可以给机器使用。但是有些人的做法就不一定了,所以我讨论的内容就会得罪一些人。但是我的目的很明确,为了“开发”而讨论编程思路。而不是为了骂人、或者抬高自己的目的,反而我只会得罪一些说不出编程思路的人。 如果你只想用1分多种来找到第一个答案就够了,那么你在代码中修改成
result = ......Take(1);
就行了。 如此方式,我同时通过代码来表达我的意思,来说明这类简单程序的设计思路,以及人为操作程序流程的地方在哪里。并且也还能通过修改一行代码来DEBUG,这种演示很实用,对每一个真正的编程人员! 如果懒得自己动手看看运行过程,那么其运行结果如下(不保证结果是正确的,欢迎指出程序代码中的bug): 2016/1/5 15:52:13开始查找: 第1个解答 2016/1/5 15:54:53: 挪威人,住1号绿房子,抽混合烟,喝咖啡,养鱼 德国人,住2号蓝房子,抽PRINCE烟,喝矿泉水,养猫 瑞典人,住3号黄房子,抽DUNHILL烟,喝牛奶,养狗 英国人,住4号红房子,抽BLUE_MASTER烟,喝啤酒,养马 丹麦人,住5号白房子,抽PALL_MALL烟,喝茶,养鸟 第2个解答 2016/1/5 16:07:02: 挪威人,住1号绿房子,抽PALL_MALL烟,喝咖啡,养鸟 德国人,住2号蓝房子,抽PRINCE烟,喝矿泉水,养鱼 瑞典人,住3号白房子,抽混合烟,喝牛奶,养狗 丹麦人,住4号黄房子,抽DUNHILL烟,喝茶,养猫 英国人,住5号红房子,抽BLUE_MASTER烟,喝啤酒,养马 第3个解答 2016/1/5 16:07:02: 挪威人,住1号绿房子,抽PALL_MALL烟,喝咖啡,养鸟 德国人,住2号蓝房子,抽PRINCE烟,喝矿泉水,养鱼 英国人,住3号红房子,抽混合烟,喝牛奶,养马 丹麦人,住4号黄房子,抽DUNHILL烟,喝茶,养猫 瑞典人,住5号白房子,抽BLUE_MASTER烟,喝啤酒,养狗 第4个解答 2016/1/5 16:09:19: 挪威人,住1号绿房子,抽PALL_MALL烟,喝咖啡,养鸟 德国人,住2号蓝房子,抽PRINCE烟,喝矿泉水,养猫 瑞典人,住3号白房子,抽混合烟,喝牛奶,养狗 丹麦人,住4号黄房子,抽DUNHILL烟,喝茶,养鱼 英国人,住5号红房子,抽BLUE_MASTER烟,喝啤酒,养马 第5个解答 2016/1/5 16:09:19: 挪威人,住1号绿房子,抽PALL_MALL烟,喝咖啡,养鸟 德国人,住2号蓝房子,抽PRINCE烟,喝矿泉水,养猫 英国人,住3号红房子,抽混合烟,喝牛奶,养马 丹麦人,住4号黄房子,抽DUNHILL烟,喝茶,养鱼 瑞典人,住5号白房子,抽BLUE_MASTER烟,喝啤酒,养狗 第6个解答 2016/1/5 16:09:49: 挪威人,住1号绿房子,抽PALL_MALL烟,喝咖啡,养鸟 德国人,住2号蓝房子,抽PRINCE烟,喝矿泉水,养猫 瑞典人,住3号白房子,抽混合烟,喝牛奶,养狗 英国人,住4号红房子,抽BLUE_MASTER烟,喝啤酒,养马 丹麦人,住5号黄房子,抽DUNHILL烟,喝茶,养鱼 ........................... 下面的输出我省略了,有兴趣的人请自己去安装一个 vs 2015 社区版开发工具,自己去运行一下。
  • 打赏
  • 举报
回复
用几秒钟时间改动一条代码,就可以再次开始运行:
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var result = from p1 in Get个体(国籍.丹麦)
                         where p1.喝 == 饮料.茶
                         from p2 in Get个体(国籍.德国, p1)
                         where p2.抽 == 烟.PRINCE
                         from p3 in Get个体(国籍.挪威, p1, p2)
                         where p3.门牌号 == 1
                         from p4 in Get个体(国籍.瑞典, p1, p2, p3)
                         where p4.养 == 宠物.狗
                         from p5 in Get个体(国籍.英国, p1, p2, p3, p4)
                         where p5.住 == 房子.红
                         let game = new List<个体> { p1, p2, p3, p4, p5 }
                         let 绿房子的人 = game.First(y => y.住 == 房子.绿)
                         let 白房子的人 = game.First(y => y.住 == 房子.白)
                         where 绿房子的人.门牌号 < 白房子的人.门牌号
                         let 抽混合烟的人 = game.First(y => y.抽 == 烟.混合)
                         let 养猫的人 = game.First(y => y.养 == 宠物.猫)
                         where Math.Abs(抽混合烟的人.门牌号 - 养猫的人.门牌号) == 1
                         let 养马的人 = game.First(y => y.养 == 宠物.马)
                         let 抽DUNHILL的人 = game.First(y => y.抽 == 烟.DUNHILL)
                         where Math.Abs(养马的人.门牌号 - 抽DUNHILL的人.门牌号) == 1
                         let 蓝房子的人 = game.First(y => y.住 == 房子.蓝)
                         where Math.Abs(p3.门牌号 - 蓝房子的人.门牌号) == 1
                         let 喝矿泉水的人 = game.First(y => y.喝 == 饮料.矿泉水)
                         where Math.Abs(抽混合烟的人.门牌号 - 喝矿泉水的人.门牌号) == 1
                         let 黄房子的人 = game.First(y => y.住 == 房子.黄)
                         where 黄房子的人.抽 == 烟.DUNHILL
                         where 绿房子的人.喝 == 饮料.咖啡
                         let 中间房子的人 = game.First(x => x.门牌号 == 3)
                         where 中间房子的人.喝 == 饮料.牛奶
                         let 抽BLUE_MASTER的人 = game.First(y => y.抽 == 烟.BLUE_MASTER)
                         where 抽BLUE_MASTER的人.喝 == 饮料.啤酒
                         let 抽PALL_MAL的人 = game.First(y => y.抽 == 烟.PALL_MALL)
                         where 抽PALL_MAL的人.养 == 宠物.鸟
                         select game;
            int cnt = 0;
            Console.WriteLine("{0}开始查找:", DateTime.Now);
            foreach (var g in result)
            {
                Console.WriteLine("第{0}个解答 {1}:", ++cnt, DateTime.Now);
                foreach (var x in g.OrderBy(x => x.门牌号))
                    Console.WriteLine("{0}人,住{1}号{2}房子,抽{3}烟,喝{4},养{5}", x.人, x.门牌号, x.住, x.抽, x.喝, x.养);
                Console.WriteLine();
            }
            Console.WriteLine("{0}结束________________________按任意键结束", DateTime.Now);
            Console.ReadKey();
        }

        /// <summary>
        /// 注意这里的嵌套顺序以及array参数,对用户体验的影响
        /// </summary>
        /// <param name="p">待生成的国籍</param>
        /// <param name="array">要与这些个体不同</param>
        /// <returns></returns>
        private static IEnumerable<个体> Get个体(国籍 p, params 个体[] array)
        {
            var query = from 饮料 c in Enum.GetValues(typeof(饮料))
                        where !array.Any(x => x.喝 == c)
                        from 烟 b in Enum.GetValues(typeof(烟))
                        where !array.Any(x => x.抽 == b)
                        from 宠物 d in Enum.GetValues(typeof(宠物))
                        where !array.Any(x => x.养 == d)
                        from s in Enumerable.Range(1, 5)
                        where !array.Any(x => x.门牌号 == s)
                        from 房子 a in Enum.GetValues(typeof(房子))
                        where !array.Any(x => x.住 == a)
                        select new 个体 { 人 = p, 住 = a, 门牌号 = s, 抽 = b, 喝 = c, 养 = d };
            foreach (var r in query)
                yield return r;
        }
    }

    public class 个体
    {
        public 国籍 人;
        public 房子 住;
        public 烟 抽;
        public 饮料 喝;
        public 宠物 养;
        public int 门牌号;
    }

    public enum 国籍
    {
        英国, 瑞典, 丹麦, 挪威, 德国
    }

    public enum 房子
    {
        红, 白, 绿, 黄, 蓝
    }

    public enum 烟
    {
        PALL_MALL, DUNHILL, BLUE_MASTER, PRINCE, 混合
    }

    public enum 饮料
    {
        茶, 咖啡, 牛奶, 啤酒, 矿泉水
    }

    public enum 宠物
    {
        狗, 鸟, 猫, 鱼, 马
    }
}
其实运行结果并不重要,重要地是把一个可以脱离人工而自动运行的代码写出来了。一旦写出来,那么下一步就可以 DEBUG。 如果没有办法去真正编程,并没有能符合这个论坛所谓“开发”的目的。 运行结果可以自己试打印一下哦!
  • 打赏
  • 举报
回复
嗯,确实是把 p4 变量写到 p3 那个位置去了。
sp1234_maJia 2016-01-03
  • 打赏
  • 举报
回复
给你写一个 c# 语言的控制台代码:
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var result = from p1 in Get个体(国籍.丹麦)
                         where p1.喝 == 饮料.茶
                         from p2 in Get个体(国籍.德国, p1)
                         where p2.抽 == 烟.PRINCE
                         from p3 in Get个体(国籍.挪威, p1, p2)
                         where p3.养 == 宠物.狗
                         where p3.门牌号 == 1
                         from p4 in Get个体(国籍.瑞典, p1, p2, p3)
                         from p5 in Get个体(国籍.英国, p1, p2, p3, p4)
                         where p5.住 == 房子.红
                         let game = new List<个体> { p1, p2, p3, p4, p5 }
                         let 绿房子的人 = game.First(y => y.住 == 房子.绿)
                         let 白房子的人 = game.First(y => y.住 == 房子.白)
                         where 绿房子的人.门牌号 < 白房子的人.门牌号
                         let 抽混合烟的人 = game.First(y => y.抽 == 烟.混合)
                         let 养猫的人 = game.First(y => y.养 == 宠物.猫)
                         where Math.Abs(抽混合烟的人.门牌号 - 养猫的人.门牌号) == 1
                         let 养马的人 = game.First(y => y.养 == 宠物.马)
                         let 抽DUNHILL的人 = game.First(y => y.抽 == 烟.DUNHILL)
                         where Math.Abs(养马的人.门牌号 - 抽DUNHILL的人.门牌号) == 1
                         let 蓝房子的人 = game.First(y => y.住 == 房子.蓝)
                         where Math.Abs(p3.门牌号 - 蓝房子的人.门牌号) == 1
                         let 喝矿泉水的人 = game.First(y => y.喝 == 饮料.矿泉水)
                         where Math.Abs(抽混合烟的人.门牌号 - 喝矿泉水的人.门牌号) == 1
                         let 黄房子的人 = game.First(y => y.住 == 房子.黄)
                         where 黄房子的人.抽 == 烟.DUNHILL
                         where 绿房子的人.喝 == 饮料.咖啡
                         let 中间房子的人 = game.First(x => x.门牌号 == 3)
                         where 中间房子的人.喝 == 饮料.牛奶
                         let 抽BLUE_MASTER的人 = game.First(y => y.抽 == 烟.BLUE_MASTER)
                         where 抽BLUE_MASTER的人.喝 == 饮料.啤酒
                         let 抽PALL_MAL的人 = game.First(y => y.抽 == 烟.PALL_MALL)
                         where 抽PALL_MAL的人.养 == 宠物.鸟
                         select game;
            int cnt = 0;
            Console.WriteLine("{0}开始查找:", DateTime.Now);
            foreach (var g in result)
            {
                Console.WriteLine("第{0}个解答 {1}:", ++cnt, DateTime.Now);
                foreach (var x in g.OrderBy(x => x.门牌号))
                    Console.WriteLine("{0}人,住{1}号{2}房子,抽{3}烟,喝{4},养{5}", x.人, x.门牌号, x.住, x.抽, x.喝, x.养);
                Console.WriteLine();
            }
            Console.WriteLine("{0}结束________________________按任意键结束", DateTime.Now);
            Console.ReadKey();
        }

        /// <summary>
        /// 注意这里的嵌套顺序以及array参数,对用户体验的影响
        /// </summary>
        /// <param name="p">待生成的国籍</param>
        /// <param name="array">要与这些个体不同</param>
        /// <returns></returns>
        private static IEnumerable<个体> Get个体(国籍 p, params 个体[] array)
        {
            var query = from 饮料 c in Enum.GetValues(typeof(饮料))
                        where !array.Any(x => x.喝 == c)
                        from 烟 b in Enum.GetValues(typeof(烟))
                        where !array.Any(x => x.抽 == b)
                        from 宠物 d in Enum.GetValues(typeof(宠物))
                        where !array.Any(x => x.养 == d)
                        from s in Enumerable.Range(1, 5)
                        where !array.Any(x => x.门牌号 == s)
                        from 房子 a in Enum.GetValues(typeof(房子))
                        where !array.Any(x => x.住 == a)
                        select new 个体 { 人 = p, 住 = a, 门牌号 = s, 抽 = b, 喝 = c, 养 = d };
            foreach (var r in query)
                yield return r;
        }

        private static bool 装逼个性(个体 obj, params 个体[] arr)
        {
            for (var i = 0; i < arr.Length; ++i)
            {
                var x = arr[i];
                if (obj.住 == x.住 || obj.养 == x.养 || obj.喝 == x.喝 || obj.抽 == x.抽 || obj.门牌号 == x.门牌号)
                    return false;
            }

            return true;
        }
    }

    public class 个体
    {
        public 国籍 人;
        public 房子 住;
        public 烟 抽;
        public 饮料 喝;
        public 宠物 养;
        public int 门牌号;
    }

    public enum 国籍
    {
        英国, 瑞典, 丹麦, 挪威, 德国
    }

    public enum 房子
    {
        红, 白, 绿, 黄, 蓝
    }

    public enum 烟
    {
        PALL_MALL, DUNHILL, BLUE_MASTER, PRINCE, 混合
    }

    public enum 饮料
    {
        茶, 咖啡, 牛奶, 啤酒, 矿泉水
    }

    public enum 宠物
    {
        狗, 鸟, 猫, 鱼, 马
    }
}
电脑不够强劲。可以看看打印结果
2016/1/3 0:28:54开始查找:
第1个解答 2016/1/3 0:30:32:
挪威人,住1号绿房子,抽混合烟,喝咖啡,养狗
德国人,住2号蓝房子,抽PRINCE烟,喝矿泉水,养猫
瑞典人,住3号黄房子,抽DUNHILL烟,喝牛奶,养鱼
英国人,住4号红房子,抽BLUE_MASTER烟,喝啤酒,养马
丹麦人,住5号白房子,抽PALL_MALL烟,喝茶,养鸟

第2个解答 2016/1/3 0:42:25:
挪威人,住1号绿房子,抽混合烟,喝咖啡,养狗
德国人,住2号蓝房子,抽PRINCE烟,喝矿泉水,养猫
瑞典人,住3号白房子,抽PALL_MALL烟,喝牛奶,养鸟
丹麦人,住4号黄房子,抽DUNHILL烟,喝茶,养鱼
英国人,住5号红房子,抽BLUE_MASTER烟,喝啤酒,养马

第3个解答 2016/1/3 0:42:25:
挪威人,住1号绿房子,抽混合烟,喝咖啡,养狗
德国人,住2号蓝房子,抽PRINCE烟,喝矿泉水,养猫
英国人,住3号红房子,抽PALL_MALL烟,喝牛奶,养鸟
丹麦人,住4号黄房子,抽DUNHILL烟,喝茶,养鱼
瑞典人,住5号白房子,抽BLUE_MASTER烟,喝啤酒,养马

第4个解答 2016/1/3 0:42:57:
挪威人,住1号绿房子,抽混合烟,喝咖啡,养狗
德国人,住2号蓝房子,抽PRINCE烟,喝矿泉水,养猫
瑞典人,住3号白房子,抽PALL_MALL烟,喝牛奶,养鸟
英国人,住4号红房子,抽BLUE_MASTER烟,喝啤酒,养马
丹麦人,住5号黄房子,抽DUNHILL烟,喝茶,养鱼

第5个解答 2016/1/3 0:42:57:
挪威人,住1号绿房子,抽混合烟,喝咖啡,养狗
德国人,住2号蓝房子,抽PRINCE烟,喝矿泉水,养猫
英国人,住3号红房子,抽PALL_MALL烟,喝牛奶,养鸟
瑞典人,住4号白房子,抽BLUE_MASTER烟,喝啤酒,养马
丹麦人,住5号黄房子,抽DUNHILL烟,喝茶,养鱼

2016/1/3 1:02:00结束________________________按任意键结束
忘世麒麟 2016-01-03
  • 打赏
  • 举报
回复
引用 11 楼 baijiaheizhiganmao 的回复:
[quote=引用 4 楼 sp1234 的回复:] [quote=引用 2 楼 baijiaheizhiganmao 的回复:] 高一学集合运算的时候的题目啊。变成程序真的有必要吗?
能编得机器可执行的程序出来,而不是偷工减料地“说”,这才是目的。[/quote] 呵呵![/quote] 通过贬低别人来太高自己,不觉得恶心吗你?每个人都有自己的看法和解法!你何必强求每个人都和你一样~! 得瑟个什么啊!
忘世麒麟 2016-01-03
  • 打赏
  • 举报
回复
引用 4 楼 sp1234 的回复:
[quote=引用 2 楼 baijiaheizhiganmao 的回复:] 高一学集合运算的时候的题目啊。变成程序真的有必要吗?
能编得机器可执行的程序出来,而不是偷工减料地“说”,这才是目的。[/quote] 呵呵!
  • 打赏
  • 举报
回复
比如说给一大堆微积分方程,程序可以“发现”几个新的微积分方程,如果将来你把数据首先带入这些新的推导出来的定理,就能最小化将来的“数据组合爆炸”问题。 这种基于符号规则进行推理和演化,这种能力为特点,才是人工智能。而prolog,其实只是一个很普通的编程工具,根本算不上人工智能工具。
  • 打赏
  • 举报
回复
上面,81~91行驶多余的,本来想在 GetXXX方法中调用,后来它直接自己实现了那个功能。自己删除吧。
  • 打赏
  • 举报
回复
显然,使用“穷举”并不是一个好的智能程序的设计方式,顶多是一种“中庸”的程序。这类程序耗时巨大,而且跟“人”有很大关系。 一个好的智能程序应该高一个层次,它具有信息系统规则的自我规约的能力,可以先在规则方面去解决信息组合爆炸问题,最后才采用自顶向下或者自底向上的数据枚举方式。
  • 打赏
  • 举报
回复
引用 楼主 Smile_Tiger 的回复:
我的问题是:如何编程实现?如果用prolog,也请说一下思路,说一下用到的数学方面的知识。 我初步感觉要用到笛卡尔积方面的知识,请高人指点
你可以把所有的所谓搜索问题,都看作是“笛卡尔积方面的知识”,因此 prolog 其实也不是什么“人工智能”,它也不过是比较容易编写自动“回溯”的数据遍历程序而已。 但是实际编程设计中,其实关键不是在于最低级的数据模型,关键是如何写出既通用又高效的程序。这就是对所谓的“笛卡儿积”的扬弃,产生新的算法模型。 例如,对于“笛卡儿积”,当你遍历了2个人的状态属性之后,第3个人则是又完全枚举一遍所有的“对个人”可能的属性取值,然后等5个人的取值都取到之后,再去消除冲突的取值。 然而优化后的做法,是在你取第三个人的所有可能的属性取值时,当时就去避免与前两个在某个属性上有重复。提前将那些迟早要失败的判断条件“推入深处”,这是常用的优化方法。因此编程时设计时也会去纠结这些。 然而更加高级的智能分析程序,并不是枚举,而是首先对原始规则进行改写,使得将来再来对数据进行枚举的时候能够遇到小一些的信息组合爆炸问题。这其实就是为什么许多人一边随便说什么“高一学集合运算的时候的题目”,一边又用程序根本写不出来智能分析的过程。因为智能分析根本不是什么集合、枚举,所以只会脱离编程去“说”而写不出来程序。 如果能把最后这部分写成程序,那就是不同层次的了。我们要是能用程序写一个真正相当于初中一年级同学的思考模式的人工智能(是真正地图灵测试,具有通用性地解决一大类智力题,而不是那些忽悠人的所谓从一开始就做假、写死规则的程序),那就很了不起了。
  • 打赏
  • 举报
回复
比如说,计算机程序是怎么知道“第一步看条件9的?” 如果根本不能用程序的思维方式来说清楚这个问题,那就肯定是瞎玩编程呢,或者其实就根本没有把编程思维当回事。
  • 打赏
  • 举报
回复
引用 2 楼 baijiaheizhiganmao 的回复:
高一学集合运算的时候的题目啊。变成程序真的有必要吗?
能编得机器可执行的程序出来,而不是偷工减料地“说”,这才是目的。
忘世麒麟 2015-12-31
  • 打赏
  • 举报
回复
由条件9=>挪威人房子在第一个
因为14. 挪威人住在蓝房子旁边 4. 绿房子在白房子的左边  1. 英国人住在红房子里
=> 挪威人住黄房子里面 第二个房子是蓝房子
由养马人住在抽DUNHILL烟人的旁边
=> 养马人住蓝房子 宠物为马
得下图

由 4. 绿房子在白房子的左边
=>绿房子可能在第三个位置,也可能在第四个位置。
假设在第三个位置 则得出绿房子主人喝牛奶和已知条件不符合
则 绿房子应该在第四个位置,白房子在最后一个位置,中间位置是英国人的红房子。根据已知条件补全下图

由:抽混合烟的人的邻居喝矿泉水。那么他可能在第二个房子也可能在第四个房子。假设在第二个房子,那么喝矿泉水的是挪威人(条件15)。又因为条件12,知道喝啤酒的可定是最后一个人,他抽BLUE MASTER。
=>第二个人喝茶,是个丹麦人
=>德国人在第四个房子里
=>最后一个是瑞典人
补全信息得下表

因此养鱼的是德国人。
其他假设不论述
忘世麒麟 2015-12-31
  • 打赏
  • 举报
回复
高一学集合运算的时候的题目啊。变成程序真的有必要吗?
Smile_Tiger 2015-12-28
  • 打赏
  • 举报
回复
一时手误。。。。未设置分数为100分,请谅解

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧