エッジ リストをスキャンし、インデックスを交換して、それぞれ(i, j)について常に true になるようにすることができますi < j。これは O(N) で行います。
並べ替えられたエッジ リストも必要です。これは O(N log N) です。並べ替えられたエッジ リストを取得したら、それを Symmetric-CSR 形式で保存できます。cell を読み取るとき(y,x)に、 if y > xthen と を交換yしxます。row_pointer[y]次にandを読みrow_pointer[y+1]、それらをPaand とし、 と の間でi のPbスキャンを開始します。>= (= または > の場合に応じて見つかったか見つからない)、または if (見つからない)の場合は終了します。CSR[i]PaPbxCSR[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 をスキャンしてから、 に進むことができます。pqNodesIJ[p] = iNodesJI[q] = iNodesIJ[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 は接続の平均数) のセルを持つことができます。何百万ものエッジのリストには、数十ギガバイトのストレージが簡単に必要になる場合があります。