演算法的定義

2022-10-10 06:57:02 字數 4898 閱讀 5154

演算法(algorithm)是一系列解決問題的清晰指令,也就是說,能夠對一定規範的輸入,在有限時間內獲得所要求的輸出。如果乙個演算法有缺陷,或不適合於某個問題,執行這個演算法將不會解決這個問題。不同的演算法可能用不同的時間、空間或效率來完成同樣的任務。

乙個演算法的優劣可以用空間複雜度與時間複雜度來衡量。

演算法可以理解為有基本運算及規定的運算順序所構成的完整的解題步驟。或者看成按照要求設計好的有限的確切的計算序列,並且這樣的步驟和序列可以解決一類問題。

乙個演算法應該具有以下五個重要的特徵:

1 有窮性:乙個演算法必須保證執行有限步之後結束;

2. 確切性:演算法的每一步驟必須有確切的定義;

3. 輸入:乙個演算法有0個或多個輸入,以刻畫運算物件的初始情況,所謂0個輸入是指演算法本身定除了初始條件;

4. 輸出:乙個演算法有乙個或多個輸出,以反映對輸入資料加工後的結果。沒有輸出的演算法是毫無意義的;

5. 可行性:演算法原則上能夠精確地執行,而且人們用筆和紙做有限次運算後即可完成。

同一問題可用不同演算法解決,而乙個演算法的質量優劣將影響到演算法乃至程式的效率。演算法分析的目的在於選擇合適演算法和改進演算法。乙個演算法的評價主要從時間複雜度和空間複雜度來考慮。

乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數多,它花費時間就多。

乙個演算法中的語句執行次數稱為語句頻度或時間頻度。記為t(n)。

在剛才提到的時間頻度中,n稱為問題的規模,當n不斷變化時,時間頻度t(n)也會不斷變化。但有時我們想知道它變化時呈現什麼規律。為此,我們引入時間複雜度概念。

一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式,用t(n)表示,若有某個輔助函式f(n),使得當n趨近於無窮大時,t(n)/f(n)的極限值為不等於零的常數,則稱f(n)是t(n)的同數量級函式。記作t(n)=o(f(n)),稱o(f(n)) 為演算法的漸進時間複雜度,簡稱時間複雜度。

在各種不同演算法中,若演算法中語句執行次數為乙個常數,則時間複雜度為o(1),另外,在時間頻度不相同時,時間複雜度有可能相同,如t(n)=n2+3n+4與t(n)=4n2+2n+1它們的頻度不同,但時間複雜度相同,都為o(n2)。

按數量級遞增排列,常見的時間複雜度有:常數階o(1),對數階o(log2n),線性階o(n),線性對數階o(nlog2n),平方階o(n2),立方階o(n3),...,k次方階o(nk),指數階o(2n)。

隨著問題規模n的不斷增大,上述時間複雜度不斷增大,演算法的執行效率越低。

2.2 空間複雜度

與時間複雜度類似,空間複雜度是指演算法在計算機內執行時所需儲存空間的度量。記作:

s(n)=o(f(n))

我們一般所討論的是除正常占用記憶體開銷外的輔助儲存單元規模。討論方法與時間複雜度類似,不再贅述。

3.1 窮舉法

窮舉法是最基本的演算法設計策略,其思想是列舉出問題所有的可能解,逐一進行判別,找出滿足條件的解。

窮舉法的運用關鍵在於解決兩個問題:

如何列舉所有的可能解;

如何判別可能解是否滿足條件;

在運用窮舉法時,容易出現的問題是可能解過多,導致演算法效率很低,這就需要對列舉可能解的方法進行優化。

以題1041--純素數問題為例,從1000到9999都可以看作是可能解,可以通過對所有這些可能解逐一進行判別,找出其中的純素數,但只要稍作分析,就會發現其實可以大幅度地降低可能解的範圍。根據題意易知,個位只可能是3、5、7,再根據題意可知,可以在3、5、7的基礎上,先找出所有的二位純素數,再在二位純素數基礎上找出三位純素數,最後在三位純素數的基礎上找出所有的四位純素數。

3.2 分治法

在電腦科學中,分治法是一種很重要的演算法。字面上的解釋是「分而治之」,就是把乙個複雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題,直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合併。這個技巧是很多高效演算法的基礎,如排序演算法(快速排序,歸併排序),傅利葉變換(快速傅利葉變換)……。

任何乙個可以用計算機求解的問題所需的計算時間都與其規模有關。問題的規模越小,越容易直接求解,解題所需的計算時間也越少。例如,對於n個元素的排序問題,當n=1時,不需任何計算。

n=2時,只要作一次比較即可排好序。n=3時只要作3次比較即可,…。而當n較大時,問題就不那麼容易處理了。

要想直接解決乙個規模較大的問題,有時是相當困難的。

分治法的設計思想是,將乙個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。

分治策略是:對於乙個規模為n的問題,若該問題可以容易地解決(比如說規模n較小)則直接解決,否則將其分解為k個規模較小的子問題,這些子問題互相獨立且與原問題形式相同,遞迴地解這些子問題,然後將各子問題的解合併得到原問題的解。這種演算法設計策略叫做分治法。

如果原問題可分割成k個子問題,1分治法所能解決的問題一般具有以下幾個特徵:

1. 該問題的規模縮小到一定的程度就可以容易地解決;

2. 該問題可以分解為若干個規模較小的相同問題,即該問題具有最優子結構性質。

3. 利用該問題分解出的子問題的解可以合併為該問題的解;

4. 該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子問題。

上述的第一條特徵是絕大多數問題都可以滿足的,因為問題的計算複雜性一般是隨著問題規模的增加而增加;第二條特徵是應用分治法的前提它也是大多數問題可以滿足的,此特徵反映了遞迴思想的應用;第三條特徵是關鍵,能否利用分治法完全取決於問題是否具有第三條特徵,如果具備了第一條和第二條特徵,而不具備第三條特徵,則可以考慮用貪心法或動態規劃法。第四條特徵涉及到分治法的效率,如果各子問題是不獨立的則分治法要做許多不必要的工作,重複地解公共的子問題,此時雖然可用分治法,但一般用動態規劃法較好。

分治法的運用關鍵在於解決三個問題:

確定分治規則,即如何分解問題。

確定終結條件,即問題分解到什麼狀態時可以直接求解。

確定歸納方法,即如何由子問題的解得到原問題的解。這一步並不總是需要的,因為對某些問題來說,並不需要對子問題的解進行複雜的歸納。

3.3 動態規劃法

動態規劃法多用來計算最優問題,動態規劃法與分治法的基本思想是一致的,但處理的手法不同。動態規劃法在運用時,要先對問題的分治規律進行分析,找出終結子問題,以及子問題向父問題歸納的規則,而演算法則直接從終結子問題開始求解,逐層向上歸納,直到歸納出原問題的解。

動態規劃法多用於在分治過程中,子問題可能重複出現的情況,在這種情況下,如果按照常規的分治法,自上向下分治求解,則重複出現的子問題就會被重複地求解,從而增大了冗餘計算量,降低了求解效率。而採用動態規劃法,自底向上求解,每個子問題只計算一次,就可以避免這種重複的求解了。

動態規劃法還有另外一種實現形式,即備忘錄法。備忘錄的基本思想是設立乙個稱為備忘錄的容器,記錄已經求得解的子問題及其解。仍然採用與分治法相同的自上向下分治求解的策略,只是對每乙個分解出的子問題,先在備忘錄中查詢該子問題,如果備忘錄中已經存在該子問題,則不須再求解,可以從備忘錄中直接得到解,否則,對子問題遞迴求解,且每求得乙個子問題的解,都將子問題及解存入備忘錄中。

例如,在題1045--square coins中,可以採用分治法求解,也可以採用動態規劃法求解,即從f(m, 1)和f(1, n)出發,逐層向上計算,直到求得f(m, n)。

在競賽中,動態規劃和備忘錄的思想還可以有另一種用法。有些題目中的可能問題數是有限的,而在一次執行中可能需要計算多個測試用例,可以採用備忘錄的方法,預先將所有的問題的解記錄下來,然後輸入乙個測試用例,就查備忘錄,直接找到答案輸出。這在各問題之間存在父子關係的情況下,會更有效。

例如,在題1045--square coins中,題目中已經指出了最大的目標幣值不超過300,也就是說問題數只有300個,而且各問題的計算中存在重疊的子問題,可以採用動態規劃法,將所有問題的解先全部計算出來,再依次輸入測試用例資料,並直接輸出答案。

3.4 回溯法

回溯法是基於問題狀態樹搜尋的求解法,其可適用範圍很廣。從某種角度上說,可以把回溯法看作是優化了的窮舉法。回溯法的基本思想是逐步構造問題的可能解,一邊構造,一邊用約束條件進行判別,一旦發現已經不可能構造出滿足條件的解了,則退回上一步構造過程,重新進行構造。

這個退回的過程,就稱之為「回溯」。

回溯法在運用時,要解決的關鍵問題在於:

如何描述區域性解。

如何擴充套件區域性解和回溯區域性解。

如何判別區域性解。

回溯法的經典案例也很多,例如全排列問題、n後問題等。

3.5 貪心法

貪心法也是求解最優問題的常用演算法策略,利用貪心法策略所設計的演算法,通常效率較高,演算法簡單。貪心法的基本思想是對問題做出目前看來最好的選擇,即貪心選擇,並使問題轉化為規模更小的子問題。如此迭代,直到子問題可以直接求解。

基於貪心法的經典演算法例如:哈夫曼演算法、最小生成樹演算法、最短路徑演算法等。

但是,貪心法的運用是有條件的,必須能夠證明貪心選擇能夠匯出最優解,且轉化出的子問題與原問題是同性質的問題,才能使用貪心法求解。

乙個比較經典的貪心法求解的問題就是找硬幣問題:有1、2、5、10、20、50、100七種面值的硬幣,要支付指定的金額,問怎麼支付所用的硬幣個數最少。這是乙個非常日常化的問題,憑直覺我們會想到,盡可能先用大面值的硬幣,這就是「貪心選擇」,而在這個問題上,這個貪心選擇也是正確的。

3.6 限界剪枝法

限界剪枝法是求解較複雜最優問題的一種演算法策略,與回溯法類似的是,限界剪枝法也是在問題狀態空間樹上進行搜尋,但回溯法是搜尋一般解,而限界剪枝法則是搜尋最優解。限界剪枝法的基本思想是通過找出權值函式的上下界函式,以下界函式來指導搜尋的方向,以上界函式來幫助剪除一些不可能含有最優解的分枝。

關於演算法和演算法策略的討論是乙個非常龐大的話題,幾乎每個問題點都能擴充套件出一大堆可討論的內容和案例。

3.7 遞迴

遞迴做為一種演算法在程式語言中廣泛應用,是指函式/過程/子程式在執行過程式中直接或間接呼叫自身而產生的重入現象。程式呼叫自身的程式設計技巧稱為遞迴(recursion)。

管理的定義

管理一詞中的 管 就是管轄,主管,就要講職務的隸屬,權力的結構,責任的界限。管理一詞中的 理 就是治理,處理,調理。就是講秩序井然,方法得當,效益明顯,一旦管理成為一門學科,一種有著自己獨特執行概念的理論體系時,對管理的定義就從不同角度出發,各說各的,到目前對管理的定義,不下幾十種。我就列舉10種具...

職責的定義

學習導航 通過學習本課程,你將能夠 理解職責管理在企業中的地位 了解職責管理中的常見問題 避免對職責管理的誤解,正確認識職責管理 明確職責的內涵,遠離職責認知的誤區。一 職責是管理問題的根源 企業管理者都希望員工盡職盡責,否則將可能給企業造成麻煩和損失。職責不是單純的管理術語,而在整個企業管理,特別...

計畫的定義

計畫 預先明確所追求的目標以及相應的行動方案的活動。目標的含義 目標 是乙個組織根據其根本任務和目的確定在未來一定時期內所要達到的成果或結果。目標是目的或宗旨的具體化,是乙個組織奮力爭取達到的所希望的未來狀況。具體地講,目標就是根據組織宗旨而提出的組織在一定時期內要達到的預期成果。1 的含義 就是對...