1. 程式人生 > >演算法科學經典書籍——《演算法導論》自序

演算法科學經典書籍——《演算法導論》自序

   在計算機出現之前,就有了演算法。現在有了計算機,就需要更多的演算法,演算法是計算的核心。
  本書提供了對當代計算機演算法研究的一個全面、綜合的介紹。書中給出了多個演算法,並對它們進行了較為深入的分析,使得這些演算法的設計和分析易於被各個層次的讀者所理解。我們力求在不犧牲分析的深度和數學嚴密性的前提下,給出深入淺出的說明。
  書中每一章都給出了一個演算法、一種演算法設計技術、一個應用領域或一個相關的主題。演算法是用英語和一種“虛擬碼”來描述的,任何有一點程式設計經驗的人都能看得懂。書中給出了244幅圖,說明各個演算法的工作過程。我們強調將演算法的效率作為一種設計標準,對書中的所有演算法,都給出了關於其執行時間的詳細分析。
  本書主要供本科生和研究生的演算法或資料結構課程使用。因為書中討論了演算法設計中的工程問題及其數學性質,所以,本書也可以供專業技術人員自學之用。
  本書是第3版。在這個版本里,我們對全書進行了更新,包括新增了若干章、修訂了虛擬碼等。
  
  致使用本書的教師
  本書的設計目標是全面、適用於多種用途。它可用於若干課程,從本科生的資料結構課程到研究生的演算法課程。由於書中給出的內容比較多,只講一學期一般講不完,因此,教師們應該將本書看成是一種“快取區”或“瑞典式自助餐”,從中挑選出能最好地支援自己希望教授的課程的內容。
  教師們會發現,要圍繞自己所需的各個章節來組織課程是比較容易的。書中的各章都是相對獨立的,因此,你不必擔心意想不到的或不必要的各章之間的依賴關係。每一章都是以節為單位,內容由易到難。如果將本書用於本科生的課程,可以選用每一章的前面幾節內容;用於研究生的課程中,則可以完整地講授每一章。
  全書包含957道練習和158道思考題。每一節結束時給出練習,每一章結束時給出思考題。練習一般比較短,用於檢查學生對書中內容的基本掌握情況。有一些是簡單的自查性練習,有一些則要更充實,可以作為家庭作業佈置給學生。每一章後的思考題都是一些敘述較為詳細的例項研究,它們常常會介紹一些新的知識。一般來說,這些思考題都會包含幾個小問題,引導學生逐步得到問題的解。
  鑑於本書前幾版使用的反饋,我們在本書配套網站上公佈了其中一些練習和思考題的答案(但不是全部)。我們會定期更新這些答案,因此需要教師每次授課前都到這個網站上來檢視。
  在那些不太適合本科生、更適合研究生的章節和練習前面,都加上了星號(·)。帶星號的章節也不一定就比不帶星號的更難,但可能要求瞭解更多的數學知識。類似地,帶星號的練習可能要求有更好的數學背景或創造力。
  
  致使用本書的學生
  希望本教材能為學生們提供關於演算法這一領域的有趣介紹。我們力求使書中給出的每一個演算法都易於理解和有趣。為了在同學們遇到不熟悉或比較困難的演算法時提供幫助,我們逐個步驟地描述每一個演算法。此外,為了便於大家理解書中對演算法的分析,對於其中所需的數學知識,我們給出了詳細的解釋。如果對某一主題已經有所瞭解,會發現根據書中各章的編排順序,可以跳過一些介紹性的小節,直接閱讀更高階的內容。
  本書是一本大部頭著作,讀者所修的課程可能只講授其中的一部分。我們試圖使它能成為一本現在對讀者有用的教材,將來在讀者的職業生涯中,也能成為一本案頭的數學參考書或工程實踐手冊。
  
  閱讀本書需要哪些預備知識呢·
  · 讀者需要有一些程式設計方面的經驗,尤其需要理解遞迴過程和簡單的資料結構,如陣列和連結串列。
  ·讀者應該能較為熟練地利用數學歸納法進行證明。書中有一些內容要求讀者具備初等微積分方面的知識。除此之外,本書的第一部分和第八部分將介紹讀者需要用到的所有數學技巧。
    
  致使用本書的專業技術人員
  本書涉及的主題非常廣泛,因而是一本很好的演算法參考手冊。因為每一章都是相對獨立的,所以讀者可以重點查閱自己感興趣的主題。
  在我們所討論的演算法中,多數都有著極大的實用價值。因此,我們在書中涉及了演算法實現方面的考慮和其他工程方面的問題。對於那些為數不多的、主要具有理論研究價值的演算法,通常還給出其實用的替代演算法。
  如果希望實現這些演算法中的任何一個,你會發現將書中的虛擬碼翻譯成你熟悉的某種程式設計語言是一件相當直接的事。虛擬碼被設計成能夠清晰、簡明地描述每一個演算法。因此,我們不考慮錯誤處理和其他需要對讀者所用程式設計環境有特定假設的軟體工程問題。我們力求簡單而直接地給出每一個演算法,而不會讓某種特定程式設計語言的特殊性掩蓋演算法的本質內容。
  
  致我們的同事
  我們在本書中給出了詳盡的參考文獻。每一章在結束時都給出了“本章註記”,介紹一些歷史性的細節和參考文獻。但是,各章的註記並沒有提供整個演算法領域的全部參考文獻。有一點可能是讓人難以置信的,就是在本書這樣一本大部頭中,由於篇幅的原因,很多有趣的演算法都沒能包括進來。
  儘管學生們發來了大量的請求,希望我們提供思考題和練習的解答,但我們還是決定基本上不提供思考題和練習的參考答案(少數除外),以打消學生們試圖查閱答案,而不是自己動手得出答案的念頭。
  
  第3版中所做的修改
  在本書的第2版和第3版之間有哪些變化呢·這兩版之間的變化量和第2版與第1版之間的變化量相當,正如在第2版的變化中所說,這些變化可以說不太大,也可以說很大,具體要看讀者怎麼看待這些變化了。
  快速地瀏覽一遍目錄,你就會發現,第2版中的多數章節在第3版中都出現了。在第3版中,去掉了兩章和一節的內容,新增加了三章以及兩節的內容。如果單從目錄來判斷第3版中改動的範圍,得出的結論很可能是改動不大。
  我們依然保持前兩版的組織結構,既按照問題領域又根據技術來組織章節內容。書中既包含基於技術的章,如分治法、動態規劃、貪心演算法、攤還分析、NP完全性和近似演算法,也包含關於排序、動態集的資料結構和圖問題演算法的完整部分。我們發現雖然讀者需要了解如何應用這些技術來設計和分析演算法,但是思考題中很少提示應用哪個技術來解決這些問題。
  
  下面總結了第3版的主要變化:
  新增了討論van Emde Boas樹和多執行緒演算法的章節,並且將矩陣基礎移至附錄。
  修訂了遞迴式那一章的內容,更廣泛地覆蓋分治法,並且前兩節介紹了應用分治法解決兩個問題。4.2節介紹了用於矩陣乘法的Strassen演算法,關於矩陣運算的內容已從本章移除。
  移除兩章很少講授的內容:二項堆和排序網路。排序網路中的關鍵思想——0·1原理,在本版的思考題8·7中作為比較交換演算法的0·1排序引理進行介紹。斐波那契堆的處理不再依賴二項堆。
  修訂了動態規劃和貪心演算法相關內容。與第2版中的裝配線排程問題相比,本版用一個更有趣的問題——鋼條切割來引入動態規劃。而且,我們比在第2版中更強調助記性,並且引入子問題圖這一概念來闡釋動態規劃演算法的執行時間。在我們給出的貪心演算法例子(活動選擇問題)中,我們以更直接的方式給出貪心演算法。
  ·我們從二叉搜尋樹(包括紅黑樹)刪除一個結點的方式,現在保證實際所刪除的結點就是請求刪除的結點(在前兩版中,有些情況下某個其他結點可能被刪除)。用這種新的方式刪除結點,如果程式的其他部分保持指標指向樹中的結點,那麼終止時就不會錯誤地將指標指向已刪去的結點。
  · 流網路相關材料現在基於邊上的全部流。這種方法比前兩版中使用的淨流更直觀。
  ·由於關於矩陣基礎和Strassen演算法的材料移到了其他章,矩陣運算這一章的內容比第2版中所佔的篇幅更小。
  · 修改了對Knuth·Morris·Pratt字串匹配演算法的討論。
  · 修正了上一版中的一些錯誤。在網站上,這些錯誤大多數都已在第2版的勘誤中給出,但是有些沒有給出。
  ·根據許多讀者的要求,我們改變了書中虛擬碼的語法,現在用“=”表示賦值,用“==”表示檢驗相等,正如C、C 、Java和Python所用的。同樣,我們不再使用關鍵字do和then而是使用“//”作為程式行末尾的註釋符號。我們現在還使用點標記法表明物件屬性。書中的虛擬碼仍是過程化的,而不是面向物件的。換句話說,我們只是簡單地呼叫過程,將物件作為引數傳遞,而不是關於物件的執行方法。
  · 新增100道練習和28道思考題,還更新並補充了參考文獻。
  · 最後,我們對書中的語句、段落和小節進行了一些調整,以使本書條理更清晰。
  
  第3版致謝
  我們已經與MIT Press合作20多年,建立了很好的合作關係!感謝Ellen Faran、Bob Prior、AdaBrunstein和Mary Reilly的幫助和支援。
  在出版第3版時,我們在達特茅斯學院計算機科學系、MIT電腦科學與人工智慧實驗室、哥倫比亞大學工業工程與運籌學系從事教學和科研工作。感謝這些學校和同事為我們提供的支援和實驗環境。
  JulieSussman,P.P.A擔當本書第3版的技術編輯,再次拯救了我們。每次審閱,我們都覺得已經消除了錯誤,但是Julie還是發現了許多錯誤。她還幫我們改進了幾處文字表述。如果有技術編輯名人堂,Julie一定第一輪就可以入選。Julie是非凡的,我們怎麼感謝都是不夠的。PriyaNatarajan也發現了一些錯誤,使得我們可以在將本書交給出版社前修正這些錯誤。書中的任何錯誤(毫無疑問,一定存在一些錯誤)都由作者負責(或許這些錯誤有些是Julie審閱材料後引入的)。
  對於van Emde Boas樹的處理出自於Erik Demaine的筆記,轉而也受到MichaelBender的影響。此外,我還將Javed Aslam、Bradley Kuszmaul和HuiZha的思想也整合到這一版。
  多執行緒演算法這一章是基於與HaraldProkop一起撰寫的筆記,其他在MIT從事Cilk專案的同事也對本部分內容有所貢獻,包括BradleyKuszmaul和Matteo Frigo。多執行緒虛擬碼的設計靈感來自MIT Cilk擴充套件到C,以及由CilkArts的Cilk 擴充套件到C 。
  我們還要感謝許多第1版和第2版的讀者,他們報告了所發現的錯誤,或者提出了改進本書的建議。我們修正了全部報告來的真實錯誤,並且儘可能多地採納了讀者的建議。我們很高興有這麼多的人為本書做出貢獻,但是很遺憾我們無法全部列出這些貢獻者。
  最後,非常感謝我們各自的妻子Nicole Cormen、Wendy Leiserson、Gail Rivest和RebeccaIvry,還有我們的孩子Ricky、Will、Debby和Katie Leiserson,Alex和ChristopherRivest,以及Molly、Noah和BenjaminStein。感謝他們在我們寫作本書過程中給予的愛和支援。正是由於有了來自家庭的耐心和鼓勵,本書的寫作工作才得以完成。謹將此書獻給他們。