2016-11-16 4 views
0

私は自分のコードで少しのランタイム問題があります。コードは正常に動作しますが、Windowsでは数十分、Linuxでは数時間かかることがあります。親和性のある数字:実行時間は長くなります。それは何が原因でしょうか?アルゴリズムの複雑さ?

このプログラムを今すぐ実行しようとすると、アルファティル1000000の数値が文字通り数時間かかると計算され始めます。 私の先生によれば、計算にはほんの数秒しかかかりません。

int main() { 
std::cout << "Hello, World!" << std::endl; 

AmicableNumbersBeta Alpha(1,1000000); 
AmicableNumbersBeta Beta(1,100000); 
AmicableNumbersBeta Gamma(1,10000); 
AmicableNumbersBeta Delta(1,1000); 

std::cout<<"Delta\n"; 
Delta.Calculate(); 

std::cout<<"\nGamma\n"; 
Gamma.Calculate(); 

std::cout<<"\nBeta\n"; 
Beta.Calculate(); 

std::cout<<"\nAlpha\n"; 
Alpha.Calculate(); 

std::cout << "Bye, World!" << std::endl; 
return 0; 
} 

私は正直、この巨大な「遅延」を引き起こす可能性があるかを理解していません。私が使用

プラットフォームは15

GCC 4.9 とLinuxのDebianとWindowsのVSいる誰かが、この行動の理由を指摘することができれば、私は本当にいただければ幸いです。

+1

同じ値に対して 'SumOfDivisors'を再計算するのを避けるためにメモを試みるかもしれません。シーブはまた、除数の計算を高めることができます。 – Jarod42

+1

あなたの問題はアルゴリズムの複雑さです。ただし、コードを並列化することもできます(標準ライブラリの並列拡張など) – foxfireee

+0

Sieveなどを使用して除数の計算を高速化する必要があります。同じ数のSumOfDivisorsを再計算することはそれほど重要ではありません - SumOfDivisorsの呼び出しの半分は1 ... nであり、回避することはできませんので、暗記はおおよそ時間を半分に減らすことができます。 –

答えて

3

コメントに記載されているように、memoizationまたはsieves、または並列性を使用することによって、コードをさまざまな方法で最適化することができます。

実際のアプリケーションでは、私はこのような最適化を行うことができますが、ここでは複雑なものは必要ありません。数分ではなく数秒でコードを実行するには、除数はあなたの値の平方根までしか計算しないでください。したがって、基本的に:

long SumOfDivisors(long value) 
{ 
    long result = 1; 

    for (long i = 2; i * i <= value; i++) 
    { 
     if (value % i == 0) 
     { 
      result += i; 
      if (value/i != i) { 
       result += value/i; 
      } 
     } 
    } 

    return result; 
} 

この簡単な変更で、1000000までの数を数秒で計算することができます。

+0

確かにこれまでと比べて信じられないほど速く動作します。しかし、平方根だけをなぜ私に説明してもらえますか?理由は分かりません... – ExOfDe

+2

@ExOfDe 'A = B * C'(' B''と 'C''は' A'の約数です)とし、 'Q'をA(Q * Q = A)。 'C * = Q'なら' B * C> = B * Q'( 'B> 0')なので' A> = B * Q'なので 'Q * Q> = B * Q'なので'Q> = B'(' Q> 0') ​​- ** 'C> = Q'なら' B <= Q' **です。 '' B''を見つけるだけで、 'C = A/B'(コード中の' value/i')を使って 'C'を計算することができます。 – Holt

関連する問題