関数の局所的な最小値と局所的な最大値をそれぞれ極小値と極大値と呼びます。微分可能な関数では、極大値をとる点で導関数(f'(x))が正から負に変化し、極小値をとる点で導関数(f'(x))が負から正に変化します。最大値や最小値は通常1つしかありませんが、極小値と極大値は複数存在する場合があります。

今回は関数の極大値・極小値を求めます。

二分探索法で極小値を求める

B – ムーアの法則

要は f(x) = x + 2^(-x / 1.5) × P の最小値を求めよという問題です。三分探索という方法もあるのですが、もっと単純に考えて普通の二分探索法で考えることもできます。

この関数のグラフを書くとこの関数は最初は減少し、そのあと増加に転ずるものであることがわかります。g(x) = f(x) – f(x + α)が正から負にかわる x の値を求めればよいのです。

相対誤差が 10^(-8) 以下であれば正答と認められるので diff = 10^(-8)、α = diff / 100 として g(x) > 0 が成立する最大のxを二分探索法で求めることにします。

では次の問題。

D – Freefall

これは f(x) = B * x + A / Math.Sqrt(1 + x) の最小値を求めよという問題ですが、前問とちがうのは x が整数であるという点です。二分探索で得た解が微妙な値の場合、切り上げ切り捨て四捨五入どれととればいいかわからないので、得られた解の周辺の整数を実際に試すことで解の正当性を確認します。

関数の極大値・極小値を求めるメソッドの定義

こんなメソッドを定義しておくと便利かもしれません。