《圍棋與電腦》我7年前在棋人棋事論壇的未完成之作。本打算寫5部分,當時因對第三部分不滿意而暫時擱筆,於是便再懶得動手寫,但這篇未完成之作卻被到處轉帖。
現在,我打算把這篇文章最終完成,並對前面做一定的修改。同時,也希望
這篇文章能夠在比較正式的場合發表。
一 從地球到月球
從電腦誕生之日起,人們對於電腦就充滿了幻想。尤其是在人工智慧上,對於電腦超過人腦,有人興奮,有人擔憂,但曾經幾乎所有人都認為這會是真的。尤其當“深藍”擊敗卡斯帕羅夫之後,人們已經開始擔憂,電腦超過人腦,會不會就發生在明天?
但這種擔憂實在是來的太早了。
本世紀七八十年代,對人工智慧學家們來說,就象是無憂無慮的童年。他們雄心勃勃,甚至排出了電腦替代人腦的時間表。在表中,現在,就已經應該是電腦超過人腦的日子了。現在,“深藍”確實戰勝了卡斯帕羅夫,但人工智慧學家們的時間表早已被拋到了腦後。有人甚至打了這樣一個比喻來說明人工智慧上所取得的成就:人們想登上月球,他們造了一個梯子,用這個梯子爬上了一棵樹,然後自豪地宣稱:“現在,我們已向月球前進了一大步!”
現在,電腦已經滲入到了我們生活的各個方面,在生產和生活中,我們已經有些難以想象脫離電腦的狀況了,如果說這些形形色色的電腦只不過是花裡胡哨的各種梯子,似乎實在是說不過去。
我們先看看梯子是怎麼回事吧。
梯子的發明人是圖靈博士。圖靈在考慮可計算的機器的性質時,首先是設想一個人在計算,他把這個人的計算行為抽象成了這樣一台機器:有一條無窮長的紙帶子,一個有很多狀態的機器在紙帶上左右滑動,並且可以根據所讀到的內容改變自己的狀態或者改寫紙帶的內容。這就是大名鼎鼎的圖靈機了。當前的所有電腦,在理論上都是可以被圖靈機類比的。
請注意圖靈機有一個重要的能力:改寫紙帶的能力。如果沒有這個能力,那這台機器叫做有窮自動機。它和圖靈機間的計算能力差著三個檔次呢。(注意:在一條無窮長的紙帶上讀東西,在另一條紙帶上寫東西的機器也是有窮自動機)。
判斷這些東西的計算能力用的是這些機器所能接受的語言的概念 。這個語言雖然是抽象的語言,但也和我們平時所說的語言差不多,你只要理解成這機器能聽懂什麼話也就差不太多了。喬姆斯基把語言分成了0, 1,2 , 3四個等級,0 級能力最強,3 級最差。這四個等級之間有著難以逾越的鴻溝。
這裡的 3級語言也叫做正規語言,就是有窮自動機能聽懂的, 2級語言叫做上下文無關語言,意思是一個詞,不用管它的上下文,就可以聽懂了。1 級語言就是上下文相關的了,也就是說機器還得揣摩這話前後的意思。零級語言就是圖靈機可以接受的語言了。
我們用數數的本事就可以體會1,2,3 型語言的能力差別了。
對於數數,有這麼一個笑話:兩個貴族比賽,看誰說出的數更大,第一個人絞盡腦汁,冥思苦想十幾分鐘後說:3, 輪到第二個人,他想了很久很久,最後說:你贏了。
數到 3 的本事哪型語言都會,我這裡說的數數本事是從一數起,只要不老死,數多少個都行。3 型語言,也就是正規語言,是不會數數的。 2 型語言(上下文無關語言)會數數,但同時數兩個數就不會了。1 型語言就是數多少個數都行的了。而 0型語言的能力又比 1型語言強的多。也就是說,圖靈機看上去簡單,實際上是還是很牛的。
但是圖靈自己就發現了圖靈機也有不照的時候了,這就是圖靈機的停機問題。我們可以這樣說明圖靈機的停機問題:假設當圖靈機聽懂了一句話,它就不再琢磨這句話了,現在我給圖靈機一句話,問它“你聽的懂嗎?”如果它聽的懂,它會回答“是”,但如果它聽不懂,很可能它永遠也不會知道自己聽不懂。
二 有窮與無窮
用天梯登上月球的想法,現代人也許會覺得荒謬,但在古人眼裡,未必如此.梯子可以上樹,可以上房,可以上城,甚至可以上山,為什麼不能上天呢?
因為做梯子的原材料數量不夠,強度不夠,天梯也沒有可搭的地方,等等等等,但古人都不清楚,他們根本不知道地球和月球之間有多遠.
國際象棋八八六十四見方的棋盤,圍棋縱橫361交叉點的棋秤,它們的變化從理論上說是有限的,因此,理論上,這些問題都是圖靈機可解決的。但是,就在我們理論上嚴謹地一步步得出結論時,我們早已不知不覺地越過了在實際計算意義上有窮與無窮的界限。
以圍棋為例,圍棋有多少種變化?在此,有兩種估計方法,一是:假設不會出現大家都被提光再從頭再來的情況,那麼,第一步有361種選擇,第二步有360種選擇,以後的情況大致如此,我們就以361為界,那麼變化數是361!,約為10的768次方。另一種估計方法大概是宋朝的沈括老先生首先使用的:棋盤上每個點有黑,白,空三種狀態,所以圍棋變化數是3的361次方,約為10的172次方,用沈老先生的說法,就是“連書‘萬’字四十三”。這雖然也很大,但比起前面的估計值來,小的實在是太多了。如果這種估計正確,那電腦下圍棋無疑輕鬆了許多。
不幸的是,沈老先生的估計方法是錯誤的。他只考慮了這種種狀態,卻沒有考慮這些狀態間的相互關係。就比如數學中的圖,沈老先生只考慮了頂點的總數,卻忘了把串連頂點的邊算進去了。
如果我們不考慮邊,就考慮這“連書‘萬’字四十三”的狀態,如果我可以對於每個狀態都精確地算出價值的話,那麼電腦只需要查價值表就可以確定該怎樣下棋了,這樣,電腦需要儲存的變化數也就是“連書‘萬’字四十三”,但問題是,這些價值是怎麼算出來的?總不會看到一個狀態之後就能猜出它的價值吧。因此,假設有一個電腦圍棋機器,雖然在執行的時候他可以只考慮不同狀態
的價值,但為了造這台機器,我們還得把所有這些狀態的關係都考慮進去。
按照第一種估計方法得到的10的768次方又是個什麼概念呢?宇宙中所有基本粒子的總數,據估計,為10的80次方,如果沒有一些簡化計算的措施,這比宇宙中粒子總數還要大數不清倍的數字對我們來說,又和無窮有什麼區別? ( 這意味著把已知全部宇宙的物質做成記憶體,每個原子,乾脆,每個夸克儲存一種狀態,都是遠遠不夠的——nn_1997 )
其實,連第一種估計方法都是錯誤的.圍棋真正的變化數,連10的(3的361次方)次方都擋不住,大學學曆的人都清楚,一旦出現指數天梯,那這個數字有多大已經是不可想象的了.
這一點並不能說明圍棋不是圖靈機實際可解的. 不過 至少告訴我們,遍曆的方法是不可行的 .所以,我們暫時把圍棋的狀態當作無窮來看.
在這裡,我們用准無窮來稱呼到達實際不可計算程度的狀態數.
人們在談到圍棋與國際象棋的比較時,總說圍棋的變化遠多於國際象棋。但如果把這作為電腦下圍棋遠難於下國際象棋的原因是不充分的,並不是狀態越多的東西越複雜,況且國際象棋的變化同樣也是天文數字 。
但是,如果把國際象棋的棋盤放大,棋子增多,使它的變化從絕對數值上來說接近甚至超過圍棋,國際象棋還是只能給人以國際象棋的感覺而不是圍棋的感覺。因為, 它們的“文法”有著本質的不同 。
現在,我們考慮這樣一個問題:國際象棋和圍棋走子後棋局狀態的變化,分別需要判斷幾個位置上的狀況?
國際象棋當我落下一子時,只要考慮落子點的狀態就可以了,如果這裡有我自己的子,這步落子無效,如果這裡有敵人的子,敵子被我吃掉,如果這裡空白,那麼僅僅是棋子的移位.象王車易位,吃過路兵等情況,我們可以把它看作可以遍曆的特例而暫時不予考慮.
讓我們回想一下喬姆斯基四級語言中的2級:上下文無關語言.當排除了特殊情況之後,我們可以認為,既然國際象棋棋局某格的狀態變化與周圍無關,那麼,它應當是可以被能聽懂(專業上叫接受)2級語言的機器聽懂的.我們可以把國際象棋理解成一個上下文無關語言.
回到圍棋,當我們落下一子時,棋盤會變成什麼樣?如果周圍全是敵子,有些敵子沒了氣,那敵子全部拿走,如果周圍有自己的子,敵子沒被拿走,自己的子反而沒了氣,那就是自填死.
聽起來好象也很簡單,但棋盤的變化是需要看周圍的情況而決定的,如果只看落子點的狀態,那我們什麼結論也得不到.也就是說,圍棋不能用上下文無關語言來等價,至少也得用上下文有關語言,就是會數很多數的1級語言.
在考慮圍棋變化數的時候,劫可是不能不提.有人說"劫乃圍棋精華",可對於1型語言來說,劫實在是要命的東西.1型語言的基本要求是它的語言產生式左邊不長於右邊,但對於劫來說,並非如此.有了劫,就意味著1型語言也接受不了圍棋了.
更要命的還在後面.象三劫迴圈,四劫迴圈,長生劫等等,在現在的圍棋規則中,都簡單地判為"無勝負",其實,如果用"全域同型禁止再現",都可以從理論上解決,並且也不如人們想象中的那麼複雜(以後我可能會另寫文章介紹多劫迴圈的規律).全域同型禁止再現也很圓滿地解釋了劫.但是,全域同型禁止再現對於用圖靈機類比圍棋,可以說是致命的一擊.因為,這意味著這台圖靈機得把以前的所有狀態都儲存起來,而具有無限種狀態數的機器不是圖靈機.
國際象棋一盤棋結束,有三種狀態,將死對方,被對方將死,和棋,和棋除了雙方自願外,還有逼和,三次同型和,以及六十步子數不變和等等,這意味著國際象棋在這些都是可以直接檢驗的,其步數不會超過32*60步.可圍棋就不一樣了,"全域同型禁止再現",這意味著理論上圍棋可以下3的361次方數量級這麼多手!這是准無窮
了.即使沒有這一規則,圍棋可走的步數依然是准無窮.
而圍棋的勝負又非要看整個棋盤的狀態才能決定,也就是說,就算沒有"全域同型禁止再現"這一規則,我們可以用圖靈機來接受圍棋,但判斷每一步的好壞必須追溯到這一局棋的終點,這意味著這台圖靈機要判斷它不同情況下停機時的狀態!而這是圖靈機所無能為力的.
這裡的狀態是理論狀態,它和我們實際計算時會選擇的狀態還不一樣,圍棋實際對局也很少超過361手,但 這已經啟示我們,既然國際象棋與圍棋在複雜程度上差了3個檔次 ,( 通過喬姆斯基語言理論的論證是否嚴格?如果真是如此,那無疑是非常精彩的論證——nn_1997 )我們能夠解決國際象棋問題的演算法能用來對付圍棋嗎?
順便把第三部分也貼出來吧。這部分有點單純科普的意思,沒什麼獨到見解,所以我不喜歡,打算對這段進行大幅刪減,再合并更多關於最佳化和尋路的內容作為第三部分,著重推出第四部分《混沌邊緣》和第五部分《感覺與計算之間》
三 迷宮之路
從理論上來說,圍棋的每一步都會有一個或幾個最佳選擇,如果我們真的可以遍曆圍棋的所有變化並加以比較的話,我們是可以找到這些最佳下法,只是這種遍曆是實際上不可實現的.
尋找圍棋最佳下法的過程就象是在走一個龐大的迷宮,迷宮中有無數的分支岔路,有些通向死路,有些通向幻象,還有一些路則僅僅是自己轉圈.置身於這個龐大的迷宮中,當我們知道憑一生的時間也只能走過這一迷宮的微不足道的一小部分時,我們自然會停下來,看看這迷宮之路中有沒有什麼規律.
我們先對問題進行簡化,拋開全域同型禁止再現,也不考慮把三劫,四劫,長生劫等等情況.這樣在走迷宮時不必判斷是否會出現迴路(就是繞了一圈又回來了),對於這種無迴路的迷宮,最簡單的走法是死貼一邊走(比如,一直貼左邊或者一直貼右邊),這就是一種遍曆搜尋,術語叫深度優先遍曆搜尋(因為它每次都要走到頭再轉回來走下一條).
按上章的計算,深度優先遍曆搜尋走完這個迷宮大概需要10^(3^361)步.
所以,我們別無選擇,只有換種辦法來走迷宮,我們所選的辦法又怎樣才能達到我們的要求呢?
我們這裡所談論的迷宮的走法,也就是解決一個問題的演算法,一般用是用複雜度的階數來衡量演算法複雜度好壞的.首先,一個問題有它自己的尺度,比如國際象棋是64格棋盤,我們可以把國際象棋問題的尺度定為64,圍棋361個交叉點,我們可以把圍棋問題的尺度定為361.如果你願意把它們的尺度分別定為8,19也可以,但考慮問題時顯然不如64和361來的自然.
解決一個問題的演算法的複雜度是根據問題的尺度與計算步數的函數來定義的,設n為問題的尺度,如果一個演算法需要n步.我們就說它的複雜度是n,如果一個演算法需要2^n步(n個2連乘),我們說它的複雜度是2^n. 對於兩種演算法來說,只要他們的複雜度函數的比值不大於一個常數,我們就稱它們為同階的.也就是說,一個需要步數為1000n的演算法與一個需要步數為n的演算法是同階的.因為我的機器只要能把速度提高一千倍,第一個演算法就能達到第二個演算法原先的速度.但一個步數為n^2的演算法就比一個步數為1000n的演算法複雜度高,因為不論你的機器有多快,對於尺度很大的問題,總還是第一個演算法複雜.
因此,我們就用O(n),o(n^2),...,o(2^n),... 來表示與步數為n,n^2,...,2^n,...的演算法同階的演算法的複雜程度.請注意這裡的2^n,一個2^n步數的演算法(其實是任何x^n(x>1)步數的演算法)比任何一個多項式步數的演算法(就是O(n), O(n^2)...這類演算法)都來的複雜. 比如說,一個演算法的步數約為2^n,第二個為n^10,當n取64的時候(國際象棋尺度),前者需要1.84*10^19步,而後者需要1.15*10^18步,第一個比第二個要多花十多倍步數,如果問題尺度是361(圍棋尺度),後者需要3.76*10^25步,而則前者需要4.69*10^108步,這次前者比後者複雜了一千億億億億億億億億億億倍.
如果說一個問題可以找到複雜度為多項式的演算法,我們稱它屬於P類問題,我們需要的就是複雜度為多項式的演算法,也就是說,如果圍棋是P類問題,我們就認為它可解.而如果我們只能找到指數等級的演算法(O(2^n)..等等),我們就認為它不可解.
而 圍棋的遍曆需要的步數,是指數複雜度問題的排序問題,它比指數複雜度的問題還要複雜的多 .
在人們試圖用電腦解決的各種問題中,有一大類問題,包括貨郎問題,背包問題等等,總計數百個之多,被人們稱為NP問題.之所以說它們是一類是因為人們已經證明了只要其中一個問題可計算(就是有多項式演算法),其他的問題就都可以計算,
但現在, 比起找這些問題的多項式演算法,人們倒寧願去證明它們不存在多項式演算法.
圍棋是NP問題嗎?不知道,好象不是,但既然NP問題都有指數複雜度的解法,而圍棋連指數複雜度的解法都找不到,看起來,圍棋似乎比NP問題還要複雜的多 .
不過,解決一個問題,找不到最好的方法,退而求其次也不失為一種明智的選擇.人們對很多NP問題的態度就是:找不到最好的答案,比較好的答案也不錯."深藍"會輸給卡斯帕羅夫一局,也說明"深藍"找到的並非最佳下法,但它已經可以在總成績上戰勝卡斯帕羅夫了.
在各種搜尋演算法中,有一個A*搜尋演算法,也叫做最佳搜尋演算法,它是對於問題的各種情況設定一個估值函數,假設我們選擇的是值最小的道路,在搜尋迷宮的時候,A*演算法根據估值函數判斷下一步應選擇的道路,並不停地用走過的實際路線的價
值加上下一點的估值函數作為新的估值.當新的估值小於以前所做的另一條路線的估值的時候,改換到另一路線中重新進行估值和搜尋,這倒有點象人下棋時的判斷:看看這樣走行不行,看到大概不行時,就換個辦法再看看.
理論上,如果估值函數永遠小於實際路線的價值,那麼,A*演算法總可以找到最優解.但這樣太困難.我們還可以有這樣的想法:如果A*演算法的估值函數可以做到差不離的話,也許我們就可以找到一個比較好的走法.比如,如果A*演算法能夠把下一手的選擇點降到平均6步,計算一路變化所需的步數降到平均20步,那麼總的計算量就變成了6^20=3.66*10^15,這就已經接近於電腦可接受的計算量了.
作者曾經設想過一個圍棋AI模型:把所有的棋子以連在一起的一塊為基本單位,而後再根據棋子的形狀,眼位情況,賦與它強度,影響力等屬性,用力學模型來分析全域勢力範圍,並據此選擇下一手的一般位置.實際上這就是對A*演算法估值函數的一種設想.
看起來,我們只要找到一個好的方法,把一個個圍棋局面量化成適當的值,再根據這些值進行A*搜尋,就可以找到相當不錯的走法.
唯一的問題是: 存在可行的量化方法嗎?