從如何解決問題到如何學習演算法

2021-07-14 22:55:25 字數 2237 閱讀 6685

學習演算法也有一段時間了,感覺學習了很久,遇到問題還是一點感覺也沒有,直到最近學習動態規劃,看了《演算法設計》這本書的第六章後,突然有了一些感悟。其中也包含上學期學習演算法課的一些總結和體會。

演算法的學習有兩個部分:

對於初學者而言,我認為第一點要比第二點重要的多,如果遇到了問題,你無法設計出乙個演算法,那麼即使你會證明正確性,會分析複雜度,又有什麼用呢?還有一點在於,初學的時候,我們遇到的多數都是不知道怎麼設計演算法,而不是不會分析複雜度。

基於這個原因,我認為《演算法設計》要比《演算法導論》更適合初學者。前者通過大量的例子教授解決問題的思路,後者花了大量的篇幅在做證明。前者會教你如何通過不斷地嘗試來解決問題,例如動態規劃中,為什麼這個問題描述時用了二維陣列,而不是一維的。後者通常會給出一些結論,但是你卻不知道如何想到這一點的。前者的習題經常會讓你先分析為什麼乙個演算法是錯的,讓你先對這個問題有乙個良好的認識,發現問題的性質和特點,再讓你設計出乙個正確的演算法,後者通常沒有什麼提示,直接給出題目。好的書,不僅傳授知識,更重要的是,要有啟發性。從這一點看,《演算法設計》要比《演算法導論》優秀。

當然,我並不否定證明演算法正確性的重要性,演算法導論中在證明演算法正確性時,提到的迴圈不變式的思想,對我們寫出正確的程式是非常有用的。如果實現演算法時,能嘗試去證明它是正確的,而不是實現了,就算完了,那麼對提高程式的品質和我們自身思維的嚴謹性,都是大有裨益的。不過,這一點並非我們在這裡要討論的問題。

記得演算法課第一節課上,老師就給我們畫了乙個大圖,告訴我們遇到乙個問題,應該沿著什麼樣的思路走。

遇到乙個實際的問題,首先應該把它形式化(formulation),即用數學的方式將它描述出來。其次,需要觀察問題(observation),即觀察問題的結構和性質

。為什麼我們要用這樣一種方式來解決問題呢?

每乙個實際問題都有它相應的性質和結構。

而每一種演算法技術和思想

,例如分治演算法,貪心演算法,動態規劃,線性規劃,網路流,

都有他們適宜解決的問題

。什麼叫適宜解決的問題呢?其實就是這一類問題有著某種結構和性質。例如動態規劃適宜解決的問題需要有最優子結構和重複子問題。一旦我們觀察出問題的結構和性質,就可以用現有的演算法技術和思想去解決它,而用數學的方式表述問題,更有利於我們觀察出問題的結構和性質。這就是我們解決問題時,需要兩步走的原因。

這其實給我們學習演算法提供了非常好的啟示,首先需要我們養成一種習慣,那就是遇到問題,

首先用數學的形式來描述它

。先不要管是否合適,總之先去描述它。然後通過這種描述來

尋找問題的結構和性質

,看看這種描述是不是合適,如果不合適,再換一種方式。在《演算法設計》第六章動態規劃中,曾經有過多次這樣的嘗試,首先用一維陣列來描述,發現不容易表示子問題,然後發現這種困難以後,就自發地轉向了二維陣列描述問題。通過反覆地嘗試,不斷地修正來達到乙個滿意的結果,我想這也是「研究」這個詞的英文為什麼叫 re-search 的原因吧,通過反覆的尋找(research),得出乙個美妙的想法。我最為反感的就是不問緣由,突然就冒出乙個結果,彷彿它本來就應該是這樣的。上演算法課時,老師講了乙個圖靈獎獲得者如何解決問題。在遇到乙個新問題時,他通常都是先用各種各樣的小例子去不斷地嘗試,在嘗試的過程中,不斷地與問題進行各種各樣的碰撞,然後發現問題的關鍵性質。當然,這種能力的乙個重要前提是,我們需要

學習各種演算法技術,學習的重點在於了解每種演算法技術分別適用於什麼樣的問題

,這些問題有著怎樣的性質和結構。

所以我們需要提高觀察問題結構的能力,又要積累一定的演算法技術,這需要耐下心來讀書,觀察模仿別人解決問題的思路和想法,多積累多思考,還需要大量的實踐。所以我覺得初學的時候,最好是先對各種演算法技術有乙個初步的認識,掌握解決問題的思路,然後分專題深入學習,專題學習時,可以把經典教材的相應章節都看看,題目都做了,做不出來,也要思考一段時間,另外讀演算法書時,要經常手工模擬演算法的執行過程,不要怕麻煩,模擬的過程可以對演算法的細節有深入的理解,也會培養起一些解決問題的感覺。然後讀這個領域經典的**,比如動態規劃,最早提出是哪篇**,重要的問題有哪些,看看科學家們是如何做問題的。最後,把oj上關於這個專題的題目做一做,實際用程式跑一下。完成這些後,相信對這個領域會變得非常熟悉。專題學習最大的好處就是利於建立問題之間的聯絡,加強理解,如果注意力太分散,盲目地做各類題,是很難有長進的。

最後這幅圖,是演算法課第一節和最後一節課老師在黑板上畫的圖,描述遇到乙個問題,應該沿著怎樣的思路去思考。

演算法課一般主要講的是組合優化方面的演算法,另乙個分支是基於統計的,這裡沒有給出,但是他們是同等重要的。

如何解決問題

最近打算去新的崗位,嘗試新的業務,當然也就需要新的思考,新的碰撞,想起前段時間看過溫伯格1982年出版的 你的燈亮著嗎?把序言中的總結點摘錄下來,希望能給自己帶來些許思路。問題其實就是你期望的東西和你體驗的東西之間的差別。動手去解決問題之前,好好想想問題的 如何站在各個角度來看待面臨的問題,以能夠知...

如何解決問題

很多時候只是解決問題的表象,即來乙個問題處理了,但並沒有歸因,找到更深層次的根本矛盾。如乙個專案比其他專案問題更多,更不可控,如果只是列出所有的問題逐個解決處理,只是在解決問題本身,並沒有定位根本原因。根本原因是專案難度更大?專案成員表現 狀態不好?根據根本原因如何處理。為了解痛點和原因,需全面評估...

我們是如何解決問題的

我們是如何解決問題的?2015年8月份自己動手寫了乙個工具 restfull request tool 0.0.1 snapshot.jar 裡面用到了 但是遇到乙個問題 沒有顯示表頭 header 如下圖 也在網上查了資料,一直沒有解決.下面才是我的預期 直到今天才解決,但是也是偶然解決的.經過是...