六年前,我完全不知道算法是什么東西。六年后,我看到算法就兩眼放光。六年的時(shí)間讓我從算法小菜鳥蛻變成算法愛好者。
大一上學(xué)期,我對算法一點(diǎn)概念都沒有,當(dāng)時(shí)老師讓我們用偽代碼寫算法,我基本上都是從網(wǎng)上找答案或者直接空著不寫。給我印象最深的一個(gè)算法是計(jì)算兩個(gè)分?jǐn)?shù)相加,其中涉及求最大公約數(shù),用的是輾轉(zhuǎn)相除法。那時(shí)覺得這個(gè)算法很難懂,現(xiàn)在回首再看時(shí),覺得這個(gè)算法還是很簡單的。大一下學(xué)期,聽到算法和數(shù)據(jù)結(jié)構(gòu)對程序員是如何如何重要的傳言,就抱著《零基礎(chǔ)學(xué)算法》,啃哧啃哧啃了大半個(gè)學(xué)期也只啃完了前幾章。那個(gè)學(xué)期我學(xué)會了二分查找算法,了解了貪心算法,遞歸算法,分治算法的基本原理。最重要的是我第一次學(xué)會了一種編程語言,C。說到學(xué)C的經(jīng)歷,我特別特別感謝一個(gè)人,我的師傅。我是在一個(gè)算法討論群里認(rèn)識師傅的,那時(shí)我傻傻呼呼的問scanf是什么東西,所有人都笑而不答,只有師傅耐心的回答我是輸入的意思。之后,我在C上遇到不懂的就問師傅,結(jié)果一個(gè)月不到就把那本C語言書啃完了,并練手寫了一堆小程序。期間,師傅還給我灌輸了代碼規(guī)范的理念,讓我受益匪淺。
大二,師傅又給我推薦ACM群,鼓勵(lì)我去hdu網(wǎng)站上刷題。我在acm.hdu網(wǎng)站上從最簡單的算法題A+B做起,然后就迷上了它,每天下課都去網(wǎng)站做題,不會的就去ACM群里,與來自不同大學(xué)的學(xué)生討論。周末從早上起床一直編代碼到睡覺,有時(shí)覺得編程的人是孤獨(dú)的,現(xiàn)在回想起那段歲月,都覺得心酸,但當(dāng)時(shí)真的很瘋狂很快樂,能做自己喜歡的事是最幸福的。師傅還給了我一張他AC掉的題目列表,讓我從容易的題目上手。他比我先刷掉200多題目,我在后面不停地追趕他,他刷掉400多個(gè)就停了。我在大二的寒假終于在AC掉的題目數(shù)目上超過了師傅,當(dāng)時(shí)還得意洋洋地把這件事告訴了師傅,就像一個(gè)小孩考試考了高分,然后眼巴巴地等著大人夸獎(jiǎng)自己。ACM刷題經(jīng)歷提高了我寫代碼的能力和邏輯推理能力,讓我對算法設(shè)計(jì)產(chǎn)生了濃厚的興趣。大二這一年,我刷過的題目類型有動(dòng)態(tài)規(guī)劃,貪心算法,數(shù)論算法,組合算法,字符串處理,圖算法,樹算法等等。我對基礎(chǔ)算法和數(shù)據(jù)結(jié)構(gòu)有了一定了解,并寫了很多小程序。
大三,我和另一個(gè)同學(xué)跟著老師做項(xiàng)目,研究蟻群算法在TSP問題中的應(yīng)用。我先把Marco Dorigo寫的書粗讀了一遍,了解了一下蟻群算法的原理、信息素的概念和輪盤算法,啟發(fā)式算法的基本思想,然后按書中的算法步驟把算法實(shí)現(xiàn)了。我們當(dāng)時(shí)實(shí)現(xiàn)5種蟻群算法,包括AS基本蟻群算法,EAS精華蟻群,ASrank基于排列的螞蟻系統(tǒng),MMAS最大最小螞蟻系統(tǒng),ACS蟻群系統(tǒng)。
大學(xué)前三年都是在學(xué)算法,而且沒有系統(tǒng)地看過基礎(chǔ)理論知識。大四,我認(rèn)認(rèn)真真地讀完《算法導(dǎo)論》,看完《組合數(shù)學(xué)》,《數(shù)論》,《圖論》的北師大視頻,讀完厚厚一本《離散數(shù)學(xué)》的經(jīng)典書籍。再回首看以前的題目,感覺過去很多模糊不清的地方都豁然開朗起來。大四這一年給我留下了太多的回憶,被計(jì)算所順利錄取,去圖書館閱讀大量書籍,生病半年,父母摯友陪我到處玩,厭學(xué),考試差點(diǎn)考掛了,第一次成功地改進(jìn)了外排算法,第一次寫博客,第一次參加ACM競賽,第一次在論壇給大家培訓(xùn)ACM……海量浮點(diǎn)數(shù)的外排算法涉及到敗者樹,基數(shù)排序,成塊I/O等等。我設(shè)計(jì)并實(shí)現(xiàn)的外部排序軟件非???,主要改進(jìn)點(diǎn)是我自創(chuàng)了一套編碼和解碼技術(shù),減少了文本中的字符串?dāng)?shù)字和計(jì)算機(jī)中的二級制數(shù)字轉(zhuǎn)換所需的時(shí)間,并利用了單批數(shù)據(jù)排序后相鄰兩個(gè)數(shù)之間的冗余信息。
研一,我了解并實(shí)踐了推薦算法和搜索引擎。我對推薦算法、機(jī)器學(xué)習(xí)的了解主要源于天貓推薦算法比賽。第一賽季時(shí),主要是理解業(yè)務(wù),用一些規(guī)則進(jìn)行篩選,比如最暢銷的品牌,最近點(diǎn)擊,周期購買等等,使用語言為C++。第二賽季前兩周,也是用一些規(guī)則進(jìn)行篩選,使用語言為SQL。后兩周使用隨機(jī)森林建模,共二十幾個(gè)特征,分?jǐn)?shù)一路飆升,當(dāng)了一天的第一,第一個(gè)月結(jié)束時(shí)排第四,被邀請到杭州參加研討會。那兩周,我和隊(duì)友了解了MapReduce編程框架,數(shù)據(jù)分析基礎(chǔ)(折線圖,散點(diǎn)圖,直方圖,相關(guān)系數(shù)等等),特征選擇方法,采樣方法,構(gòu)建訓(xùn)練預(yù)測驗(yàn)證數(shù)據(jù)集,各種模型特點(diǎn)(邏輯回歸,隨機(jī)森林),嘗試分組建模,各種去噪方法。后面兩個(gè)月,我們還嘗試了歸一化,GBDT模型,曲線擬合,后驗(yàn)概率,模型融合等方法。一個(gè)學(xué)期下來,我對推薦算法和機(jī)器學(xué)習(xí)的基礎(chǔ)知識有了初步的認(rèn)識。另外,我研究的方向是生物信息學(xué),主攻蛋白質(zhì)搜索引擎。研一,我參考師兄的畢業(yè)論文,自己實(shí)現(xiàn)了一個(gè)蛋白質(zhì)搜索引擎,掌握了倒排索引技術(shù)和核函數(shù)打分技術(shù)等。研一主要是基礎(chǔ)課程的學(xué)習(xí),印象最深的三門課是統(tǒng)計(jì)學(xué),隨機(jī)算法,生物信息學(xué)算法三門課。從中我了解到假設(shè)檢驗(yàn),隨機(jī)游走,隱馬爾科夫等知識。我通過閱讀論文,自己動(dòng)手實(shí)現(xiàn)了個(gè)半隱馬爾科夫算法,解決的是第三類問題,學(xué)習(xí)問題,目的是調(diào)整模型參數(shù),涉及Baum-Welch算法。

研二,進(jìn)入實(shí)驗(yàn)室,上半個(gè)學(xué)期主要是接手軟件。我接手了兩個(gè)大不相同的蛋白質(zhì)搜索引擎,每個(gè)引擎的核心代碼大約幾萬行。因?yàn)閮蓚€(gè)軟件都是剛寫完不久,所以我在閱讀代碼和測試軟件時(shí),發(fā)現(xiàn)了不少bug,改得我頭都大了。不過從中,我也學(xué)到不少東西。最重要的就是索引技術(shù),我們組的索引技術(shù)種類繁多,各有各的優(yōu)勢,組合起來非常厲害。比如在蛋白質(zhì)搜索領(lǐng)域,用后綴數(shù)組來構(gòu)造索引就比普通的倒排索引快得多。另外,我還學(xué)習(xí)了迭代式的半監(jiān)督學(xué)習(xí)算法。1月份的時(shí)候參加智能交通算法大賽,用Java實(shí)現(xiàn)了深度優(yōu)先遍歷算法,嘗試了一些簡單的流量控制策略,不過進(jìn)第二賽季之后就沒怎么弄了,聽說第一名用的是強(qiáng)化學(xué)習(xí)算法。研二下學(xué)期,也就是今年,我的主要任務(wù)是優(yōu)化蛋白質(zhì)搜索引擎,完勝前一個(gè)版本。之前兩個(gè)月主要做數(shù)據(jù)分析,修改原軟件的bug,順便學(xué)了pandas數(shù)據(jù)分析工具。后兩個(gè)月就是各種嘗試,基本流程就是分析數(shù)據(jù)->修改算法->測評->分析數(shù)據(jù)->修改算法->測評……
總結(jié)一下,學(xué)習(xí)算法可以沿襲先博后淵的套路。
1、了解《算法導(dǎo)論》里的基礎(chǔ)算法,HDOJ上刷題200+或者LeetCode上刷題100+或者在其他OJ上刷掉一定數(shù)目的題目,找一下感覺。
2、認(rèn)真學(xué)習(xí)一段時(shí)間的數(shù)學(xué)知識,特別是離散數(shù)學(xué),強(qiáng)推薦《組合數(shù)學(xué)》,《數(shù)論》,《圖論》三套北師大視頻。
3、自己動(dòng)手實(shí)現(xiàn)一個(gè)”高級“算法去解決實(shí)際應(yīng)用。比如用蟻群算法解決TSP問題,優(yōu)化外部排序程序,自己寫一個(gè)簡單的搜索引擎等等。這一步能培養(yǎng)一個(gè)人的科研能力,能讓人長時(shí)間專注于一個(gè)算法,而不是像第一步那樣全面撒網(wǎng)。
4、了解機(jī)器學(xué)習(xí)算法。無論是推薦引擎還是搜索引擎,都會涉及機(jī)器學(xué)習(xí)算法。了解回歸,分類問題的基礎(chǔ)算法,來一個(gè)問題,大致知道它是屬于哪類問題。比如預(yù)測用戶下個(gè)月是否購買某商品,可以將其劃為分類問題,成績排名預(yù)測可以將其劃為排名問題,使用learning to rank方法求解,資金流入流出預(yù)測屬于回歸問題或時(shí)間序列預(yù)測問題。了解一些常用的線性模型,非線性模型。
5、深度研究一種算法。
文章首發(fā)于我的CSDN博客。
ps:研二結(jié)束的那年暑假,CSDN舉辦了一個(gè)征文活動(dòng),我的這篇文章有幸榜上有名,獲得了一本技術(shù)書——《算法的樂趣》。