讀古今文學網 > 算法神探:一部谷歌首席工程師寫的CS小說 > 9 倒退一步,繼續搜索 >

9 倒退一步,繼續搜索

Mudwall這個港口的名字聽起來相當不起眼。然而實地看到的甚至比它的名字還要讓人失望。其實它根本算不上是一個港口。搖搖晃晃的船塢只能勉強容得下兩艘中等尺寸的船。而Mudwall原本準備建成的一堵兩英尺高的城牆,更是從來就沒有建成過。整座城的周圍只有小半段散落著星星點點的兩英尺高的土堆。

Frank踏過土堆,來到了城裡的商店。Notation和Socks緊跟在他身後。

店主看到他們的到來,驚喜萬分,急切地走向他們。經過櫃檯的時候,卻不慎將一摞畫著胡蘿蔔的遊客手冊撞到了地上。

「你好!」店主以幾乎要叫出來的語氣說道,「歡迎來到Mudwall,著名的土蘿蔔農場之鄉。你們需要點什麼?食物?補給品?蘿蔔?蘿蔔味蛋糕?我們有一個特別好吃的胡蘿蔔派。」

「信息。」Frank說道。

店主的臉沉了下去。「哦,」他說,「那看來你們不是來參加蘿蔔節的了?」

「蘿蔔節?」Notation問道。

店主點了點頭:「再過兩天就是第50屆蘿蔔節了。」

「會有很多人來看嗎?」Notation問道。

「最近沒那麼多,」店主承認道,「Mudwall不像過去那樣對遊客有吸引力了。自從G』Raph開始辦他們自己的土蘿蔔節後,人們就都去那裡看了。」

Notation和Socks對望了一眼。Socks用唇語說道:「土蘿蔔是什麼?」Notation聳了聳肩。

「你知道關於前兩天經過這裡的一艘船的信息嗎?」Frank問道。

「什麼船?」店主問道,「這裡幾個月都沒有船經過了。倒是有幾個驢車從公路上經過,但從沒有過船。」

「你確定嗎?」Notation說道,「我們在調查公務,你最好告訴我們關於最近從這經過的船的所有消息。」

「如果有船經過的話,我想我會知道的,」店主說道,「我的窗外正好可以看到船塢。就算我沒有親眼看到,也會聽別人說過。現在這裡都沒什麼船經過了。要是有船經過的話,蘿蔔之聲——我們這的一個三人樂團——會去演奏迎接他們的。所以要是有過船經過的話我肯定會聽說。」

Notation似乎準備開始新一輪的提問。但Frank插話道:「謝謝了,先生。麻煩了。」

緊接著,Frank帶著Notation和Socks走出了商店,回到了泥濘的街上。

「你覺得他在說真話嗎?」Notation問道。

Frank點了點頭,來回巡視著這條街。「我們提到船的時候,他看起來是真心驚訝。」他說,「但再多打聽一下總沒有壞處。」

他們又問了十幾個小鎮上的居民同樣的問題。這幾乎是小鎮上一半的人口了。結果讓他們徹底死心了。沒有人看到過任何船經過,也沒有人聽說過有任何船經過,甚至都沒有人想過會有船經過。很明顯,這座港口城市已經很久沒有被船造訪過了。

「也許那艘船是晚上來的。」當他們走回TCP Flyer號的時候,Notation說道,「也許他們派了一小隊人划小船上岸,把文件交給了在這裡等著的人,然後就離開了。」Notation邊說邊指向船塢上一塊毫不起眼的木板。

「有可能,」Frank說道,「不過這都沒用。沒有證人,就沒有線索。」

「你是什麼意思?我們就找不到他們了?調查就到此為止了?」Socks問道。

Frank笑了笑說:「當然不是,年輕人。調查案子總會遇到走不通的死路。所以我們才會用一種可以支持倒退的搜索算法。」

Socks眼神空洞地看著Frank。看到Socks並沒有理解自己在說什麼,Frank補充道:「我們沿著最有可能找到答案的路一直往下走。但如果遇到了死路,就倒退一步,換一條之前沒有走過的路繼續調查。」

「所以你還有其他線索?」Socks問道。

「有一些吧。」Frank承認道。

「那我們倒退一步,考慮一下以前沒有走過的路。」Notation沉思道,「之前我們找到的航海日誌上,還列了另一個地方:Frayed Cable島。」

Frank點了點頭,開始回憶他們還有哪些線索沒有用過。之前那個資格最老的惡棍提到過一個叫什麼聯盟的地名。這樣看來,Frank現在還沒用過的線索有:

Frayed Cable島

Array Cart上的線頭?

Vinettes

聯盟?

倒退一步的話,便是回到了那本航海日誌,和上面寫著的他們還沒有去過的Frayed Cable島。要是他們在那個島上也找不到任何線索的話,就只能去追查Array Cart上的線頭,或者那些希望更渺茫的線索了。

「所以案子還沒有結束,你還有其他線索對吧?」在TCP Flyer號開往Frayed Cable島的一路上,Socks至少問了十次。

「在調查中遇到死路後倒退一步是家常便飯。」Notation再一次告訴Socks不必擔心,「難道你們這行在做事兒的時候就從來不需要倒退一步嗎?比如做藥水的時候?」

Socks看起來十分驚訝:「做藥水的時候怎麼倒退一步啊?你又不能把加進去的蜘蛛腿給去除掉,也不能讓藥水回到攪拌前的樣子。」

「我是說在你研究藥水配方的時候,就像你加入蜘蛛腿後,如果發現它破壞了藥水的魔性或者什麼其他問題,你可以在配方上去掉蜘蛛腿,再嘗試一種新的配方,對吧?每一個藥水配方才是你搜索空間中的一個狀態,而對你來說,倒退一步,便是退回之前成功過的其他配方。」

「哦,」Socks說道,「你是說改良配方的過程啊。當你研究藥水配方的時候,總會需要不斷地改進它。就像走一條彎彎曲曲的路才能找到你要的配方。沒有人可以第一次就把所有東西給弄對。」

「就是這樣。我們在說的是一回事。」Notation說道。

Mavis也加入到他們的談話中,說道:「就好比你在一個洞穴裡面找一堆丟了的東西。你會沿著一條路找,直到發現那條路上沒有任何有價值的東西時,就會倒退一步,換其他的路繼續找。」

「是的,」Notation猶豫地點了點頭,「搜索中的倒退就像在洞穴裡找東西一樣。不過……」

「說到搜索,我們已經到了你們要去的地方了,」Mavis插話道,「Frayed Cable島沒有船塢。我們只能把TCP Flyer號停在這裡,讓你們划船走剩下的路了。」

警用算法導論:倒退一步

節選自Drecker教授講義

幾乎調查所有案子的過程中,都會需要倒退。即使是最厲害的警察也沒有辦法從頭到尾一步到位。辦案的過程中會遇到很多沒用的誤導人的信息,以及有歧義的線索。不僅如此,人自己也會犯錯。所以在遇到死路時一定要學會如何倒退。簡單地說,就是倒退一步,退回到之前一步的狀態,然後選擇另一條不同的路繼續搜索下去。

對於目前所看到的算法,我們都可以高效地從任意一個狀態跳到另一個狀態。比如說在一個數組裡面,我們可以很容易地通過序號來查看任何一個地方存放的數字。而在賓館的走廊裡,我們也可以在各個房間之間任意跑動。這種靈活性讓我們的算法可以很高效。

但是也有很多搜索問題會限制你只能以特定的方式從一個狀態跳到另一個狀態。比如,在現實生活中的一個城堡裡進行搜索時,你不能從一個房間直接跳到另一個房間。要想到另一個房間,你得先經過走廊和一些其他的房間。而在計算機領域中,一些數據結構(比如圖和鏈表)也會做一些類似的限制。

即使可以在狀態中自由跳轉時,你也可以把倒退這個操作想像成是在你之前走過的路上去尋找新的沒有走過的狀態。在算法世界中,退回之前的狀態比在現實生活中走回之前來的地方要省力得多。但是這兩者在本質上是類似的:你退回一步,然後選一條新的路繼續搜索下去。

在接下來的講座中,我們會看到很多搜索算法遇到死路時倒退的例子。而一旦你正式成為了一名警察,你在工作中會遇到的死路將比你想像的要多得多。