问题背景:
维特比算法是数学家维特比提出的、用于寻找“篱笆网络”中的最短路径的一种算法。
篱笆网络的结构如下图所示:
这个图的意思是:从
S
S
S到
E
E
E一共需要经过
m
m
m个步骤(或时刻);对于第
i
i
i个时刻,一共有
n
i
n_i
ni个取值;
X
i
j
X_{ij}
Xij表示第
i
i
i个时刻的第
j
j
j个可能值,其中,
1
≤
i
≤
d
1\leq i\leq d
1≤i≤d。目标是找到一条从
S
S
S到
E
E
E的路径,使得所有步骤上的值加起来最小。
注意:图中每个步骤的取值个数都是 n n n,这是因为我用的画图软件无法在下标中再继续写下标,实际上每个步骤的最后一个取值为 X 1 n 1 X_1n_1 X1n1, X 2 n 2 X_2n_2 X2n2,……
算法基础
在这个问题中,以下结论是显然成立的,并且构成了维特比算法的基础:
- 如果最短路径
P
P
P经过点
X
i
j
X_{ij}
Xij,那么路径
P
P
P的从
S
S
S到点
X
i
j
X_{ij}
Xij的子路径
P
1
P_1
P1 一定是
S
S
S到
X
i
j
X_{ij}
Xij之间的最短路径;否则,存在另一条从
S
S
S到
X
i
j
X_{ij}
Xij的更短路径
R
R
R,用
R
R
R代替
Q
Q
Q,则得到比
P
P
P更短的路径,这与已知条件矛盾。
意思也很简单:如图所示,假设从 S S S到 E E E的最短路径 P P P为图中的黑色箭头,那么,路径 P P P的从 S S S到点 X 33 X_{33} X33的子路径 P 1 P_1 P1也一定是该两点之间最短的;否则,就会存在另外一条从 S S S到点 X 33 X_{33} X33的路径 P 2 P_2 P2(如红色箭头)最短。用 P 2 P_2 P2替换 P 1 P_1 P1,就会得到从 S S S到 E E E的更短的路径,从而推导出矛盾。 - 从 S S S到 E E E,一定经过任一时刻 i i i的某个取值,即路径一定经过每个时刻的某一个节点。假定 i i i时刻有 n i n_i ni个状态,那么如果记录了从S到时刻 i i i的所有 n i n_i ni个状态的最短路径,最终的最短路径必然经过其中一条。
- 结合1和2,假定从时刻 i i i进入时刻 i + 1 i+1 i+1时,从 S S S到时刻 i i i上各个节点的最短路径已经找到,并且记录在对应节点上,那么在计算从 S S S到时刻 i + 1 i+1 i+1的某个节点的最短路径时,只要考虑从 S S S到时刻i所有的 n i n_i ni个节点的最短路径,以及从这 n i n_i ni个节点到 i + 1 i+1 i+1时刻所有 n i + 1 n_{i+1} ni+1的距离即可。
算法步骤
- 从点 S S S出发,对于时刻 i = 1 i=1 i=1的 n 1 n_1 n1个节点,计算从 S S S到它们之间的最短距离 d ( S , X 1 j ) d(S,X_{1j}) d(S,X1j),其中, j = 1 , 2 , . . . , n 1 j=1,2,...,n_1 j=1,2,...,n1。显然, S S S到任一 X 1 j X_{1j} X1j的距离即为最短距离。
- 由
i
=
1
i=1
i=1到
i
=
2
i=2
i=2时,需针对
i
=
2
i=2
i=2的
n
2
n_2
n2个节点,计算
S
S
S到它们的最短距离。对于某个特定的节点
X
2
j
X_{2j}
X2j,从
S
S
S到该点的路径可以经过
i
=
1
i=1
i=1时刻所有
n
1
n_1
n1个节点中的任意一个,因此,对应路径的长度为
d
(
S
,
X
2
j
)
=
d
(
S
,
X
1
j
1
)
+
d
(
X
1
j
1
,
X
2
j
)
d(S,X_{2j})=d(S,X_{1j_1})+d(X_{1j_1},X_{2j})
d(S,X2j)=d(S,X1j1)+d(X1j1,X2j)。
j
1
j_1
j1有
n
1
n_1
n1种可能性,因此
S
S
S到
X
2
j
X_{2j}
X2j的最短路径为:
d ( S , X 2 j ) = m i n j 1 ∈ [ 1 , n 1 ] ( d ( S , X 1 , j 1 ) + d ( X 1 j 1 , X 2 , j ) ) d(S,X_{2j})=min_{j_1\in [1,n_1]}(d(S,X_{1,j_1})+d(X_{1j_1},X_{2,j})) d(S,X2j)=minj1∈[1,n1](d(S,X1,j1)+d(X1j1,X2,j))
因此,对于 i = 2 i=2 i=2的每个节点需要进行 n 1 n_1 n1次乘法运算,一共需要进行 n 1 ∗ n 2 n_1*n_2 n1∗n2次乘法。 - 采用与2中类似的步骤,对于每个 i i i的值进行运算,就可以得到全局最短路径。
复杂度分析
时间状态数为 m m m,记对于任一时刻所可能取值的个数的最大值为 N N N,那么整个算法需要进行运算的次数不超过 m ∗ N 2 m*N^2 m∗N2。