第4回配布プリント

漸化式の計算法
1
特性方程式による解法
まず次のような例題を考える:
いまここに産まれたての一つがいのウサギがいる。この一つがいが成長して二年
後からは毎年一つがいずつ産んでいくものとする。生まれたばかりの一つがいも,
同様に二年後からは毎年一つがいずつ産んでいくものとする。そうすると n 年後
には合計何つがいになっているだろうか。
最初の年 (0 年とする) にいた一つがいは,次の年 (1 年とする) にはまだ子供を産めないので,
次年の年末にはまだ一つがいである。この一つがいは翌々年 (2 年) には新たに一つがいを産むの
で,2 年末には合計二つがいになる。 3 年末には,この二つがいのうち初めからいた方がまた一
つがい産むので,合計三つがいになる。このように数えていくと下の表のようになる。
ウサギのつがい数
年
つがい
0
1
2
3
4
5
···
···
1
1
2
3
5
8
···
···
ここで,n 年末と n+1 年末のつがい数をそれぞれ fn と fn+1 とする。そうすると n+2 年には,
n 年末にいた fn つがいがそれぞれ一つがい産むので,年末は fn つがい増えて,fn+2 = fn+1 +fn
つがいとなる。したがって fn の値は,差分方程式 (漸化式) (difference equation)
fn+2 = fn+1 + fn ,
f0 = f1 = 1
(1)
を計算していけば順次求まることになる。上式で表される数列 {fk } は フィボナッチ数列 (Fibonacci
sequence) と呼ばれでいる。
下に fn を計算する C によるプログラムを示す。
1: #include <stdio.h>
2: main()
3: {
4:
int n,f[11];
5:
f[0]=1; f[1]=1;
6:
printf("
n
f_n \n");
7:
8:
for (n=0; n<=8; n++)
9:
f[n+2]=f[n+1]+f[n];
10:
1
11:
for (n=0; n<=10; n++)
12:
printf(" %2d %3d \n",n,f[n]);
13: }
実行結果
n
f_n
0
1
1
1
2
2
3
3
4
5
5
8
6 13
7 21
8 34
9 55
10 89
これを配列を用いないで書くとつぎのようなプログラムになる。
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
#include <stdio.h>
main()
{
int n,f0=1,f1=1,f2;
printf("
n
f_n \n");
n=0;
printf("
n=1;
printf("
%2d %3d \n",n,f0);
%2d %3d \n",n,f1);
for (n=2; n<=10; n++) {
f2=f1+f0;
printf(" %2d %3d \n",n,f2);
f0=f1; f1=f2;
}
}
ここで数値計算によらず,解析的な手法によって式 (1) の解を求めることを考える。まず fn
を
fn = λn ,
λ = 0
(2)
と置いてみる。これを式 (1) に代入して両辺を λn で割ると
λ2 − λ − 1 = 0
(3)
となる。この方程式は差分方程式 (1) の 特性方程式 (characteristic equation) と呼ばれている。
特性方程式 (3) の解は
√
√
1+ 5
1− 5
,
λ2 =
λ1 =
2
2
となるので,n にも λ にも依らない定数 c1 , c2 を用いて
fn = c1 λn1 + c2 λn2
2
(4)
と表したのが差分方程式 (1) の 一般解 (general solution) になる。ここで,任意定数 c1 , c2 を初
期条件
f0 = f1 = 1
にあわせて決めると
√
√
1+ 5
−1 + 5
√
c1 = √ ,
c2 =
2 5
2 5
を得る。これを式 (4) に代入すると,解は
⎧
⎫
√ n+1 √ n+1 ⎬
⎨
1+ 5
1
1− 5
fn = √
−
,
⎭
2
2
5⎩
(5)
n = 0, 1, . . .
(6)
となる。
一般の差分方程式
fn+2 = a fn+1 + b fn ,
f0 = α, f1 = β
(7)
に対しては,同様に特性方程式
λ2 − a λ − b = 0
(8)
を求め,その解 λ1 , λ2 から一般解
fn = c1 λn1 + c2 λn2
を求め,それに含まれる任意定数 c1 , c2 を初期条件にあわせて決める。ここで特性方程式 (8) が
重解 λ を持つ場合は
fn = (c1 + c2 n) λn
(9)
が一般解になる (演習問題4参照)。
演習問題
1. 式 (4) で与えられる解 (一般解) が方程式
fn+2 = fn+1 + fn
を満たすことを示せ。
2. 定数 c1 , c2 が式 (5) で与えられることを示せ。
3. 式 (4) で与えられる fn は
lim
n→∞
fn+1
= λ1
fn
を満たすことを示せ。
4. 特性方程式 (8) において,a2 + 4 b = 0 が成り立っているとき,この方程式は重解 λ = a/2
を持つ。このとき,漸化式 (7) の一般解は (9) になることを示せ。
5. 次の漸化式を初期条件のもとに解け。
(a) fn = 2 fn−1 + 1, f0 = 1
(b) fn = 2 fn−1 ,
3
2
f0 = 1
fn+1 − 12 fn ,
(c) fn = 5 fn−1 − 6 fn−2 ,
f0 = 1, f1 = 0 (d) fn+2 =
(e) fn = 6 fn−1 − 9 fn−2 ,
f0 = 1, f1 = 6 (f) fn+2 = 4 fn+1 − 4fn ,
3
f0 = 0, f1 = 1
f0 = 0, f1 = 1
6. 長さ n (n ≥ 2) のビット列で 0 が 2 つ連続して続かないものの数を fn で表す。
(a) f2 , f3 を求めよ。
(b) fn が満たす漸化式を求めよ。
(c) f5 を求めよ。
7. 長さ 1 秒の符号 A と長さ 2 秒の符号 B を用いて,AABABA· · · , BABAA· · · のような
メッセージを送りたい。 n (n ≥ 2) 秒で送れるメッセージの総数を fn で表す。
(a) f1 , f2 を求めよ。
(b) fn の満たす漸化式を求めよ。
(c) fn を n の関数で表せ。
8. 次の漸化式の解を求めよ。
fn = 6 fn−1 − 11 fn−2 + 6 fn−3 ,
f0 = 2, f1 = 5, f2 = 15
9. 漸化式 Ln+1 = Ln + Ln−1 , L0 = 1, L1 = 3 で与えられる数列 Ln は
Ln = fn+1 + fn−1
を満たすことを数学的帰納法を用いて示せ。ここで fn はフィボナッチ数である。
2
行列による解法
こんどは次の問題を考える:
現在 A 市の人口は 10,000 人で,隣の B 村の人口はたった 1,000 人である。に
もかかわらず,B 村では人口の 6 割もが毎年 A 市に流れ,逆に A 市から B 村
へ移動するのは,毎年 A 市の人口の 1 割に過ぎない。このままでは B 村は 10
年後には消滅しているのだろうか。
n 年における A 市と B 村の人口をそれぞれ an , bn とする。この二市町村以外からの流出流
入はなく,また出生死亡による変化もないとすると,翌年の人口 an+1 , bn+1 は
an+1 = 0.9 an + 0.6 bn ,
a0 = 10000
bn+1 = 0.1 an + 0.4 bn ,
b0 = 1000
(10)
で表される。この式を計算機で計算してみると, 10 年後には B 村は消滅するどころか, 50%も
増えているという意外な結果が得られた。
1: #include <stdio.h>
2: int main ()
3: {
4:
double a[11],b[11];
5:
int n;
6:
a[0]=10000;
4
7:
8:
9:
10:
11:
12:
13:
14:
15:
16: }
b[0]=1000;
for (n=0; n<10; n++) {
a[n+1]=0.9*a[n]+0.6*b[n];
b[n+1]=0.1*a[n]+0.4*b[n];
}
printf(" 年 A 市 B 村 \n");
for (n=0; n<=20; n++)
printf(" %2d %9.0f
%9.0f \n",n,a[n],b[n]);
年 A 市 B 村
0
10000
1000
1
9600
1400
2
9480
1520
3
9444
1556
4
9433
1567
5
9430
1570
6
9429
1571
7
9429
1571
8
9429
1571
9
9429
1571
10
9429
1571
式 (10) を行列とベクトルを用いて表すと
an+1
0.9 0.6
an
=
bn+1
bn
0.1 0.4
となる。この行列を A で表すと an , bn は
an
a0
= An
bn
b0
(11)
(12)
と表される。
ここで A のベキ An の計算法を考える。まず,行列 A の固有値は
λ1 = 1,
λ2 = 0.3
となる。一方これらの固有値に対応する固有ベクトルを p1 , p2 とすると
1
1
p1 = 1 ,
p2 =
−1
6
となる。したがって,行列 A は T = (p1 , p2 ) という行列によって
1 0
A=T
T −1
0 0.3
のように 対角化 (diagonalize) できる。これより
n
1
0
1
0
An = T
T −1 = T
T −1
0 0.3
0 0.3n
5
(13)
を得る。T −1 は
T −1
6
=
7
となる。以上より An を計算すると
6
A =
7
n
となり
an
bn
6
=
7
1
1
6
0.3n
6
1−0.3n
6
1+
1
−1
1 − 0.3n
1
n
6 + 0.3
n
(1 + 0.36 ) a0 + (1 − 0.3n ) b0
n
(1 − 0.36 ) a0 + ( 16 + 0.3n ) b0
(14)
(15)
を得る。n = 20 のとき 0.3n = 5.90 × 10−6 なので,これを 0 で置き換えると
a10 =
6
(a + b0 ) = 9429,
7 0
b10 =
1
(a + b0 ) = 1571
7 0
となり,数値計算結果と同じ結果が得られる。
別解
仮定より A 市と B 村の人口の和は一定だから an + bn = 11000 である。これを式 (10) の最
初の式に代入すると
an+1 = 0.9 an + 0.6 (11000 − an )
= 0.3 an + 0.6 × 11000
(16)
を得る。これを解いて
an = α + 0.3n (a0 − α)
(17)
となる。ここで α は
α = 0.3 α + 0.6 × 11000
の解である。式 (17) より limn→∞ an = α となる。α = 67 × 11000 ≈ 9429 なので,n = 10 のと
き 0.310 = 5.9 × 10−6 となり,an ≈ α = 9429 となり,前と同じ結果が得られる。
6