5.4 應用:Fibonacci 與馬可夫鏈#
本節目標#
- 把 Fibonacci 遞迴改寫成矩陣冪次,用特徵值導出 Binet 公式——親眼看黃金比現身
- 認識馬可夫鏈:轉移矩陣、機率向量、以及「穩態 = 特徵值 1 的特徵向量」
- 用
np.linalg.eig求穩態,再用迭代收斂實驗驗證 - 走完「實際問題 → 矩陣 → 特徵值 → 預測長期行為」的完整套路
應用一:Fibonacci 數列 = 矩陣冪次#
Fibonacci 數列 \(0, 1, 1, 2, 3, 5, 8, 13, \dots\) 的規則人人都會背:
遞迴要一步步算,第 100 項就得算 100 步。線性代數的魔法是: 把「兩個相鄰項」打包成一個向量,遞迴就變成矩陣乘法:
一路迭代下去:
**求第 100 項 = 求 \(A^{99}\) **——正好是 5.3 節剛練好的招式!
特徵值:黃金比現身#
看到 \(\frac{1+\sqrt{5}}{2} \approx 1.618\) 了嗎?**這就是黃金比 \(\varphi\) **! \(F_{n+1} = F_n + F_{n-1}\) 這條樸素的遞迴規則裡,居然藏著古希臘的美學常數。 (這不是巧合: \(1 + \varphi = \varphi^2\) 正是遞迴關係本身的代數化身。)
Binet 公式推導#
由 5.3 節, \(A^n\) 的元素是 \(\varphi^n\) 與 \(\psi^n\) ( \(\psi = \frac{1-\sqrt5}{2} \approx -0.618\) ) 的線性組合;用初始條件 \(F_0 = 0\) 、 \(F_1 = 1\) 定出係數,得到閉式公式:
由於 \(|\psi| < 1\) , \(n\) 大時 \(\psi^n \to 0\) ,所以:
第 100 個 Fibonacci 數,不用迭代一步就能寫下。
import numpy as np
# 驗證三種演算法
n = 30
phi, psi = (1 + np.sqrt(5)) / 2, (1 - np.sqrt(5)) / 2
F_iter = int(round((phi**n - psi**n) / np.sqrt(5))) # Binet 公式
A = np.array([[1.0, 1.0], [1.0, 0.0]])
F_power = int(np.linalg.matrix_power(A, n - 1)[0, 0]) # 矩陣冪次
vals, P = np.linalg.eig(A)
F_diag = (P @ np.diag(vals ** (n - 1)) @ np.linalg.inv(P) @ np.array([1.0, 0.0]))[0]
print(F_iter, F_power, F_diag) # 832040 832040 832040.0 三者一致
print("F_n / F_{n-1} ->", (phi**n / phi**(n - 1))) # 1.618... 收斂到黃金比
應用二:馬可夫鏈與穩態#
常客問題:某城市每人每個月只喝咖啡或茶,且習慣會變: 喝咖啡的人下個月有 \(70\%\) 繼續喝咖啡、 \(30\%\) 改喝茶; 喝茶的人下個月有 \(40\%\) 改喝咖啡、 \(60\%\) 繼續喝茶。 長期下來,市場佔比會變成什麼樣?
用狀態向量 \(\mathbf{x} = \begin{bmatrix} c \\ t \end{bmatrix}\) ( \(c + t = 1\) ,各佔比)描述人群,轉移規則寫成轉移矩陣:
(注意每行加起來是 1——機率守恆。)這個「狀態只依賴上一步」的隨機模型 就是馬可夫鏈。
穩態 = 特徵值 1 的特徵向量#
「市場飽和、佔比不再變化」的數學描述是 \(\mathbf{x}^* = M\mathbf{x}^*\) —— 這正是特徵方程 \(M\mathbf{v} = \lambda\mathbf{v}\) 在 \(\lambda = 1\) 的特例! 馬可夫轉移矩陣必定有特徵值 \(1\) (列隨機矩陣的性質),所以穩態一定存在:
用 np.linalg.eig 求穩態 + 迭代驗證#
import numpy as np
import linalg_viz as viz
M = np.array([[0.7, 0.4],
[0.3, 0.6]])
# --- 方法一:特徵向量法 ---
vals, vecs = np.linalg.eig(M)
print("特徵值:", vals) # [ 1. 0.3] ← 必有特徵值 1!
idx = np.argmin(np.abs(vals - 1)) # 找出最接近 1 的特徵值
x_star = np.real(vecs[:, idx])
x_star = x_star / x_star.sum() # 標準化:機率和為 1
print("穩態:", np.round(x_star, 4)) # [0.5714 0.4286]
# --- 方法二:迭代驗證(模擬真實世界的收斂) ---
x = np.array([0.0, 1.0]) # 假設一開始人人喝茶
history = [x.copy()]
for k in range(20):
x = M @ x
history.append(x.copy())
print("迭代 20 步後:", np.round(x, 4)) # 收斂到同一個穩態!
H = np.array(history)
viz.plot_lines(H[:, 0], H[:, 1], labels=["咖啡佔比", "茶佔比"])
viz.axhline(x_star[0], linestyle="--") # 穩態畫成虛線
viz.title("馬可夫鏈收斂到穩態")
viz.show()
圖上兩條曲線一開始劇烈波動,之後貼著虛線走——不管初始狀態是 「人人喝茶」還是「各半」,長期都收斂到 \(\begin{bmatrix} 0.5714 \\ 0.4286 \end{bmatrix}\) 。 這就是「穩態由矩陣本身決定、與起點無關」的視覺證據。
為什麼一定收斂?特徵值給答案#
\(M\) 的特徵值是 \(1\) 和 \(0.3\) 。把狀態分解到特徵基底上:
\(k \to \infty\) 時 \(0.3^k \to 0\) ,只剩特徵值 1 的分量—— 這就是收斂到穩態的完整解釋,而且 \(|0.3|\) 越小收斂越快。 (回頭看 5.3 的 \(A^n = PD^nP^{-1}\) :應用的閉環在此合攏。)
換個模型:三態天氣#
import numpy as np
# 晴天/多雲/雨天,行 = 明天的條件機率
T = np.array([[0.6, 0.3, 0.1],
[0.3, 0.4, 0.3],
[0.1, 0.3, 0.6]])
vals, vecs = np.linalg.eig(T)
idx = np.argmin(np.abs(vals - 1))
steady = np.real(vecs[:, idx]); steady = steady / steady.sum()
print("穩態天氣分佈:", np.round(steady, 3))
# 約 [0.333 0.333 0.333]:長期三天氣均分
x = np.array([1.0, 0.0, 0.0]) # 今天大晴天
for k in range(30):
x = T @ x
print("迭代 30 步:", np.round(x, 3)) # 同一個穩態
PageRank(第 8 章)就是同一套套路放大到數十億網頁: 「網頁重要性」是超連結轉移矩陣在特徵值 1 上的特徵向量。
小結與練習#
本節重點#
- 遞迴關係可打包成向量 + 矩陣: \(\mathbf{u}_{n+1} = A\mathbf{u}_n\) ,第 \(n\) 項 = \(A^n\) 作用在初值上
- Fibonacci 的特徵值是黃金比 \(\varphi = \frac{1+\sqrt5}{2}\) ,由此得 Binet 公式 \(F_n \approx \varphi^n / \sqrt5\)
- 馬可夫鏈:轉移矩陣每行和為 1;穩態 = 特徵值 1 的特徵向量(標準化和為 1)
- 收斂動力學由特徵值大小決定: \(|\lambda_2| < 1\) 保證收斂,且越小收斂越快
- 特徵值 1 的特徵向量法(直接解)與迭代法(模擬)必須給出相同答案——雙向驗證是好習慣
練習#
- 用 Binet 公式計算 \(F_{50}\) ,與
np.linalg.matrix_power的結果比對。 - 常客問題中,若咖啡黨忠誠度升為 \(80\%\) ( \(M = \begin{bmatrix} 0.8 & 0.4 \\ 0.2 & 0.6 \end{bmatrix}\) ), 手算新穩態,並用
np.linalg.eig驗證。 - 畫出練習 2 的迭代收斂圖,比較新舊兩個矩陣哪個收斂更快 (提示:看 \(|\lambda_2|\) 的大小)。
- 三態天氣模型中,把雨天機率矩陣改成 \(\begin{bmatrix} 0.5 & 0.2 & 0.3 \\ 0.3 & 0.4 & 0.3 \\ 0.2 & 0.4 & 0.4 \end{bmatrix}\) , 求新的穩態天氣分佈。
- 挑戰:證明列隨機矩陣(每行和為 1)必有特徵值 1 (提示:考慮 \(M^{\!\top}\mathbf{1} = \mathbf{1}\) ,即 \(M^{\!\top}\) 有特徵值 1, 再利用 \(M\) 與 \(M^{\!\top}\) 特徵值相同)。