Fine-Grained学习笔记(2):矩阵乘法与图论

问题:矩阵乘法

方阵乘法:

给定两个n×n的矩阵A=(aij),B=(bij),计算C=AB,cij=Σk=1naikbkj.

(由于语言习惯,本文中提到矩阵且无其他说明的场合,均指方阵)

朴素算法的复杂度:O(n3)

设想中的复杂度下界:Ω(n2)(把n×n的矩阵读取完就需要O(n2)时间了)

Strassen算法(1969):

热身:考虑n=2的情况:

c11=a11b11+a12b21

c12=a11b12+a12b22

c21=a21b11+a22b21

c22=a21b12+a22b22

共需8次乘法

思路:

考虑

p1=a11(b11b21)

p2=(a11+a12)b21

p3=a22(b22b12)

p4=(a21+a22)b12

p5=(a11+a22)(b21+b12)

p6=(a12a22)(b21+b22)

p7=(a21a11)(b11+b12)

c11=p1+p2

c12=p5+p6+p3p2

c21=p5+p7+p1p4

c22=p3+p4

总共只需要进行7次乘法.

然后考虑任意n的情况,将A,B划分为四个子矩阵

A=[A11A12A21A22]

B=[B11B12B21B22]

并进行递归分治,分析时间复杂度

T(n)=7T(n/2)+O(n2)

T(n)=O(nlog27)O(n2.81)

其他的分治法思路

Laderman在1976年证明了3×3的矩阵乘法只需进行23次乘法运算,然而对矩阵乘进行三路分治的复杂度T(n)=23T(n/3)+O(n2)=O(nlog223)O(n2.85),反倒不如二路分治

Pan在1978年证明了k=70的矩阵乘法共需k34k3+6k2=143640次乘法,因此对矩阵乘法进行70路分治的复杂度T(n)=143640T(n/70)+O(n2)=O(nlog70143640)O(n2.796)

Pan又在1978年证明了k=46的矩阵乘法共需41952次,因此对矩阵乘法进行46路分治的复杂度为T(n)=41952T(n/46)+O(n2)=O(nlog4641952)O(n2.781)

Bini等人在1980年使用"Border Rank"理论使得矩阵乘法复杂度降低到了O(n2.780)

Schonhage在1981年矩阵乘法复杂度降低到了O(n2.522)

Strassen在1986年使用"Laser Method"将矩阵乘法复杂度降低到了O(n2.479)

目前对矩阵乘法的复杂度下界尚没有一个定论,在本文中使用O(nω)表示矩阵乘法的复杂度,并认为ω=2.372.

(长方形)矩阵乘法:

给定n1×n2的矩阵A=(aij),n2×n3的矩阵B=(bij),计算n1×n3的矩阵C=AB,cij=Σk=1naikbkj.

M(n1,n2,n3)为进行该运算所需的时间复杂度,记ω(a,b,c)=logn(M(na,nb,nc))

以下结论是显然的:

1,ω(,,)是凸函数

ω(ta1+(1t)a2,tb1+(1t)b2,tc1+(1t)c2)tω(a1,b1,c1)+(1t)ω(a2,b2,c2),t[0,1]

2,ω(,,)是对称的

ω(a,b,c)=ω(c,b,a)=

简单的下界性质:

考虑M(n,l,n)形式的问题,根据l,n之间的大小关系,将矩阵分为两种情况,根据矩阵乘法中左侧的矩阵的形状,将这两种情况称为"瘦矩阵"和"扁矩阵"

瘦矩阵乘:

按照如上方式,将两个矩阵分别拆分成n/ll×l的矩阵,总时间复杂度为O((n/l)2lω)=O(lω2n2)

扁矩阵乘:

按照如上方式,将两个矩阵分别拆分成l/nn×n的矩阵,总时间复杂度为O((l/n)lω)=O(lnω1)

但实际上,针对这两种分类还有更好的算法:

对于瘦矩阵乘:

Coppersmith在1982年给出了M(n,n0.172,n)=O~(n2)的结论

LeGall和Urrutia在2018年给出了M(n,n0.3189,n)=O(n2+ϵ)的结论

对于扁矩阵乘:

k>1,M(n,nk,n)=O(nk+1+f(k)),其中,当k时,f(k)0

稀疏矩阵乘:

对于两个n×n的矩阵A,B,其中的非零元素为m个,mn2

朴素算法:

复杂度为O(mn),由于mnω1,因此优于O(nω)

博主注:这个O(mn)的算法是怎么样的我没有想明白,感觉并不是那么朴素.

Yuster和Zwick的算法(2005):

思路:按照矩阵A中每列非零元素个数多少,将所有列分为高频和低频两类讨论

deg(k)=|{i:aik0}|

H={k:deg(k)>Δ}

L={k:deg(k)Δ}

这样便保证了|H|m/Δ

低频列:

计算cijL=ΣkLaikbkj,具体的方法是:

对于所有使得bkj0k,j: (循环次数O(m))

对于所有使得aik0i: (循环次数O(Δ)

cij+=aikbkj

该情况时间复杂度O(mΔ)

高频列:

H中所对应的矩阵A中的列和矩阵B中的行提取出来,构造出两个长方形矩阵:n×|H|的矩阵A,|H|×n的矩阵B,计算AB,得到cijH=ΣkHaikbkj,该情况时间复杂度M(n,m/Δ,n)

总时间复杂度O(mΔ+M(n,m/Δ,n))

应用:与矩阵和线性代数有关的问题

矩阵求逆,Ax=b线性方程求解......

应用:有向图中寻找三元环

给定有向图G=(V,E)

判断是否存在三个点u,x,vV,使得(u,x),(x,v),(v,u)E

朴素算法:

(1)暴力枚举三个点,时间复杂度:O(|V|3)

(2)枚举所有边(v,u),再枚举第三个点x,判断(u,x),(x,v)是否存在,时间复杂度:O(|V||E|),在|E||V|2的稀疏图中较优

(3)利用矩阵乘法:

对于所有的u,vV,计算cu,v=xV({(u,x)V}{(x,vV)}),可由矩阵乘法计算.

然后对于所有u,v,判断cuv=1(v,u)E

总时间复杂度O(|V|ω),相比算法(2)更适用于稠密图.

(4)利用稀疏矩阵乘法,复杂度O(|E|Δ+M(|V|,|E|/Δ,|V|))

Alon,Yuster,Zwick的算法(1997):

思路还是分为高低频,根据点的度数划分(算法描述中使用的是点的出度)

H={vV:deg(v)>Δ}

L={vV:deg(v)Δ}

情况1:

部分点在L中的三角形,不妨记xL

对于所有使得(u,x)Eu,x(循环次数O(|E|))

对于所有使得(x,v)Ev:  (循环次数O(Δ))

判断是否有(v,u)E

该情况的时间复杂度:O(|E|Δ)

情况2:

三个点都在H中的三角形

注意,|H||E|/Δ

运行朴素算法(3),该情况时间复杂度O((|E|/Δ)ω)

总时间复杂度:O(|E|Δ+(|E|/Δ)ω)

Δ=|E|ω1ω+1,因为前文约定了ω=2.372,

得到O(|E|2ωω+1)O(|E|1.41)

应用:有向图中寻找k元环(k为常数)

Alon,Yusher,Zwick:Color coding,时间复杂度O(|V|ω),具体算法待查

对于稀疏图:

k=4:O(|E|1.48)

应用:k-Clique(k团)

在无向图中寻找k个两两相连的点构成的子图,k为常数

暴力枚举:O(|V|k)

kmod3=0,则可用O(|V|k/3)时间暴力枚举出图中的所有k/3团,将所有k/3团作为超级节点加入新点集V中,|V|=O(|V|k/3),然后对于所有的A,BV,若AG中对应的点,均有指向BG中对应的点,则将边(A,B)加入新边集E中,这样,问题就变为了在G=(V,E)上寻找三元环的问题,总时间复杂度O((|V|k/3)ω)

应用:带权图

定义:(min,+)矩阵乘

cuv=minxV(aux+axv)

类似于最短路算法中的"松弛"操作

下一章将会讨论这个算法

应用:传递闭包(全局连通性)

给定有向图G=(V,E),判断对于s,tV,是否存在从st的路径

朴素算法:

(1)进行|V|次DFS/BFS:O(|V||E|)O(n3)

(2)Warshall DP(类似于Floyd):枚举中点xV,再枚举两端点u,vV,若边(u,x),(x,v)均存在,则将边(u,v)加入边集E中,时间复杂度O(n3)

Warshall算法使用重复矩阵乘的改进:

cuv(k)为真,当且仅当存在一条k跳的,从uv的路径.

对于k=1,2,4,,|V|,用矩阵乘法计算cuv(k)=xV(cux(k/2)cxv(k/2))

总时间复杂度:O(||ωlog|V|)O(|V|2.373)

Munro算法(1971):

考虑G是一个DAG(有向无环图)的情况,对于任意的图,可以通过搜索出所有强连通分量并合并为超级节点做到这一点.

搜索强连通分量并缩点的方法是Tarjan算法,一种DFS算法,在DFS的过程中将搜索到的顺序作为时间戳标记在每个节点上,并记录从该点回溯能够到达的时间戳最小的节点.在许多博客都有相应的讲解,这里不再赘述.

这样做的意义在于,DAG保证了邻接矩阵必定是一个上三角矩阵,记A=(aij),auv为真,当且仅当uv之间有一条边,A=(aij),auv为真,当且仅当uv之间存在着连通的路径.

A写成如下分块矩阵的形式:

A=[A11A120A22]

那么

A=[A11A11A12A220A22]

由于A11,A22也是上三角矩阵,因此可以递归求解,矩阵维数为1时,A11=A11,A22=A22,因此总复杂度T(n)=2T(n/2)+O(nω),复杂度相比重复的矩阵乘减少了一个对数项.

 

posted @   Isakovsky  阅读(100)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示