演習課題「黄金分割探索による高速化」
右側のコードエリアには、ある関数の最小値を求める三分探索プログラムが実装されています。
このコードを黄金分割探索に変えて、より高速に計算するプログラムを作成してみましょう。
なお、このコードでは実行時エラーのところに関数の呼び出し回数が出力されるようにしてあります。
また、この演習課題はデフォルトコードでも正解になりますが、より高速に計算するプログラムを作成した場合でも正解になるように取り組んでみてください。
期待する出力値
2.964
#04:黄金分割探索
このチャプターでは、三分探索をより高速におこなう黄金分割探索について学習します。
・ 黄金比 φ = (1 + √5) / 2 = 1.6180339887...
・ この φ を用いて、φ : 1 : φ の比率で区間を分割することを黄金分割という
・ 区間 l, r に対する左側の分割点: m1 = (l + (φ - 1) × r) / φ
・ 区間 l, r に対する右側の分割点: m2 = ((φ - 1) × l + r) / φ
・ 黄金比を用いることで、以下のように分割点を使いまわすことができる
・■□□□□□□□□□□■□□□□□□■□□□□□□□□□□□■
・↓
・■□□□□□□■□□□■□□□□□□■
・↓
・■□□□■□□■□□□■
・ l, r, m1, m2, f_m1, f_m2 を初期化
・ m1, m2 ← l と r の黄金分割点, f_m1, f_m2 ← f(m1), f(m2)
・
・ 探索範囲が小さくなるまで以下の処理を繰り返す
・
・ 1. f_m1 < f_m2 の場合
・ 1.1 右側の区間を削除する: r ← m2, m2 ← m1, f_m2 ← f_m1
・ 1.2 新しい分割点 m1 を求める: m1 ← 左分割点, f_m1 ← f(m1)
・
・ 2. f_m1 ≧ f_m2 の場合
・ 2.1 左側の区間を削除する: l ← m1, m1 ← m2, f_m1 ← f_m2
・ 2.2 新しい分割点 m2 を求める: m2 ← 右分割点, f_m2 ← f(m2)