5


4

多数の因数分解

クラスでこのプログラミングの問題を発見しましたが、現在、その解決方法はわかりません。

_ 正の整数「n」が指定されます。 「n = p * q」(「p」と「q」は素数、「p ⇐ q」と「| q-k * p | <10 ^ 5」)は既知の正の整数「k」であることが知られています。 「p」と「q」を見つける必要があります。 _

入力:

35 1
121 1
1000730021 9

出力:

5 * 7
11 * 11
10007 * 100003

宿題ではなく、いくつかの興味深い問題を解決しようとしているだけです。 アイデアがあれば、ここに投稿してください

4 Answer


2


ここで話しているサイズの数値の場合、最速の因数分解法は(おそらく)エラトステネスのふるいを使用して、ほぼ最大の平方根までの素数を生成し、それらによる試行除算を使用してどれを見つけるかです)は除数です。

より多くの数に対して、かなり少数のファクタリング方法が発明されました。 「Fermatの因数分解法」、「Pollard Rho」、「Brentの法」、「Lenstra楕円曲線」、「複数の多項式2次ふるい」、および「一般的な数体ふるい」をGoogleに求めます。 それらを(おおよそ)複雑さの昇順でリストし、より大きな数を因数分解する能力を示しました。 一般的な数値フィールドのふるいについて言及する必要があるかどうかは疑問ですが、非常に大きな数値を因数分解するために現在知られている最も効率的な方法ですが、約110桁以下のMPQSでは非常に有用ですより高速ですが、GNFSが高速である大きな数値を考慮するには、通常のデスクトップまたはサーバーがサポートできるよりも多くのメモリが必要です(最小の開始点としてテラバイトのRAMを考えますが、おそらくそれ以上です)。


2


ECMメソッドを使用して大きな整数を因数分解しました。 これは、知られている最も効率的なアルゴリズムの1つです。 アルゴリズムがどのように機能するかを知りたい場合は、読むべきことがたくさんありますが、それを利用して研究を行う場合は、一部の人々がそれを実装しています。 たとえば、次のオープンソースパッケージを入手できます。C/ C ++の場合はhttp://ecm.gforge.inria.fr/[GMP-ECM]、Pythonの場合はhttp://www.sourceforge.net/projects/pyecm[Pyecm] 。

$ python
>>> import math
>>> import pyecm
>>> n = 1000730021
>>> list(pyecm.factors(n, False, False, 2 * math.log(math.log(n)), 1.0))
[10007, 100003]


1


n = p * q
|q-k*p|<10^5

n`と k`が入力として与えられます。 だから

q-k*p=a

with

-10^5<=a<=10^5

「q-k * p = a」に「q」を掛け、「p * q」にnを代入すると、

q^2-a*q-k*n=0

各 `a`についてこの二次方程式を解く

-10^5<=a<=10^5`

そして、「q」が「n」を分割するかどうかを確認します。 二次方程式の解は多項式時間で行うことができ、これは「2 * 10 ^ 5 + 1」方程式を解く場合に当てはまります。 小さい値の「n」と「k」、およびもちろん大きい値の「n」と「k」にはより良いアルゴリズムがあります。

ypercubeが述べたように、方程式をチェックするだけです。

a^2+4*k*n

正方形です。


0


n = p * qおよび| q-k * p | <10 ^ 5(nおよびkは入力として指定)。 したがって、q-k * p = a、-10 ^ 5 ⇐ a ⇐ 10 ^ 5、q-k * p = aにq ansを掛け、p * qをnに代入すると、q ^ 2-a * q-k * n = 0になります。 -10 ^ 5 ⇐ a ⇐ 10 ^ 5で各aについてこの2次方程式を解き、qがnを除算するかどうかを確認します。 二次方程式の解法は多項式時間で行うことができ、これは2 * 10 ^ 5 + 1方程式の解法にも当てはまります。 nとkの小さい値にはより良いアルゴリズムがあります

pはintervallにあります

[(sqrt(k*n+2500000000)-50000)/k,(sqrt(k*n+2500000000)+50000)/k]

したがって、pの10 ^ 5 / k値のみをチェックする必要があります。 qはintervallにあります

[sqrt(k*n+2500000000)-50000,sqrt(k*n+2500000000)+50000]

常に約10 ^ 5個の整数が含まれています