蛮力法(Brute Force)
蠻力法是一種簡單直接地解決問題的方法(暴力求解),常常直接基于問題的描述和所涉及的概念定義。注意,這里的“力”是指計算機的計算“能力”。一般來說,蠻力策略常常是最容易應用的辦法。
雖然巧妙和高效的算法很少來自于蠻力法,但我們不應該忽略它作為一種重要的算法設計策略的地位。第一,蠻力法可以解決廣闊領域的各種問題。實際上,它可能是唯一一種幾乎什么問題都能解決的一般性方法。第二,對于一些重要的問題(如排序、查找、字符串匹配等)來說,蠻力法可以產生一些合理的算法。第三,如果要解決的問題實例不多,而且蠻力法可以用一種能夠接受的速度對實例求解,那么設計一個更高效算法所花費的代價很可能是不值得的。第四,即使效率通常很低,仍可使用蠻力法解決一些小規模的問題實例。第五,蠻力法可以作為研究或教學目的服務,如可以以之為準繩,來衡量同樣問題的更高效算法(如計算最壞時間復雜度)。
設計思想
蠻力法是指采用遍歷(掃描)技術,即采用一定的策略將待求解問題的所有元素依次處理一次,從而找出問題的解。依次處理所有元素是蠻力法的關鍵,為了避免陷入重復試探,應保證處理過的元素不再被處理。
蠻力法本質是先有策略地窮舉,然后驗證。簡單來說,就是列舉問題所有可能的解,然后去看看是否滿足題目要求,是一種逆向解題方式。(雖然不知道答案是什么,但知道答案肯定在這些范圍里面,一個個試就完了。)
注意,即便是窮舉,也要“聰明地”窮舉。同樣是窮舉,也有不同的方法。
實例
接下來,將從實例出發,介紹蠻力法的具體應用。
選擇排序
考慮蠻力法在排序問題中的應用,給定一個可排序的nnn個元素序列,將它們按照非降序方式排列。針對這個問題,存在多種解法。這里介紹下選擇排序。
選擇排序在開始的時候,先掃描整個列表,以找到列表中的最小元素,然后將這個元素與第一個元素進行交換。這樣最小元素就放到它的最終位置上。然后,從第二個元素開始掃描,找到n-1個元素中的最小元素,然后再與第二個元素進行交換。以此類推,直到第n-1個元素(如果前n-1個元素都已在最終位置,則最后一個元素也將在最終位置上)。更多選擇排序相關介紹,參考鏈接。
冒泡排序
除了選擇排序,蠻力法在排序算法的另一個應用是冒泡排序。冒泡排序,需要比較表中的相鄰元素,如果它們是逆序的話,就交換它們的位置。重復多次之后,最終,最大的元素就"冒泡"到列表的最后一個位置。第二遍操作,將第二大元素"冒泡"到最終位置。依次執行n-1次,直到前n-1個元素到達最終位置。更多冒泡排序相關介紹,參考鏈接。
順序查找
蠻力法除了在排序算法中有應用,在查找算法中也有應用。這里介紹下順序查找算法。順序查找的查找過程為:從表中最后一個元素開始,逐個元素進行比較,如果存在相等的元素,則查找成功。如果直至第一個元素,也沒有與之相等的元素,則表明沒有所查找的元素,查找不成功。當使用列表來存儲元素時,為避免每次循環檢查是否到達了行尾,可以將查找的元素插入行尾。更多順序查找相關介紹,參考鏈接。
字符串匹配
接下來介紹蠻力法在字符串匹配問題上的應用。字符串匹配問題描述如下:給定一個n個字符組成的文本,再給定一個m個字符的子串,從文本中尋找匹配模式的子串。
使用蠻力法求解的算法描述如下:將模式對準文本的前m個字符,然后從左到右匹配每一個相應的字符,直到m個字符全部匹配或者遇到不匹配的字符。在不匹配的情況下,模式向右移動一位,然后重復匹配文本上的相應字符。這里,最壞情況下,最后一輪子串匹配的起始位置是n-m(假設下標從0開始)。該算法的偽代碼實現如下:
該算法的輸入規模是同時依賴待查找文本長度和待匹配子串。對于該非遞歸算法,其基本操作是內層for循環的比較操作。其最壞情況下的執行次數是:(n-m+1)*m。所以該算法的時間復雜度是KaTeX parse error: Undefined control sequence: \* at position 4: O(n\?*?m)。
這里給出java版本實現:
深度優先查找和廣度優先查找
蠻力法在圖論中也有應用,如圖的深度優先查找和廣度優先查找。深度優先查找基本思想如下:假設初始狀態時圖中所有頂點都未曾被訪問,則深度優先遍歷算法從圖中某個頂點(任一頂點)出發,訪問此頂點并把該頂點標記為已訪問,然后依次從該頂點鄰接的未被訪問的頂點出發,深度優先遍歷圖,直至圖中所有和該頂點有路徑相通的頂點都被訪問到;若此時圖中尚有頂點未被訪問,則另選圖中一個未被訪問的頂點作為起始點,重復上述過程,直至圖中所有頂點都被訪問到為止。更多深度優先查找相關介紹,參考鏈接。
廣度優先查找基本思想如下:假設初始狀態時圖中所有頂點都未曾被訪問,則廣度優先遍歷算法從圖中某個頂點(任一頂點)出發,訪問此頂點并依次訪問該頂點的各個未曾訪問過的鄰接點。然后,分別從這些鄰接點出發依次訪問他們的臨鄰接點,并使"先被訪問的頂點的鄰接點"先于"后被訪問的頂點的鄰接點"被訪問,直至圖中所有已被訪問的頂點的鄰接點都被訪問到。若此時圖中尚有頂點未被訪問,則另選圖中一個未被訪問的頂點作為起始點,重復上述過程,直至圖中所有頂點都被訪問到為止。換句話說,廣度優先遍歷的過程是以任一頂點開始,由近及遠,依次訪問和該頂點路徑相通且路徑長度為1,2,3,…的頂點。更多廣度優先查找相關介紹,參考鏈接。
總結
蠻力法,通過使用問題規模的所有元素來求解問題,是一種窮舉算法。如果問題的輸入規模在一個可預估的范圍內,蠻力法表現出實用性。但隨著問題規模的增大,蠻力法在某些場景(如時間復雜度是指數級的蠻力法,如使用蠻力法求解的背包問題)下將不再適用。
蠻力法的一個應用是得到一個算法,此算法可以通過適度的努力來提升它的性能。也就是,蠻力法提供了一個性能提升的基準。
參考
《算法設計與分析基礎》 第三版 Anany Levitin 著 潘彥 譯
https://blog.csdn.net/weixin_42929607/article/details/108895699 蠻力法的基本問題分析
https://blog.csdn.net/Wwinky/article/details/115052584 算法小結之蠻力法
原創不易,如果本文對您有幫助,歡迎關注我,謝謝 ~_~
總結
以上是生活随笔為你收集整理的蛮力法(Brute Force)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MYSQL关闭安全模式
- 下一篇: 对称加密、非对称加密和散列算法