📘 CodingMarble Learn

アルゴリズムの計算量:処理の手数はどれだけ増える?

同じ問題を解く方法はたくさんありますが、必要な手数が大きく違うものがあります。アルゴリズムの良し悪しは、ストップウォッチの秒数ではなく、入力の大きさ n が増えたときの基本的な手数の数え方で測ります。その増え方に名前をつけたのがビッグO記法です。O(1)は定数、O(log n)は対数、O(n)は線形、O(n log n)、O(n²)は2乗の増え方を表します。線形探索はO(n)、二分探索はO(log n)。バブルソートはO(n²)、マージソートはO(n log n)です。使うメモリの量は空間計算量といいます。

🎬 ステップ別ストーリー

  1. 16個の箱から数字の13を探します。箱を1つずつ開けていき、開けた箱1つが1手です。これが線形探索で、最大 n 手かかります。
  2. 箱が順番に並んでいるなら、真ん中を開けて、外れの半分を捨てます。これをくり返すと、二分探索はたった4手で13を見つけます。
  3. n = 16 のとき、5種類のアルゴリズムを比べます。棒の高さが手数です。小さいままのものもあれば、とても高いものもあります。
  4. 入力を8から16に2倍にします。O(n)は2倍、O(n²)は4倍になり、O(log n)はたった1だけ増えます。
  5. 1000個を並べ替えるとき、バブルソートは約100万回の比較、マージソートは約1万回です。入力が大きいほど、増え方の差が効いてきます。
  6. 今度はあなたの番です。スライダーで n を2から1024まで動かして、どの棒がいちばん速く伸びるか見てみましょう。

ヒント:3Dをドラッグすると回せます。2本指で拡大・縮小できます。

🤔 よくある疑問をスッキリ解決

どうしてストップウォッチで測ってはいけないの?

時間はコンピューターごとに変わりますが、手数は変わりません。ステップ1では、秒ではなく開けた箱の数を数えています。

二分探索は、なぜ箱の半分を飛ばせるの?

箱が順番に並んでいるからです。真ん中が探している数より小さければ、その左側もぜんぶ小さいので、答えにはなりえません。ステップ2の灰色の箱を見てみましょう。

ビッグOでは、どうして定数を捨てるの?

ビッグOは、仕事がどれだけ速く増えるかの話だからです。2n も n も、n を2倍にすれば2倍になるので、同じ増え方です。ステップ4で2倍の様子を見られます。

O(n²) は、いつも O(n log n) より遅いの?

n がとても小さいときは、O(n²) のほうが速いこともあります。でも n が大きくなると、n² はあっという間に追い越します。ステップ5の n = 1000 では、差は約100倍です。

ここでの log n は、結局どういう意味?

log₂ n は、n を1になるまで半分にできる回数です。1024なら10回です。最後のステップでスライダーを動かして、n が2倍になるたびに青い棒が1だけ伸びるのを見てみましょう。

1つの問題にたくさんのアルゴリズム

アルゴリズムとは、問題を解くための決まった手順のことです。たいていの問題は、2つ以上のアルゴリズムで解けます。たとえばリストから名前を探すとき、全部の名前を順に確かめることもできますし、リストが並んでいれば、半分ずつに絞っていくこともできます。

どちらも正しい答えが出ます。違うのは効率、つまりどれだけ手間とメモリが必要かです。データが大きくなっても速いままのアルゴリズムを選ぶのが、よいプログラマーです。

かかる時間で比べるには

ストップウォッチで測るのは公平ではありません。速いパソコンなら、遅いアルゴリズムでも速く見えてしまうからです。そこで、入力の大きさ n に対して、比較・入れ替え・足し算などの基本的な手数を数えます。

最良・平均・最悪のケース

最良のケースは、いちばん運のよい入力です(13が最初の箱にある:1手)。最悪のケースは、いちばん運の悪い入力です(13がない:n手)。ふつうは最悪のケースを使います。それは「どんなときでもこれより遅くならない」という約束になるからです。

時間計算量と空間計算量

時間計算量は、n が増えたときに手数がどう増えるかを表します。空間計算量は、n が増えたときに追加のメモリがどう増えるかを表します。マージソートは速いですが追加のメモリが必要です。バブルソートは追加のメモリがほとんどいりませんが、遅いです。

ビッグO記法

ビッグOは、細かい部分を無視して、増え方だけを表します。いちばん大きい項だけを残し、定数は捨てます。3n² + 5n + 2 は O(n²) になります。n が大きいとき、n² の部分がほぼ全部を占めるからです。

ビッグO名前n = 16n = 1000例
O(1)定数11配列の5番目の要素を読む
O(log n)対数4約10二分探索
O(n)線形161000線形探索、最大値を探す
O(n log n)n log n64約10,000マージソート
O(n²)2乗2561,000,000バブルソート、二重ループ

コードを見るときの目安:n個を1回まわるループはO(n)、ループの中にループがあればO(n²)、毎回問題を半分にするならO(log n)です。

線形探索と二分探索の効率

線形探索は、要素を1つずつ調べます。最悪の場合は n 回の比較なので O(n) です。並んでいてもいなくても、どんなリストにも使えます。

二分探索は、並んだリストが必要です。真ん中を見て、それが大きすぎれば右半分を捨て、そうでなければ左半分を捨てます。1手ごとにリストが半分になるので、最悪の場合は約 log₂ n + 1 回の比較、つまり O(log n) です。100万個なら、100万回ではなく約20回ですみます。

並べ替えアルゴリズムの効率

バブルソート、挿入ソート、選択ソートは、ループの中にループがあるので、比較は約 n²/2 回、つまり O(n²) です。挿入ソートは、すでに並んでいるリストなら最良のケースで O(n) になります。

マージソートは、リストを約 log₂ n 回半分にし、各段階で約 n の仕事をします。だから O(n log n) です。追加で O(n) のメモリが必要です。

二分探索には並んだリストが必要です。探すのが1回だけなら、先に並べ替える(n log n)ほうが、線形探索1回(n)より手間がかかります。何回も探すなら、1回並べておく価値があります。

事前条件・事後条件と再帰の落とし穴

事前条件とは、アルゴリズムが始まる前に成り立っていなければならないことです(二分探索なら、リストが並んでいること)。事後条件とは、終わったときに保証されることです(並べ替えなら、どの要素も次の要素以下になっていること)。これを書いておくと、アルゴリズムのテストや証明がしやすくなります。

再帰とは、関数が、より小さい問題に対して自分自身を呼び出すことです。よくある間違いは次のとおりです。

やってみよう:2つの探し方で競争

1から32までの数字を紙のカードに書き、順番に伏せて並べます。友だちに秘密の数を1つ選んでもらいます。まず1枚ずつめくって、めくった枚数を数えます。次に、いつも真ん中のカードをめくって探します。これを5回くり返しましょう。6回より多くめくらずにすんだのはどちらの方法でしょう。最後の3Dステップのスライダーで確かめてみましょう(n = 32 のとき log₂ 32 = 5)。

重要な公式と用語

例題

1. リストに名前が50個あります。線形探索の比較回数は、最良と最悪のケースでそれぞれ何回ですか。

最良のケース:名前が最初にある → 比較1回。最悪のケース:名前が最後にある、またはない → 比較50回。線形探索は O(n) です。

2. 並んだ1024個のリストで、二分探索が必要とする比較は最大で何回ですか。

1手ごとに半分になります:1024 → 512 → 256 → 128 → 64 → 32 → 16 → 8 → 4 → 2 → 1。半分にするのが10回で、最後の確認を足して、最大11回の比較です(log₂ 1024 = 10)。

3. f(n) = 4n² + 10n + 7 のビッグOを答えましょう。

いちばん大きい項(4n²)を残し、定数の4を捨てて、O(n²) です。

4. i を1から n まで動かすループがあり、その中で j を1から n まで動かすループがあります。内側の行は何回実行されますか。

i の n 個の値のそれぞれについて n 回なので、n × n = n² 回です。時間計算量は O(n²) です。

5. O(n²) のプログラムが1000個の並べ替えに2秒かかります。3000個ならおよそ何秒かかりますか。

n が3倍になるので、n² は 3² = 9 倍になります。約 2 × 9 = 18 秒です。

6. n = 1000 個のとき、バブルソートとマージソートを比べましょう。

バブルソート:約 n²/2 = 500,000 回の比較。マージソート:約 n log₂ n = 1000 × 10 = 10,000 回。マージソートの仕事量は約50分の1ですが、追加のメモリが必要です。

よくある間違い

練習クイズ

1. 線形探索の最悪の場合の時間計算量はどれですか。
2. 二分探索が使えるのは、リストがどんなときですか。
3. n が2倍になると、O(n²) のアルゴリズムにかかる時間はおよそどうなりますか。
4. O(n log n) の並べ替えはどれですか。
5. 7n + 300 のビッグOはどれですか。

練習:自分で答えてみよう

答えを入力するか選んで、「チェック」を押そう。困ったらヒントを見てね。解答は答えたあとに表示されます。

よくある質問

時間計算量を一言でいうと?

入力が大きくなったとき、アルゴリズムの手数がどう増えるかを表すものです。たとえば O(n) は、入力を2倍にすると手数も2倍になるという意味です。

時間計算量と空間計算量はどう違うの?

時間計算量は手数を、空間計算量は追加で使うメモリを測ります。マージソートのように、速いけれどメモリをたくさん使うアルゴリズムもあります。

いちばん速いビッグOはどれ?

O(1)(定数)がいちばんよく、次に O(log n)、O(n)、O(n log n)、O(n²) と続きます。指数の O(2ⁿ) は、よく出てくるものの中でいちばん悪いです。

学ぶ場所

Canada (Ontario)Grade 12C. Designing Modular Programs
Ukraine11 класAlgorithms
England (GCSE, A level)Year 103.1 Fundamentals of algorithms
USA (Common Core, NGSS, AP)Grade 11Selection and Iteration
USA (Common Core, NGSS, AP)Grade 11Algorithms and Programming
South Korea고등학교 2학년Algorithms and programming
South Korea고등학교 3학년Abstraction and algorithms

先に学ぼう

次に学ぼう