1. 程式人生 > >矩陣的運算 --- 倍增法-矩陣連乘求和(UVA11149

矩陣的運算 --- 倍增法-矩陣連乘求和(UVA11149

相信大家對於矩陣快速冪都有一定的瞭解。大家也就知道快速冪對於冪運算的迅速,但是當出現了這樣的問題:在這裡插入圖片描述 我們就會發現即便矩陣快速冪再快,我們計算和我們都是O(n)的演算法。那麼在這個問題上,我們研究問題的重心就從矩陣的冪,轉化為了矩陣冪的和。光看這個好像也想不出什麼,那麼我們換一個角度來思考這個問題。我們現在是要讓計算變得更快,對吧?那麼怎麼樣才能變得更快呢?時間複雜度的定義,就是從運算的次數來衡量時間的吧。那麼現在我們就有目標了。我們要怎麼減少運算的次數呢?顯然就是儘量避免重複計算,換而言之就是儘可能的找出公共部分。於是我們很容易的得到下列式子: 在這裡插入圖片描述 現在我們發現公共部分,我們已經找到了,提取公因式:在這裡插入圖片描述

同理我們還可以繼續對式子後半部分(A^1 + A^2 + … + A^(n/2) )做相同的處理,於是我們驚奇的發現,我們將O(n)的複雜度降低為 O(log n)的時間複雜度了。

以下是程式碼實現:

//Matrix 類,同矩陣快速冪的Matrix類
 
//倍增法求解a^1 + a^2 + ... + a^n
Matrix slove(const Matrix &a, int n){
    //遞迴終點
    if(n == 1) return a;
    //temp 遞迴表示a^1 + a^2 + ... + a^(n/2)
    Matrix temp = slove(a, n/2);
    //sum 表示 a^1 + a^2 + ... + a^(n/2) + (a^(n/2))*(a^1 + a^2 + ... + a^(n/2))
    Matrix sum = temp + temp*a.pow(n/2);
    //如果當n為奇數,我們會發現我們的(n/2 + n/2) == n-1
    //於是我們需要補上一項: a^n
    if(n & 1) sum = sum + a.pow(n);
    return sum;
}

還有一種計算矩陣連乘求和

矩陣連乘求和:1 + A^2 + A^3 + … + A^n
1. 構造矩陣
|A 1|
|0 1|

例如求矩陣
|2 1|
|3 4|
的1 + A^2 + A^3 + … + A^n可以把矩陣構造成
|2 1 1|
|3 4 1|
|0 0 1|
結果為
7 6 4
18 19 8
0 0 1
結果的的第一行的全部相加結果就是1 + A^2 + A^3 + … + A^n的每一個A的i次冪的矩陣的第一行的和