SlideShare a Scribd company logo
計算量のはなし
稲盛 徹
発表の内容
計算量の概念
計算量の理論﴾計算可能性等﴿
計算量と計算時間の関係
スクリプトの計算量の求め方
有名アルゴリズム/データ構造の計算量
計算量を改善する方法の一部を紹介
複雑なアルゴリズムの高速化方法
想定対象者
計算量の概念を知らない人﴾特に時間計算量﴿
自分のスクリプトがどの程度実行時間がかかるか推定したい
人
計算量とは
ある処理を行うプログラムを作成する際に、どのように計算を行
っていくかという計算手順﴾アルゴリズム﴿は複数の方法が考えられ
ます。
アルゴリズムの性能を比較する方法は色々ありますが、計算機の
消費するリソースを基にどの手法が良いかと判断する1つの指標と
して計算量があります。
時間計算量と空間計算量
プログラムの実行に必要な計算時間や計算領域﴾メモリ﴿の量が、入
力に対してどのくらい変化するのかを示す指標を計算量といいま
す。
時間計算量
「プログラムの実行に必要な計算ステップ数が入力に対してどの
ように変化するのか」という指標を時間計算量といいます。
今回の発表はこちらがターゲットです。
空間計算量
「プログラムの実行に必要なメモリの量が入力に対してどのよう
に変化するのか」という指標を空間計算量といいます。
オーダー記法 O(・) について
厳密な計算ステップ数や必要な記憶領域の量は実装方法や言語等
に依存するため、計算量の厳密な見積もりは大変です。
そこで以下のようにオーダー記法 O(・) を用いて大体の見積もり
を行います。
算出手順
ステップ1:係数を省略する。﴾ただし定数については1﴿
ステップ2:Nを大きくしたときに一番影響が大きい項を取り
出し、 O(項) と書く。
例:3N^2+2N+1 ‐> O(N^2)
「一番影響が大きい項」は、Nを大きくしていったときに「大きく
なるスピードが最も速い項」というイメージで大体あっていま
す。
計算量の大まかな概要﴾1/2﴿
主な計算量の大小関係は以下のようになります。
O(1) < O(logN) < O(N) < O(NlogN) < O(N^2) < O(2^N)
計算量の大まかな概要﴾2/2﴿
入力 N と実行時間の感覚の対応を次の表に示します。﴾C++例﴿
Pythonだと2~10倍くらい遅くなるかも?
計算量を意識することの意義
計算量を意識することで以下のようなメリットがあるはず
計算量を意識すると、データ数が増えても速度が低下しにく
いコードを書けるようになる。
計算量を見積もることができれば、コードをレビューする時
に潜在的なパフォーマンス問題に気づけるようになる。
等
一方でNが小さい場合は意識する必要はあまりありません。
有名アルゴリズム/データ構造の計算量の例﴾C++で概算﴿
Pythonなら以下を読めばいいかも。
Pythonistaなら知らないと恥ずかしい計算量のはなし
計算量の求め方
以下を意識すると良いかと思います。
最悪ケースについて考える
「ループのネスト数」と、そのループの中で使っている「API
の計算量」に注目する
問題1:このコードの計算量は?
// 緑の果物を特定するプログラム
string[] fruits = GetFruits();
string[] greenfoods = GetGreenFoods();
var greenfruits = new List<string>();
foreach (var fruit in fruits)
{
    if (greenfoods.Contains(fruit))
    {
        greenfruits.Add(fruit);
    }
}
答えは O(N^2)
Nのループの中で、計算量 O(N) のArray.Containsを使っているた
め、計算量は O(N^2) になる。
問題2:このコードの計算量は?
// 緑の果物を特定するプログラム
string[] fruits = new []{"avocado", "banana", "cherry"};
string[] greenfoods = GetGreenFoods();
var greenfruits = new List<string>();
foreach (var fruit in fruits)
{
    if (greenfoods.Contains(fruit))
    {
        greenfruits.Add(fruit);
    }
}
答えは O(N)
foreachのループ回数は3回なので 3N 。定数の係数は省くので
O(N) となる。
計算量観点からの高速化について
高速化方法は色々あるが、計算量観点から高速化する場合は以下
の2つのアプローチが有用そう。
適切なデータ構造を使用するように変更する
アルゴリズムを見直す
問題3:このコードの計算量を下げて高速化しろ
// 緑の果物を特定するプログラム
string[] fruits = GetFruits();
string[] greenfoods = GetGreenFoods();
var greenfruits = new List<string>();
foreach (var fruit in fruits)
{
    if (greenfoods.Contains(fruit))
    {
        greenfruits.Add(fruit);
    }
}
回答1:適切なデータ構造を使う
Array.Containsは O(N) であるが、Arrayの代わりにContainsが O(1)
の HashSet<T> を使用すれば、計算量を下げられる。
// 緑の果物を特定するプログラム
string[] fruits = GetFruits();
HashSet<string> greenfoods = new HashSet<T>(GetGreenFoods());
var greenfruits = new List<string>();
foreach (var fruit in fruits)
{
    if (greenfoods.Contains(fruit))
    {
        greenfruits.Add(fruit);
    }
}
計算量は O(N) になった。
回答2:アルゴリズムを見直す
greenfruitsはfruitsとgreenfoodsの集合積であるとも考えられる。
集合積にはHashSet<T>が使える。
// 緑の果物を特定するプログラム
HashSet<string> tmp_fruits = new HashSet<string>(GetFruits());
HashSet<string> tmp_greenfoods = new HashSet<string>(GetGreenFoods())
tmp_fruits.IntersectWith(tmp_greenfoods);
var greenfruits = new List<string>(tmp_fruits);
HashSet<T>.IntersectWithの計算量は O(N) なので、計算量は O(N)
になった。
まとめ
大きなデータを扱うときは計算量を意識すると性能劣化の起
きにくいコードが作れる。
計算量を見積もるときは「ループのネストの数」と「APIの計
算量」を意識する。
参考文献
特集!知らないと損をする計算量の話
計算量オーダーの求め方を総整理! ~ どこから log が出て来るか
~
計算量に注目してプログラムを高速化する
Pythonistaなら知らないと恥ずかしい計算量のはなし
C++入門 AtCoder Programming Guide for beginners ﴾APG4b﴿
2.06.計算量

More Related Content

PDF
CV分野におけるサーベイ方法
PDF
平面グラフと交通ネットワークのアルゴリズム
PDF
計算機アーキテクチャを考慮した高能率画像処理プログラミング
PDF
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
PPTX
研究の進め方
PDF
【メタサーベイ】Neural Fields
PPTX
【DL輪読会】Language Conditioned Imitation Learning over Unstructured Data
PPTX
畳み込みニューラルネットワークの高精度化と高速化
CV分野におけるサーベイ方法
平面グラフと交通ネットワークのアルゴリズム
計算機アーキテクチャを考慮した高能率画像処理プログラミング
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
研究の進め方
【メタサーベイ】Neural Fields
【DL輪読会】Language Conditioned Imitation Learning over Unstructured Data
畳み込みニューラルネットワークの高精度化と高速化

What's hot (20)

PDF
[DL輪読会]A Bayesian Perspective on Generalization and Stochastic Gradient Descent
PDF
SSII2019OS: 深層学習にかかる時間を短くしてみませんか? ~分散学習の勧め~
PDF
Newman アルゴリズムによるソーシャルグラフのクラスタリング
PPTX
ラベル付けのいろは
PPTX
【DL輪読会】Llama 2: Open Foundation and Fine-Tuned Chat Models
PDF
Attentionの基礎からTransformerの入門まで
PPTX
[DL輪読会]YOLOv4: Optimal Speed and Accuracy of Object Detection
PPTX
[DL輪読会]Deep High-Resolution Representation Learning for Human Pose Estimation
PPTX
画像キャプションの自動生成
PPTX
[DL輪読会]GQNと関連研究,世界モデルとの関係について
PDF
Deep Learningによる超解像の進歩
PDF
Prophet入門【Python編】Facebookの時系列予測ツール
PDF
多すぎるユニットテストは却ってよくない?私が実践しているテストコードのリファクタリング
PPTX
論文の書き方・読み方
PPTX
TensorFlowをもう少し詳しく入門
PPTX
機械学習 / Deep Learning 大全 (4) GPU編
PPTX
機械学習 / Deep Learning 大全 (1) 機械学習基礎編
PDF
強化学習その3
PDF
自然言語処理を 役立てるのはなぜ難しいのか(2022/10/25東大大学院「自然言語処理応用」)
PDF
0から理解するニューラルネットアーキテクチャサーチ(NAS)
[DL輪読会]A Bayesian Perspective on Generalization and Stochastic Gradient Descent
SSII2019OS: 深層学習にかかる時間を短くしてみませんか? ~分散学習の勧め~
Newman アルゴリズムによるソーシャルグラフのクラスタリング
ラベル付けのいろは
【DL輪読会】Llama 2: Open Foundation and Fine-Tuned Chat Models
Attentionの基礎からTransformerの入門まで
[DL輪読会]YOLOv4: Optimal Speed and Accuracy of Object Detection
[DL輪読会]Deep High-Resolution Representation Learning for Human Pose Estimation
画像キャプションの自動生成
[DL輪読会]GQNと関連研究,世界モデルとの関係について
Deep Learningによる超解像の進歩
Prophet入門【Python編】Facebookの時系列予測ツール
多すぎるユニットテストは却ってよくない?私が実践しているテストコードのリファクタリング
論文の書き方・読み方
TensorFlowをもう少し詳しく入門
機械学習 / Deep Learning 大全 (4) GPU編
機械学習 / Deep Learning 大全 (1) 機械学習基礎編
強化学習その3
自然言語処理を 役立てるのはなぜ難しいのか(2022/10/25東大大学院「自然言語処理応用」)
0から理解するニューラルネットアーキテクチャサーチ(NAS)
Ad

計算量のはなし