[VBA] 関数の最大値を判定するマクロ

[VB-06] 関数の最大値の判定

(1) 関数 f(n) = an2 + bn + c (a, b, c は実数) において、n が整数値 -s, ..., 0, 1, 2, ... s をとるとき、f(n) を最大にする n と、そのときの f(n) の値を返す Functionプロシージャ(ユーザー定義関数)を作成してください。この関数の名前は NQuad とし、a, b, c, s は引数で指定するものとします。

(2) f(n) = -n2 + 15n + 6 において、n が整数値 -10, ..., 0, 1, 2, ... 10 をとるとき、f(n) を最大にする n と、そのときの f(n) の値を求めてください。
 

VB-06 のヒント(異なる型の変数をセットにします)

 NQuad関数は 2 つの値を返さなくてはなりませんし、f(n) を最大にする n は Long あるいは Integer, 最大値のほうは Double で宣言する必要があります。このように異なる型の複数のデータをまとめて扱うときにはユーザー定義型変数(構造体)を用います。構造体については Excel VBA 言葉の工房あとりえこばと に詳しい説明があるので参照してください。
 

VB-06 の解答

(1) 宣言セクションで Typeステートメントを使って、f(n) が最大となる変数を入れる nmax を Long型で、最大値を入れる変数 fmax を Double型で宣言しておきます。NQuad関数は次のようなアルゴリズムで作成します。

[1] n = 0 の 1 点だけを考えると、最大値をとる n は nm = 0 であり、最大値は fm = f(0) = c となります。

[2] k = -s とします。f(-s) が f(0) より大きければ nm を -s に、fm を f(-s) で置き換えます。そうでなければ nm, fm はそのまま据え置きます。k に 1 を加えます。

[3] k = -s とします。f(-s + 1) が f(-s) より大きければ nm を -s + 1 に、fm を f(-s + 1) で置き換えます。そうでなければ nm, fm はそのまま据え置きます。k に 1 を加えます。

[4] [2] と [3] を k = s になるまで繰り返します。

[5] NQuad.nmax に nm を、NQuad.fmax に fm を入れます。
 
VB-06 の解答コード

'最大値をとる n と、最大値 f(n) を格納する変数
Type Maxdata
 nmax As Long
 fmax As Double
End Type

'f(n) = an2 + bn + c の最大値をとる n と、最大値 f(n) を求める関数
Function NQuad(a As Double, b As Double, c As Double, s As Long) As Maxdata

Dim k As Long
Dim nm As Long
Dim fm As Double
Dim func As Double

'f(n) が最大となる n の初期値
nm = 0

'最大値 f(m) の初期値
fm = c

For k = -s To s

 func = a * k ^ 2 + b * k + c

 'func が fm より大きければ
 If func > fm Then

  'f(n) が最大値となる n を置き換える
  nm = k

  '最大値 f(m) を置き換える
  fm = func

 End If

Next k

NQuad.nmax = nm
NQuad.fmax = fm

End Function

 
(2) NQuad関数の引数に、a = -1, b = 15, c = 6, s = 10 を入れて呼び出します。

Sub NQuadTest()

 Debug.Print "nmax = " & NQuad(-1, 15, 6, 10).nmax
 Debug.Print "f(nmax) = " & NQuad(-1, 15, 6, 10).fmax

End Sub

 このマクロを実行すると、

 nmax = 7
 f(nmax) = 62

という結果が表示されます。

スポンサーリンク
スポンサーリンク
末尾広告
末尾広告

コメントをどうぞ

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください