2次計画法

モジュールのインポート

import numpy as np
import scipy as sp
from scipy.optimize import minimize

不等式制約条件がある場合

関数 $f(x,y)$ \begin{gather} f(x,y)=(x-1)^2 + (y-2.5)^2 \end{gather} を次の1次式の(不等式)制約条件のもとで最小化しよう. \begin{align} &x-2y+2 \ge 0 \\ &-x-2y+6 \ge 0 \\ &-x+2y+2 \ge 0 \\ &x \ge 0 \\ &y \ge 0 \end{align}
fun = lambda x: (x[0]-1)**2 + (x[1]-2.5)**2
cons = ({'type':'ineq', 'fun': lambda x: x[0]-2*x[1]+2},
        {'type':'ineq', 'fun': lambda x: -x[0]-2*x[1]+6},
        {'type':'ineq', 'fun': lambda x: x[0]+2*x[1]+2})
bnds = ((0,None),(0,None))
res = minimize(fun, (2,0), bounds=bnds, constraints=cons)
res
fun: 0.8000000011920985
jac: array([ 0.80000002, -1.59999999])
message: 'Optimization terminated successfully'
nfev: 10
nit: 3
njev: 3
status: 0
success: True
  x: array([1.4, 1.7])
同様にして, \begin{gather} f_2(x_1, x_2) = \frac{1}{2} (5x_1^2 + 6x_1 x_2 + 5x_2) - 95x_1 -105 x_2 \end{gather} を次の(不等式)制約条件のもとで最小化せよ. \begin{align} &-x_1 -2x_2 \ge -10 \\ &-3x_1 - x_2 \ge -15 \\ &2x_1 -3x_2 \ge -30 \\ &15x_1 - 13x_2 \ge 0 \\ &x_1 \ge 0 \\ &x_2 \ge 0 \end{align}
f1 = lambda x: (5.0*x[0]**2 + 6.0*x[0]*x[1] + 5.0*x[1])/2.0 - 95.0*x[0] - 105.0*x[1] 
cons = ({'type':'ineq', 'fun': lambda x: -x[0]-2.0*x[1]+10.0},# 制約条件
        {'type':'ineq', 'fun': lambda x: -3.0*x[0]-x[1]+15.0},
        {'type':'ineq', 'fun': lambda x: -2.0*x[0]-3*x[1]+30.0},
        {'type':'ineq', 'fun': lambda x: 15.0*x[0]-13.0*x[1]})
bnds = ((0,None),(0,None))# 変数の範囲
res1 = minimize(f1, (1,1), bounds=bnds, constraints=cons)
res1
fun: -611.4999999544007
jac: array([-66. , -90.5])
message: 'Optimization terminated successfully'
nfev: 6
nit: 2
njev: 2
status: 0
success: True
  x: array([4., 3.])

等式制約条件がある場合

\begin{gather} f_2(\boldsymbol{x}) = x_1^2 + x_2^2 + x_3^2 + x_4^2 + x_5^2 -2x_2x_3 -2x_4x_5 -2x_1 \end{gather} を次の(等式)制約条件のもとで最小化せよ. \begin{align} &x_1 + x_2 + x_3 + x_4 + x_5 =5 \\ &x_3 - 2x_4 - 2x_5 = -3 \end{align}
f2 = lambda x: x[0]**2 + x[1]**2 + x[2]**2 + x[3]**2 + x[4]**2 -2.0*x[1]*x[2] - 2.0*x[3]*x[4] - 2.0*x[0]
cons = ({'type':'eq', 'fun': lambda x: x[0]+x[1]+x[2]+x[3]+x[4]-5.0},# 制約条件
        {'type':'eq', 'fun': lambda x: x[2]-2.0*x[3]-2.0*x[4]+3.0})
res2 = minimize(f2, (0,2,2,2,0), constraints=cons)
res2
fun: -0.9999999998375628
jac: array([-1.75833702e-05, -6.37769699e-06,  6.34789467e-06,  1.72853470e-05,
  -1.73151493e-05])
message: 'Optimization terminated successfully'
nfev: 38
nit: 6
njev: 6
status: 0
success: True
  x: array([0.9999912 , 1.00000162, 1.00000479, 1.00000552, 0.99999687])