Floyd Warshall アルゴリズムを実装しましたが、動作しますが、問題は、定義されていないすべてのパスを見つける方法がわからないことです。Web を検索しましたが、グラフに負のサイクルがあるかどうかを検出する方法しか見つかりません。
vector< vector <int> > floyd_warshall(vector< vector<int> > d, int n){
for(int i = 0; i < n; i++) d[i][i] = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
for(int k = 0; k < n; k++){
if(d[j][i] + d[i][k] < d[j][k] and d[j][i] != INF and d[i][k] != INF){
d[j][k] = d[j][i] + d[i][k];
}
}
}
}
return d;
}
グラフでアルゴリズムを実行した後:
from: to: weight:
0 1 1
1 2 -1
2 1 -1
1 3 1
4 0 1
隣接行列を取得します。
| 0 1 2 3 4
--|----------------------------
0 | 0 -1 -2 -2 INF
1 | INF -2 -3 -3 INF
2 | INF -3 -4 -4 INF
3 | INF INF INF 0 INF
4 | 1 -2 -3 -7 0
ノード i が負のサイクルの一部である場合、行列の位置 d[i][i] に負の値があることがわかっています。したがって、マトリックスの対角線をチェックすると、負のサイクルの一部であるすべてのノードを見つけることができます。したがって、上記の例を見ると、ノード 1 と 2 が負のサイクルの一部であることがわかります。問題は、定義されているパスと定義されていないパスを見つけたいということです。負のサイクルを介して A から B に到達できる場合、パスの長さは任意に短くなる可能性があるため、未定義にする必要があります。
問題は、未定義のパスをすべて見つけるにはどうすればよいですか?
アルゴリズムが行列を返すようにしたい:(上記の代わりに)
| 0 1 2 3 4
--|----------------------------
0 | 0 -INF -INF -INF INF
1 | INF -INF -INF -INF INF
2 | INF -INF -INF -INF INF
3 | INF INF INF 0 INF
4 | 1 -INF -INF -INF 0
d[i][j] = INF は i と j の間にパスがないことを意味し、 -INF は i と j の間に任意の小さなパスがあることを意味し (パスはどこかで負のループを通過します)、そうでない場合は d[i ][j] i と j の間の最短の長さ。
パスごとにテストすることを考えていましたが、おそらく遅すぎます。この問題を解決するための標準的な方法があるはずですよね?
ありがとうございました