现有题号称爱因斯坦出的智力题全世界只有2%能够做出。
------------------------------------------------
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香烟的人有一个喝水的邻居
为了便于消除翻译的误差,先将英文版本贴出:
Let us assume that there are five houses of different colors next to each other on the same road. In each house lives a man of a different nationality. Every man has his favorite drink, his favorite brand of cigarettes, and keeps pets of a particular kind.
- The Englishman lives in the red house.
- The Swede keeps dogs.
- The Dane drinks tea.
- The green house is just to the left of the white one.
- The owner of the green house drinks coffee.
- The Pall Mall smoker keeps birds.
- The owner of the yellow house smokes Dunhills.
- The man in the center house drinks milk.
- The Norwegian lives in the first house.
- The Blend smoker has a neighbor who keeps cats.
- The man who smokes Blue Masters drinks bier.
- The man who keeps horses lives next to the Dunhill smoker.
- The German smokes Prince.
- The Norwegian lives next to the blue house.
- The Blend smoker has a neighbor who drinks water.
The question to be answered is: Who keeps fish?
~
现在请你用c#写出解这个问题的程序!
相信不少人对此题的第一个想法是通过暴力算法穷举所有可能让计算机进行求解。如果是这样那么你不用辛苦了,下面早就有人这么干过了:
暴力算法解益智题(c#2.0版本):http://www.webasp.net/article/27/26094.htm
C#轻松解决世纪迷题 :http://tech.ccidnet.com/pub/article/c1081_a94061_p1.html
这些解法虽然都是对的,但是正如有人评论道:用笔解这题时候可比用程序看起来省力多了........算的上“轻松”吗?
在这里我向大家隆重推荐香港城市大学计算机科学院的陈汉伟博士(Dr. Andy Chun, Hon Wai)的人工智能工具 NSolver
用NSolver如何解决问题?
先举一个简单的例子:
IQ 题:
农场里有兔子和鸡若干只,知道共20个头和56条腿。问兔子和鸡各多少只?
用c#来解这个问题,可能是:
using System;
public class Rabbit
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public int rabbit = 0;
public int pheasant = 0;
public void Run()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
for (rabbit = 0; rabbit<=20; rabbit++)
for (pheasant = 0; pheasant<=20; pheasant++)
if (rabbit+pheasant==20
&& rabbit*4+pheasant*2==56)
Console.WriteLine(
"Rabbit["+rabbit+"] Pheasant["+pheasant+"]");
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public static void Main()
{(new Rabbit()).Run();}
}
有什么不足?
1、没有变量/未知量的概念
2、没有什么值合法什么不合法的概念(问题域)
3、没有变量间的关系/约束概念
4、所有都Hardcode了,不能扩展到更复杂的问题
5、暴力破解穷举
比较一下NSolver的解法:
using ai.net.Solver;
using System;
public class Rabbit : Solver
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public Var rabbits, pheasants;
public void Run()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
rabbits = var(0, 20, "Rabbits");
pheasants = var(0, 20, "Pheasants");
Post(rabbits.Sum(pheasants).Eq(20));
Post(rabbits.Prod(4).Sum(pheasants.Prod(2)).Eq(56));
Console.WriteLine(rabbits+" "+pheasants);
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public static void Main()
{(new Rabbit()).Run();}
}
现在用NSolver解决爱因斯坦问题:
using System;
using System.Text;
using ai.net.Solver;
using System.Diagnostics;
using System.Collections;
![](/Images/OutliningIndicators/None.gif)
class Einstein : Solver
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public void Run()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// the 房子s
Var 红房子 = var(0, 4, "红房子");
Var 绿房子 = var(0, 4, "绿房子");
Var 白房子 = var(0, 4, "白房子");
Var 黄房子 = var(0, 4, "黄房子");
Var 蓝房子 = var(0, 4, "蓝房子");
VarList all房子s = varList(红房子, 绿房子, 白房子, 黄房子, 蓝房子);
![](/Images/OutliningIndicators/InBlock.gif)
// nationalities
Var 英国人 = var(0, 4, "英国人");
Var 瑞典人 = var(0, 4, "瑞典人");
Var 丹麦人 = var(0, 4, "丹麦人");
Var 挪威人 = var(0, 4, "挪威人");
Var 德国人 = var(0, 4, "德国人");
VarList allNationalities = varList(英国人, 瑞典人, 丹麦人, 挪威人, 德国人);
![](/Images/OutliningIndicators/InBlock.gif)
// beverages
Var 茶 = var(0, 4, "茶");
Var 咖啡 = var(0, 4, "咖啡");
Var 牛奶 = var(0, 4, "牛奶");
Var 啤酒 = var(0, 4, "啤酒");
Var 矿泉水 = var(0, 4, "矿泉水");
VarList allBeverages = varList(茶, 咖啡, 牛奶, 啤酒, 矿泉水);
![](/Images/OutliningIndicators/InBlock.gif)
// cigarettes
Var pallMall = var(0, 4, "Pall Mall");
Var dunhill = var(0, 4, "Dunhill");
Var 混合烟 = var(0, 4, "混合烟");
Var BlueMasters = var(0, 4, "BlueMasters");
Var Prince = var(0, 4, "Prince");
VarList allCigs = varList(pallMall, dunhill, 混合烟, BlueMasters, Prince);
![](/Images/OutliningIndicators/InBlock.gif)
// pets
Var 狗 = var(0, 4, "狗");
Var 鸟 = var(0, 4, "鸟");
Var 鱼 = var(0, 4, "鱼");// <-- Who owns the 鱼?
Var 马 = var(0, 4, "马");
Var 猫 = var(0, 4, "猫");
VarList allPets = varList(狗, 鸟, 鱼, 马, 猫);
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
// More clues
Post(红房子.Eq(英国人));
Post(狗.Eq(瑞典人));
Post(茶.Eq(丹麦人));
//The 绿 房子 is on the left of the 白 房子
Var gLeft = 白房子.Diff(绿房子);
gLeft.SetRange(0, 1);
Post(gLeft.Neq(0));
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
Post(绿房子.Eq(咖啡));
Post(pallMall.Eq(鸟));
Post(黄房子.Eq(dunhill));
Post(牛奶.Eq(2));
Post(挪威人.Eq(0));
![](/Images/OutliningIndicators/InBlock.gif)
Var 混合烟Vs鱼 = 鱼.Diff(混合烟);
混合烟Vs鱼.SetRange(-1, 1);
Post(混合烟Vs鱼.Neq(0));
![](/Images/OutliningIndicators/InBlock.gif)
Var 马VsDunhill = 马.Diff(dunhill);
马VsDunhill.SetRange(-1, 1);
Post(马VsDunhill.Neq(0));
![](/Images/OutliningIndicators/InBlock.gif)
Post(BlueMasters.Eq(啤酒));
Post(Prince.Eq(德国人));
![](/Images/OutliningIndicators/InBlock.gif)
Var 蓝Vs挪威人 = 蓝房子.Diff(挪威人);
蓝Vs挪威人.SetRange(-1, 1);
Post(蓝Vs挪威人.Neq(0));
![](/Images/OutliningIndicators/InBlock.gif)
Var 混合烟Vs矿泉水 = 混合烟.Diff(矿泉水);
混合烟Vs矿泉水.SetRange(-1, 1);
Post(混合烟Vs矿泉水.Neq(0));
![](/Images/OutliningIndicators/InBlock.gif)
Post(AllDiff(all房子s));
Post(AllDiff(allNationalities));
Post(AllDiff(allBeverages));
Post(AllDiff(allCigs));
Post(AllDiff(allPets));
![](/Images/OutliningIndicators/InBlock.gif)
Activate(all房子s);
Activate(allNationalities);
Activate(allBeverages);
Activate(allCigs);
Activate(allPets);
![](/Images/OutliningIndicators/InBlock.gif)
while (NextSolution())
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Console.WriteLine(allNationalities);
Console.WriteLine(all房子s);
Console.WriteLine(allBeverages);
Console.WriteLine(allCigs);
Console.WriteLine(allPets);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public static void Main()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Einstein solver = new Einstein();
solver.Run();
}
}
看看这一行行代码吧,多么简洁易懂! 现在你要做的就是陈述问题,NSolver帮你做剩下的!
延伸阅读
http://sc.info.gov.hk/gb/www.ugc.edu.hk/rgc/rgcnews9/Pages/6%20AI-C.html
NSolver的好处就是,它不仅仅能解决这个爱因斯坦的问题,它所能解决的是属于一个叫做“Constraint Satisfaction Problems”的一大堆问题。
我这里再给大家出个类似的题目,请你用NSolver来解决它:
Our problem consists of three mice living next to each other in three holes in the wall. Each mouse has a favorite cheese flavor and a favorite TV show. Here are the hints:
- Mickey Mouse loves Gouda
- Mighty Mouse's favorite TV show is Emergency Room
- The mouse that lives in the left hole never misses an episode of Seinfeld
- Mickey Mouse and Mighty Mouse have one mouse hole between them
- The Simpsons fan does not live on the left of the Brie lover