用 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;
}
}
}
}
}