C++で学ぶ興味深い時間計算量の問題
時間計算量(Time Complexity)とは、アルゴリズムが平均的なケースで実行されるまでに必要となる時間として定義できます。
ここでは、基本的な関数の時間計算量を実際に見ていきながら、その求め方を解説します。
例1:内側のループが i ずつ増加する場合
void counter(int n){
for(int i = 0; i < n; i++){
for(int j = 1; j < n; j += i){
cout << i << " " << j;
}
cout << endl;
}
}上記のメソッドでは、内側のループは各 i の値に対して n / i 回実行されます。つまり、最初の反復では約 n 回、最後の反復では 1 回実行されることになります。
これに基づくと、合計の時間計算量は次のように表せます。
(n/1 + n/2 + n/3 + … + n/n) = n × (1/1 + 1/2 + 1/3 + … + 1/n)
ここで、(1/1 + 1/2 + 1/3 + … + 1/n) は調和級数と呼ばれるもので、その値は O(log n) に相当します。
したがって、このコード全体の時間計算量は O(n log n) となります。
例2:内側のループが log(i) 回実行される場合
void counter(int n){
int i, j;
for(int i = 1; i <= n; i++){
for(j = 1; j <= log(i); j++){
cout << i << " " << j;
}
}
}この関数の合計計算量は、O(log 1) + O(log 2) + O(log 3) + … + O(log n) となります。これは対数の和をまとめて O(log n!) と表すことができます。
さらに、スターリングの近似によれば log n! は O(n log n) と近似できるため、実質的な計算量は O(n log n) であると考えることもできます。
まとめ
このように、ネストしたループの計算量を求める際には、単に「ループが二重だから O(n²)」と結論づけるのではなく、内側のループが実際に何回実行されるのかを数学的に分析することが重要です。調和級数や対数の和といった数列の性質を理解しておくと、より正確な計算量の評価ができるようになります。
-
漸近解析とは?アルゴリズムの計算量と実行時間の関係を解説
漸近解析(Asymptotic Analysis)とは漸近解析を用いることで、入力サイズに基づいてアルゴリズムの性能をおおよそ把握することができます。ここで重要なのは、正確な実行時間を求めることではなく、実行時間と入力サイズの間にある「関係」を見出すことです。つまり、入力サイズが大きくなるにつれて実行時間がどのように増加していくかに着目して解析を行います。また、空間計算量(スペース複雑性)に関しては、アルゴリズムを完了させるためにメインメモリ上でどれだけの領域が占有されるかを示す関係式や関数を導くことを目標とします。漸近的挙動(Asymptotic Behavior)関数 f(n) の漸近的挙
-
C/C++で実装するバークレーアルゴリズム――分散システムの時刻同期を徹底解説
バークレーアルゴリズムとは バークレーアルゴリズム(Berkeleys Algorithm)は、分散システムにおいて各ノードの時計を同期させるために用いられるアルゴリズムです。特に、以下のような状況にあるシステムで有効とされています。 マシンに正確な時刻源が存在しない場合 ネットワークやマシンにUTCサーバーが用意されていない場合 分散システムとは、物理的に離れた場所に配置された複数のノードが、ネットワークを介して相互に接続されたシステムのことを指します。各ノードの時計は独立して動作しているため、誤差が生じやすく、何らかの同期機構が必要になります。 バークレーアルゴリズムの仕組み このア