PDFOPowell 無導(dǎo)數(shù)優(yōu)化求解器
PDFO(Powell's Derivative-Free Optimization solvers,Powell 無導(dǎo)數(shù)優(yōu)化求解器)為 Michael J. D. Powell 的無導(dǎo)數(shù)優(yōu)化求解器提供跨平臺(tái)的調(diào)用接口。這些求解器包括 COBYLA,UOBYQA,NEWUOA,BOBYQA,LINCOA,最初由 M. J. D.Powell 采用 Fortran 77 實(shí)現(xiàn)。它們可求解黑箱優(yōu)化,用于機(jī)器學(xué)習(xí)超參數(shù)調(diào)節(jié)。
Powell 的求解器旨在僅使用函數(shù)值而不使用目標(biāo)函數(shù)或非線性約束函數(shù)的導(dǎo)數(shù)來求解連續(xù)變量的一般非線性優(yōu)化問題 。實(shí)際應(yīng)用中,此類函數(shù)通常是基于仿真模擬的黑箱。因此,相應(yīng)的優(yōu)化問題通常被歸類為黑盒優(yōu)化或基于仿真模擬的優(yōu)化 。 UOBYQA 和 NEWUOA 可求解無約束問題,除了相當(dāng)小的問題外, NEWUOA 通常表現(xiàn)更好;BOBYQA 可求解無約束和界約束問題;LINCOA 可求解決無約束、界約束和線性約束問題;COBYLA 可求解一般的非線性優(yōu)化問題。由顯式公式定義的問題往往可以用其他方法更有效地處理。
PDFO 當(dāng)前的版本支持 MATLAB 和 Python 。 它依賴 MEX 和 F2PY 來編譯 Powell 的 Fortran 代碼,并將其封裝為用戶友好的函數(shù)。MATLAB 或 Python 用戶可在直接調(diào)用 Powell 的求解器而無需了解其 Fortran 實(shí)現(xiàn)。
Hans D. Mittelmann 的優(yōu)化軟件決策樹收錄了 PDFO,建議將其用于“只用函數(shù)值求解一般非線性問題”。 這里,“一般非線性問題”包括無約、界約束,線性約束和非線性約束問題。
更多信息請(qǐng)?jiān)L問 PDFO 主頁 (https://pdfo.net)。
安裝
PDFO 的 Python 版本可通過 pip 安裝:
pip install pdfo
MATLAB 版本可從碼云 (https://gitee.com/pdfo/pdfo) 或 PDFO 主頁 (https://pdfo.net) 下載源代碼,用其中提供的 setup 腳本安裝。
代碼示例
Python
from pdfo import pdfo, Bounds, LinearConstraint, NonlinearConstraint
# If SciPy (version 1.1 or above) is installed, then Bounds, LinearConstraint,
# and NonlinearConstraint can alternatively be imported from scipy.optimize.
import numpy as np
def chrosen(x): # the subroutine defining the objective function
return sum((1 - x[:-1]) ** 2 + 4 * (x[1:] - x[:-1] ** 2) ** 2)
def nlc_ineq(x): # the subroutine defining the nonlinear inequality constraints
return x[:-1] ** 2 - x[1:]
def nlc_eq(x): # the subroutine defining the nonlinear equality constraints
return sum(x ** 2) - 1
if __name__ == '__main__':
print('\nMinimize the chained Rosenbrock function with three variables subject to nonlinear constraints:\n')
x0 = [0, 0, 0] # starting point
lb = [0, 0, 0]
ub = [np.inf, np.inf, np.inf] # ub = [None, None, None] or ub = None works equally well
bounds = Bounds(lb, ub) # bound constraints: lb <= x <= ub
# Bound constraints can also be written as: bounds = [(lb[0], ub[0]), (lb[1], ub[1]), (lb[2], ub[2])]
A = [[0.5, -1, 0], [0, 0.5, -1]]
lin_lb = [-np.inf, -np.inf]
lin_ub = [0, 0]
lin_con = LinearConstraint(A, lin_lb, lin_ub) # inequality constraints: lin_lb <= A*x <= lin_ub
nonlin_lb = [0, 0]
nonlin_ub = [np.inf, np.inf]
nonlin_con_ineq = NonlinearConstraint(nlc_ineq, nonlin_lb, nonlin_ub) # inequality constraints: nonlin_lb <= nlc_ineq(x) <= nonlin_ub
nonlin_con_eq = NonlinearConstraint(nlc_eq, 0, 0) # equality constraint: nlc_eq(x) = 0
# Nonlinear constraints can also be defined as dictionaries:
#nonlin_con_ineq = {'type': 'ineq', 'fun': nlc_ineq} # inequality constraint: nlc_ineq(x) >= 0
#nonlin_con_eq = {'type': 'eq', 'fun': nlc_eq} # inequality constraint: nlc_eq(x) = 0
res = pdfo(chrosen, x0, bounds=bounds, constraints=[lin_con, nonlin_con_ineq, nonlin_con_eq])
print(res)
MATLAB
function rosenbrock_example()
fprintf('\nMinimize the chained Rosenbrock function with three variables subject to nonlinear constraints:\n');
x0 = [0; 0; 0]; % starting point
% linear inequality constraints A*x <= b
A = [0.5, -1, 0; 0, 0.5, -1];
b = [0; 0];
% linear equality constraints Aeq*x = beq
Aeq = [];
beq = [];
% bound constraints lb <= x <= ub
lb = [0; 0; 0];
ub = []; % ub = [inf; inf; inf] works equally well
% nonlinear constraints
nonlcon = @nlc; % see function nlc given below
% The following syntax is identical to fmincon:
[x, fx, exitflag, output] = pdfo(@chrosen, x0, A, b, Aeq, beq, lb, ub, nonlcon)
% Alternatively, the problem can be passed to pdfo as a structure:
%p.objective = @chrosen; p.x0 = x0; p.Aineq = A; p.bineq = b; p.lb = lb; p.nonlcon = @nlc;
%[x, fx, exitflag, output] = pdfo(p)
return
function f = chrosen(x) % the subroutine defining the objective function
f = sum((x(1:end-1)-1).^2 + 4*(x(2:end)-x(1:end-1).^2).^2);
return
function [cineq, ceq] = nlc(x) % the subroutine defining the nonlinear constraints
% The same as fmincon, nonlinear constraints cineq(x) <= 0 and ceq(x) = 0 are specified
% by a function with two returns, the first being cineq and the second being ceq.
cineq = x(2:end) - x(1:end-1).^2;
ceq = x'*x - 1;
return
