見出し画像

高校数学をプログラミングで解く(数学B編)「3-6 漸化式と数列」

マガジンリスト > 数学B編 3.数列 > 3-6 漸化式と数列


はじめに

今回は、数学Bで学ぶ「漸化式と数列」について、漸化式から一般項を求めてそれを関数化して利用するプログラムを作成します。

漸化式と一般項

まず、漸化式と一般項との関係についてまとめておきます。

① $${a_{n+1} = a_n + d \ \ \ \ \rightarrow \ \ \ \ }$$ 公差$${d}$$の等差数列
② $${a_{n+1} = ra_n \ \ \ \ \rightarrow \ \ \ \ }$$ 公比$${r}$$の等比数列
③ $${a_{n+1} = a_n + f(n) \ \ \ \ \rightarrow \ \ \ \ }$$ 数列$${\{a_n\} }$$の階差数列が$${\{f(n)\} }$$。
$${n \geq 2}$$のとき、

$$
a_n = a_1 + \sum_{k=1}^{n-1} f(k)
$$

④ $${a_{n+1} = pa_n + q \ \ (p \neq 0, p \neq 1) \ \ \ \ \rightarrow \ \ \ \ }$$ $${a_{n+1} - c = p( a_n - c ) }$$と変形。
数列$${ \{a_n-c\} }$$は初項$${a_1-c}$$、公比$${p}$$の等比数列。($${c}$$は$${c=pc+q}$$を満たす数)

階差数列をもつ数列の漸化式と一般項

まず、階差数列をもつ数列の漸化式から一般項を求めて、関数にする問題を考えてみます。

問題1
次の条件によって定められる数列$${\{a_n\}}$$の一般項を求めて関数化し、第10項までの値をコンソールに出力せよ。
(1) $${a_1=1, a_{n+1}-a_{n} = 4n }$$
(2) $${a_1=1, a_{n+1}-a_n = 4^n }$$

解析的な解答

(1)の問題の階差数列は等差数列になります。一般に階差数列が初項$${a}$$、公差$${d}$$の等差数列となる場合、$${n \geq 2}$$で、

$$
a_n = a_1 + \sum_{k=1}^{n-1} (a + (k-1)d) = a_1 + \frac{1}{2} (n-1) \{ 2a + (n-2) d \}
$$

となります。これは、$${n=1}$$のときも成り立ちます。
このことから、(1)の問題の階差数列は初項$${4}$$、公差$${4}$$の等差数列となるので、

$$
a_n = 1+2n(n-1)
$$

 となります。
次に、(2)の問題の階差数列は等比数列になります。一般に階差数列が初項$${a}$$、公比$${r}$$の等比数列となる場合、$${n \geq 2}$$で、

$$
a_n = a_1 + \sum_{k=1}^{n-1} ar^{k-1} = a_1+ a \frac{r^{n-1}-1}{r-1}
$$

となります。これは、$${n=1}$$のときも成り立ちます。
このことから、(2)の問題の階差数列は初項$${4}$$、公比$${4}$$の等比数列となるので、

$$
a_n = 1+\frac{4}{3} (4^{n-1}-1) = \frac{1}{3} (4^n-1)
$$

 となります。

プログラムの作成(1)

では、まず(1)に関するプログラムを作成します。

// 階差数列が等差数列となる数列の問題
void setup(){

  int n = 10; // 項数

  float a1 = 1.0; // 数列の初項
  float a = 4.0; // 階差数列の初項
  float d = 4.0; // 階差数列の公差
  
  for(int k=1; k<=n; k++){
    println("第"+k+"項:", difference_progression_arithmetical(a1,a,d,k));
  }
}

// 初項a,公差d,項数nの等差数列の和を求める関数
float sum_arithmetical_progression(
  float a, // 初項
  float d, // 公差
  int n // 項数
){
  return n * (2.0*a + (n-1.0)*d) / 2.0;
}

// 階差数列が初項a、公差dの等差数列となる数列の一般項
float difference_progression_arithmetical(
  float a1, // 初項
  float a, // 階差数列の初項
  float d, // 階差数列の公差
  int n // 第n項
){
  return a1 + sum_arithmetical_progression(a,d,n-1);
}

ソースコード1 階差数列が等差数列となる場合(問題1(1))のプログラム

解析的な解答で見たように、階差数列が等差数列となる場合の数列の一般項$${a_n}$$の第2項は、等差数列の初項から第$${n-1}$$項までの和となっています。等差数列の和は、記事『高校数学をプログラミングで解く(数学B編)「3-2 等差数列の和」』で解説していて、このとき作成した sum_arithmetical_progression 関数を再利用しています。そして、この関数を利用して、階差数列が等差数列となる場合の数列の一般項$${a_n}$$を関数 difference_progression_arithmetical として作成しています。difference_progression_arithmetical 関数は引数として、
a1:初項 float型
a:階差数列の初項 float型
d:階差数列の公差 float型
n:第$${n}$$項 int型
を取ります。返り値は階差数列が等差数列となる場合の数列の一般項$${a_n}$$の値を返します。

ソースコード1を、Processingの開発環境ウィンドウを開いて(スケッチ名を「difference_progression_arithmetical_case」としています)、テキストエディタ部分に書いて実行すると、開発環境ウィンドウのコンソール部分に

第1項: 1.0
第2項: 5.0
第3項: 13.0
第4項: 25.0
第5項: 41.0
第6項: 61.0
第7項: 85.0
第8項: 113.0
第9項: 145.0
第10項: 181.0

と出力されます(図1)。

図1 スケッチ「difference_progression_arithmetical_case」の実行結果

プログラムの作成(2)

次に(2)に関するプログラムを作成します。

// 階差数列が等比数列となる数列の問題
void setup(){

  int n = 10; // 項数

  float a1 = 1.0; // 数列の初項
  float a = 4.0; // 階差数列の初項
  float r = 4.0; // 階差数列の公比
  
  for(int k=1; k<=n; k++){
    println("第"+k+"項:", difference_progression_geometrical(a1,a,r,k));
  }
}

// 初項a,公比r,項数nの等比数列の和を求める関数
float sum_geometrical_progression(
  float a, // 初項
  float r, // 公比
  int n // 項数
){
  return a * (pow(r,n)-1.0)/(r-1.0); 
}

// 階差数列が初項a、公比rの等比数列となる数列の一般項
float difference_progression_geometrical(
  float a1, // 初項
  float a, // 階差数列の初項
  float r, // 階差数列の公比
  int n // 第n項
){
  return a1 + sum_geometrical_progression(a,r,n-1);
}

ソースコード2 階差数列が等比数列となる場合(問題1(2))のプログラム

こちらも解析的な解答で見たように、階差数列が等比数列となる場合の数列の一般項$${a_n}$$の第2項は、等比数列の初項から第$${n-1}$$項までの和となっています。等比数列の和は、記事『高校数学をプログラミングで解く(数学B編)「3-3 等比数列とその和」』で解説していて、このとき作成した sum_geometrical_progression 関数を再利用しています。そして、この関数を利用して、階差数列が等比数列となる場合の数列の一般項$${a_n}$$を関数 difference_progression_geometrical として作成しています。difference_progression_geometrical 関数は引数として、
a1:初項 float型
a:階差数列の初項 float型
r:階差数列の公比 float型
n:第$${n}$$項 int型
を取ります。返り値は階差数列が等比数列となる場合の数列の一般項$${a_n}$$の値を返します。

ソースコード2を、Processingの開発環境ウィンドウを開いて(スケッチ名を「difference_progression_geometrical_case」としています)、テキストエディタ部分に書いて実行すると、開発環境ウィンドウのコンソール部分に

第1項: 1.0
第2項: 5.0
第3項: 21.0
第4項: 85.0
第5項: 341.0
第6項: 1365.0
第7項: 5461.0
第8項: 21845.0
第9項: 87381.0
第10項: 349525.0

と出力されます(図2)。

図2 スケッチ「difference_progression_geometrical_case」の実行結果

漸化式が④のタイプの数列と一般項

今度は、漸化式が④のタイプの数列の一般項を求めて、関数にする問題を考えてみます。

問題2
条件$${a_1=1, a_{n+1}=2a_{n}-3}$$によって定められる数列$${\{a_n\}}$$の一般項を求めて関数化し、第10項までの値をコンソールに出力せよ。

解析的な解答

より一般的な形$${a_{n+1} = pa_n + q \ \ (p \neq 0, p \neq 1)}$$で考えます。漸化式と一般項④で説明されているように、

$$
c=\frac{q}{1-p}
$$

とすると、問題2の一般項は

$$
a_n = c + (a_1-c)p^{n-1}
$$

となります。
このことから、問題2では、$${p=2, q=-3}$$なので、

$$
c = 3, \ \ a_n = 3-2^n
$$

となります。

プログラムの作成

では、問題2に関するプログラムを作成します。

// 漸化式と一般項④のタイプの数列の問題
void setup(){

  int n = 10; // 項数

  float a1 = 1.0; // 数列の初項
  float p = 2.0; // 漸化式の係数p
  float q = -3.0; // 漸化式の係数q
  
  for(int k=1; k<=n; k++){
    println("第"+k+"項:", recursion_formula_type4(a1,p,q,k));
  }
}

// 初項a,公比dの等比数列の第n項を求める関数(一般項)
float calc_geometrical_progression(
  float a, // 初項
  float r, // 公比
  int n // 第n項
){
  return a * pow(r,n-1);
}

// 漸化式と一般項④のタイプの数列の一般項
float recursion_formula_type4(
  float a1, // 初項
  float p, // 漸化式の係数p
  float q, // 漸化式の係数q
  int n // 第n項
){
  float c = q/(1.0-p);
  return c + calc_geometrical_progression(a1-c,p,n);
}

ソースコード3 漸化式と一般項が④のタイプになる数列のプログラム

解析的な解答で見たように、漸化式と一般項が④のタイプになる数列の一般項$${a_n}$$の第2項は、等比数列となっています。等比数列は、記事『高校数学をプログラミングで解く(数学B編)「3-3 等比数列とその和」』で解説していて、このとき作成した calc_geometrical_progression 関数を再利用しています。そして、この関数を利用して、漸化式と一般項が④のタイプになる数列の一般項$${a_n}$$を関数 recursion_formula_type4 として作成しています。recursion_formula_type4 関数は引数として、
a1:初項 float型
p:漸化式の係数p float型
q:漸化式の係数q float型
n:第$${n}$$項 int型
を取ります。返り値は漸化式と一般項が④のタイプになる数列の一般項$${a_n}$$の値を返します。

ソースコード3を、Processingの開発環境ウィンドウを開いて(スケッチ名を「solve_recursion_formula_type4」としています)、テキストエディタ部分に書いて実行すると、開発環境ウィンドウのコンソール部分に

第1項: 1.0
第2項: -1.0
第3項: -5.0
第4項: -13.0
第5項: -29.0
第6項: -61.0
第7項: -125.0
第8項: -253.0
第9項: -509.0
第10項: -1021.0

と出力されます(図3)。

図3 スケッチ「solve_recursion_formula_type4」の実行結果

まとめ

今回は、数学Bで学ぶ「漸化式と数列」について、漸化式から一般項を求めてそれを関数化して利用するプログラムを作成しました。
最初は階差数列が等差数列になる場合と等比数列になる場合のプログラムを作成し、次に漸化式が$${a_{n+1}=pa_n+q}$$の形(タイプ④)を持つ場合のプログラムを作成しました。
いずれの問題も等差数列や等比数列の一般項や和に帰着することができますので、以前作成した一般項や和の関数を再利用して新たな数列の関数を作成しました。プログラミングでは今回のように関数を再利用すると、便利なことが多いので、このような利用の仕方に慣れていってください。
また、関数化する際、例えば問題2では$${a_n = 3-2^n}$$を関数化するのではなく、$${a_n = c + (a_1-c)p^{n-1}}$$というより一般的な形で関数化を行いました。このように、問題に特化した形ではなく、$${p}$$や$${q}$$の値が変わっても利用できるようにしておくことはプログラミングをする際に大事になってきます。このような考え方にも少しずつ慣れていってください。

参考文献

改訂版 教科書傍用 スタンダード 数学B(数研出版、ISBN9784410209468)


この記事が気に入ったらサポートをしてみませんか?