ラグランジュの未定乗数法をpythonで実装する

最近「これならわかる最適化数学基礎原理から計算手法まで」を購入し、読み進めています。今回はラグランジュの未定乗数法の例題をpythonで実装してみようと思います。

ラグランジュ未定乗数法を簡単にまとめる以下の通りです。

定理:ラグランジュの未定乗数法

制約条件  g(x_1, ... , x_n)=0 のもとで関数 f(x_1, ... , x_n) が極致をとる点は

 F(x_1, ... , x_n, λ)=f(x_1, ... , x_n)- λg(x_1, ..., x_n)

と置くと、次の式を満たす

 \frac{∂F}{∂x_i}=0 ,  \  i=1, ..., n , \    \frac{∂F}{∂λ}=0

上の定理を用いて例題を解いてみます。

制約条件が1つの場合

  • 制約条件が $x+y+z=1$ のもとでの関数 $f(x,y,z)=xy^2z^3$ の極致を求めよ p.67

上の定理を用いると、制約条件を  g(x, y, z) = x+y+z-1 = 0 として、

 F(x, y, z, λ) = xy^2z^3 -λ(x+y+z-1)

と置くことができます。

ここで一度、関数fと、関数g、関数Fを実装しておきます。
pythonのsympyライブラリを使用して微分を計算します。

from sympy import diff, symbols, solve

# 変数を定義
x, y, z, l = symbols("x y z l")

# 関数fを定義
f = x * y**2 * z**3

# 制約条件gを定義
g = x + y + z - 1

各変数に関して偏微分してその結果を0と置くと

 \frac{∂F}{∂x} = y^2z^3 - λ=0
 \frac{∂F}{∂y}=2xyz^3-λ=0
 \frac{∂F}{∂z}=3xy^2z^2-λ=0
 \frac{∂F}{∂λ}=-x-y-z+1=0

となります。
この偏微分の部分は、pythonのコードで書くと、

# 定理式に代入
theor = f - l * g

# 各変数で偏微分する
diffx = diff(theor, x)
diffy = diff(theor, y)
diffz = diff(theor, z)
diffl = diff(theor, l)

res = solve([diffx, diffy, diffz, diffl])

この連立方程式を解くことで極値をとるときのx, y, zの値がわかります。

上の連立方程式を解くと、 x=\frac{1}{6} , \ \ \ y = \frac{1}{3}  ,  \ \ \  z = \frac{1}{2}

となります。この時の関数fの値は、 (\frac{1}{6}) * (\frac{1}{3})^2 * (\frac{1}{2})^3 = \frac{1}{432} となる。

pythonコード全体は以下の通りです。

from sympy import diff, symbols, solve

# 変数を定義
x, y, z, l = symbols("x y z l")

# 関数fを定義
f = x * y**2 * z**3

# 制約条件gを定義
g = x + y + z - 1

# 定理式に代入
theor = f - l * g

# 各変数で偏微分する
diffx = diff(theor, x)
diffy = diff(theor, y)
diffz = diff(theor, z)
diffl = diff(theor, l)

# 連立方程式を解く
res = solve([diffx, diffy, diffz, diffl])