我有一个有大约10,000个节点的有向图。所有边都是加权的。我想找到一个只包含3个边的负循环。有没有比O(n ^ 3)更快的算法?
示例代码:(g是我的图表)
if (DETAILS) std::printf ("Calculating cycle of length 3.\n");
for (int i=0;i<NObjects;i++)
{
for (int j=i+1;j<NObjects;j++)
{
for (int k=j+1;k<NObjects;k++)
{
if ((d= g[i][j]+g[j][k]+g[k][i])<0)
{
results[count][0] = i;
results[count][1] = j;
results[count][2] = k;
results[count][3] = d;
count++;
if (count>=MAX_OUTPUT_SIZE3)
goto finish3;
}
if ((d= g[i][k]+g[k][j]+g[j][i])<0)
{
results[count][0] = j;
results[count][1] = i;
results[count][2] = k;
results[count][3] = d;
count++;
if (count>=MAX_OUTPUT_SIZE3)
goto finish3;
}
}
}
}
finish3:
答案 0 :(得分:4)
我无法想到任何具有低于O(n 3 )的明确复杂度的算法,而且常数因子在实践中也很重要。以下算法允许修剪以加速找到具有负权重总和的长度为3的循环 - 或者检查没有这样的循环。
这个想法是,具有负和的圆柱体的至少一个边缘必须具有负重量。并且我们可以在循环中以最低权重开始循环。
如果你知道负权重的数字边是O(n)那么这个算法将是O(n 2 ld n),因为算法将由步骤1支配(=排序边缘根据其重量而定。)