最小公約数


11

基本的に、問題は次のとおりです。正の数のセットの場合、の任意の要素の約数ではない最小数、つまり見つけます。SdSxS, dx

n = | S |を表す n=|S|およびC=max(S)。関数F(x)= xをF(x)=除算しない最小素数を考えます。F(x)\ leq \ log xであることが簡単にわかります。また、セットSの場合、F(S)= Sの要素を分割しない最小素数とします。上限がありますxF(x)logxSF(S)=S

F(S)F(lcm(S))F(Cn)nlogC.

したがって、1からn \ log Cまでのすべての数値を列挙しnlogCSの要素を除算しないかどうかをチェックする単純な総当たりアルゴリズムSは多項式であり、時間の複雑さはO(n2logC)です。

問題を解決するもう1つの方法は、Sのすべての要素のすべての因子を計算Sし、それらをブルートフォースアルゴリズムで使用して、xO(1)時間で答えかどうかをチェックすることです。このアルゴリズムは時間の複雑さO(nmin(C,nlogC)+nlogC)持ち、O(nlogC)メモリを使用します。n \ log Cより大きい保存因数nlogCnCが小さい場合はCパフォーマンスが向上します。

詳細には、アルゴリズムは2つの部分で構成されています。

  1. セット構成S^のすべての要素のすべての要素からなるS、すなわち

    xS fnlogC, (fxfS^)
    これは、O(nmin(C,nlogC))時間とO(nlogC)メモリで実行できます。(これはどこから来るのですか?Sの任意の要素について、\ sqrt {C}Sまでのすべての数値またはn \ log Cまでのすべての素数のいずれか小さい方の試算因数分解を使用して因数分解できます。したがって、Sの各要素時間O(\ min(\ sqrt {C}、n \ log C))時間で因数分解できます。)CnlogCSO(min(C,nlogC))
  2. 最小数を見つけます。が時間で実行できるかどうかを確認する場合、このステップには時間が必要です。dS^O(|S^|)=O(nlogC)xS^O(1)

興味のある質問が2つあります。

  1. 問題を解決するためのより高速なアルゴリズムはありますか?
  2. 与えられたとに対して、最大の最小公約数である非除数を持つ集合をどのように構築できますか?nCS

1.「事前計算」とは、総当たりアルゴリズムを開始する前を意味します。ファクタリングの2.複雑さは確かに準指数である、のdefiniton参照の。C
SkyterX 2015年

ポイント2の@DWでは、因数分解の複雑さは数値を表すビット文字列の長さで指数関数未満ですが、SkyterXはそれが、つまり、サイズの平方根に比例すると正しく述べています数字。O(C)
Lieuwe Vinkhuijzen 2015年

@LieuweVinkhuijzen、それは私には正しくないようです。GNFSを使用した因数分解の複雑さはになり、。en.wikipedia.org/wiki/…を参照してください。O(exp{1.9(logC)1/3(loglogC)2/3})O(C)
DW

2番目の方法の方が「と小さい」の方が優れているという記述は、正しくありません。場合にのみ、パフォーマンスが向上し。したがって、2番目の方法のパフォーマンスを向上させるには、を大きくする必要があります(小さくはない)。nCnC/log(C)n
DW

@DWそうです、私はGNFSの複雑さを知りませんでした。
Lieuwe Vinkhuijzen 2015年

回答:


6

整数分解のためのより良いアルゴリズムを使用することにより、2番目のアルゴリズムを改善することが可能です。

ここに関連する整数因数分解の2つのアルゴリズムがあります。

  • GNFSは、実行時間整数を因数分解できます。CO(LC[0.33,1.92])

  • ECMは、実行時間因子(存在する場合)を見つけることができます。すべての要因を見つけるには、倍の時間がかかり ECMの実行時間と比べて比較的小さい)。nlogCO(LnlogC[0.5,1.41])O(logC/log(nlogC))

ここでです。Ln[α,c]=exp{c(logn)α(loglogn)1α}

これは、実行時間に対してかなりひどく見える表現ですが、重要な事実は、これはあなたが述べた方法よりも速いということです。特に、はよりも漸近的に小さくなり。つまり、GNFSはすべての可能な要素試すよりもはるかに高速です。また、漸近よりもはるかに小さい、すなわち、ECMは、はるかに速く、すべての可能な要因試みるよりも。LC[0.33,1.92]CCLnlogC[0.5,1.41]nlogCnlogC

したがって、このメソッドの合計実行時間はおおよそであり、これは漸近的にあなたの最初の方法で、2番目の方法よりも漸近的に優れています。もっと上手くやれるかどうかわかりません。O~(nmin(LC[0.33,1.92],LnlogC[0.5,1.41]))


この問題の高速アルゴリズムには、入力セットある種の因数分解を含める必要があると思います。これらの因数分解アルゴリズムを確認しますが、適切にテストするという問題がまだあります。これは、最大の回答でセットを構築することについて述べた2番目の問題を引き起こします。SS
SkyterX 2015年

ECMは、指定した時間に1つの要素を見つけます。数値のすべての因子が≤n log Cの場合、アルゴリズムを最大でlog C / log(n log C)回繰り返す必要があります。
gnasher729 2016年

3

最も一般的ではない非除数はN log Cと同じくらい大きくなる可能性がありますが、N個の数値がランダムに分布している場合、最も一般的でない非除数はおそらくNよりもはるかに小さく、おそらくNよりもはるかに小さくなります。素数は、その数の約数です。

各素数pについて、インデックスがありますこれは、そのインデックスまでのすべての数がpによる可分性について調べられたことを意味し、除算可能であったそれらすべての数のリストを持っています。kp

次に、d = 2、3、4、...の場合、dで割り切れる数値を見つけるか、何もないことを示します。dの最大素因数pをとります。次に、pで割り切れるすべての数値を、dでも割り切れるのかどうかをチェックします。何も見つからない場合は、p > で割り切れるインデックス>数値をさらにチェックし、とpで割り切れる数のリストを更新して、各数がdで割り切れるかどうかをチェックします。kpkp

pで割り切れる数があるかどうかをチェックするために、平均p数をチェックします。後で2pで割り切れる数があるかどうかを確認すると、50%の確率で1つの数(pで割り切れる数)だけをチェックする必要があり、50%の確率で平均2p以上の数をチェックします。3pで割り切れる数を見つけるのは非常に高速であり、以下同様です。Nの数しかないため、pで割り切れる数についてNを超える数をチェックすることはありません。

これが約分割可能性チェックでうまくいくことを願っています。N2/logN

PS。乱数の結果はどのくらい大きいでしょうか?

N個の乱数があるとします。N個の数値の1つがdで割り切れる確率は1-(1-1 / d)^ Nです。1≤d≤kの各数値が乱数の1の因数である確率は、これらの確率を乗算することで計算されると想定します(Ok、これらの確率はおそらく完全に独立しているわけではないため、少し危険です)。

その仮定では、N = 1000の場合、1..244の数値のいずれかが数値を除算しない可能性が50%あり、10億分の1が507までのすべての数値がいずれかの数値を除算する可能性があります。N = 10,000の場合、50%の確率で、1..1726の数値のいずれかが任意の数値を除算せず、10億分の1が2979までのすべての数値がいずれかの数値を除算する可能性があります。

N個のランダム入力の場合、結果のサイズはN / ln Nよりも少し大きいと思います。N / ln N *(ln ln N)^ 2のようなものかもしれません。理由は次のとおりです。

N個の乱数のうち少なくとも1つが乱数dで割り切れる確率はです。dがN前後の場合、(1-1は約1-exp(-1)≈0.6321です。それは単一の除数です。いくつかの数値d≈NのそれぞれがN個の数値の少なくとも1つの約数である可能性は非常に小さいため、最大のdはNよりも大幅に小さくなります。1(11/d)N1(11/d)N

d << Nの場合、です。1(11/d)N1exp(N/d)

d≈N / ln Nの場合、です。1exp(N/d)1exp(lnN)=11/N

約N / ln Nの値dに対してこれらの確率を追加しますが、ほとんどのdでは結果が大幅に大きくなるため、最大のdはN / ln Nよりもある程度大きくなりますが、Nよりも大幅に小さくなります。

PS。dで割り切れる数を見つける:

dの最大の素因数pを選び、次に、pで割り切れることがすでにわかっている数を最初に調べます。d = kpと言います。次に、この特定のdをチェックしながら、平均してpで割り切れるkの数だけをチェックし、pで割り切れるすべてのdについて、全体でpで割り切れるかどうか、最大N個の値をチェックします。実際には、ほとんどの素数pについてN未満の値をチェックする可能性が高いです。これは、すべてのN値をチェックした後、アルゴリズムが終了する可能性が最も高いためです。したがって、結果がRの場合、N未満の値がR未満の各素数で除算されることを期待します。R≤Nと仮定すると、これは約N ^ 2 / log Nチェックです。

PS。いくつかのテストを実行する

N = 1,000,000の乱数> 0でこのアルゴリズムを数回実行しました。最も一般的でない非除数は68,000〜128,000で、実行の大部分は100,000〜120,000でした。分割数は5億2千万から1億8千万で、(N / ln N)^ 2よりもはるかに少ないです。大多数のケースでは、1億から1億5000万の部門が使用されました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.