選單
×
   ❮   
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP How To W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

表格法


表格法

表格法是一種用於解決問題的方法。

表格法使用一個表格,其中首先儲存最基本子問題的結果。然後,表格會不斷填充更多的子問題結果,直到我們找到所求的完整問題的結果。

由於其先解決最基本子問題的方式,表格法被認為是以“自底向上”的方式解決問題的。

表格法是一種在 動態規劃 中使用的技術,這意味著要使用表格法,我們必須解決的問題必須包含重疊的子問題。


使用表格法求 \(n\)th Fibonacci 數

Fibonacci 數 非常適合演示不同的程式設計技術,以及演示表格法的工作原理。

表格法使用一個表格,首先(自底向上)用最低的 Fibonacci 數 \(F(0)=0\) 和 \(F(1)=1\) 填充。下一個要儲存在表格中的 Fibonacci 數是 \(F(2)=F(1)+F(0)\)。

下一個 Fibonacci 數始終是前面兩個數字的和

\[ F(n)=F(n-1)+F(n-2) \]

透過這種方式,表格會不斷用下一個 Fibonacci 數填充,直到我們找到所求的 \(n\)th Fibonacci 數。

示例

使用表格法查詢第 10 個 Fibonacci 數

def fibonacci_tabulation(n):
    if n == 0: return 0
    elif n == 1: return 1

    F = [0] * (n + 1)
    F[0] = 0 
    F[1] = 1

    for i in range(2, n + 1):
        F[i] = F[i - 1] + F[i - 2]
    
    print(F)
    return F[n]
  
n = 10
result = fibonacci_tabulation(n)
print(f"\nThe {n}th Fibonacci number is {result}")
執行示例 »

查詢 \(n\)th Fibonacci 數的其他方法包括 遞迴,或者使用 記憶化 的改進版本。


表格法是一種自底向上方法

請參閱下面的圖示,以更好地理解為什麼表格法被稱為“自底向上”方法。

作為比較,請參閱查詢 \(n\)th Fibonacci 數的 “自頂向下”遞迴方法 的圖示。

F(10) F(9) . . . . F(2) F(1) F(0)
查詢第 10 個 Fibonacci 數的自底向上表格法。
F(10) F(9) F(8) F(7) F(8) F(7) F(6)
查詢第 10 個 Fibonacci 數的自頂向下遞迴方法。

表格法從自底向上構建表格以查詢第 10 個 Fibonacci 數,從 \(F(0)\) 和 \(F(1)\) 開始。

遞迴方法首先嚐試查詢 \(F(10)\),但為了找到它,它必須呼叫 \(F(9)\) 和 \(F(8)\),因此它一直向下直到 \(F(0)\) 和 \(F(1)\),然後函式呼叫開始返回可以組合成最終答案的值。


其他用表格法解決的問題

就像查詢 \(n\)th Fibonacci 數一樣,表格法也可以用來解決其他問題

  • 0/1 揹包問題是關於擁有一組物品,我們可以將它們裝入一個揹包中,每個物品都有不同的價值。為了解決這個問題,我們需要找到能夠最大化我們所裝物品總價值的物品,但由於揹包有重量限制,我們無法攜帶所有想要的物品。
  • 最短路徑問題可以使用 Bellman-Ford 演算法 來解決,該演算法也使用表格法來查詢圖中的最短路徑。更具體地說,Bellman-Ford 演算法的表格法體現在“距離”陣列中的值如何被更新。
  • 旅行商問題可以使用 Held-Karp 演算法精確解決,該演算法也使用表格法。該演算法未在此教程中進行描述,因為它雖然優於窮舉法 \(O(n!)\),但仍然效率不高 \(O(2^n n^2)\),並且相當複雜。

動態規劃中的表格法

如開頭所述,表格法(就像記憶化一樣)是用於 動態規劃 的技術。

動態規劃是一種設計算法來解決問題的方法。

為了使動態規劃起作用,我們要解決的問題必須具備以下兩個特性

  • 問題必須由較小的、重疊的子問題構成。例如,Fibonacci 數 \(F(3)\) 的解與 Fibonacci 數 \(F(2)\) 和 \(F(1)\) 的解重疊,因為我們透過組合 \(F(2)\) 和 \(F(1)\) 來得到 \(F(3)\)。
  • 問題還必須具有最優子結構,這意味著問題的解可以從其子問題的解中構建出來。在查詢 \(n\)th Fibonacci 數時,可以透過將 \(F(n-1)\) 和 \(F(n-2)\) 相加來得到 \(F(n)\)。因此,僅知道前兩個數字不足以找到 \(F(n)\),我們還必須知道結構,以便知道如何將它們組合起來。

下一頁 上閱讀更多關於動態規劃的內容。



×

聯絡銷售

如果您想將 W3Schools 服務用於教育機構、團隊或企業,請傳送電子郵件給我們
sales@w3schools.com

報告錯誤

如果您想報告錯誤,或想提出建議,請傳送電子郵件給我們
help@w3schools.com

W3Schools 經過最佳化,旨在方便學習和培訓。示例可能經過簡化,以提高閱讀和學習體驗。教程、參考資料和示例會不斷審查,以避免錯誤,但我們無法保證所有內容的完全正確性。使用 W3Schools 即表示您已閱讀並接受我們的使用條款Cookie 和隱私政策

版權所有 1999-2024 Refsnes Data。保留所有權利。W3Schools 由 W3.CSS 提供支援