愛因斯坦有一道思考題,據說世界上只有2%的人可以解答。
題目是這樣的,據說有五個不同顏色的房間排成一排,每個房間裡分別住著乙個不同國籍的人,每個人都喝一種特定品牌的飲料,抽一種特定品牌的煙,養一種寵物,沒有任意兩個人抽相同品牌的香菸,或喝相同品牌的飲料,或養相同的寵物,問題是誰在養魚作為寵物?為了尋找答案,愛因斯坦給出了十五條線索:
(1)、英國人住在紅色的房子裡;
(2)、瑞典人養狗作為寵物;
(3)、丹麥人喝茶;
(4)、綠房子緊挨著白房子,在白房子的左邊;
(5)、綠房子的主人喝咖啡;
(6)、抽pall mall牌香菸的人養鳥;
(7)、黃色房子裡的人抽dunhill牌香菸;
(8)、住在中間那個房子裡的人喝牛奶;
(9)、挪威人住在第乙個房子裡面;
(10)、抽blends牌香菸的人和養貓的人相鄰;
(11)、養馬的人和抽dunhill牌香菸的人相鄰;
(12)、抽bluemaster牌香菸的人和啤酒;
(13)、德國人抽prince牌香菸;
(14)、挪威人和住在藍房子的人相鄰;
(15)、抽blends牌香菸的人和喝礦泉水的人相鄰。
這道題是一道邏輯推理題,按照我們常人的思維就是拿出一張紙和一支筆,然後用假設法慢慢去推倒,但是也肯定要想很久。
於是我們想到了把推理的過程交給計算機去做,但是怎麼做呢?計算機不會思考?
計算機不會思考,但是會計算,我們可以讓計算機算出最終答案。
解題思路:1.窮舉所有的組合結果 2.對結果進行判斷
多維窮舉演算法:
整個演算法的過程就是這兩個核心的整合。
先建立數學模型:把問題抽象成乙個二維陣列,data[i][j],其中下標i代表大類(房子顏色、寵物等),j代表的是小類(綠色、藍色、貓和狗等)。
然後通過多個遞迴排列組合演算法進行窮舉。
結果判斷:
結果判斷分成三大類,一類是組內關係繫結,第二類是組間關係繫結,第三類是過濾線索。
組內關係繫結是乙個屬性型別和乙個值繫結,如:綠房子的主人喝咖啡,丹麥人喝茶。
組間關係繫結是乙個組和相鄰的組之間產生關係,如:挪威人住在藍房子的人相鄰,抽blends牌香菸的人和喝礦泉水的人相鄰。
過濾類線索是很難歸為一二類繫結關係的判斷條件,我們只能通過在窮舉演算法中過濾掉。
所以這對我來說也是乙個巨大的挑戰,但是我最終戰勝了困難,解出了這道題。
下面一張圖是**執行出現結果的圖,我對照了書上的最終結果,完全正確:
將近兩億個列舉,我的演算法不夠好,用了接近15秒的時間才解出這道題。
下面是我的實現**:
test類是主類,用於啟動程式
package 二維窮舉愛因斯坦的思考題_待完成;
public class test ;
public static int count;
public static int judge1;
public static int judge2;
public static void main(string args)
public void initmain()
}
think類是多維窮舉演算法實現類,用於窮舉排列組合:
package 二維窮舉愛因斯坦的思考題_待完成;
public class think;
public int j;
public think(),,,
,};public static int count;
public static boolean judge1(int data)
}
outoffrouprelation類給定組間關係:
package 二維窮舉愛因斯坦的思考題_待完成;
public enum outoffrouprelation
}
這就是我這幾天做的多維窮舉演算法。
我覺得學習演算法一定要思路清晰,頭昏腦漲的時候最好不要學習演算法,因為那時候效率很低,往往學不到東西,還浪費時間。
作者部落格:
演算法系列之七 愛因斯坦的思考題
據說有五個不同顏色的房間排成一排,每個房間裡分別住著乙個不同國籍的人,每個人都喝一種特定品牌的飲料,抽一種特定品牌的煙,養一種寵物,沒有任意兩個人抽相同品牌的香菸,或喝相同品牌的飲料,或養相同的寵物。問題是誰在養魚作為寵物?為了尋找答案,愛因斯坦給出了以下 15 條線索。英國人住在紅色的房子裡 瑞典...
演算法系列之七 愛因斯坦的思考題(下)
checkgrouprelation 函式需要根據當前組group的位置進行適當的處理,如果當前組是第乙個組或最後乙個組,則group的相鄰組只有乙個,就是最靠近group的組,其它情況下group的相鄰組都是兩個。checkgrouprelation 函式的實現如下 162bool checkgr...
演算法系列之七 愛因斯坦的思考題(下)
checkgrouprelation 函式需要根據當前組group的位置進行適當的處理,如果當前組是第乙個組或最後乙個組,則group的相鄰組只有乙個,就是最靠近group的組,其它情況下group的相鄰組都是兩個。checkgrouprelation 函式的實現如下 162boolcheckgro...