王曉華是一位熱衷於算法研究的程序員,也是《算法的樂趣》一書的做者。他目前在中興通信上海研發中心從事光纖接入網通信設備開發,擔任EPON(以太網無源光網絡)業務軟件開發經理,參與開發的PON設備在全球部署過億線,爲數億家庭提供寬帶接入服務。html
對於算法,王曉華更願意稱本身是在「玩」,「玩算法」最大的樂趣就是用程序解決生活中的問題。當年爲了方便使用Visual Studio 6.0開發軟件,他特地編寫了一個tabbar插件,並隨後開源了這個軟件。爲了文檔安全,他開發了一個基於layerFSD技術的透明文件加密系統,在朋友圈內廣爲流傳。後來他在使用Source Insight軟件的時候,又之外掛的形式爲Source Insight開發了TabSiPlus插件,受到了不少程序員朋友的歡迎。程序員
關於算法該怎麼「玩」,王曉華自有多年的經驗分享:算法
爲了玩遊戲而開始的算法之旅編程
從上大學時候開始,我迷上了算法。那時候,像我這樣的懶人以爲拼音輸入法太繁瑣,因而就去學「表形碼」(固然,由於笨的緣由,如今還在用拼音輸入法)。資深一點的遊戲玩家都還記得,那個時候爲了玩中文DOS遊戲,不少人都裝了UCDOS中文環境,UCDOS沒有表形碼,可是支持經過碼錶文件增長自定義輸入法。我研究了Windows上的表形碼碼錶文件(老師給的,適用於Windows 3.x版本)和UCDOS碼錶文件的格式,發現兩者有必定的類似性:都是文本文件,有固定的格式,每一行由一組編碼和一個字或詞組成一個編碼對。兩者的區別僅僅在於一個文件是編碼在前,對應的字或詞在後面,另外一個恰好相反,字或詞在前,對應的編碼在後面。碼錶文件有十幾萬行,手工修改是不可能了,恰好當時在上C語言課,就決定寫個程序來作這個事情。安全
神奇的表形碼網絡
第一次運行我寫的程序,十幾秒鐘都沒有結束。由於我以前寫的C語言做業,歷來沒有哪一個程序運行時間超過1秒鐘的,因此我以爲這個程序掛了,因而我就「Ctrl+Break」了。可是分析代碼又以爲沒有問題,看了遺留在磁盤上的碼錶文件,發現轉換了幾千行,而且內容是對的。因而再次運行程序,等了2-3分鐘,程序結束了。我急不可待地將獲得的碼錶文件導入UCDOS,發現能夠用,當時就感受很是有成就感。這是我第一次爲解決一個實際的問題編寫算法,儘管當時尚未算法、軟件的概念,可是隱隱約約就以爲這東西有用,不是隻用於完成做業,還能夠解決實際的問題。後來我接觸到了更多的有用算法以及各類算法競賽,一直到如今,寫個程序解決問題幾乎成了一種習慣。數據結構
學習算法難在哪裏?框架
許多算法是有難度的,理論很複雜,不容易理解和掌握,這是客觀存在的現實。可是咱們能夠經過提升自身分析問題和解決問題的能力來相對地下降學習難度。從基礎來說,要深刻理解數據結構,至少要很是熟練地掌握一種排序算法,各類線性表的插入、刪除算法,樹的遍歷和插入、刪除算法,圖的遍歷算法等等。而後要多學習,掌握一些常見問題的解決模式,好比窮舉算法如何應用,動態規劃算法如何應用等等。最後要勤思考,對應已經掌握並解決的算法,要想一想爲何用這種方法解決,有沒有其餘方法,相似的問題怎麼辦,提升觸類旁通的能力。iphone
想學好計算機算法,數學問題是沒法迴避的。數學的重要性不在於算法中用了哪些公式或數學原理,其重要性在於一種思惟方式的培養。當咱們遇到一個新的問題的時候,一般有兩種解決問題的方式,一種方式是創造一種新的方法來解決這個問題,另外一種方式是將新問題分解、轉化成已知問題,而後用已知的方法解決這個問題。這兩種方式都很須要抽象思惟能力,現實生活中不多有機會鍛鍊抽象思惟能力,而學習數學是一種很好地培養這種能力的方法。可是並非說要學好算法就必需成爲數學大咖,而是經過學習數學促進抽象思惟能力的提升。機器學習
算法設計又難在何處?
參加算法競賽實際上是一件很痛苦的事情,要通過大量的訓練,不少人會選擇背一些算法或整理一些算法模板,到時候能夠直接套用。在理解算法的基礎上熟記一些經典的算法實現其實也是一件無可厚非的事情,我上學的時候也參加過一些比賽,一般在比賽以前也會突擊訓練一兩個月,背不少東西,基本上也是過後一個月就全忘了。
比賽的題目通常都有特定的套路,可是現實生活中的算法每每就事而論,有可能只有你遇到過,沒有現成的經驗,須要本身從無到有來解決問題。我認爲算法設計有三個方面須要強調:模型的創建、演化算法和輸入、輸出的轉換。這三個方面中模型的創建是關鍵,不少狀況下,模型建好了,演化算法和輸入、輸出的轉換就水到渠成。
創建模型的基礎是數據結構。當一個問題的數據存在先進先出的特性時,你要想到隊列。當一個問題的數據須要頻繁查找操做時,你要想到有序表、hash、map。當一個問題的數據須要頻繁的插入、刪除操做時,你要想到鏈表。當一個問題中的數據包含父子關係時,你要想到樹。當一個問題中的數據中既有節點又有路徑什麼的,你要想到圖。這些都和使用數據結構的經驗有關,只要多練習就能掌握。
創建模型還須要抽象的邏輯思惟能力。簡單地說,就是運用抽象的邏輯思惟,抓住問題的主要因素,忽略次要因素,創建問題的框架。
算法設計之難體如今思惟方式的轉換和模型的創建。前面說過,這須要有抽象思惟能力,缺少這種能力,連問題都很難想明白,更不用說設計解決問題的算法了。幸運的是這種能力是能夠培養的,學好數學,多研究一些算法,積累些經驗,都是很好的提升抽象思惟能力的方法。
算法學習的乾貨推薦
在我學習算法的過程當中,興趣是最大的推進力。興趣來自於我以爲這東西能解決問題,對本身有用。我在策劃《算法的樂趣》這本書的時候,我依然沿用了這種思想。我選取、介紹的例子都是你們生活中沒有在乎,可是卻到處都會遇到的算法,經過這些例子讓你們以爲算法是有用的,並經過這個來吸引你們關注算法,學習算法,從而達到提升能力的做用。
算法學習是一條並不簡單的路,就個人經驗而言,在計算機上學習算法首先須要熟悉編程語言和數據結構,關於編程語言和數據結構有不少經典的書籍,我就很少介紹了。就算法而言,我看過的書有Cormen的《算法導論》、Knuth的《計算機程序設計藝術》、Weiss的《數據結構與算法分析》、Levitin的《算法設計與分析基礎》、Kleigberg的《算法設計》等等。想參加算法競賽的同窗能夠參考劉汝佳等人編寫的《算法藝術與信息學競賽》,以及《ACM國際大學生程序設計競賽題解》。由於時間過去過久了,已經不記得看這些書的順序了,只記得最先看的是《算法導論》,關於順序實在沒有什麼經驗可談。
至於如何讀這些算法的經典書籍,我卻是有一些經驗和你們分享:
無論哪一本書,都不要泛泛地看一遍就以爲看懂了,而是要把書中的每個例子算法都用程序寫出來,這樣才能留下深入的印象。若是遇到看不懂的地方,不要停下來,跳過去看其餘算法,過幾天在回頭來看,若是還看不懂就再過幾天再回頭來看。千萬不要在一個地方停下來,不然你極可能就此失去興趣,恐怕永遠也看不完這本書了。
此外,還有一些學習算法的網站值得推薦:
遊戲開發相關的算法介紹:
http://theory.stanford.edu/~amitp/GameProgramming
俄羅斯方塊遊戲的算法網站:
http://gforge.inria.fr/projects/mdptetris
http://colinfahey.com/tetris/tetris.html
leetcode,最近很火的算法網站:
Topcoder,也很經典,每週都有競賽,有獎金的:
http://community.topcoder.com/tc
還有不少大學也有本身的競賽題庫,好比北大、杭電和華中科技大學等等。
編程算法、推薦算法、數據挖掘涉及的算法的區別和聯繫?
編程算法應該只是算法的一種表達形式,咱們還能夠用表格或流程圖來表達算法。數據挖掘領域涉及的算法和其餘領域的算法並沒有本質的區別,只是問題域不一樣。數據挖掘和機器學習經常使用的方法,好比決策樹、貝葉斯學習、神經網絡、遺傳算法等等,在其餘領域也都是有應用的。神經網絡、遺傳算法做爲啓發性搜索算法在人工智能和最優化求解領域也獲得了普遍應用。貝葉斯學習在一些電子郵件應用程序中也有應用,主要用於垃圾郵件的識別。在人工智能領域或各類專家系統中,決策樹算法也是經常使用算法。各類算法之間的聯繫仍是很廣泛的,在不一樣的領域扮演着不一樣的角色,本質上沒有區別。
在平常生活中,咱們有機會見到愈來愈多的推薦算法,我曾經想買一個佳能鏡頭,因而用了一下百度,想了解幾種鏡頭的評價,結果一連幾天,只要登陸京東或淘寶,首頁都會給我推薦與數碼相機有關的配件或鏡頭信息。由於工做領域的緣由,我對推薦算法沒有深刻的研究,我認爲這種算法應該主要是創建在大數據上的數據分類、篩選和過濾。不過就我對算法的理解來講,目前的推薦算法仍是有改進餘地的,好比要能區分同一臺計算機的不一樣使用者,不要在我用電腦的時候向我推薦女式內衣和化妝品,那是我老婆關注的東西。(笑)
生活中到處有算法
應該說,在個人工做和生活中也是到處都有算法。說到網絡協議,TCP協議中的「滑動窗口算法」也是很經典的算法。路由器和交換機中爲了不出現端口環路,都會使用最小生成樹算法。在接入網設備中,一般語音報文的優先級高於視頻報文,視頻報文的優先級又高於通常的數據報文,當一大波各類報文來臨時,設備如何處理?這個算法也很經典,就是用多個隊列加上一個調度算法,簡單說就是六個字:分分類,排排隊。
隨着寬帶的普及,如今幾乎家家都有路由器,不少人都會在路由器上給各個端口配置帶寬,這就會用到帶寬分配算法,令牌算法和Max-Min Fairness帶寬分配算法都是經典的帶寬分配算法。網絡傳輸的數據報文出了錯碼怎麼辦?那就要糾錯,Reed-Solomon編碼和解碼算法就是這樣的經典糾錯算法,除此以外,Reed-Solomon編碼和解碼算法還用於光盤、磁盤的數據糾錯。
說實話,我曾經「玩」過的算法,絕大多數都沒有機會直接應用到工做當中,可是「玩」算法對個人影響是顯而易見的,它提升了個人動手能力,以及遇到問題時分析並解決問題能力,這就是收穫,也是任何一個軟件企業對程序員最基本的要求。
雷鋒網原創文章,未經受權禁止轉載。詳情見轉載須知。