讀古今文學網 > 算法神探:一部谷歌首席工程師寫的CS小說 > 2 窮舉搜索尋線人 >

2 窮舉搜索尋線人

「高效算法的關鍵在於信息。」這是Drecker教授的口頭禪,在每一堂警用算法課的開始,他都會沖學員厲聲強調這句話,Frank對這句話的印象如此強烈,以至於將它永久封存在了自己的記憶中:「一個好的算法取決於發現數據中的結構並善加利用。而這取決於信息。」

回憶至此,Frank暗地裡微微一笑,此時他走在了三比特街巷,這是一條坑坑窪窪的泥土路,兩旁交相排列著破舊的酒吧和高檔的咖啡廳。他沖兩位路過的騎士禮貌地點點頭,騎士們身著盔甲走過時還發出鏘鏘的響聲。Frank暗自盤算著,待會兒在離開之前,必須要來杯三倍特濃的意式咖啡。首先,他需要的是信息,來幫助指導搜索。他很確切地知道要從哪裡開始。

「玻璃箱」Billy此時一定在某處靜靜地坐著,傾聽著屋內飄蕩的每一段對話。人們並非成心想在Billy身邊說這說那的,其實是壓根沒注意到他的存在。Billy被賜予了一種特別值得一提的天賦,那就是徹徹底底的不顯眼。不管做什麼,Billy身上總有一種東西,能讓人們注意不到他。或許是他的白皮膚或小身板,或許是他對穿著分外平庸的品味。不管是什麼,Billy早已決定,要充分發揮他的天賦,竊聽並收集信息,再賣給任何願意收購的人。

Frank打量著三比特巷上擠在一塊兒的八個店面,琢磨著Billy會選其中哪一個。他在腦中思考了半打的搜索算法,但一無所獲,沒有任何信息可以用來確定Billy的位置。Billy有可能在其中任意一家酒吧或咖啡館中。

他不得不採用窮舉搜索了——索性試遍所有的可能性,直到他找到Billy。這其實不太適合他。多年的偵探和私人調查經歷已經讓他明白,幾乎所有算法都優於窮舉搜索算法,而他厭惡訴諸如此低效的方式。

Frank一邊抱怨,一邊開始了搜索。他走進了街上的第一家酒吧,名字叫Absolute Value。

酒保是一個名叫Abe的粗暴男人,從Frank一進門便瞪著他,目的明確地把手放到滿是劃痕的吧檯下面。信息很明確:「我正握著武器,至於是哪種,你猜去吧。但如果你找我麻煩,我會讓你嘗嘗滋味的。」

「我不是來找茬的,Abe,」Frank說道,舉起雙手,「我只是來這兒見Billy的。」

「那好,Billy不在這兒。」酒保說道。

Frank幾乎如釋重負地一笑,說道:「那我就撤了。」

Abe草草地點了點頭,看著Frank離開,手仍然留在吧檯下面。

Frank做了幾下深呼吸,在微涼的空氣中搖搖頭。Abe記仇的時間比Frank見過的其他任何人都長。不過話又說回來,Frank已經逮走了Abe的四個兄弟姐妹。

街上的下一個店面是Brazen Boolean,這是一間現代化的咖啡廳,擁有典型的布爾類型風格——鮮明的黑白兩色。布爾市的居民素以狂熱傾心於邏輯的絕對概念而聞名,在他們眼中,一切事物要麼為真,要麼為假。他們是很稱職的目擊者。作為鎮上唯一的布爾咖啡廳,Brazen Boolean是那些背井離鄉者的避風港。畢竟,在布爾人眼中只有兩種人:布爾人和其他人。

Frank把頭伸進門內,向在場的所有人問道:「Billy在這兒嗎?」沉默了一會,20雙眼睛仔細地掃視了咖啡館內的每一個角落。如非絕對肯定,布爾人是不會回答問題的。

「不在。」傳來了確切的答覆。

Frank繼續他的窮舉搜索。

第三和第四家店舖的經歷雖然明顯更令人愉快,但同樣無果而終。第三家店Constant Const的酒保熱情地歡迎了Frank,並邀請他一道懷念過去的美好歲月,不過Frank上個月剛認識他,所以這樣說顯得有點怪怪的。而第四家店Daring Double裡的人們則是一群出了名吵鬧的集會巫師,每當有新人到場他們都會歡呼,並舉著熱氣騰騰的杯子歡快地高歌。

Frank在第五家店舖Exponentiated Expresso裡找到了Billy。這是迄今為止大街上最喧鬧、最俗氣的咖啡館,卻憑借其含有三倍咖啡因的咖啡豆,成功招攬到了最忠實的粉絲們。生意好的日子裡,每桌都會擠滿絮絮叨叨的人,他們似乎認為一場愉快交談的關鍵在於說話的音量。

今早,Exponentiated Expresso裡的客人不那麼喧鬧,只有少數幾張桌子有人,而其中大多數都是孤身一人的咖啡客,他們晃動著身體輕聲哼唱。

Billy在中間的一張桌子坐下,扭曲著身子努力聽著身旁的談話。似乎沒人注意到他。Frank在第一次掃視屋內時,甚至看漏了Billy。

「Billy!」Frank叫道。

Billy懷有愧疚感地跳了起來。「Frank?」他咧嘴笑了起來,很高興有人對他打招呼,然後又坐了回去,「拉把椅子過來唄。」

「我正在找一些信息,」Frank一邊解釋,一邊在Billy對面坐了下來。

「說不准我有呢,」Billy說,「不過,最近我覺得有些事情想起來挺吃力的。」Billy說道,同時朝一個空了很久的杯子瞧著,估計並不是他的。

Frank示意咖啡師很快在桌上放了一杯啤酒。「記得任何有關警局失竊案的事嗎?」Frank問Billy。

Billy睜大眼睛,畏縮了。「你是說……搶劫?」他心虛地問道。他的雙眼掃視著屋內,但一如既往,並沒人留意他。

Frank在桌上放了兩枚金幣,並努力讓自己不要心疼這兩枚金幣。他花不起這錢,尤其當他不知道自己花錢買的是線索還是閒話時。但他清楚,讓Billy提供信息不會便宜的。他俯身湊近一些:「前天晚上,」他悄然說道,「一大堆文件被賊偷走了。」

「聽起來不像是容易想起來的事情啊。」Billy說,他盯著金幣,「恐怕你問錯人了,Frank。」

「這可是金子啊!」Frank咆哮道。

「抱歉,我幫不到你。」Billy說,他再次環視一下屋內,然後補充道,「即便我知道一些關於失竊的事,我也會努力忘掉的。或許我知道一些小事,比如是誰幫忙運走了文件,但這不值得冒險,免得我睡醒一睜眼發現自己的鞋裡塞滿了牛糞。」

Frank瞪大了眼睛,但Billy沉默不語了。作為一個靠分享信息過活的人,Billy不肯透露這件事情的行為顯得非常奇怪。「牛糞?」Frank問。

Billy點點頭,但不再多說。

「你就不能再具體點嗎?」Frank問道,「是說北方或南方的犛牛嗎?」

「這重要嗎?」Billy問,「問題在於,即使知道是誰安排的運輸,我也不會記住的。如果那些人碰巧在鎮外大約五英里處擁有一個大農場,在那兒可以輕易地讓某人消失,那我就更不會記住了。而如果那座農場的主人有著非法活動的歷史記錄和危險的幽默感,那我就加倍更不會記住了。在這種情況下,記住任何事情都是絕對不明智的。」

「太糟糕了,」Frank笑著說,「也許下次能記起來點。」他朝金幣點點頭,「希望它能讓你將來能記住事兒。」

Frank起身,大步走出Exponentiated Expresso。他向左轉,沿著街繼續走。一走出三比特巷,他便可以兜回去,前往Crannock的農場——唯一與Billy的描述有點相似的農場。

在他經過第六家店Faulty Register時,他注意到一道影子鑽進了附近的小巷。他壓低嗓音罵了一句,但沒有停步。Frank意識到自己被人跟蹤了:看來警長上門找他時沒有十分地謹慎。

但當他離開城裡,踏上前往Crannock農場的粗糙泥土路時,發現自己的心情很好。Billy給他的並不多,但即便利用這一點點信息,也能看出使用高效搜索算法和使用窮舉算法的不同。

警用算法導論:窮舉搜索

節選自Drecker教授講義

用窮舉搜索算法搜索目標值是要在整個搜索空間範圍內嘗試每一種可能性。最常見的窮舉搜索是線性搜索,即按照順序簡單地檢查所有不同的可能性。

想像一下,當你正在追逐強盜進入了一個廢棄旅館的二樓走廊時,接下來會發生什麼?走廊裡有30道門,全部是關閉的。如果你遵循正確的警方工作程序,你的同伴已經封鎖了對面的樓梯,你和強盜被困在這層樓上,你將如何找到強盜?是隨機選擇一扇門打開,發現沒有強盜,然後出來再隨機打開一扇門,就這樣跑來跑去,直到你幸運地找到了強盜?不!你應該搜索整個樓層,把所有的門依次踢開。

或者來思考一個算法,在一個數字列表(數組)中尋找一個目標值。線性搜索算法要從第一個數字開始查找,逐個地檢查數字列表中的每一個值,直到找到目標值。假如我們要在一個數組中搜索5,那麼搜索的過程如下:

線性搜索算法的優勢是它們在任何領域都容易實現,即使要處理的是非結構化數據。你不必猜測強盜會在哪個房間,你只需要依次檢查所有房間。窮舉搜索算法的缺點是,在已經結構化的數據中採用這種搜索方式往往不夠高效。如果你知道強盜在哪裡,你可以使用這個情報來大大減少你踢開門的次數。

高效算法的關鍵在於有用的信息!