老鳥向新手講解各種程式設計比賽

demoZ發表於2015-05-18

過去十年間我一直在參加各種程式設計比賽。我參加了很多比賽,更重要的是,我參加了很多不同型別的比賽。我的冒險起始於經典演算法,之後我轉到了優化問題。目前我主要參加機器學習競賽(作為兼職),我也參加一些只是為了好玩的比賽。

考慮到有像我這樣廣泛經歷的人並不多,我想我應該寫一個程式設計(演算法?)競賽流行型別的(相對)簡短的總結。這不是一個完整的列表,我只關注了那些最流行的,並且在我看來最有用的競賽。

這篇文章的結構是以競賽型別,而不是競賽網站為導向的。也就是說,我把有相似特徵的網站/競賽歸類,而不是呈現給你們僅僅加了我個人描述的隨機網站。由於有些網站提供了幾種型別的競賽,我不得不多次列出它們。

如果你對程式設計競賽的世界感到困惑或者好奇,這篇文章能給你關於這個主題的詳盡綜述。

經典演算法

有時又被稱為二元問題或(帶貶義地)消遣演算法。提供給你問題陳述,你的目標是寫一個通常很短的程式:讀入輸入,處理它並輸出計算結果。任何東西都是按給定的問題陳述來的。大部分情況下, 你要提交程式原始碼,原始碼在遠端伺服器上編譯並執行一些對你隱藏的資料。下面要提到的所有競賽的共性是:你的程式要麼被認為是完全正確的,要麼是完全錯誤的,沒有中間結果。

經典演算法競賽通常是程式設計競賽的入門級別。難度從答案顯而易見,到只有問題作者知道怎麼解答。對於新手程式設計師,它們提供了小的挑戰,是很棒的實踐練習。在更高的級別,它們需要高度的專注,很好的長期記憶,解決問題的技巧以及很深的專業知識。如果能在這些競賽中做好,你會開發出很多可以輕易遷移到電腦科學其他領域的技能。前提是你專注於開發純粹的技能,而不是把時間花在解決成百上千的問題上以期望今後能遇到類似的問題。(譯者注:即不要用題海戰術

競賽聯盟

有兩個主要的網站定期舉辦比賽。第一個是 TopCoder(以下簡稱 TC),舉辦Single Round Matches (SRMs)。第二個是 CodeForces(以下簡稱 CF)。

這兩個網站很相似。一週會舉辦幾次比賽(即將到來的比賽連結:TCCF)。比賽持續大約2小時。每種比賽都會用幾個(TC 是 3 個,CF 是 5 個)為這輪特別準備的原創經典問題(通常,對於所有的比賽都是這樣的,但我想澄清這一點)。你只需提交程式原始碼,程式會在伺服器上遠端執行。你的程式如果想要被認定為正確,需要在指定的時間和記憶體限制下執行,產生正確的輸出。美中不足的是,只有在比賽結束後你才知道你的解答是否正確。當這輪結束後,你的排名會得到更新(類似於 ELO 等級系統),這很準確地代表了你目前的水平。賽前參賽者(根據他們當前的排名)會被分到兩個不同的賽區,每個賽區使用根據參賽者水平量身定做的題目。另外,賽後你可以看其他人的提交,也會發布題解(解釋了問題的正確解答)。所有的題目會新增到練習區,這樣你之後就可以去解答那些你在比賽中未能解答的題目。這使得這兩個網站成為完美的訓練場。

這些是它們的相似之處,那麼不同之處是什麼呢?TC 最大的缺點是(除了糟糕的管理,不過那又是另一回事了)它使用一個陳舊的 Java applet 來用於競賽。儘管這使得參加第一次比賽比它應有的過程更復雜(TC 那設計糟糕的網站對此也沒什麼幫助),但從長遠看來比“HTML5”介面也差不了多少。另一個差別是兩個網站的題目的關注點稍有不同。TC 上的任務通常向解決問題傾斜,有時候甚至像謎題,然而 CF 就包含很多基於資料結構的“filler”(缺乏想象力的代名詞)問題,但這主要取決於問題作者。基於我的經歷,TC問題(平均來說)稍微有趣些,但CF的題目更為多樣—主要是因為CF每輪有更多的題目。兩種競賽都有一個特性是提供尋找他人程式碼中bug的機會(如果你成功找到了會獲得額外的分數),但是CF對此的設計很可怕(譯者注:表示對此沒什麼感受),最好就是完全忽略它。

年度現場比賽

有四個大的比賽:Google Code JamFacebook Hacker CupYandex.AlgorithmTopCoder Open(演算法組)。它們都很相似。為了取得現場比賽資格,你要參加一系列線上資格賽。通常都是採用淘汰賽的形式,在隨後的每一輪減少參賽者的數量。通常對參賽者的身份沒有限制(除非你的國家不幸在美國的禁止入境名單上)。每一輪時間都很短,在 90 分鐘和 3 個小時之間,只考經典的二元問題(譯者注:前面提過了)。如果你取得了現場賽資格,他們會支付你參加比賽的交通食宿費用。他們也給獲勝者獎金,但對於大多數人來說,你能贏得的最重要的東西是旅行本身,或者(通過比賽)在頂級 IT 公司找到工作。

這些比賽之間有一些小的差別(題目質量、晉級結構、提交系統),但是它們有兩個共性:晉級其中任何一個都非常難(如果你沒有兩年經驗,想要取得資格是極不可能的,即使你聰明且專注於此)。另一個是有個人(Gennady Korotkevich)在2014年贏了個大滿貫。考慮到所有這些競賽要想贏都有很高不確定性,這是一個難以置信的壯舉。

伯樂線上補充:Gennady Korotkevich年僅11歲時便參加國際資訊學奧林比克競賽,創造了最年輕選手的記錄。在2007-2012年間,總共取得6枚奧賽金牌;2013年美國計算機協會程式設計比賽冠軍隊成員;2014年Facebook黑客杯冠軍得主。截止目前,穩居俄程式設計網站Codeforces聲望第一的寶座,在TopCoder演算法競賽中暫列榜眼位置。

線上判題系統

這些有很多了,僅列舉一些:SPOJUVATimus。通常,它們主要作為過去的ICPC(譯者注:即 International Collegiate Programming Contest, 國際大學生程式設計競賽)競賽題的存檔。

你在這些網站上花時間原因不外乎那麼幾個:

  • 一:你覺得你很不擅長某些型別的題目,因此你在尋找一些很難的特定題目(如果你以成為世界前100為目標,這甚至都不應該發生),而你在其他地方又找不到這些題目。
  • 二:你參加了一場比賽,那些題目被上傳到判題網站,你想繼續嘗試那些你沒有解決的問題或者嘗試其他的解題方案。
  • 三:你的演算法課老師很懶,他討厭他的工作。

優化問題

這種問題的標準例子是旅行商問題。這些問題以這樣的事實來刻畫:根據你的解答質量,你得到不同的分數。它們被(或者至少應該被)設計為不可能獲得完美的分數。

有優化問題的比賽通常持續時間更長,因此相對於經典演算法比賽關注於不同的技能集,比如心理耐力、時間管理或開箱即用的問題解決技能。通常,優化問題要求你是個多面手,但是你不必擅長於任何特定領域。它們也更接近於做實際研究,因此如果你想把你的職業生涯與軟體開發以外的事綁在一起,嘗試下它們是個不錯的主意。

馬拉松比賽

不幸的是,沒有太多地方可以讓你磨練在這個領域的技能。Topcoder有馬拉松比賽,但是他們不再定期舉辦比賽,幾年前他們還這麼做。在馬拉松比賽旗下舉辦的大多數比賽都屬於機器學習類(在下面描述),例外是年度TopCoder Open比賽中的馬拉松類,現場決賽和資格賽都使用優化問題。有傳聞他們想重新舉辦定期比賽,但到目前為止什麼都還沒改變。

幸運的是,儘管沒有太多比賽,TopCoder有過去比賽題目的存檔。因此如果你的目標只是更擅長優化題目,你可以練習這些舊題。好處是你可以獲得所有的優勝解答,另外在這些過去的比賽對應的論壇通常有個“釋出你的方法”的帖子。

在一些其他的比賽中你也可以遇到優化問題。但不幸的是,我不認為有可以與馬拉松比賽相提並論的。這個類別下最流行的比賽大概是 Al Zimmermann 的程式設計比賽,但是那的題目都很淺,不太有趣。

機器學習

有時被錯誤地稱為資料科學。這是個有大把錢的地方,因為對專長於機器學習的人才有很大需求,至少相比對經典和優化問題人才的需求來說是很大的。

相比其他型別的比賽,機器學習需要的知識要多得多,通常來說也不那麼有趣。儘管如此,這些比賽仍然是目前在這個領域獲得一些親身實踐經歷的最容易的方式。如果你需要一些動力,記住需要機器學習技能的工作的報酬在整個IT界是最高的那部分。

馬拉松比賽(再次)

我可能提到上面提過的網站/比賽。Topcoder把優化和機器學習問題結合到一個類別。說得更準確些,在某些時候馬拉松比賽類別擴張為包括機器學習比賽。

Topcoder的機器學習比賽通常只以一種方式呈現。由於整個Topcoder是個眾包平臺(再加上圍繞它構建的社群),客戶有時候會有用“簡單的”軟體競賽不能解決的問題。在有些情況下,他們處理的問題可以包裝成一個機器學習比賽,給表現最好的方案大筆錢。由於機器學習比賽仍然是馬拉松比賽,整個提交系統的執行方式是和優化問題完全一樣的。唯一的差別是機器學習比賽通常不加入到練習區。

Kaggle

Kaggle是個很大程度圍繞機器學習比賽而建的網站。我將關注於TC和Kaggle的差別。最大的差別是在Kaggle你只提交你的解答的輸出,而不是整個程式,這有很多後果。首先,你獲得整個資料集,對你可以使用的語言/庫沒有限制。沒有任何時間限制,如果你想(並且支付得起)的話,甚至可以用整個叢集來計算結果。由於大家不用提交原始碼,在比賽結束後你不能檢視解答。另一方面,社群要活躍得多。當比賽還在進行中時,會有很多“練習賽”,在此人們分享他們的解答。Kaggle的比賽時間也長得多(對於有獎金的比賽通常是兩個月)。

總體來說,兩個網站各自為稍有不同的目的服務,各有利弊。對於那些對高層知識,而不是各種機器學習技術如何工作的低層內部機制更感興趣的人來說,Kaggle應該更為友好,然而TC對於有很強演算法背景的人來說可能更好。另一種看待這個的方式是,在Kaggle你(通常)使用工具,而在馬拉松比賽你(通常)寫你自己的工具。

歡樂24小時

15年前,第一屆 Challenge24 組織起來了。我不會細說它的歷史,因為實際上我也所知甚少。但我會把這個比賽描述為“24小時的瘋狂”。它是在布達佩斯舉辦的年度團隊比賽。你有大概15道題。題目的範圍很廣:經典、優化、TCP/IP之上的遊戲、計算機視覺、聲音分析、謎題,以及難以用語言描述的東西。你把你自己的硬體帶到比賽現場,整個比賽是離線完成的。老實說,這是我參加過的最有趣的比賽。即使我上次參加時發燒了,我還是要這麼說。

Challenge24啟發了Deadline24,這反過來又啟發了Marathon24(兩個都是在波蘭舉行)。它們是Challenge24的簡化版,但仍然很有趣。它們沒有大量題目,通常只有三個遊戲,每輪遊戲和比賽同時開始。例如,過去的一個遊戲是30個選手同時玩經典的行星遊戲。

由於只有有限數量的隊伍會被邀請到決賽,這些比賽都舉辦線上資格賽。由於這些比賽並沒有其他年度比賽那麼流行,實際上即使沒有任何顯著的演算法(甚至程式設計)背景,也很可能獲得其中之一的資格。

還有一個額外的年度比賽值得一提,它和這些24小時比賽有些類似:網際網路問題解決比賽。這個比賽也有很多工,儘管它們更類似於經典演算法。

其他

還有兩個大的網站被遺漏了。第一個是CodeChef,有兩種不同的月度比賽。兩種都是經典演算法比賽。另一個是HackerRank,混合了線上判題系統和舉辦各種型別一次性比賽的功能。我遺漏它們的原因是,它們都因問題陳述的質量低而聞名(譯者注:譯者使用過這兩個網站,對此沒什麼感受)。考慮到有大量的其他比賽,通常你應該避開它們(儘管有很少的例外)。

如果你還在讀高中,對你來說最重要的比賽是國際資訊學奧林匹克競賽。每個國家都有其國家級奧林匹克競賽和自己的規則。在很多國家,在國家級奧林匹克競賽中表現優異是進入理想大學最簡單和安全的方式。

國際大學生程式設計競賽(ACM/ICPC)是“經典演算法”比賽,在這裡所有的比賽/網站中歷史最為悠久。它是面向學生的團隊比賽。每支隊由同一大學的3個人組成。ICPC的主要目標是程式設計在世界範圍的普及。這是用複雜的多層獲得資格制度和(同樣複雜)的合格標準來達成的。這保證了世界總決賽中隊伍的多樣性。作為取捨,根據你所在的地方,要想晉級世界總決賽,要麼是令人吃驚地容易,要麼是近乎不可能。專門針對ICPC來練習可能是把你的時間投資在程式設計競賽中最壞的方式,因為它提升的技能集是最窄的,唯一的例外是你生活在那些“幸運的”(譯者注:即容易晉級的)地區。

鼓勵獎要頒給Hello World Open,因為它創造了年度最大的扯淡比賽,有著很成功的銷售計劃。如果你仔細看,你會看到在比賽發起後,他們甚至在維基頁面加入了他們的連結。我猜如果你製作收入最高的手機app,你會很熟悉這個。說真的,Topcoder應該向他們學習。

另一個鼓勵獎要頒給 Imagine Cup。我參加了四次Imagine Cup。兩次作為參賽者,一次作為裁判,最後一次作為助手。這些年我看著它從一個聚集多個不同領域(初創,數字藝術,演算法/人工智慧)的學生的創新年度比賽,到微軟產品的傻逼公關。裁判經常是因政治原因被挑選的,絕對不能勝任他們的工作。並且所有沒有直接微軟產品的類別都停掉了。事實是,Imagine Cup是我參加過的最好的現場賽事。同時,現在我不會推薦任何人蔘加它們。

Project Euler是一種特別的線上判題系統(偏重數學),這在於你以程式設計為工具來解決問題,而不在於它本身。如果你真的想在沒有時間壓力的情況下做一些程式設計題,我建議你做Project Euler,而不是我提到的其他判題系統。另外,由於它很流行,如果你在某個問題卡住了,在網上找到一些幫助要容易得多。

編注:推薦幾篇相關文章

打賞支援我翻譯更多好文章,謝謝!

打賞譯者

打賞支援我翻譯更多好文章,謝謝!

任選一種支付方式

老鳥向新手講解各種程式設計比賽 老鳥向新手講解各種程式設計比賽

相關文章