単目的関数に対する設計変数の最適化
次のステップとして、単一目的関数に対する設計変数(今回は2つ)の最適化を行ってみる。単一目的関数は前回と同様にpythonで実施し、以下のようなBeale's functionとする。
minimize f(x1,x2)=(1.5-x1+x1*x2)^2+(2.25-x1+x1*x2^2)^2+(2.625-x1+x1*x2^3)^2
subject to |x1|<=4.5, |x2|<=4.5
(Ref.) Test functions for optimization - Wikipedia, the free encyclopedia
dakota.inは以下の通り。最適化手法として制約条件付CG法(comin_frcg)を用い、勾配計算にはnumerical_gradient(差分法)を利用する。
注意点として、responcesの部分では、"response_fucntions"ではなく、"objective_functions"として指定する必要がある。
# Dakota Input File: dakota.in
# Usage:
# dakota -i dakota.in -o dakota.out > dakota.stdout
environment
graphics
tabular_graphics_data
tabular_graphics_file = 'objective.dat'
method
conmin_frcg
# conmin_mfd
max_iterations = 100
convergence_tolerance = 1e-4
model
single
variables
continuous_design = 2
initial_point 1.0 1.0
lower_bounds -4.5 -4.5
upper_bounds 4.5 4.5
descriptors 'x1' "x2"
interface
fork
analysis_driver = 'simulator_script'
parameters_file = 'params.in'
results_file = 'results.out'
work_directory directory_tag
copy_files = 'templatedir/*'
named 'workdir' file_save directory_save
aprepro
responses
objective_functions = 1
# no_gradients
# analytic_gradients
numerical_gradients
method_source dakota
interval_type forward
fd_gradient_step_size = 1.e-4
no_hessians
最適化の結果は、以下の通りとなり、解析値 f(3, 0.5)=0 をほぼ見出している。
FINAL OPTIMIZATION INFORMATION
OBJ = 0.206091E-06
DECISION VARIABLES (X-VECTOR)
1) 0.29989E+01 0.49972E+00
THERE ARE 0 ACTIVE SIDE CONSTRAINTS
TERMINATION CRITERION
ABS(OBJ(I)-OBJ(I-1)) LESS THAN DABFUN FOR 3 ITERATIONS
NUMBER OF ITERATIONS = 15
OBJECTIVE FUNCTION WAS EVALUATED 46 TIMES
GRADIENT OF OBJECTIVE WAS CALCULATED 15 TIMES
これまでは制約条件(constraints)が無かったが追加してみる。Dakotaでは、
以下の2通りの制約条件関数を指定できる。
- nonlinear_inequality_constraints gmin<=g(x1,x2)<=gmaxのような大小関係の高速関数
- nonlinear_equality_constraints g(x1,x2)=g0のような形の拘束関数
以上の制限関数は、g(x)<0もしくはg(x)=0の形に帰着するので、以下の通りに正弦関数を1つ追加してみる。
minimize f(x1,x2)=(1.5-x1+x1*x2)^2+(2.25-x1+x1*x2^2)^2+(2.625-x1+x1*x2^3)^2
subject to g(x1,x2)=x1^2-x2<=0,
|x1|<=4.5, |x2|<=4.5
<objective.py>
#!/bin/python
from sys import argv
from math import *
import numpy as np
def f(x1, x2):
return (1.5-x1+x1*x2)**2+(2.25-x1+x1*x2**2)**2+(2.625-x1+x1*x2**3)**2
def c(x1, x2):
return x1**2-x2
if __name__ == '__main__':
x1 = float(argv[1])
x2 = float(argv[2])
print f(x1,x2)
print c(x1,x2)
<dakota.in>
[snip]
responses
objective_functions = 1
nonlinear_inequality_constraints = 1
upper_bounds 0
[snip]
実行結果
FINAL OPTIMIZATION INFORMATION
OBJ = 0.827842E+01
DECISION VARIABLES (X-VECTOR)
1) 0.68224E+00 0.46544E+00
CONSTRAINT VALUES (G-VECTOR)
1) 0.43735E-05
THERE ARE 1 ACTIVE CONSTRAINTS
CONSTRAINT NUMBERS ARE
1
THERE ARE 0 VIOLATED CONSTRAINTS
THERE ARE 0 ACTIVE SIDE CONSTRAINTS
TERMINATION CRITERION
ABS(1-OBJ(I-1)/OBJ(I)) LESS THAN DELFUN FOR 3 ITERATIONS
ABS(OBJ(I)-OBJ(I-1)) LESS THAN DABFUN FOR 3 ITERATIONS
NUMBER OF ITERATIONS = 11
OBJECTIVE FUNCTION WAS EVALUATED 34 TIMES
CONSTRAINT FUNCTIONS WERE EVALUATED 34 TIMES
GRADIENT OF OBJECTIVE WAS CALCULATED 11 TIMES
GRADIENTS OF CONSTRAINTS WERE CALCULATED 11 TIMES
※ 制約条件を微妙に満たしていない結果となったが、これは数値計算上の誤差のためと思われる。method/convergence_tolerance = 1e-4などを調整してみると良い。