暴力法、窮舉搜尋與回溯

暴力法(brute force)

假設你忘了一個三位數密碼鎖的號碼。最笨、最不需要技巧的辦法,就是試 000、再試 001、再試 002,一路試到 999——按順序把每一個組合都試一遍,直到某一個打開為止。這就是暴力法:把問題允許的所有候選答案全部試一遍,留下那個(或那些)行得通的。它不需要任何巧思,只需要耐心和記帳。

更精確地說,暴力法仰賴兩樣東西。第一,你必須能描述出全部的候選解——全部 1000 組密碼、n 位賓客的所有座位安排、一組物品的所有子集合。第二,你必須有一個便宜的檢驗,給它一個候選就能回答是或否(這組密碼打得開鎖嗎?這個座位安排有沒有滿足每個人的要求?)。暴力法接著掃過整個候選集合,對每一個都套用這個檢驗。只要有一個候選通過,你就找到了解;而當你掃完整個集合卻沒人通過,你也能確定無解。

它的魅力在於誠實與正確:因為它檢查了每一種可能,暴力法永遠不會漏掉答案,也不需要什麼巧妙的證明才能讓人信任。代價是時間。如果候選有 2^n 或 n! 個,工作量會隨輸入規模爆炸式成長,所以暴力法是你的出發基準線,接著你要設法打敗它——靠的是更聰明地決定哪些候選根本不必去看。本領域許多偉大的範式(分治法、貪婪、動態規劃,以及回溯的剪枝)正是「如何避免一次完整暴力掃描」的藝術。

要用暴力法在 n 個點中找出最近的一對:試遍每一對 (i, j)(i < j),算出距離,留下最小的那個。一共有 n(n-1)/2 對,所以工作量是 Theta(n^2)。它顯然正確,因為沒有任何一對被跳過——而稍後一個分治法能用 O(n log n) 完成同樣的工作。

暴力法是「構造上即正確」的基準線;巧思的價值,就用你超越它多少來衡量。

暴力法的正確性不等於它沒用——對小輸入來說,它常是你能交付的最簡單、最可靠的程式碼,也是拿來驗證更快演算法的絕佳對照組。

又称
brute-force searchexhaustive approach窮舉法蠻力法