讀古今文學網 > 算法神探:一部谷歌首席工程師寫的CS小說 > 23 最佳優先搜索:偵探最值得信賴的工具 >

23 最佳優先搜索:偵探最值得信賴的工具

過去的五年中,Donovan警長的辦公室幾乎沒有什麼改變。房間的角落仍放著同樣的書桌,上面整齊地擺放著四個貼有「輸入」「輸出」「需歸檔」「需銷毀」標籤的籃子。牆上除了Frank早已見過的數量眾多的獎狀外,又多出了幾張新的。只有一張圖片——警長與兩個孩子的全家福速寫——見證了時間的流逝。

「Frank,坐吧。」警長頭也不抬地說。

Frank看著警長面前的椅子,回想起上一次他坐在這把椅子上的情景——那是他警隊生涯的最後一天。那時他終於搜集到了足夠的證據,正準備對Rebecca Vinettee實施抓捕,但是他用的方法卻十分走險。儘管當時Frank發現了新證據,但警長並不贊同他的這一做法,因為他更在意的是Frank公然違反了相關規定。Frank從回憶中回過神來,倚靠在椅子的扶手上,繼續等待。

終於,警長處理完手中的公文,並將其放到「輸出」的籃子裡,目光投向Frank說道:「你有什麼新發現嗎?」

「這個案子並不僅是文件盜竊這麼簡單,要比想像中嚴重得多。」Frank回答道。

警長看起來並不驚訝:「有多嚴重?」

在過去的一個小時裡Frank在腦海中想像了這場談話的各種版本,以及可能的回答方案。最終他決定靠自己的能力——這些絕不是投機取巧就能做到的。

「為什麼不一開始就將你知道的全都告訴我?」Frank說,「也就是事實你上到底知道什麼。請不要說謊。」

警長鎮定地望著他說:「我從未騙過你,Frank,當初我過來找你時已經把我所知道的都告訴你了。」Frank想要說些什麼,但警長抬起手示意不要打斷他,接著說道:「但是,事態時刻都在發生變化,我們談話的時候情況或許也正在改變,今天早上我得到了最新的消息。」

「又有盜竊案了嗎?」Frank問道。

「是其他事情。」警長回答。

警長快速地翻了翻面前貼有「輸出」標籤的籃子,找到一封寫著「請轉交給Frank Runtime」字樣的信封,並遞給了Frank。「給你,這也省得別人再給你送了。」他說。

Frank拆開信封,快速地瀏覽了裡面的內容。他發現其中包含了四份案情報告——其中有三份是關於其他警局盜竊案的細節描述,第四份是有關軍方車隊被襲擊的詳細描述。Frank之前就聽說過這個案件,但是這些細節還是令他大吃一驚。

「加速腐蝕的咒語?」他問道。

「我們已經讓巫師來確認過,」警長說,「這些盜賊把檔案室的門給腐蝕了,輕輕一推就開了。」

「那車隊是怎麼回事?」

「帶有腐蝕魔法的弩。」警長說,「還有一個車子的輪胎,我想應該是左後輪,報告裡應該寫到了。」

「那些寶劍和斧頭呢?」

「你能不能仔仔細細地看一下那些報告?那些盜賊們用了加速銹蝕的咒語,這雖然不算什麼高級的魔法,但非常有效。」

「那個裡面根本就沒有提到他們偷了些什麼。」Frank說道,「有關魔法面具的事更是隻字未提。」

警長驚訝地豎起了眉毛:「你怎麼知道面具的事?這可是高級機密!」

Frank聳聳肩:「是你讓我去尋找線索的呀。」他並沒有告訴警長這條信息其實是Socks說漏嘴告訴他的,永遠不能讓你的客戶知道你的成功有多少是建立在別人的愚蠢行為之上的。

「這很令人擔憂,」警長說,「那是個很強大的東西。我們收到了一個匿名信息,說城堡可能遭到襲擊,現在所有警力都處於戒備狀態,我們已經把所有的人都調來保衛城堡。」

「對於攻擊城堡這件事,我也聽說過。」Frank說道,他又看了一遍文件,「沒有關於襲擊者的信息嗎?」

「我們也只是聽到一些謠傳,並不肯定。至少沒有什麼可以被放到報告裡的可靠信息。」

「那你的警員們怎麼樣呢?有沒有任何可疑的人員在那兒?」

警長打量了一下Frank。Frank知道,如果警長確信沒有任何內鬼的話,是絕不會來找他的。但這也僅僅是他的猜測。

「還沒有,」警長說,「我還沒有找到任何可疑的人員。盜竊案之間沒有形成規律,不同的警局,不同的值班警員,連失竊的部門都不同。」

Frank思考著這些盜竊案,默默地點了點頭。在進行到調查警察內部調職記錄時,案件似乎進入了一個死胡同。每個事件都至少有一位新轉來的警員值班,但是從來沒有一個警員出現兩次。他曾經考慮過這可能是整個新手班的陰謀,但是很快就否決掉了。這個人能組織這麼大型的背叛事件,他的能力應該足以編排更微妙的盜竊案,至少不至於驚動方圓100英里的所有警力。

「那Notation警官呢?」Frank問。

警長看起來有些吃驚:「她怎麼了?」

「她在你的名單上嗎?」Frank又問。

「她那天值班,所以她當然在名單上。」警長說,「但是她在名單的最後。她是個好孩子,雖然是個新手,但她在警局盡忠職守。」

「你知道她在擅自調查這個案子嗎?」

警長皺了皺眉頭:「我覺得這沒有什麼好驚訝的,就像我所說,她很敬業。你什麼時候碰見她的?」

「在Crannock的農場,」Frank說,「在這之後我們一起調查了一段時間。」

「那她現在在哪裡?」

「我不信任她。」Frank說。

「你誰也不信,Frank。」警長補充道。

Frank歎了一口氣。「這不重要,」他說,「如果你發現什麼奇怪的事情,請盡快告訴我。」

「那你呢,」警長問,「你發現了什麼?」Frank簡潔地概括了一下案件的進展,他告訴警長他是如何根據一個提示找到了Crannock農場,又在那裡發現了新的線索,線索指向了Usb港,也就是Vinettee集團的船,還有Rebecca Vinettee。

聽到這個消息後,警長咯咯的笑聲打斷了他。「Frank,又和Vinettee家族相關?又是Rebecca Vinettee?我很驚訝你還在為此事奔波,你把他們家多少個人送到監獄裡去了?」

「還遠遠不夠。」Frank說。

「好了」,警長回應道,「你是怎麼從那裡逃脫的?」

「後來突然出現了一個年輕的巫師,開始到處扔裝滿醃鰻魚的桶。」Frank把這一切說得彷彿只是一個正常的巧合。

警長看了他一眼:「什麼?」

「有一個叫Socks的初級巫師,」Frank解釋道,「他是一個名叫Gretchen的巫師的學徒,看來是國王帶了幾個高級巫師來協助我們破這個案子。」

「我沒聽說過Gretchen,但我一點也不驚訝國王會請巫師來。」警長說,「在軍隊遭到襲擊之後,國王動員了所有人,甚至Ann公主都正在回來的路上,明天就能到城堡。」

這句話意味著現在的情形非常嚴重。Ann公主幾乎永遠都在出使任務、調查或者是談判。既然她回來了,那現在的情況一定糟糕透了。

「Ann公主正在回來的路上?」Frank問。

「她認為最近的襲擊一定和Unnecessary Complexity聯盟有關。」

「Unnecessary Complexity聯盟?」

「一切都和那個叫Exponentious的邪惡巫師有關,」警長說,「就是那個總是想摧毀王國的巫師。」

Frank點了點頭。很顯然,他還清楚地記得當年Exponentious發動的襲擊所帶來的恐慌。在那些天裡,關於他發起的這次運動一直在年輕巫師與騎士中間流傳。

警長繼續說道:「他現在被牢牢地關在皇家監獄裡,但Ann公主擔心他可能有別的團伙在行動。比如說他的追隨者、幫兇或者崇拜他的人。Ann公主一直在找有關這個神秘巫師聯盟的線索,目前他們一直躲在陰暗處,進行一些小範圍的襲擊,但是皇室成員非常擔心。」

Frank一臉茫然地盯著警長。這會不會就是Vinettee提到的那個聯盟?如果真是的話,那麼他怎麼會把自己牽扯到這種事情中來。於是Frank腦中又萌生出了另一種假設。

「攻擊城堡!會不會和Ann公主返回有關?」Frank說,「如果她在調查Unnecessary Complexity聯盟,他們有可能會報復她。」

「我們已經想到了這一點,」警長說,「當Ann公主回來時,我會調派一百多個警察去保護她。雖然這會使軍械庫、監獄和警局的警力減少,但我們絕不能讓Ann公主有任何閃失。」

「那魔法面具呢?有人會利用面具潛入安保人員的隊伍。」

「是的,這是一個溜進城堡的絕好機會,」警長承認道,「即使沒戴面具,在增加了一百多個新的警察後,我們也很難在人群中找出他們。但是我們採取了措施,皇家巫師Marcus創造了一種有魔法的身份徽章分配給那些城堡的安保人員。身份徽章是無法偽造的,一旦佩戴的人與徽章上的照片或者名字不一樣,徽章就會發出紅色的光。」

Frank努力思考是否還有其他的安全隱患。

「你再想想,」警長說,「你還有沒有發現別的問題?」

Frank飛速地思考著,回憶他們在TCP Flyer號船上發生的事,以及他們在Mudwall和Frayed Cable島上的搜索。他描述了監獄中遇到的襲擊和公文被燒燬的經過,最終,他從調職記錄中找到了更多線索。

「這也是為什麼你想瞭解Notation的原因吧,」警長說,「她是剛從警察學院調過來的。」

「確實,」Frank承認,「她的名字在我的搜索範圍之內。」

警長想了想後說道:「我不認為她是這種人,我的直覺告訴我,她是一個好警官,但是我不確定我現在應該相信誰。不管怎樣她是不應該去調查這個案子的,這並不是她的任務。」

「謝謝你。」Frank說道。

「還有沒有其他新調來的人需要去特別關注的?」

Frank搖搖頭:「新調來的警察們分佈在不同的犯罪現場,但是沒有規律,沒有任何一人與兩個以上的盜竊案相關,除非一整個班都是叛徒才有可能,所以我認為這行不通。」

「你調查得很好,Frank。」警長說道,「這是我這麼多年來見過的能把最佳優先搜索用到極致的案例之一。」

Frank笑了,即使在警隊,也很少有人會知道這種類型的調查需要使用最佳優先搜索。多數人只會說「我正在調查」或是「這些線索我正在跟進」。

儘管對其認知不足,最佳優先搜索仍是警官們辦案必備法寶之一,它就像記事本或者是一雙舒服的鞋子一樣重要。在最佳優先搜索中,你需要時刻維護一個線索列表,每次從中選擇最可靠的一個線索去調查,調查完畢後,再從列表中選出下一個最可靠的線索繼續調查。當然如果在調查的過程中發現了新的線索,就將其及時加入到列表中。這種方法對於查案很有幫助。

Frank搖搖頭。

「那好,」警長說,「繼續調查。如果Unnecessary Complexity聯盟真的存在,而且一直在背後操縱這個案子,那麼我們已經深陷危機之中了。注意安全,Frank。」

「我一向很謹慎。」Frank回答,他站了起來,又停住了,「最後一個問題,你知道Notation是如何知道Array Cart的嗎?」

「我不知道,」警長回答道,「為什麼不直接問問她呢,她現在似乎正站在我的辦公室門口。」

警用算法導論:最佳優先搜索

節選自Drecker教授講義

假如你在這門課程中只記住了一個算法,那麼你一定要記住最佳優先搜索這個算法,它將是你警隊生涯中最有用的工具。也許所有的案件到最後你都需要使用這個算法。

最佳優先搜索是基於某種估值分數或者評價函數來選擇接下來探索哪個狀態的算法。每一個新發現的狀態也都將被賦予一個分數,這個分數就是算法對這個新發現狀態的估值。例如,我們可以為每一個狀態標記上一個值,可能是目標狀態的概率(如果這個概率可以被估計的話)或者是在調查中線索的重要程度。其實最佳優先搜索就是在每時每刻維護著一個帶有估值分數的狀態列表,每次從這個有序列表取出下一個估值分數最高的狀態去探索。

當然,最佳優先搜索也可以按照代價最小的規則來選取下一個要探索的狀態,這個代價可以是當前狀態到目標狀態的估算距離。在這種情況下,每一步都要選擇列表中估值最小的一個狀態進行探索。

我們來看一個迷宮問題。現在我們已知起點和終點的坐標,可以在搜索空間中為每個點(狀態)都設置一個值,這個值就可以是從該點到終點的距離,例如,可以使用曼哈頓距離——兩點之間的垂直距離加上水平距離之和。雖然這個值不一定意味著當前點到目標點的實際步數,但它可以為最佳優先搜索算法提供更有效的選擇依據。

隨著搜索的進行,算法開始嘗試探索不同的點(即下圖中帶陰影的圓圈),每當遇到一個新點,都要將其添加到一個列表中等待之後進一步探索(即下圖中帶有虛線的圓圈)。在每次迭代中,算法將根據每個點的估值分數來選擇最佳的那個點去探索。在這個例子中,每次將選擇估值最小的那個點去探索。

一旦找到目標點,我們就可以終止搜索。在這個例子中,我們只需要探索一半多一點的點。例如,我們不會選擇探索第二個距離為4的點,因為我們總是有一個更好的選擇可以優先嘗試。

在搜索中,我們必須先確定線索的優先順序。根據具體情況,你可以從最新的線索或可信度最高的線索開始。無論如何,最佳優先搜索都需要按照某個優先順序進行。