私は現在、隣接行列を含むいくつかのグラフ計算を行っており、そのすべてを少しずつ最適化する過程にあります。
最適化できると思う指示の1つは、元の形式のタイトルの指示です。
if ((adjMatrix[i][k] > 0) && (adjMatrix[k][j] > 0) && (adjMatrix[i][k] + adjMatrix[k][j] == w))
ただし、簡単にするために、タイトルに記載されているフォームに固執します。
if (a > 0 && b > 0 && a + b == c)
私が気に入らないのは>0の部分です(隣接行列であるため、初期の形式では0と1しか含まれていませんが、プログラムが進むにつれて、ゼロがなくなるまで2以降の数値に置き換えられます。
テストを行い、aとbの両方で> 0の部分を削除しましたが、大幅な改善が見られました。60088回の反復で、3762ミリ秒から2880ミリ秒に792ミリ秒の減少がありました。これは、元の時間の78%であり、私にとっては優れています。
だから私の質問は:C#でこのようなステートメントを最適化して同じ結果を得る方法を考えられますか?たぶん、いくつかのビット演算または類似のもの、私はそれらにあまり精通していません。
たとえそれが適切でなくても、あなたの心を横切るあらゆる考えで答えてください。自分で速度テストを行い、結果をお知らせします。
編集:これは、自分のコンピューターで自分で実行するコンパイラー用です。私が今説明したことは、私が不満を言っている問題/ボトルネックではありません。現在の形式のプログラムは私のニーズには問題なく動作しますが、私はそれを前進させ、可能な限り基本的で最適化したものにしたいと思っています。これが少し明確になることを願っています。
編集私は完全なコードを提供することは有用なことだと信じているので、ここにありますが、下の太字で言ったことを覚えておいてください。ifステートメントに厳密に集中したいと思います。プログラムは基本的に隣接行列を取り、存在するすべてのルートの組み合わせを保存します。次に、いくつかの係数に従ってソートおよびトリミングされますが、これは含まれていません。
int w, i, j, li, k;
int[][] adjMatrix = Data.AdjacencyMatrix;
List<List<List<int[]>>> output = new List<List<List<int[]>>>(c);
for (w = 2; w <= 5; w++)
{
int[] plan;
for (i = 0; i < c; i++)
{
for (j = 0; j < c; j++)
{
if (j == i) continue;
if (adjMatrix[i][j] == 0)
{
for (k = 0; k < c; k++) // 11.7%
{
if (
adjMatrix[i][k] > 0 &&
adjMatrix[k][j] > 0 &&
adjMatrix[i][k] + adjMatrix[k][j] == w) // 26.4%
{
adjMatrix[i][j] = w;
foreach (int[] first in output[i][k])
foreach (int[] second in output[k][j]) // 33.9%
{
plan = new int[w - 1];
li = 0;
foreach (int l in first) plan[li++] = l;
plan[li++] = k;
foreach (int l in second) plan[li++] = l;
output[i][j].Add(plan);
}
}
}
// Here the sorting and trimming occurs, but for the sake of
// discussion, this is only a simple IEnumerable<T>.Take()
if (adjMatrix[i][j] == w)
output[i][j] = output[i][j].Take(10).ToList();
}
}
}
}
プロファイラーの結果にコメントを追加すると、ビルドが最適化されます。
ちなみに、タイミングの結果はまさにこのコードで得られました(実行時間を劇的に増加させるソートとトリミングなしで)。私の測定に含まれている他の部分はありませんでした。このコードの直前にStopwatch.StartNew()があり、直後にConsole.WriteLine(EllapsedMilliseconds)があります。
サイズについて考えたい場合、隣接行列には406行/列があります。つまり、基本的には、多くの反復を実行するfor-命令が組み合わされているだけなので、最適化のオプションはあまりありません。速度は今のところ問題ではありませんが、いつになるかを確認したいと思います。
そして、「別の部分を最適化する」問題を除外するために、この主題についても話し合う余地がありますが、この特定の問題については、抽象的な問題/概念としてこれに対する解決策を見つけたいと思います。私や他の人がC#コンパイラがどのように機能し、ifステートメントと比較を処理するかを理解するのに役立つかもしれません。それがここでの私の目標です。