アルゴリズムの計算に数因子の定番号
-
02-07-2019 - |
質問
この最適化アルゴリズムの性能的に設計できる数の因子の定番ですか。
かきをご提供いただければ擬似コードやリンクの一例です。
編集:すべての回答をしても、ありがとうございます。私の実施にふるいのアトキンおよびそれを用いて、うどジョナサン-Leffler表示されます。リンクを掲載するジャスティンBozonierしてさらに詳しい情報があります。
解決
Dmitriyでいたのふるいのアトキンの生成のリストがなくなるとは思えることなどを中心に、全体の問題です。これで、リスト盛りだく多くの素数として公約子(とど).
こちらは一部のpythonのためのアルゴ はこちらを参照してください 検索対象:数学が必要となります因子のアルゴリズム".だが、数項目のリストで返却しました。
この研数学 を説明するようにすればよいの数学的モデル化を行っている。
基本的にあげた場合の数 n
:
n = a^x * b^y * c^z
(a、b、c nの素因子およびx、y、zの数倍divisorが繰り返し)
その総数の因子は:
(x + 1) * (y + 1) * (z + 1)
.
編集:ちなみに、a、b、c、などだいたいなの欲張りなアルゴについて知っておきましょこれらを理解します。を始めた当初は最大級の盛りdivisorび掛けるが、それまでの更なる増殖回数。そして先週末、例のギフトショップへ最も低い要因と倍に増^回数で掛けを盛り続けを乗じるまで、次の超n...など。の回数で掛け算するの因子と合わせ、その数を数式です。
ない100%の必ず自分のアルゴ説明が合う機会を設けていきたいと思いますか。
他のヒント
あり 多く 以上の技術を織り込んで、ふるいのアトキン.例えば、仮にしたい要因5893.でも、そのsqrtは76.76...今まで書いてみよう5893として訳です。(77*77 - 5893)=36 6角で5893 = 77*77 - 6*6 = (77 + 6)(77-6) = 83*71.だん働いたかどうか78*78 - 5893 一部のブランド広場があります。います。この技術で迅速に測影響を与える要因について近くの平方根nよりはるかに早く検査による個々の素数.組み合わせるこの手法政大きな素数をふるい、より良い保理の方法のふるいます。
このほか、シンプルで飽きの来ない定多数の技術が開発されている。このシンプルなものになった。もうすでに長時間を学習し、十分な数の理論を理解する織の技法に基づく楕円曲線に対する(よく知っています。う必要はありません忘れないようにしてください。
ていない場合の取り扱小の整数でかしこの問題を解決す。代わりに私が見るものを使っておけば間違いないように PARI 図書館において高い効率的なソリューションを実装します。とができる因子をランダムに40桁の番号のような124321342332143213122323434312213424231341約.05秒です。(その解いただいた場合、ん、29*439*1321*157907*284749*33843676813*4857795469949.るものと、私は確信してこなかったこの図を用いて、ふるいのアトキン...)
@Yasky
お因子機能のバグがっていると正しく動作しないレーザダイオードおよ訳です。
う:
int divisors(int x) {
int limit = x;
int numberOfDivisors = 0;
if (x == 1) return 1;
for (int i = 1; i < limit; ++i) {
if (x % i == 0) {
limit = x / i;
if (limit != i) {
numberOfDivisors++;
}
numberOfDivisors++;
}
}
return numberOfDivisors;
}
私は国立大学志望の浪人生でのふるいのアトキンはできなチェック毎の番号[1,n]のprimalityように削減することにより、この数字部門に
こちらは一部のコードが少しhackier一般にはより速い:
import operator
# A slightly efficient superset of primes.
def PrimesPlus():
yield 2
yield 3
i = 5
while True:
yield i
if i % 6 == 1:
i += 2
i += 2
# Returns a dict d with n = product p ^ d[p]
def GetPrimeDecomp(n):
d = {}
primes = PrimesPlus()
for p in primes:
while n % p == 0:
n /= p
d[p] = d.setdefault(p, 0) + 1
if n == 1:
return d
def NumberOfDivisors(n):
d = GetPrimeDecomp(n)
powers_plus = map(lambda x: x+1, d.values())
return reduce(operator.mul, powers_plus, 1)
ps このpythonコードの必要がありません。
この興味深い質問がどのように見えますが、もしていない答えいたします。のできるであろうと織り込2つの異なる。
1さNのリストLのNの素因数
2さLの計算においては、複数の組み合わせ
すべての回答を見ることをご参照#1において失敗するのではない扱いのために膨大な数です。のための緩やかにサイズNでも、64ビット番号です;巨大Nを織り込んで問題でした。公開鍵暗号化すことになりました。
質問ストラン#2のニーズでしまいます。合のみを含むユニークな番号で簡単な計算を組み合わせ方式を選択k物からnます。実際に、和の結果から印式が異なるk1sizeof(L).しかし、Lは、通常、複数の発生の複素数.例えば、L={2,2,2,3,3,5}は、因子分解のN=360があります。現在この問題は非常に難しい!
Restating#2では、指定されたコレクションCを含むkど、その項目では"複製、品目bはb'重複等どのような組み合わせが1のk-1項目があるのでしょうか。例えば、, {2}, {2,2}, {2,2,2}, {2,3}, {2,2,3,3} けれ発生後に一度だけの場合L={2,2,2,3,3,5}.各サブコレクションは独自のdivisor Nを乗じることによって項目を収集します。
不明な点があれば、ここでお答えによって大きく異なるサイズの整数です。方法少数などして100ビット、数字~1000ビットなどを使用暗号化)は全く異なります。
値が小さい
n
とつかの有用な参考文献: A000005:d(n)とも呼ぶに対するtau(n)又はsigma_0(n))の因子のn.実世界での例: 因子分解の整数
ここでは直進O(sqrt(n))アルゴリズムです。この解決 プロジェクトオイラー
def divisors(n):
count=2 # accounts for 'n' and '1'
i=2
while(i**2 < n):
if(n%i==0):
count+=2
i+=1
count+=(1 if i**2==n else 0)
return count
一線
だなと思っていても申込み方法は次の通報をお問いて書いてみました効率的performantコード
印刷すべての因子を指定の数字を画面いっラインのコード!(オプション-std=c99を経由gcc)
for(int i=1,n=9;((!(n%i)) && printf("%d is a divisor of %d\n",i,n)) || i<=(n/2);i++);//n is your number
実数の因子は以下のようなものを使います非常に高機能正常に動作し全ての整数を除く1、2)
int number_of_divisors(int n)
{
int counter,i;
for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
return counter;
}
たまた番号として公約子(正常に動作し全ての整数を除く1、2)
int number_of_divisors(int n)
{
int counter,i;
for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
return ++counter;
}
すのでご注意ください上記の機能が正常に動作しない問題をすべて正の整数以外番号1 2 その機能のためのすべての数が以上2 ものが必要な場合は1、2を使用でき、以下のいずれかの操作をちょっと遅)
int number_of_divisors(int n)
{
int counter,i;
for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
if (n==2 || n==1)
{
return counter;
}
return ++counter;
}
または
int number_of_divisors(int n)
{
int counter,i;
for(counter=0,i=1;(!(i==n) && !(n%i) && (counter++)) || i<=(n/2);i++);
return ++counter;
}
小美:)
内ふるい網のアトキンが最適化された版のふるいのEratosthenesるすべての素数に指定された整数.対応することができるでしょうgoogleことがあります。
きることリストで簡単に分割お客様のご人数による各盛り合で正確に公約子(つまり、残りはゼロ).
の基本ステップの計算の因子のための数(n)[この擬似コードから変換されたリアルコードの思いを導入しの誤り]:
for z in 1..n:
prime[z] = false
prime[2] = true;
prime[3] = true;
for x in 1..sqrt(n):
xx = x * x
for y in 1..sqrt(n):
yy = y * y
z = 4*xx+yy
if (z <= n) and ((z mod 12 == 1) or (z mod 12 == 5)):
prime[z] = not prime[z]
z = z-xx
if (z <= n) and (z mod 12 == 7):
prime[z] = not prime[z]
z = z-yy-yy
if (z <= n) and (x > y) and (z mod 12 == 11):
prime[z] = not prime[z]
for z in 5..sqrt(n):
if prime[z]:
zz = z*z
x = zz
while x <= limit:
prime[x] = false
x = x + zz
for z in 2,3,5..n:
if prime[z]:
if n modulo z == 0 then print z
ございます。奥高尾にひっそりと建つ料亭。hackishで合理的に早いです。
def factors(n):
for x in xrange(2,n):
if n%x == 0:
return (x,) + factors(n/x)
return (n,1)
までの素因数分解があり、この因子.すそれぞれの指数は各個々の要素のそれぞれの指数です。
例えば:36 素因数分解:2^2*3^2 因子:1, 2, 3, 4, 6, 9, 12, 18, 36 多数の因子:9
追加し、各指数2^3*3^3 掛ける指数:3*3=9
する前にコミットへの解決策を考えることをふるいにアプローチがない答えの典型のようです。
械的風味さん一応前に線路がありました盛りかかった時間試験のための32ビット整数を少なくともいるかどうかを判断するこ盛りにしたよりも遅すぎます。が要因か。
1)人間が行う事業部では非常に迅速にコンピュータ--と同様のコストを見上げたと言えるのでしょうか。
2)していない場合、盛りテーブルできる"ループ"を作ることで、すべてL1ます。これが速くなります。
これは効率的なソリューション:
#include <iostream>
int main() {
int num = 20;
int numberOfDivisors = 1;
for (int i = 2; i <= num; i++)
{
int exponent = 0;
while (num % i == 0) {
exponent++;
num /= i;
}
numberOfDivisors *= (exponent+1);
}
std::cout << numberOfDivisors << std::endl;
return 0;
}
因子な絶景:分断している。を確認することができますの因子のための番号 n
, ることは明らかでは冗長となるスパン全体のスペクトル 1...n
.思い切り深い研究のためのこだ解決 プロジェクトオイラーの問題12三角数字.私の解決のために よそ500因子 試験走りのための309504マイクロ秒(~0.3ます。わたしは、この数ソリューションとなります。
int divisors (int x) {
int limit = x;
int numberOfDivisors = 1;
for (int i(0); i < limit; ++i) {
if (x % i == 0) {
limit = x / i;
numberOfDivisors++;
}
}
return numberOfDivisors * 2;
}
各アルゴリズムが弱点なのです。しかし、ここに弱い素数.ても三角形の番号を印刷しませんでおり、その目的、奥.私のプロファイリングだと思っていたのですね。
嬉しい休みです。
いのふるいのアットキン著、ここで記載している: http://en.wikipedia.org/wiki/Sieve_of_Atkin
の素数方法を明らかにします。P[]リストの素数の場合には、以下のsq=sqrt(n);
for (int i = 0 ; i < size && P[i]<=sq ; i++){
nd = 1;
while(n%P[i]==0){
n/=P[i];
nd++;
}
count*=nd;
if (n==1)break;
}
if (n!=1)count*=2;//the confusing line :D :P .
i will lift the understanding for the reader .
i now look forward to a method more optimized .
数論の教科書コーナルの編集-集計機能のtau.最初に興味深いこの内容に関する考えという意味の乗法吟味した。τ(ab)=τ(a)τ(b)、およびbのない共通の要因です。(証:各ペアの因子a、b、異なるdivisorのab).
現在に注意してください続ける気持ちを持って、盛り、τ(p**k)=k+1の力です。このように簡単に計算するτ(n)からfactorisation.
しかしfactorising多くゆっくりできる(セキュリティのRSA crytopraphy製品により異なりの大盛りはしていても、あるいはfactorise).ることを示唆この最適化アルゴリズム
- 試験場の盛り(快速)
- その場合、戻り2
- その他、 factoriseの (ゆっくりとした複数ある場合には大きな盛り要因)
- 計算τ(n)からfactorisation
以下は、Cプログラムに数因子の番号です。
の複雑性の上のアルゴリズムはO(sqrt(n)).
このアルゴリズムが正しく動作するための最適スクエアなどの数がない完璧なエアがあります。
なお、upperlimitループの設定の平方根の番号のアルゴリズムの最も効率的です。
ご注意を格納するupperlimit別の変数もに保存する時間を過ごすべきではないのsqrt機能の条件セクションのためのループも省けてお計算す。
#include<stdio.h>
#include<math.h>
int main()
{
int i,n,limit,numberOfDivisors=1;
printf("Enter the number : ");
scanf("%d",&n);
limit=(int)sqrt((double)n);
for(i=2;i<=limit;i++)
if(n%i==0)
{
if(i!=n/i)
numberOfDivisors+=2;
else
numberOfDivisors++;
}
printf("%d\n",numberOfDivisors);
return 0;
}
の代わりに上記のループにお使いいただけます以下のループは効率的なものとしていくことが除去の必要性の平方根に多くの注目を集めています。
for(i=2;i*i<=n;i++)
{
...
}
といったものを書く。この最悪の時間計算量がO(sqrt(n)、時にはO(log(n)).すべての因子との洞.
public static List<Integer> divisors(n) {
ArrayList<Integer> aList = new ArrayList();
int top_count = (int) Math.round(Math.sqrt(n));
int new_n = n;
for (int i = 2; i <= top_count; i++) {
if (new_n == (new_n / i) * i) {
aList.add(i);
new_n = new_n / i;
top_count = (int) Math.round(Math.sqrt(new_n));
i = 1;
}
}
aList.add(new_n);
return aList;
}
もっとも基本的な方法をコンピューティングするこ数divissors:
class PrintDivisors
{
public static void main(String args[])
{
System.out.println("Enter the number");
// Create Scanner object for taking input
Scanner s=new Scanner(System.in);
// Read an int
int n=s.nextInt();
// Loop from 1 to 'n'
for(int i=1;i<=n;i++)
{
// If remainder is 0 when 'n' is divided by 'i',
if(n%i==0)
{
System.out.print(i+", ");
}
}
// Print [not necessary]
System.out.print("are divisors of "+n);
}
}
@ケンダルインターナショナル
でコードを作れたので、改善、現在でも高速に行います。私も試@هومن جاویدپورコードすることでよりも早く彼のコードです。
long long int FindDivisors(long long int n) {
long long int count = 0;
long long int i, m = (long long int)sqrt(n);
for(i = 1;i <= m;i++) {
if(n % i == 0)
count += 2;
}
if(n / m == m && n % m == 0)
count--;
return count;
}
でないことのためだけではなく、今ファクタリングの決定の要因にかかりますか?できるか決める必要なすべての組み合わせが一つ以上の要因に
なので、このアルゴリズムにすることはできない。
factor(N)
divisor = first_prime
list_of_factors = { 1 }
while (N > 1)
while (N % divisor == 0)
add divisor to list_of_factors
N /= divisor
divisor = next_prime
return list_of_factors
それを踏まえた上で、ごみを決定する重要な因子の残りの答えになります。
こうした基づくジャスティンの答えです。が必要とする最適化。
n=int(input())
a=[]
b=[]
def sieve(n):
np = n + 1
s = list(range(np))
s[1] = 0
sqrtn = int(n**0.5)
for i in range(2, sqrtn + 1):
if s[i]:
s[i*i: np: i] = [0] * len(range(i*i, np, i))
return filter(None, s)
k=list(sieve(n))
for i in range(len(k)):
if n%k[i]==0:
a.append(k[i])
a.sort()
for i in range(len(a)):
j=1
while n%(a[i]**j)==0:
j=j+1
b.append(j-1)
nod=1
for i in range(len(b)):
nod=nod*(b[i]+1)
print('no.of divisors of {} = {}'.format(n,nod))
こうしたものです。私はまさにそのものをお楽しみいただけます。コピー&ペーストでメモ帳です。保存の場合、次のようになります.bat.ます。入ります。掛けるプロセス2と粉遊数の因子.いることを目的にしたものを決める因子の速:
Plsるので注意することCMD varriableん支援値999999999
@echo off
modecon:cols=100 lines=100
:start
title Enter the Number to Determine
cls
echo Determine a number as a product of 2 numbers
echo.
echo Ex1 : C = A * B
echo Ex2 : 8 = 4 * 2
echo.
echo Max Number length is 9
echo.
echo If there is only 1 proces done it
echo means the number is a prime number
echo.
echo Prime numbers take time to determine
echo Number not prime are determined fast
echo.
set /p number=Enter Number :
if %number% GTR 999999999 goto start
echo.
set proces=0
set mindet=0
set procent=0
set B=%Number%
:Determining
set /a mindet=%mindet%+1
if %mindet% GTR %B% goto Results
set /a solution=%number% %%% %mindet%
if %solution% NEQ 0 goto Determining
if %solution% EQU 0 set /a proces=%proces%+1
set /a B=%number% / %mindet%
set /a procent=%mindet%*100/%B%
if %procent% EQU 100 set procent=%procent:~0,3%
if %procent% LSS 100 set procent=%procent:~0,2%
if %procent% LSS 10 set procent=%procent:~0,1%
title Progress : %procent% %%%
if %solution% EQU 0 echo %proces%. %mindet% * %B% = %number%
goto Determining
:Results
title %proces% Results Found
echo.
@pause
goto start
このひとつとしても重宝し精度
スクリプトpyton
>>>factors=[ x for x in range (1,n+1) if n%x==0]
print len(factors)
ようこれらのテーマに沿った:
int divisors(int myNum) {
int limit = myNum;
int divisorCount = 0;
if (x == 1)
return 1;
for (int i = 1; i < limit; ++i) {
if (myNum % i == 0) {
limit = myNum / i;
if (limit != i)
divisorCount++;
divisorCount++;
}
}
return divisorCount;
}
できprecompute素数のsqaureルートを最大でNの計算指数の素因数の番号です。数の因子のn(n=p1^p2^b p3^c...)を(a+1)(c+1)(c+1)でのものと同じ数の方法を組み合わせが素数の要因(その数因子).これは非常に速い場合はprecomputeの素数
より詳細な情報をこの方法:
https://mathschallenge.net/library/number/number_of_divisors
https://www.math.upenn.edu/~deturck/m170/wk2/numdivisors.html
http://primes.utm.edu/glossary/xpage/tau.html
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
int divisors_count(const vector<int>& primes, int n)
{
int divisors = 1;
for (int i = 0; i < primes.size(); ++i) {
int factor = primes[i];
int factor_exponent = 0;
while (n % factor == 0) {
++factor_exponent;
n /= factor;
}
divisors *= (factor_exponent + 1);
}
if (n > 1)
return 2*divisors; // prime factor > sqrt(MAX_N)
return divisors;
}
int main()
{
const int MAX_N = 1e6;
int max_factor = sqrt(MAX_N);
vector<char> prime(max_factor + 1, true);
for (int i = 3; i <= max_factor; i += 2) {
if (prime[i]) {
for (int j = 3*i; j <= max_factor; j += 2*i) {
prime[j] = false;
}
}
}
vector<int> primes;
primes.reserve(max_factor/2);
primes.push_back(2);
for (int i = 3; i <= max_factor; i += 2) {
if (prime[i]) {
primes.push_back(i);
}
}
int n;
while (cin >> n) {
cout << divisors_count(primes, n) << endl;
}
}
わからない、最も効率的な方法が思いの
- テーブルを作成する素数をすべての素数の場合には、以下の平方根の数(個人的に、私のふるいのアットキン著)
- カウントすべての素数の場合には、以下の平方根の数を掛けると。た場合の平方根の数が整数を差し引からのカウントに変更します。
すべ\o/
必要な方は、できるコードとも明日Cんでいる。