プログラミング入門

Download Report

Transcript プログラミング入門

補講:アルゴリズムと漸近的評価
アルゴリズム
アルゴリズムと問題
「アルゴリズム」とは「問題」を解くために、
「基本操作」(命令)を有限個組み合わせ
てできる手順。
色々な問題
データのソート
命令
アルゴリズム
四則演算
組み合わせ方
代入演算
比較演算
2進数への変換
連立方程式を解く
最大公約数
アルゴリズム例1
10進数を2進数に変換する方法
25の2進数は?
2で割り算
商
余
25/2 =12
12/2 = 6
6/2 = 3
3/2 = 1
1/2 = 0
・・・1
・・・0
・・・0
・・・1
・・・1
アルゴリズム例2
最大公約数を求める方法(ユークリッドの互除法)
2つの自然数m,nの最大公約数を求めるアルゴリズム
[step1]:mをnで割って余りをrとする。
[step2]:r=0ならアルゴリズム終了する。このときのnが
最大公約数
[step3]:r0なら、mにnを代入し、nにrを代入してstep1にもどる。
実行例
m=12 n=8 の最大公約数
1回前の余り
余り
で割り算
12/8=1・・・4
8/4=2 ・・・0
次回の値
m=8 n=4
最大公約数は4
アルゴリズムとプログラム
アルゴリズム
+
プログラミング
プログラム
プログラム言語
データ構造
ユークリッドの互除法
+
整数型データ
int gcd(int m, int n){
int r;
do {
r= m % n;
m=n;
n=r;
}while(r != 0);
return m;
}
アルゴリズムの評価
問題の大きさ
同じ問題でも、
その大きさ毎に必要な演算数(総ステップ数、計算時間)は異なる。
大きさも考えた問題
n桁の足し算
n桁の10進数をmビットの2進数へ変換
n変数の連立方程式
n個のデータに対する、ソート
n桁の数とm桁の数の最大公約数
通常入力サイズは、n,m等の文字で表します。
アルゴリズムの評価
アルゴリズムは通常「問題」を解くためのものであり、
どんな大きさでも解けないといけない。
総ステップ数を、入力サイズnの関数T(n)で評価します。
(使用メモリ量を、入力サイズnの関数S(n)で
評価することもあります。)
計算時間と関数
1000MIPS(1秒間に10億回の演算可能)の
コンピュータで考えてみましょう。
関数
サイズ n
10
10 log n
8
10 n
5
2
10 n
2n
10
10秒
1秒
100
3
10
20秒
10秒
30秒
1分40秒
1分40秒
甚大
104
105
40秒
16分40秒
約2時間47分
甚大
50秒
約2時間47分
約11.5日
甚大
約3.2年
甚大
6
10
1分
約1日
0.01秒
1秒
6
1.0

10
約
秒
約3京世紀
関数の分類(オーダー記法)
関数の増加傾向により、
関数を大まかに分類したい。
log n
2log n
n
10n
1000log n
1000n
O(log n)
対数(時間)
O(n)
n
n
n2
2
10n
2
k
100n
k
3n
cn
O(n2 )
k
O(n )
多項式(時間)
O(cn )
指数(時間)
O記法
O記法
定義
2つの正の値しかもたない数列を { f (n)},{g(n)} とする。
2つの定数 c , n0 が存在し、
n  n0 なる全てのnに対し,
f (n)  cg(n)
ならば、
f (n)  O( g(n))
と書き、
f (n)
はオーダー
g (n)
と読む。
注意1:O記法では、「=」の左辺と右辺の交換は不可。
O記法のイメージ
O記法の例
(1) f (n)  2n
n0  1, c  2, g (n)  n
とすれば、
n  1 に対して、 f (n)  2g (n)
よって、 2n  O(n)
(2) f (n)  5n2  100n
n0  100, c  6, g(n)  n2
n  100
に対して、
よって、
とすれば、
f (n)  6g(n)
5n2  100n  O(n2 )
注意2:通常O記法では、最も簡単な関数で表す。
O記法の例
(3) f (n)  10000000000
n0  1, c  10000000000, g(n)  1 とすれば、
n 1
に対して、
f (n)  cg(n)
よって、 10000000000  O(1)
(4) f (n)  2n  n100
n0  1000, c  2, g(n)  2n とする。
1000
2
 2

10 100
n  1000
 (1024)100  (1000)100 なので、
に対して、
f (n)  cg(n)
よって、 2n  n100  O(2n )
O記法の練習
次の数列の一般項(関数)をO記法で表せ。
(1) f (n)  10n  500
(2) f (n)  10n n  100000n2
(3) f (n)  1000log2 n  10log10 n
(4) f (n)  n  log2 n
(5) f (n)  2n  3n
プログラムと漸近的評価
仮定1
プログラム内の加減算は、ある定数
c1時間以下で実行できる。
仮定2
プログラム内の乗除算は、ある定数
c2時間以下で実行できる。
仮定3
プログラム内の比較は、ある定数
c3 時間以下で実行できる。
仮定4
プログラム内の代入は、ある定数
c4 時間以下で実行できる。
.
.
.
プログラムでは、このように仮定できることが多い。
プロうグラムの漸近的評価
仮定1-4より、 c  max{c1 , c2 , c3 , c4 }
なる
c
をとると、
プログラム内の4則演算、比較等はある定数時間以下で実行できる。
つよめて
プログラム内では、
繰り返し構造、
(再帰関数を含む)関数呼び出し、
以外は定数時間で実行できると仮定できることが多い。
プログラムにおける計算時間の漸近評価例
function1()
{
for(k=0;k<n;k++)
{
・・・・
}
}
function1の計算時間は、 O(n)
である。
この部分がn回
実行されることに
注意する。
プログラムにおける計算時間の漸近評価例2
function2()
{
この部分は n 回
実行されることに
注意する。
for(k=0;k<n;k++)
{
for(j=0;j<n;j++)
{
・・・・
}
}
}
この部分は n2 回
実行されることに
注意する。
この部分はn 回
実行されることに
注意する。
2
function2の計算時間は、O(n )で ある。
プログラムにおける計算時間の漸近評価例3
function3()
{
for(k=0;k<n;k++)
{
for(j=0;j<k;j++)
{
・・・・・・
}
}
}
function3の計算時間 f (n) を評価してみましょう。
f (n)  c(1  2  3 
n(n  1)
 n)  c
 O(n2 )
2
プログラムにおける計算時間の漸近評価例4
int function4(int n)
{
if(n<1)
{
return(0);
}
f (n)  O(n) である。
{
function4(n}
f (1)  c1


 f (n)  f (n  1)  c2
この漸化式より、
else
1);
function4の計算時間 f (n) を評
価してみましょう。
プログラムにおける計算時間の漸近評価例5
int function5(int n)
{
if(n<1)
{
return(0);
}
else
{
function5(n/2);
}
function5の計算時間 f (n) を評
価してみましょう。
f (1)  c1



n
f
(
n
)

f
(
)  c2

2
この漸化式より、
f (n)  O(log n) である。
プログラムにおける計算時間の漸近評価例6
int function6(int n)
{
if(n<1)
{
return;
}
else
{
function6の計算時間 f (n) を評
価してみましょう。
 f (1) 

 f (n) 



c1
f (n  1)  f (n  1)  c2
2 f (n  1)  c2
function6(n-1);
function6(n-1);
}
}
この漸化式より、
f (n)  O(2n ) である。
プログラムにおける計算時間の漸近評価練習1
次のプログラムの計算時間をO記法で求めよ。
ただし、入力サイズは仮引数nに入っている数とする。
(1) exercise1(int
n)
{
for(j=0;j<n;j++)
{
for(k=0;k<n;k++)
{
・・・・・・
}
}
for(l=0;l<n;l++)
{
××××
}
}
(2)
exercise2(int n)
{
if(n<2)
{
return;
}
else
{
exercise2(n-1);
exercise2(n-2);
}
}