思維探索者 從問題到答案的思維過程 像偵探一樣思考

2022-05-03 10:27:16 字數 4214 閱讀 5862

目前幾乎所有的演算法書的講解方式都是歐幾里德式的、瀑布式的、自上而下的、每乙個推導步驟都是精準制導直接面向目標的。由因到果,定義、引理、定理、證明 一樣不少,井井有條一絲不亂毫無贅肉。而實際上,這完全把人類大腦創造發明的步驟給反過來了。看起來是陽關大道,實際上車馬不通。

而對讀者來說,這就等於直接告訴你答案和做法了,然後讓你去驗證這個答案和做法是可行和成立的。而關於答案和做法到底是怎麼來的,從問題到答案之間經歷了怎樣的思維過程。卻鮮有書能夠很好的闡釋。

我們要的不是相對論,而是誕生相對論的那個大腦。我們要的不是金蛋,而是下金蛋的那只雞。

人類對問題的思維形式

我們在思考乙個問題的過程中有兩種思維形式:

1. 聯想

這種思維某種程度上可以說是「混亂」的(雖然從乙個更根本的層面上說是有規則的),所謂混亂是指很多時候並不確定聯想到的做法最終是否可行,這些聯想也許只是基於題目中的某個詞語、語法結構、問題的某個切片、一些零星區域性的資訊。這個過程是試探性的。最後也許有很大一部分被證明是不可行的。很多時候我們解決問題用的都是這種思維,簡言之就是首先列舉你關於這個問題能夠想到的所有你學過的知識,然後一一往上套看看能否解決手頭的問題。這種思維方式受限於人腦聯想能力本身的侷限性。

聯想本身需要記憶提取的線索,所以受到記憶提取線索的制約,如果線索不足,那怎麼也聯想不起來。而提取線索的建立又取決於當初儲存記憶的時候的加工方法,同時,面對乙個問題,你能夠從中抽取出來的聯想線索又取決於你對問題的認識層度/抽象深度,表淺的線索很可能是無關的,導致無效的聯想和試錯。總之,聯想這個過程充滿了錯誤的可能。

2. 演繹和歸納

演繹和歸納是另一種思維形式。它們遠比聯想有根據。其中演繹是嚴格的,必然的。歸納也是有一定根據的。在面對乙個問題的時候,我們有意無意的對問題中的各個條件進行著演繹;譬如福爾摩斯著名的「狗叫」推理——狗+生人=>吠叫 和 昨晚狗沒有叫 => 那個人是熟人。就是乙個典型的對問題的各個條件進行演繹的推理過程。還有就是通過對一些特殊形式的觀察來進行歸納,試圖總結問題中的規律。

然而,不幸的是,面對複雜的問題,演繹和歸納也並不總是「直奔」問題的解決方案的。人的思維畢竟只能一下子看到有限的幾步邏輯結論,一條邏輯演繹路徑是否直奔答案,不走到最後往往是不知道的,只要答案還未出現,我們大腦中的邏輯演繹之樹的末端就始終隱藏在黑暗之中。而當最終答案出現了之後,我們會發現,這棵演繹之樹的很多分支實際上都並不通往答案。所以,雖然演繹和歸納是一種「必然」的推理,然而卻並不「必然」引向問題的結論,它也是試錯的,只不過比聯想要更為靠譜一些。

像偵探一樣思考

既然認識到,人類解決問題的兩大思維方式實際上都是有很大的試錯成分的(好聽一點叫「探索」),那麼就不難意識到,對乙個問題的思考過程實際上是相當錯綜複雜的,而且充滿了無效分支——在思考的過程中我們也會不斷的對分支進行評估,做適當的剪枝——因此當我們找到問題的解之後,一來思維的漫長繁雜的過程已經在大腦裡面淡化得差不多了,只有那些引向最終結論的過程會被加「高亮」——我們在思考的過程中本就會不斷的拋棄無效的思路,只留下最有希望的思路。簡而言之就是最後證明沒用或者早先我們就不抱希望的一些想法就被從工作記憶中扔掉了。二來,思考過程是我們的空氣和水,而「魚是最後乙個感覺到水的」,我們感覺不到思維法則本身的存在,我們只是不知不覺運用它。三來,由於我們的目標是問題的解,解才是我們為之興奮和狂喜的東西,而不是求解的過程,過程只是過程,目的才是目的。這就像乙個尋寶者,在漫長曲折的尋寶歷程之後,在找到寶藏的時候,他會對寶藏感到狂喜(記得阿基公尺德的「找到了!」嗎?)而迫不及待地要展示出來,而漫長的思考本身卻成了註腳。我們是有目的的動物,目的達到了,其它的就相對不那麼重要了。最後,對於傳授知識的人,也許還有其四:感到介紹思維過程是不相干的,畢竟思維過程並不是演算法問題的解,演算法問題的解才是演算法問題的解。然而不幸的是,忽視到達解的那個過程實際上卻變成了捨本逐末。我們看到的是寥寥數行精妙絕倫的演算法,然後仰天長嘆自己想不出來啊想不出來。為什麼想不出來,因為你不知道那短短數行演算法背後經歷的事怎樣漫長的思考過程,如果問題求解是一部偵探**,那麼演算法只是結局而已,而思考過程才是情節。

如何培養解決問題的能力

然而,我們都是人,人類該有的思維形式,我們難道不是都有嗎。既然如此,思維本身又有什麼需要一遍遍教的呢?

並非如此的。

1. 像騎自行車一樣將將思維方法內隱化。思維法則其實也是知識(只不過它是元知識——是幫助我們獲得新知識的知識);是內隱的記憶。我們在思考的過程中覺察不到思維法則的作用,它們卻在幕後實實在在的左右著我們的思維軌跡。要將思維方法內隱化,需要不斷練習,就像需要不斷練習才能無意識狀態下就能騎自行車一樣。

2. 強化思維習慣以觸類旁通。思維法則也是知識記憶,是問題解決策略。既然是記憶,就受到提取線索的制約,這就是為什麼當波利亞告訴你要「注意未知數」之後你還是不能真正在所有需要你「注意未知數」的地方都能提醒自己「注意未知數」。很多時候未知數是很隱蔽的,未知數並不會總是頭頂乙個大帽子上面寫著「我是未知數」。所以很多時候缺乏對這個策略的「提醒」線索,這也是為什麼你學會了在解決數學問題的時候「注意未知數」卻不一定能在解決現實生活中的問題中時刻都能「注意你的未知數」(《你的燈亮著嗎?》整本書的價值便在於此),因為解數學題和解決生活中問題的場景不一樣,不同的環境線索,在你大腦中激發的記憶也不一樣。就連問題求解中,不同的問題之間的細小差別也可能導致思維軌跡很大的不同,有時你的注意力會被乙個無關線索激發的聯想吸引開去,忘記如「注意你的未知數」這樣的重要法則。而一本從思維角度來講問題求解的書則可以一遍遍將你置於不同的問題場景下然後在該提醒你的時候提醒你,讓你醒悟到「哦,原來這個時候也應該想到這個啊。」,做多了這樣的思維演習你就會逐漸從中領悟到某種共性,並將一些思維習慣得到強化,於是終於能夠在需要運用某策略的時候能適時的想起來了。

3. 注意提取記憶的線索。我們平時學習演算法時幾乎僅止於「理解」,別人把乙個方案放在你面前,你去驗證一下,心說「哦,不錯,這個的確可以工作」。然後就沒了。稍微簡單一點的演算法還好,複雜一點的對於記憶的負擔是很大的,這就是為什麼有時候我們看到乙個絕妙的解法,這個解法看上去不知道從**來的,但經過我們的理解,卻發現是對的,我們感嘆,真巧妙,結果一些天之後,別人問起這個問題,我們說:「唉,那是個多麼巧妙的演算法啊,但是我只記得它巧妙,卻不記得它到底是怎樣的了。」 為什麼?因為在不知其所以然的情況下,演算法只是一堆離散的機械步驟,缺少背後的思想的支撐,這些步驟之間就沒有乙個本質層面上的關聯(先知亞里斯多德早就指出:學習即聯接)。所以就跟背歷史書也沒多大區別。然而,知道了演算法是怎樣一步步被推導出來的,我們就一下擁有了大量的記憶提取線索:對演算法發現過程中的任何乙個關鍵步驟(尤其是本質)的回憶都可能使我們能夠自己動手推導出剩餘的內容。譬如你知道堆(heap)是怎樣由樸素的決策樹演化而來的,它又是為了解決什麼問題的,你即便忘記了具體的細節,也可以自己推導出來。譬如你知道kmp演算法的本質在於消除回溯,至於如何消除回溯卻並不是那麼難以推導的,所以即便忘了也可以借助於大腦的邏輯演繹能力再現出來。譬如你知道tarjan演算法其實只是從後序遍歷經過兩個優化調整而來的(其中並查集的使用其實只是優化手段——為了能夠迅速判斷祖先節點是誰——而非演算法本質——當然,演算法設計的主要任務本來就是通過問題條件中蘊含的知識來「消除冗餘計算」和「避免不必要計算」,所以你也可以說並查集的使用是關乎本質的,只不過,知道了為什麼需要引入並查集,就會強烈地感覺到一切是順理成章的了),那這個出了名的繞人的演算法也就不那麼難以理解和記憶了。譬如你知道排序的本質,就能夠對什麼是最優排序,為什麼它是最優排序有深刻的認識。四兩撥千斤。

4. 從抽象到本質。記乙個演算法,就只有乙個演算法。乙個蘿蔔乙個坑。就好比背99乘法表只能解決乘法問題一樣。而記背後的思想,卻有助於解決一類問題。思想所處的抽象層面往往比到處都是實現細節的演算法本身要低,越是低的抽象層次,越是本質,涵蓋範圍越是廣泛。數學的發展本身就體現了這個過程,抽象代數就是非常好的例子。演算法誕生過程中的思路往往包含了比實際演算法更本質得多的知識,實際演算法乃至演算法的某個特定語言的實現包含了太多表面的不相干知識,它們會阻礙對本質的理解。

5. 重在分析推理,而不是聯想。學了一大通演算法和資料結構之後的乙個***就是,看到乙個問題之後,腦袋裡立即不管三七二十一冒出一堆可能相干的資料結構和演算法來。聯想是強大的思維捷徑,在任何時候都會搶占大腦的工作記憶,由不得你控制——比如我問你「如何尋找區間的最大值」,首先進入你的意識的肯定就是學過的那個演算法,甚至演算法的實現細節都一一跳了出來,也許最先跳出來的還是演算法實現中某個最容易弄錯的邊界細節,或是某個比較tricky的實現技巧!然而這些其實根本不反映乙個演算法的本質,結果想來想去總是停留在問題的表層。而另一方面,重在思維的傳授則可以讓人養成從問題本質入手,逐步分析推理的習慣,而不是直接生搬硬套。當然,完全不可否認,聯想本身也是極其重要的思維方法,甚至可以說是人類思維最重要的特徵。很多時候我們並不知道問題的本質是什麼,就需要靠聯想、模擬來領路探索。只不過,養成優先從問題的本質入手進行考察的好習慣絕對是有更大的好處的。

具體到演算法的學習

具體到演算法書,那就不是光看text book就足夠的了,為了深入理解乙個演算法的來龍去脈前因後果,從乙個演算法中領悟盡量深刻的東西,則需要做到三件事情:

一起特殊中文全文檢索問題的解決 探索者

事件起因 好幾個月前,我製作的某個 覺得有必要採用全文索引擎,簡單地自己的電腦上測試了一下全文索引,搜尋一些英文本元沒有問題,但搜尋中文時就出現 查詢子句只包含被忽略的詞 的錯誤,任何中文都是如此。由於此 不是很急,也就過去了。近幾天,我原來製作好的乙個 需要轉移,它使用了全文索引。突然發現新的專業...

資料擴增中的逆向思維解決過擬合問題

常規在機器學習與深度學習模型訓練過程中,經常會對較少的類別進行擴增。資料擴增一定程度上可以緩解類別的不平衡性,也可以擴充套件樣本的多樣性。在機器學習訓練中,還有乙個很難繞開的問題是 過擬合 過擬合的主要原因是學習到了一些 假模式 這也是因果律被詬病的主要原因之一 比如在進行分類的時候,狗狗類別的影象...

思維的蛻變 從程式設計師到專案經理

文 火星人 出處 it168 因為我在參與的軟體專案開發表現出色,公司在新乙個軟體開發專案上委派我做專案經理,全權負責專案各種事務的管理。繁忙的事務處理使我體力透支,有一種脫了一層皮的感覺,但最使我心力交瘁的是從軟體程式設計師到專案經理的一種思維方式和觀念的痛苦轉變。在軟體越來越複雜,需求多變的情況...