• ベストアンサー

ステップ数と計算量?

ステップ数と計算量とは何でしょうか? 問題で、 int x = 0; for(int c = 0; c < n; ++c) a += c との問題があり「これのステップ数と計算量をnについて求めよ。」との問題でした。 しかしステップ数と計算量というものがよくわかりません。 ステップ、つまり行数でいいのでしょうか? 計算量もO(オーダ)を使うどうのと一応知人から教わったのですが、 知人自体もよくわかっていないようで結局何なのだか・・・。 ステップ数と計算量というものについて教えてください。 あとできれば上記の問題についても・・・

noname#177863
noname#177863

質問者が選んだベストアンサー

  • ベストアンサー
  • hitomura
  • ベストアンサー率48% (325/664)
回答No.1

ややこしいことに処理を行う行数をステップ数と呼ぶ場合もあるのですが、 この場合のステップ数というのは何らかの処理を行った回数のことです。 あなたの場合では、 int x = 0;          /* 変数 x の確保&初期化 */ for(int c = 0; c < n; ++c) /* 変数 c の確保&初期化 */ // (1)                 /* c と n の比較 */                 /* (2)へ処理を移す(前期条件を満たした場合のみ) */                 /* c に 1 を加算 */ a += c            /* a に c を加算 */                 /* (1)へ処理を移す */ // (2) という処理が行われます。人によっては「(*)へ処理を移す」を処理に含めない場合がありますし、「確保&初期化」を2つの処理に分けるという考え方もあります。 あとは n という値が与えられたとき全体で処理が何回行われるかを数えてやればステップ数が計算できます。 で、おおざっぱにいうと、こうやって求めたステップ数が n の増え方と比較してどういう割合で増えるかを計算量といいます。 このとき、増え方が一番きついものを代表として採用し、n に関係しない値は無視します。 複数のアルゴリズムの効率を比較する場合、そっちの方が正確なステップ数を比較するよりわかりやすいからです。 え、問題の答? 上の処理を実際の値でいくつか試してみて、どういう風に各処理が行われるか(ここは毎回通るなとかここは 1 回だけだなとか)を調べるだけです。頑張ってください。

その他の回答 (2)

回答No.3

とりあえず,計算量というか時間計算量について。 処理の実行時間が仮にf(n)で表すことができるとして, nがある正数Nより大きい場合に常に|f(n)| ≦ M|g(n)|となる正定数Mとnの関数g(n)がある場合,その処理の計算量はΟ(g(n))であると言います。 通常,ランダウの記号で出てくるのはΟですが,|f(n)| ≧ M|g(n)|となるのであればΩ(g(n)), M|g(n)| ≦ |f(n)|かつ|f(n)| ≦ M'|g(n)| (M'も正定数) であればΘ(g(n))と表記します。 言い換えると,nが無限大に漸近していくときの上界がΟ,下界がΩです。 # 両方が一致するのがΘ。 例題は, ・1行目:nに依存しない時間がかかる ・2行目:nに比例する時間がかかる ・3行目:nに依存しない時間がかかる ため,全体としてはnに比例する時間がかかります。 つまり,f(n) = an + b (a, bは定数/aは正数)のように数式化されると仮定され,nが無限大に漸近していくと, (a - 1)n < an + b < (a + 1)n という関係が成り立ちます。 故に,Θ(n)と表記できます。 なので,Ο(n)であり,Ω(n)であり,Ο(n log n)であり,Ω(log n)であり……となります。 同様に,メモリをどれだけ使うか,という「空間計算量」というのもありますが,今回はΘ(1)なので省略します (nに依存しない)。 ステップというのは,「何回通るか」を意味する場合もあれば,「文の数」を意味する場合,「物理的な行の数」を意味する場合もあります。 最初の物をnについて数式化するとf(n)になるわけですが (各式の計算量を加味する必要はある), 残りはそのまんまな,言語文法だったりファイルの物理構造だったりの問題になります。

回答No.2

ステップ数も計算量も明確な定義がありません。 使用する目的や要求者の思想によって変わってきます。 この場合だと教科書や授業で定義が明示されているのでなければ問題の答としては。 「定義されていないから回答不能」 です。

関連するQ&A

  • 再帰呼び出しの計算量

    再帰呼び出しを用いた関数の計算量を求める方法がわからないので質問させていただきます. xのn乗を再帰呼び出しを用いて求める関数に関して,計算量を求める問題なのですが,どのような方針で求めればよいのでしょうか? int exponent(int x, int n) {   if(n == 0){     return 1;   }else{     return x * exponent(x, n-1);   } } exponentがn回呼ばれるからO(n)というのは間違いでしょうか?

  • 計算量オーダーについて O(1/n)オーダー?

     こんにちは、c#初心者です。  今回は計算量オーダーの話なので、基本的に言語は関係ないと思います。  計算量オーダーの基本的な部分は分かるのですが、O(1/n)オーダーのアルゴリズムは(今のところは)まだ見かけないというか、名前程度しか知らないので、これに関しては無知です。そこで、この場合はどういうオーダーになっているのかという質問です。  質問は3つあります。 1)この一連の処理はO(1/n)オーダーになっているか? int count = 1000 / length; // lengthは正の整数 for ( int i = 0; i < count; i++ ) Do(); // O(1)オーダーの処理 2) (1がO(1/n)の場合)繰り返す処理がO(n^2)になった場合に、この一連の処理はO(n)オーダーになるのか? int count = 1000 / length; // lengthは正の整数 for ( int i = 0; i < count; i++ ) Do(); // O(n^2)オーダーの処理 3)配列型のコレクション(コレクションって、c#の呼び方だったっけ?) [c#] List<T>,[c++] Bector, [Java] ArrayList(だったっけ?)のようなクラスのAddメソッドのオーダーは? //Addメソッドの中身 if ( Capacity == Count ) Expand(); // Expandは配列の容量を2倍に拡張するO(n)処理とします。 array[Count++] = item;  以上です。  補足で、2)については大学の教授に「一回でもO(n^2)の処理が呼び出されたら、O(n^2)オーダーになる」と言われましたが、納得いかないです。確かに、O(1/n)オーダーの処理の後にO(n^2)オーダーの処理を行えば、そうなるのは納得いくのですが……という感じです。教授が読み間違えたとは考えにくいですが(確かにちょっと忙しそうでしたが)、念のため質問です。  それと、3)はよくある配列型のコレクションのまねです。「もし内容物が容量一杯になれば拡張→追加」を繰り返すとした場合です。ExpandメソッドのオーダーがO(n)なので、単純に計算すればO(n)オーダーになるのですが、呼び出される頻度が「(拡張された容量)回に1回」です。  例えば、容量が4ずつ拡張されるとすれば、「4回に1回」拡張が必要になり、10ずつ拡張されるとすれば、「10回に1回」の拡張が必要です。この場合、どう考えても全体として定数で割っているだけなので、O(n)オーダーのままになるのは明白なのですが、今回は容量2倍とさせていただきました。すると拡張の頻度は「(さっきまでの容量)回に1回」の頻度で、容量に反比例し、直感的にはO(Count / Capacity) = O(1)オーダーに見えるのですが、この判断は正しいでしょうか?  皆さんのご意見を伺わせてください。

  • 計算量について

    プログラムの計算量について質問です。計算量には時間計算量と空間計算量がありますが、そのうち空間計算量の概念がいまいち分かりません。アルゴリズムが必要とする記憶容量といっても漠然としててどのように求めたらいいのか分かりません。 例えばプログラムの基本構成が for(n回){ for(n回){ 処理 } } のようだったら時間計算量がO(n^2)というのはわかるんですが、この場合の空間計算量はどのようになりますか?

  • 漸化的計算量のオーダー記法O表記について

    漸化的計算量のオーダー記法O表記について オーダー記法Oでの表記の仕方って、ようするにnをn→∞とした時に、一番大きくなる項を抜き出しきて、n→∞の時、増加量が微少な係数は無視をする。という考え方でいいんでしょうか? 例えば 1000*(2^n)+0.5(n^n)=O(n^n) nlogn+n√n=O(n√n) n^2.01+(n^2)log(n^2)=O((n^2)log(n^2)) であってますか?

  • ソートの計算量などについて

    こんにちは ソートに関することの質問です。 1.バブルソートの計算量を出す式ですが O(n^2)=O(n-1)*O(n/2)*O(1)=O(n)*O(n)=O(n^2) で合っていますでしょうか? 2.クイックソートの(平均)計算量が nlog n(底は2)になるのは、なぜなのかを わかりやすく教えて下さい。(できれば式も) 3.クイックソートが最も高速に実行されるのは、ピボットの要素が真中にある場合で、反対に最も効率が悪いのはピボットが端にある場合ですが、この理由をやさしい言葉で教えて下さい。 どなたか教えて下さい。 よろしくお願いします

  • アルゴリズムの計算量O(n)の証明

    O()ビッグオーダについての証明問題なのですが どうすればよいのかわかりません。どなたか教えていただけませんか? O(n*log n + n) = O(n*log n)を証明せよ f(n) ε O(n) f(n) > 0で、ある定数Cがあり ここでlim n→∞ f(n)/n ≦ C おそらく上を使うと思うのですが式変形を行っても 左辺-右辺で0にできません。ひょっとしたら はさみうち等を使うのでしょうか? よろしくお願いいたします。

  • 計算量(PやNP)について

    ネット上で計算量理論に関する説明を読んでいますが、いまいち理解ができません。 例えば、木の形で表せれる問題で、一つのノードに対する子がN個(定数)あり、深さX(未知、変数)に答えがある場合、計算量は N^X(NのX乗) になると思います。 N^Xは計算量のクラス(NP困難やNP完全等)でいうと何に属するのでしょうか?

  • 桁数が増えると正しく計算されません。

    今、Perlで作成したモジュールをCに移しています。 Perlではうまく動いているのですが、Cで作った以下のプログラムでは、 nを13以上にすると、値が正しく計算されなくなります。 ユーザ関数をdoubleにしたりすると、全て0になったりコンパイルできません。 せめてdouble型の最大値くらいまでは計算したいと考えています。 また、下のプログラムでC言語ならではの修正すべき点があれば教えてください。 よろしくお願いします。 #-----------------------------------------------------------# #include <stdio.h> int factorial(int j); int main(void) { /* 試行回数n回 */ int i, j, n, r, x; int combination; //printf("試行回数は?"); //scanf("%d", &n); n=13; for (i=1; i<=n; i++){ for (r=0; r<=i; r++){ combination = factorial(i) / (factorial(r) * factorial(i - r)); printf("%5d",combination); } printf("\n"); } } int factorial(int j){ int i; int x; x = 1; for (i = 1; i <= j; i++){ x *= i; } return x; } #-----------------------------------------------------------#

  • 【計算量Log n】僕は実際の面接でソートの計算量

    【計算量Log n】僕は実際の面接でソートの計算量を聞かれて、log nですかねと言ったら「は?」という顔をされたので即座に「nより速いのはありえないですよねー、HAHAHA!」とごまかして事なきを得た。 ツイッターより 計算量のlog nのnより早いのはあり得ないってどういう意味ですか? あとLog nの計算量とOのオーダ量の違いは何ですか?

  • 計算量の少ないn乗根の求め方

    現在C++であるクラスのインスタンスaのN乗根を求める関数を作成中なのですが、どうしても実行時間が長くなってしまいます。 現在ニュートン法に則って X(m+1)=((N-1)(Xm)^N+a)/(N*(Xm)^(N-1)) という漸化式を回して変化量が一定値以下になったら終了という関数なのですが、 値によっては累乗計算のところで時間を大幅にロスしてしまうようです。 原因としては累乗計算が同じ数をN回掛けるという単純な仕組みなため、 Nが大きすぎるとループがなかなか終わらないということがわかっています。 もしご存知であれば 1.極力累乗計算を使わないN乗根の求め方 2.計算量の少ない累乗計算の仕方 のどちらかを教えていただけないでしょうか? なお、クラスを使っている関係上powなどの既存の関数は使えません。 よろしくお願いいたします。

専門家に質問してみよう