エッジ リストをスキャンし、インデックスを交換して、それぞれ(i, j)
について常に true になるようにすることができますi < j
。これは O(N) で行います。
並べ替えられたエッジ リストも必要です。これは O(N log N) です。並べ替えられたエッジ リストを取得したら、それを Symmetric-CSR 形式で保存できます。cell を読み取るとき(y,x)
に、 if y > x
then と を交換y
しx
ます。row_pointer[y]
次にandを読みrow_pointer[y+1]
、それらをPa
and とし、 と の間でi のPb
スキャンを開始します。>= (= または > の場合に応じて見つかったか見つからない)、または if (見つからない)の場合は終了します。CSR[i]
Pa
Pb
x
CSR[i]
i == Pb
また、2 番目のエッジ リスト where を生成しj > i
、それを並べ替えることもできます。この時点で、両方のエッジを同時にスキャンし、対称性を必要とせずに CSR リストを生成できます。
j0 = j1 = N+1
# i-th row:
# we are scanning NodesIJ[ij] and NodesJI[ji].
If NodesIJ[ij][0] == i
j0 = NodesIJ[ij][1]
If NodesJI[ji][0] == i
j1 = NodesIJ[ji][1]
if (j0 < j1)
j = j0
j0 = N+1
ij++
else
if (j1 == N+1)
# Nothing more on this row, and j0 and j1 are both N+1.
i++;
continue
j = j1
j1 = N+1
ji++
# We may now store (i,j) in CSR
if (-1 == row_ind[i])
row_ind[i] = csr;
col_ind[csr++] = j
前者のリストは右上の三角形を記述し、後者は左下の三角形を記述しているため、上記のアルゴリズムは、任意の に対して、 および が存在する場合、それは常に存在することを観察して改善できi
ます。したがって、i になるまで NodesJI をスキャンしてから、 に進むことができます。p
q
NodesIJ[p] = i
NodesJI[q] = i
NodesIJ[p][1] > NodesJI[q][1]
NodesJI[p][0]
NodesJI[q]
また、インデックスが変更されない場合、行が空になり、対応する値が -1 (または N+1、または必要な「無効な」値) になる可能性があることにrow_ind
注意して、初期化を常にチェックすることを避けることもできます。csr
の前の値csr
。
scsr = csr;
while NodesIJ[ij][0] == i
col_ind[csr++] = NodesIJ[ij++][1]
while NodesJI[ji][0] == i
col_ind[csr++] = NodesJI[ji++][1]
row_ind[i++] = (csr == scsr) ? -1 : scsr;
上記は O(N log N) で実行されます。
別の方法は、行列を割り当て、エッジ リストを行列にデコードし、それを解析して CSR にすることです。これは O(N) ですが、必要なメモリが多すぎる可能性があります。リスト サイズが N の場合、最大 N^2 (または (N/a)^2、a は接続の平均数) のセルを持つことができます。何百万ものエッジのリストには、数十ギガバイトのストレージが簡単に必要になる場合があります。