Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions docs/02advanced/05order/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
sidebar_position: 5
---

import ViewSource from "@site/src/components/ViewSource";
import Answer from "@site/src/components/Answer";

# 計算量

ここでは、計算量について学んでいきます。

## 計算量とは

計算量とは、アルゴリズムの実行に要する計算資源の量です。

計算量には、大きく時間計算量と空間計算量の2つがあります。

時間計算量は、アルゴリズムの実行に要するステップの数です。

空間計算量は、アルゴリズムの実行に要する記憶容量の数です。

## 計算量オーダー

ここで、計算量を比較することを考えてみましょう。

例えば、次の 2 つのプログラムを考えてみましょう。

<ViewSource path="/order/example1.ipynb" />

<ViewSource path="/order/example2.ipynb" />

$n = 2$ なら、2 番目のプログラムは、1 番目のプログラムの 2 倍の計算が必要です。
しかし、$n = 10000$ なら、2 番目のプログラムは、1 番目のプログラムの 10000 倍の計算が必要です。
$n = 2$ 程度なら計算量の差はほとんどありませんが、$n$ の値が大きくなると非常に大きな差が生まれてきます。

このように、アルゴリズムを比較するときには、入力サイズ $n$ が大きい時にどうなるのかを考えることが大切になります。
そのため、計算量を比較するときには、入力サイズ $n$ に対する関数を比較します。
1 番目のプログラムでは、$n$ 回、2 番目のプログラムでは、$n^2$ 回の計算が必要と考えます。

また、$n$ が十分大きいときには、$n$ と $n^2$ には大きな差が生じますが、$2n^2$ や $n^2 + n$ と $n^2$ の間にはほとんど違いがありません。このため、定数倍は無視し、最高次数以外の項も考えません。

## ランダウの記号

計算量を表すのには、ランダウの記号が便利です。

ランダウの記号は、$n$ が非常に大きい時の計算量を表します。
例えば、$n$ 回のステップが必要な時には、$O(n)$ と表します。

1. 最高次以外の項は、無視します。例: $n^2 + n + 1 = O(n^2)$
1. 係数は無視します。例: $3n^2 = O(n^2)$

## 各オーダーの比較

それぞれのオーダーを比較してみましょう。Python では、1 秒で $10^7$ 回ぐらいの計算ができます。$10^7$ 回を超えたところは、「-」で表します。

| データサイズ | $O(1)$ | $O(\log n)$ | $O(n)$ | $O(n\log n)$ | $O(n^2)$ | $O(n^3)$ | $O(2^n)$ | $O(n!)$ |
| ------------ | ------ | ----------- | -------- | ------------ | -------- | -------- | -------- | ------- |
| 5 | 1 | 3 | 5 | 12 | 25 | 125 | 32 | 120 |
| 10 | 1 | 4 | 10 | 34 | 100 | 1000 | 1024 | 3628822 |
| 20 | 1 | 5 | 20 | 87 | 400 | 8000 | 1048576 | - |
| 50 | 1 | 6 | 50 | 283 | 2500 | 125000 | - | - |
| 100 | 1 | 7 | 100 | 665 | 10000 | 1000000 | - | - |
| 1000 | 1 | 10 | 1000 | 9966 | 1000000 | - | - | - |
| $10^4$ | 1 | 14 | 10000 | 132878 | - | - | - | - |
| $10^5$ | 1 | 17 | 100000 | 1660965 | - | - | - | - |
| $10^6$ | 1 | 20 | 1000000 | - | - | - | - | - |
| $10^7$ | 1 | 24 | 10000000 | - | - | - | - | - |
| $10^8$ | 1 | 27 | - | - | - | - | - | - |
| $10^9$ | 1 | 30 | - | - | - | - | - | - |
| $10^10$ | 1 | 34 | - | - | - | - | - | - |

## 練習問題 1

次のプログラムの計算量を求めてください。

<ViewSource path="/order/exercise1.ipynb" />

<Answer>

for 文の中が `n` 回繰り返されるので、$O(n)$ となります。

</Answer>

## 練習問題 2

次のプログラムの計算量を求めてください。

<ViewSource path="/order/exercise2.ipynb" />

<Answer>

こちらも for 文の中がデータ数を $n$ とすると、 $n$ 回繰り返されるので、$O(n)$となります。

</Answer>

## 練習問題 2

次のプログラムの計算量を求めてください。

<ViewSource path="/order/exercise3.ipynb" />

<Answer>

処理自体は一回しか行われないので、$O(1)$となります。

</Answer>
31 changes: 31 additions & 0 deletions static/order/example1.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {},
"cells": [
{
"metadata": {},
"source": [
"def calc_sum(n):\n",
" s = 0\n",
" for i in range(1, n + 1):\n",
" s += i\n",
" return s\n",
"\n",
"\n",
"print(calc_sum(10))"
],
"cell_type": "code",
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"55\n"
]
}
],
"execution_count": null
}
]
}
32 changes: 32 additions & 0 deletions static/order/example2.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {},
"cells": [
{
"metadata": {},
"source": [
"def calc_sum_square(n):\n",
" s = 0\n",
" for i in range(1, n + 1):\n",
" for j in range(1, n + 1):\n",
" s += i * j\n",
" return s\n",
"\n",
"\n",
"print(calc_sum_square(10))"
],
"cell_type": "code",
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"3025\n"
]
}
],
"execution_count": null
}
]
}
35 changes: 35 additions & 0 deletions static/order/exercise1.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {},
"cells": [
{
"metadata": {},
"source": [
"n = 10\n",
"for i in range(n):\n",
" print(i)"
],
"cell_type": "code",
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"0\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"9\n"
]
}
],
"execution_count": null
}
]
}
32 changes: 32 additions & 0 deletions static/order/exercise2.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {},
"cells": [
{
"metadata": {},
"source": [
"def calc_max(data):\n",
" max_val = data[0]\n",
" for i in range(1, len(data)):\n",
" if max_val < data[i]:\n",
" max_val = data[i]\n",
" return max_val\n",
"\n",
"\n",
"print(calc_max([1, 4, 3, 5, 2]))"
],
"cell_type": "code",
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"5\n"
]
}
],
"execution_count": null
}
]
}
28 changes: 28 additions & 0 deletions static/order/exercise3.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {},
"cells": [
{
"metadata": {},
"source": [
"def calc_square(n):\n",
" return n**2\n",
"\n",
"\n",
"print(calc_square(9))"
],
"cell_type": "code",
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"81\n"
]
}
],
"execution_count": null
}
]
}