セットのすべてのペアを比較する必要がありますか? (ユーザー ID をメンバーシップにマップするデータ構造を保持する場合、これは必要ありません。)
交差度を数えるには、ユーザーが持っている他のグループにアクセスする必要がありますが、これはまだ立方体です。カウントするハッシュ テーブルまたはその他のスパース配列を使用できますが、それでも、各ユーザーが属するグループのペアごとに各ユーザーの増分が必要になるだけです。 group と各ユーザーが属するグループの数 T を比較すると、グループの各ペアを比較するために G G S/2 が得られ、ユーザーからグループへのインデックスがある場合はN T T が得られます。T = G S/N なので N T T=G G SS/N; S=20 と数百万の N の場合、利点があるはずです。残念ながら、交差カウント用に少なくとも G*G 個のストレージ (4 ビットの非スパース カウンターの場合は 25 TB 程度) も必要であり、構造を並行してインクリメントできるようにする必要があります。
20 人からなる 1,000 万のグループに属する 100 万人のユーザーの場合、ユーザーが特定のグループに所属する確率はほぼ 2e-6 であり、2 つのグループがユーザーを共有する確率は 40e-6 であるため、25 TB は 1 GB になります。データであるため、通常のサイズのコンピューターのスパース配列では不可能ではありません。
ただし、共通の 15 要素に対して 20 要素のセットを比較すると、より明白な最適化が得られます。
- グループがソートされている場合、作業用ストレージは必要ありません。入力グループ間の差異の程度を直接出力するだけです。
- ほとんどのメモリ アクセスは連続したメモリ領域で線形になり、結果はデータ セット全体の合計に依存するのではなく、比較される 2 つのセットのみに依存します。メイン メモリにランダムにアクセスすると、線形にアクセスするよりも大幅に遅くなります。バス ロックを使用してメイン メモリをランダムに変更すると、バスをロックせずにキャッシュにアクセスするよりも桁違いに遅くなります (ただし、コアあたり数 GB のメモリがある場合は、同期を行わなくてもユーザー -> グループ アプローチを使用できます)。
- セット間で異なる 5 つの要素のみをカウントする必要があります。データがランダムな場合、ほとんどのセットは互いに素であるため、アクセスされる要素の平均数は少なくなります。
- 差を距離として扱うことにより、特定のグループをすばやく割り引くことができます (A が B と 11 異なっており、C が B と 5 異なっている場合、C は A と 6 から 16 の間の差であるため、A と C を比較せずに割り引くことができます)。直接)。ほとんどのセットは完全にバラバラなので、これはあまり役に立ちません。
user->group マップを使用してグループ間の比較を行うハイブリッド アプローチのオプションもあります。これには、共有データ構造のインクリメントを必要としないという利点があります。
- ユーザーが属するグループのペアごとに、そのペアをリストに追加して調査します。
- 少なくとも 1 人のユーザーが共通するグループのペアのリストを並べ替えます。
- リスト内の各ペアの出現回数は、共通のユーザーの数です。
マージソートを使用すると、これは純粋なストリーミングユニットに並列化するのに非常に便利です。約 20*200*1000 万/2 = 200 億のグループ ID ペア (20 ユーザーの各グループ×各ユーザーが属するグループ数/2) をソートします。