1. 程式人生 > >009-矩陣乘法-分治法-《演算法設計技巧與分析》M.H.A學習筆記

009-矩陣乘法-分治法-《演算法設計技巧與分析》M.H.A學習筆記

A、B是兩個n*n的矩陣,計算C=A*B。

傳統演算法:

按照下面公式計算,需要n3次乘法和n3-n2次加法,時間複雜度為Θ(n3)。



遞迴演算法:

假定n為2的冪,將A、B、C分成4個大小為(n/2)*(n/2)的子矩陣。


用分治法來計算C。

需要8次(n/2)*(n/2)矩陣的乘法和4次(n/2)*(n/2)矩陣的加法,其中乘法是原來的1/8倍消費,加法是原來的1/4倍耗費。用m表示n=1是乘法的耗費,用a表示加法的耗費。
於是有了下面的遞推式:

可以推出:

同樣需要n3次乘法和n3-n2次加法,與傳統方法相比,時間複雜度沒有改進,反而還增加了遞迴帶來的管理開銷。


Strassen演算法:

複雜度為o(n3),執行時間漸進少於n3。
像遞迴方法一樣劃分矩陣,但在計算C的時候有一些不同。
首先計算出一些中間值:

再由這些中間值得出C:

Strassen演算法進行了18次加法和7次乘法。對於執行時間有如下的遞推式:

經過計算可得,執行時間為Θ(nlog7)=O(n2.81)。


三個演算法的比較:

沒有相關程式碼,但貼一個常用的矩陣類模板:

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;

const int dim=20; //最高的維度,可調
int mod=1000000007; // 結果取的模,可調
int mk=5;// 運算時是運算幾維矩陣的,可調

struct Matrix
{
    ll a[dim][dim];
    Matrix(){memset(a,0,sizeof(a));}
};


Matrix operator *(const Matrix& a,const Matrix& b)
{
    Matrix ret;
    for(int i=0;i<mk;++i)
        for(int j=0;j<mk;++j)
            for(int k=0;k<mk;++k)
            {
                ret.a[i][j]+=a.a[i][k]*b.a[k][j];
                ret.a[i][j]%=mod;
            }
    return ret;
}
Matrix operator ^(Matrix x, ll n)
{
    Matrix ret;
    for(int i=0;i<mk;++i)ret.a[i][i]=1;
    while(n)
    {
        if(n&1)ret=ret*x;
        x=x*x;
        n>>=1;
    }
    return ret;
}

int main()
{
    int a;
    cin>>a;
}


相關推薦

009-矩陣乘法-治法-《演算法設計技巧分析M.H.A學習筆記

A、B是兩個n*n的矩陣,計算C=A*B。傳統演算法: 按照下面公式計算,需要n3次乘法和n3-n2次加法,時間複雜度為Θ(n3)。 遞迴演算法: 假定n為2的冪,將A、B、C分成4個大小為(n/2)*(n/2)的子矩陣。 用分治法來計算C。 需要8次(n/2)*(n/2

010-最近點對問題-治法-《演算法設計技巧分析M.H.A學習筆記

設S是平面上n個點的集合,在S中找到兩點p、q,使得他們的歐幾里得距離d(p,q)是所有點對中最小的。 樸素的演算法是計算所有點對的距離,在求出最小的,需要Ω(n2)。 採用分治法可以在Θ(nlogn)完成任務。 基本思路: 我們用分治正規化來解釋這一過程: (a)劃

005-二分搜尋-治法-《演算法設計技巧分析M.H.A學習筆記

二分搜尋又稱折半查詢,用於在排序好的序列表中進行搜尋,搜尋效率高,可在最壞的情況下用O(log n)完成搜尋任務。 基本思想: 將n個元素分成個數大致相同的兩半,取a[n/2]與欲查詢的x作比較,如果x=a[n/2]則找到x,演算法終止。如 果x<a[n/2],

007-尋找第k小元素-治法-《演算法設計技巧分析M.H.A學習筆記

在n個元素的陣列中查詢第k小的元素。Θ(n) 顯然先排序的話,複雜度為O(nlogn)。 但我們還有一個很漂亮的Θ(n)的演算法。 先說一下分治法的閾值:我們有一種吊炸天的分治演算法,可以用很好的效率求解出某個問題,分治演算法當然在達到一個非常小的規模時,會能

演算法設計技巧分析(中文版)》下載

2018年11月01日 21:04:02 qq_43580768 閱讀數:1 標籤: 程式設計 資料

021-回溯法深搜的關係-《演算法設計技巧分析M.H.A學習筆記

關於回溯法與深搜的關係,一直沒有很好的搞明白,其實百度百科已經寫得很好了: 回溯法的基本思想: 在包含問題的所有解的解空間樹中,按照深度優先搜尋的策略,從根結點出發深度探索解空間樹。當探索到某一結點

演算法設計技巧分析筆記 第一章

1.搜尋:設A【1……n】為一個n個元素的陣列,判定給定元素x是否在A中 線性搜尋:直接掃描A中所有專案,將每個專案與x做比較。 二分搜尋: A【low……high】為有序非空陣列(假定為升序),A【mid】為中間元素 假定x>A【mid】,則丟棄A【low…mid】

演算法設計技巧分析)CloseStpair

#include<iostream> #include<time.h> #include<math.h> using namespace std; class Point { public: int x; int y; void

011-最長公共子序列-動態規劃-《演算法設計技巧分析M.H.A學習筆記

給出兩個長度分別為n和m的字串A和B,確定A和B中最長公共子序列的長度。 樸素演算法:列舉A中所有的子序列2n個,並逐個判斷其是否在B中(Θ(m)耗費)。時間複雜度為Θ(m2n)。 利用動態規劃可

演算法設計技巧分析)LCS

#include<iostream> #include<stack> using namespace std; void LCS(int **,char[],int,char[],int); void LCS_print(int **,stack&

【 專欄 】- 《演算法設計技巧分析M.H.A學習筆記

《演算法設計技巧與分析》M.H.A學習筆記 期末到了開始複習演算法,順便寫寫部落格,看的書是M.H.Alsuwaiyel的《演算法設計技巧與分析》,書挺好的,就是有一些解釋不是很清楚。 這裡寫我自己的理解,重新簡單排版下一些有價

凸多邊形最優三角剖演算法設計:動態規劃)

一、動態規劃       和分治法類似,把原問題劃分成若干個子問題,不同的是,分治法(子問題間互相獨立),動態規劃(子問題不獨立)       動態規劃: (1)找出最優解的性質,刻畫其結構特徵 (2)遞迴地定義最優值

資料結構和演算法解:第九章 演算法設計技巧

9.1 貪婪演算法 演算法思想:貪婪演算法分階段的工作。在一個階段,可以認為是所做的決定中最好好的,而不考慮將來的後果。通常,這意味著選擇的是某個區域性最優。這種“眼下就能拿到的就拿”的側臉是這類演算法的來源。在演算法終止的時候,我們希望區域性最優等於全域性最優。 9.2 分治演算法

240. Search a 2D Matrix II(搜尋二維矩陣治法

題目連結 https://leetcode.com/problems/search-a-2d-matrix-ii/description/ 題目描述 Write an efficient algorithm that searches for a value in an m x n matrix

單峰問題治法演算法(C++實現)

給定含有n個不同的陣列成的陣列L=<x1,x2,x3,…,xn>,如果L中存在xi使得,則稱x1<x2 <…<xi-1<xi且xi>xi+1>…>xn則稱L是單峰的,並稱xi是L的峰頂。假設L是單峰的,設計演

搜尋 (演算法設計分析課後習題)

三分搜尋演算法的做法是:它先將待查元素x與n/3處的元素比較,然後將x與2n/3處的元素進行比較。比較的結果或者找到x,或者將搜尋範圍縮小的原來的n/3 1)編寫C++程式實踐演算法 2)分析演算法的時間複雜度 1) #include <cstdio> in

演算法設計技巧--離散暴力將時間將為O(0);

/*摘要:Let A=∑ni=1ai∗10n−i(1≤ai≤9)(n is the number of A's digits). We call A as “beautiful number” if and only if a[i]≥a[i+1] when

治法演算法設計

    首先要申明的是減治法思想並不等同於分治法思想,減治法技術利用一個問題給定例項的解和同樣問題較小例項的解之間的某種關係。一旦建立了這種關係,就可以從頂至下(遞迴),或者從底之上(迭代)地來運用該關係。減治法有3種主要的變種: 1 減去一個常量 2 減去一個常量因子,大

【子矩陣】【高效演算法設計

.子矩陣 小A 有一個N×M 的矩陣,矩陣中1~N*M 這(N*M)個整數均出現過一次。現在小A 在這個矩陣內選擇一個子矩陣,其權值等於這個子矩陣中的所有數的最小值。小A 想知道,如果他選擇的子矩陣的

大整數乘法——治法

一。最原始的方法: import java.util.Scanner; public class Big { static int N=100; static int a[]=new int[N]; static int b[]