PDFO(Powell's Derivative-Free Optimization solvers,Powell 无导数优化求解器)为 Michael J. D. Powell 的无导数优化求解器提供跨平台的调用接口。这些求解器包括 COBYLA,UOBYQA,NEWUOA,BOBYQA,LINCOA,最初由 M. J. D.Powell 采用 Fortran 77 实现。它们可求解黑箱优化,用于机器学习超参数调节。
Powell 的求解器旨在仅使用函数值而不使用目标函数或非线性约束函数的导数来求解连续变量的一般非线性优化问题 。实际应用中,此类函数通常是基于仿真模拟的黑箱。因此,相应的优化问题通常被归类为黑盒优化或基于仿真模拟的优化 。 UOBYQA 和 NEWUOA 可求解无约束问题,除了相当小的问题外, NEWUOA 通常表现更好;BOBYQA 可求解无约束和界约束问题;LINCOA 可求解决无约束、界约束和线性约束问题;COBYLA 可求解一般的非线性优化问题。由显式公式定义的问题往往可以用其他方法更有效地处理。
PDFO 当前的版本支持 MATLAB 和 Python 。 它依赖 MEX 和 F2PY 来编译 Powell 的 Fortran 代码,并将其封装为用户友好的函数。MATLAB 或 Python 用户可在直接调用 Powell 的求解器而无需了解其 Fortran 实现。
Hans D. Mittelmann 的优化软件决策树收录了 PDFO,建议将其用于“只用函数值求解一般非线性问题”。 这里,“一般非线性问题”包括无约、界约束,线性约束和非线性约束问题。
安装
PDFO 的 Python 版本可通过 pip 安装:
pip install pdfo
代码示例
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