データベースにn
行があり、すべての行を相互に比較したい場合、ループ(またはプロセス)をいくつ実行する必要がありますか。
それですかn2? (つまり、30,000行ある場合、900,000,000になります)
またはそれは:
for (i = 0; i < 30000; i++) {
for (j = i + 1; j < 30000; j++) [
// Process
}
}
それが遅い場合、それはいくつのプロセスですか(そして、n
が与えられた場合、それを解決するための方程式はありますか)?
また、各行をy
回処理する必要がある場合、それは計算にどのように影響しますか?
会社のデータベースで重複の可能性を確認する必要があります。確認するには、会社名、電話番号などの一般的なフィールドで類似性チェックを実行します。フィールドの差が特定のパーセンテージのしきい値を下回っている場合は、重複の可能性があるとしてマークします。私は自分でこれをうまくコーディングできますが、彼のパフォーマンスへの影響について興味があります。
[〜#〜] o [〜#〜](n2) 定義により。
Nの違い2 そして、n *(n-1)/ 2アルゴリズムは重要ではありません。
「重複」を見つけるには、はるかに優れたアルゴリズムを考案する必要があります。この「類似性チェック」ビジネスは、おそらくSQLクエリよりもはるかにスマートなアルゴリズムを必要とするようなものです。
ファジーハッシュとメタフォンおよび関連する手法について読む必要があります。 「類似」を非常に明確に定義し、類似を検出する方法を見つける必要があります。何十億ものデータベース操作を行うには、実行時に数日かかります。
経験則として、RDBMSは1秒あたり約5000行をフェッチできます。
これらのいずれかを実行するには、180,000秒(50時間)です[〜#〜] o [〜#〜](n2)クエリ。
30,000行のいくつかの属性(たとえば、1ダース)は360,000オブジェクトです。これは、iPhoneよりも大きなコンピュータのメモリに収まります。
これがあなたのアルゴリズムです。
30,000行すべてをメモリに読み込みます。
ハッシュマップやツリーマップなど、意味のあるものを作成して、数十のフィールドのハッシュや要約などを計算します。
for x in object_list:
name_map[soundex(x.name)].append(x)
other_map[transformatioN(x.other)].append(x)
統計要約レポートを作成して、類似性の測定値が何らかの合理的な意味を持つことを確認します。
print( len(name_map), "similar names out of", len(object_list) )
気に入った結果が得られたら、その結果でデータベースを更新します。
for n in name_map:
similar_set = [ s.primary_key for s in name_map[n] ]
c.execute( "UPDATE SOMETHING SET NAME_KEY=n WHERE ID IN ( %0 )", similar_set )
これはSQLには適していません。ただし、「オールインメモリ」には適しています。
_((n*(n-1))/2)
_だと思います
コードループは正しいです。行Yと比較した行Xは行Xと比較した行Yと同じであるため、各行を自分自身と比較して2で割る必要がないため(n * n-1)です。
以下を見ると、それは明確であるはずです(n行n列のテーブルとして表示されている場合):
_ 123
1-xx
2 -x
3 -
3*2/2 = 3
1234
1-xxx
2 -xx
3 -x
4 -
4*3/2 = 6
_
ちなみに、O _((n*(n-1))/2) = O((n*(n-1))) = O((n*n)) = O(n^2)
_なので、まだO(n^2)
にあると思いますが、間違っている可能性があります。私を訂正する人はいますか?
問題の実際のパラメータによっては、これは実際にはO(n ^ 2)ではない場合があります。データベースがインデックスを使用できるようにクエリを記述できる場合は、実際にすべての行を比較する必要がない場合があります。この場合、O(n * Log(n))ソリューションを検討している可能性があります。
WuHoUnited が提供する回答と同様に、クラスターまたはマッチコードを作成することで、必要な比較の数を大幅に減らすことができます。基本的に、レコードのいくつかの顕著な特徴を含むクラスターフィールドを作成し、クラスターフィールドが一致するレコードのみを比較します。たとえば、会社名の最初の5文字を含むクラスターフィールドを作成できます。これで、そのクラスターに分類されるレコードを照合するだけで済みます。データと必要な精度に応じて、郵便番号や電話番号の一部などの他のデータをクラスターに追加できます。