《演算法謎題》書評

高博發表於2014-05-24

《演算法謎題》是一本有趣而且有用的書。作為譯者之一,這本書給我帶來的個人體驗中相當重要的一點,是它喚起了我一些早年的閱讀記憶。在計算機、程式設計語言還沒有像如今這樣鋪天蓋地,主導著有關計算的一切文字的年代,演算法相關的圖書就已經以趣味數學或邏輯圖書的面貌出現了。只是當演算法已經成為一門學科,成為考試和麵試的內容時,它的趣味性才逐漸地被掩蓋起來,現在幾乎已經被當作是計算機專業才會去接觸和思考的某種高階技巧了。這樣造成的局面是,近年來出版的所有演算法相關的圖書,幾乎全部是要以原始碼或是虛擬碼的形式來表述,似乎演算法天然地就必須和計算機、和程式設計結合成一體才有意義。這種觀點其實也無可厚非,但是它比較糟糕的另一面是感覺演算法的關鍵在於寫程式碼這件事本身,這就大錯特錯了。演算法的設計與分析是比寫程式碼更上游的工作,它並不需要藉助程式碼這種形式來進行,而是純粹地通過其自身的數學分析和邏輯推理就可以在思維層次完成的。更何況,並不是所有的演算法都是以解決具體問題為目的,有些只是給出一般的可行性結論的,根本沒有辦法落實成程式碼。從這個意義上說,《演算法謎題》是試圖對已經浸淫在計算機和程式設計中太久的人們進行二次啟蒙,而這種矇昧是“只緣身在此山中”帶來的。我們十分需要這樣的一本帶人迴歸初心,反思在接觸任何計算機和程式設計的專業知識之前,我們怎樣使用演算法的思維和工具來解決問題。

在這樣的背景下,全書以150道精心挑選的謎題為核心展開。其中不乏一些經典,比如狼羊菜過河、一筆畫、生命遊戲、各種跳棋走位、各種國際象棋擺位和對弈、各種砝碼稱重、各種平面鋪陳、各種心算猜數等等,還有一些以生活中的事件為謎面,實際上卻是難度不小的演算法謎題的,比如在《程式設計之美》等圖書中被擴充到高維討論的煎餅翻面問題等。也許讀者很早就通過不同的渠道接觸到過其中的一些謎題,並且知道如何去解決它們的“土辦法”。但是,如果想要閱讀本書並取得最大程度的收穫,則應該克服可能會有的靠直覺和簡單推理來取得答案就滿足的習慣,而要訓練自己換用演算法思維來重新求解。當然,能得出解當然還是比得不出解要好,關鍵在於在得到解以後,不是主要滿足於求解某道特定謎題的特定思路,而是要反過來想想這樣的思路屬於演算法工具集中的哪一種,以及若想套用這種工具需要滿足的前提條件。很多情況下,演算法謎題在設計時,條件是隱而不露的,但如果不能形成思維的敏捷性,就必然會被矇蔽和誤導。

如果把《演算法謎題》和作者Levitin的另一本更加“標準”的教材著作《演算法設計與分析基礎》相對比,馬上會發現這兩本書的一些很有意思的相同和不同之處。這兩本書採用了一些共同的謎題作為講解演算法的例項,尤其是對於演算法工具集的結構編排簡直如出一轍。但是相對而言,《演算法設計與分析基礎》仍然基本上要求讀者受過相當系統化的電腦科學專業訓練,而且大量的篇幅在討論矩陣計算中用到的專用演算法(雖然是在 “變治法”的框架下),更不必提它把一些高階資料結構如雜湊表、2-3樹、B樹和並查集等的掌握視為理所當然,在討論圖演算法時更是毫不猶豫地把圖搜尋、最小生成樹和尋找最短路徑的一系列經典演算法直接拿了出來(雖然是在“貪心法”的框架下)。而在《演算法謎題》中,則看不到這些內容。從這裡就可以看出這兩本書受眾的區別,或者說寫作目的的區別。《演算法謎題》是寫給更廣義的猜謎愛好者看的,他們不一定來自電腦科學或工程專業,可能連二叉查詢樹都不知道是什麼,以往的演算法圖書是把他們擋在門外的。然而,《演算法謎題》卻熱情慷慨地擁抱他們,向他們指出:演算法不是計算機專業人士的專利,任何人只要知道,有定義良好的輸入和輸出、有可機械描述的步驟,並且有窮盡的任何問題求解過程,都是一種演算法。比如把大象裝進冰箱的經典演算法,甚至可以上春晚——可誰又能否認這確實是一種演算法呢?但是將計算機專業的所有工具都去除,僅僅採用演算法思維工具來解決演算法問題,其實是並不容易的事。稍不留神,線性表、樹和圖這些天天在用,並且已經發展了十幾年的,熟悉電腦科學的人幾乎須臾不能離開的工具和術語就會跳出來。然而演算法謎題做到了,它通篇都沒有提到這些工具中的任何一種,連陣列都沒有,連Dijkstra演算法都沒有(僅僅在一道國旗排列的謎題中提到了這位偉大的荷蘭電腦科學的名字)。它只用數學公式、示意圖形,以及大篇敘述性的思路講解來完成演算法謎題的求解。這些內容,尤其是講解文字是極其少見而且寶貴的,實際上相當於作者直接把思考的過程原原本本地呈現出來,這就比通常需要讀者從表面上抽象、簡潔的演算和定理反推出背後的大量思考和取捨的過程要省力很多。當然,仔細閱讀還是必須的,因為很多謎題也並不像敘述的那樣顯而易見,有時候作者也會省略掉一些“思維除錯”的過程,直接把正確答案告訴讀者。而讀者一方面可以從自行求解的困難中看出作者的解法妙處何在,另一方面也可以從作者的解法與自己的解法的差異中,看出演算法在運用時的重要技巧,比如建立怎樣的結構或作怎樣的結構變換更容易看出應該應用哪種演算法(如第27題等),在選取不變數或是不變結構時,怎樣能夠佔用更少的“大腦記憶體”(如第51題等),以及如何能從複雜或抽象的謎面中找到所需要的關鍵結構(第116題等)。當然,有些謎題還是有相當難度的,即使一開始大致能夠依據直覺判斷出大致的正確方向,也絕對無法經過幾步簡單的推演就得出答案。其中有些需要學習和掌握高階的數學技巧如對角線法(第136題)、不等式(第124題)和同餘式(第147題)等,甚至有些題目直接來自國際數學奧林匹克競賽(第134題),雖然大量的謎題還是在使用最重要也是最基礎的遞推公式和求和公式來求解。

《演算法謎題》可以說是一本謎題大全,它蒐羅謎題的來源非常豐富。不僅有Martin Gardner在《科學美國人》上的數學趣題專欄這樣人盡皆知的謎題寶庫,還包括數量驚人的對於幻方、九宮環、棋局對弈等專門分類謎題的圖書、論文集,以及研究機構的內網資源。它不僅給出了很多經典謎題的最早來源考據,同時還順著線索在時間軸上向後追溯,把一些演算法已經為人熟知的謎題如n皇后、漢諾塔、約瑟夫問題等的擴充套件形式或現代形式拿出來,如同Volodos改編《土耳其進行曲》那樣,使人們切實地感覺到,這些經典並沒有過時,而是作為靈感的源泉不斷地在當代知識和技術背景下融入人類不斷進步和發展的思維成果,催生新的挑戰問題。我在《演算法謎題》的前言中也提到,這本書的最難得之處就在於它深厚的文化意義,它蘊含著所有態度進取、積極創新的人們都能感同身受的智力和工程符號。因此,享受解謎的過程,並在探討求解過程中發生妙不可言的心靈碰撞,這才是《演算法謎題》的作者身為一個電腦科學教授,卻要一反其擅長的科班出身,費心費力地編寫這麼一本書的原始動力所在吧。

《演算法謎題》簡體中文版甫一出版,立刻成為暢銷書,銷量連續近20周在亞馬遜和京東商城新書榜上名列前茅。這對於編輯和譯者團隊而言,是喜出望外的收穫。尤其是瞭解到,很多讀者並非僅僅抱著它作為“面試經典圖書”的功利目的而購買,而是想要“看看大師的思考過程”、“重溫最初參加資訊學競賽的心動”,甚至“覺得這樣的書就是有趣好看”,就更加感覺中國的演算法學習氛圍真的比十幾年前要濃厚得多了。當然,本書的實用性就更在不言中了。好幾封讀者來信中都提到,看完本書去參加面試,“直接考了原題”,“幸虧看了砝碼稱重那道高難題目的提示,不然臨場無論如何不可能想到了”。由此可見,本書作為面試經典著作實力不容小覷,只是最好拿它來修煉內功而不是作為押題工具,這才是正確的學習之道呀。

相關文章