用 Warshall’s 算法计算传递闭包
(1)时间复杂度为:O(nnn)
(2)用R的无穷闭包时间复杂度为O(nnn*(n - 1))
经典实现:
下面展示一些 经典代码片。
void computeAPSP(const int n) {
/* calculate shortest paths from every vertex to every vertex */
for (int k = 0; k < n; k++)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
a[i][j] = min( a[i][j], a[i][k] + a[k][j] );
}
}
}
}
利用矩阵的对称性优化:
void computeAPSP(const int n)
{
for (int k = 0; k < n; k++)
{
for (int i = 0; i < n; i++)
{
if (k != i)
{
const int a_ki = (k < i) ? a[i][k] : a[k][i];
for (int j = 0; j < min(k, i); j++)
a[i][j] = min( a[i][j], a_ki + a[k][j] );
for (int j = k + 1; j < i; j++)
a[i][j] = min( a[i][j], a_ki + a[j][k] );
}
}
}
}
只使用矩阵的下三角部分进行优化:
void computeAPSP(const int n)
{
for (int k = 0; k < n; k++)
{
for (int i = 0; i < n; i++)
{
if (k != i)
{
const int a_ki = (k < i) ? a[i][k] : a[k][i];
for (int j = 0; j < min(k, i); j++)
a[i][j] = min( a[i][j], a_ki + a[k][j] );
for (int j = k + 1; j < i; j++)
a[i][j] = min( a[i][j], a_ki + a[j][k] );
}
}
}
}
避免大量调用数学函数进行优化:
void computeAPSP(const int n)
{
for (int k = 0; k < n; k++)
{
for (int i = 0; i < n; i++)
{
if (k != i)
{
const int a_ki = (k < i) ? a[i][k] : a[k][i];
// skip if no path
if (a_ki == POSITIVE_INFINITY) continue;
for (int j = 0; j < min(k, i); j++)
{
const int s_kj = a_ki + a[k][j];
if( s_kj < a[i][j] ) a[i][j] = s_kj;
}
for (int j = k + 1; j < i; j++)
{
const int s_jk = a_ki + a[j][k];
if( s_jk < a[i][j] ) a[i][j] = s_jk;
}
}
}
}
}
本文介绍Warshall算法用于计算传递闭包的过程及优化方法,详细解释了该算法的时间复杂度,并通过经典代码片段展示了如何实现这一算法。此外还讨论了如何通过矩阵特性进一步优化算法效率。
878

被折叠的 条评论
为什么被折叠?



