[英]Quadratic Programming in python using data from octave
我正在将 MATLAB 程序的一部分转换为 Python 和 Octave。
我使用 Octave 生成两个矩阵,然后使用oct2py
将这些矩阵导入到 python 中。 我的问题的根源是 MATLAB 中的这些行(下面的H_combined
和f_combined
)
handles.options =optimset('algorithm','interior-point-convex','Display','off','TolFun',1e-15,'TolX',1e-10,'MaxFunEvals', 1E5);
handles.x_ridge_combined = quadprog(H_combined, f_combined, [], [], [], [], handles.lb_re, handles.ub_re, handles.x_re_0, handles.options);
目前,我正在寻找 Python 或 Octave 中的解决方案,该解决方案会产生类似的输出但无济于事。
我曾尝试使用 Octave 的optim
quadprog
,但是我在quadprog
得到了120, 1, 1, 1, ..., 1
的x_ridge_combined
,而不是我期望的各种浮点值。 我已经验证H_combined
和f_combined
与在 MATLAB 中运行时的完全相同,但我认为 Octave 中的quadprog
无法正常工作。
在尝试 Octave 方法后,我尝试将值导入 Python 以尝试使用quadprog
包。
尝试quadprog
,
print(quadprog.solve_qp(H,f))
产生错误
ValueError: Buffer has wrong number of dimensions (expected 1, got 2)
H
和f
的类型和形状如下:
<class 'numpy.ndarray'> #H
(123, 123)
<class 'numpy.ndarray'> #f
(1, 123)
有谁知道为什么我可能会收到这些错误? 或者关于如何从 MATLAB 翻译该行的任何其他建议?
尝试使用cvxopt_quadprog 。 作者声称它模仿了 MATLAB quadprog
,并且它应该以相同的方式接受参数:
def quadprog(H, f, L=None, k=None, Aeq=None, beq=None, lb=None, ub=None):
"""
Input: Numpy arrays, the format follows MATLAB quadprog function: https://www.mathworks.com/help/optim/ug/quadprog.html
Output: Numpy array of the solution
"""
最有可能的错误是因为您的f
是矩阵 [1x123],而它应该是长度为 [123] 的向量。 你可以尝试重塑它:
f = f.reshape(f.shape[1])
是的,尽管 cvxopt_quadprog 的问题在于它对于时间序列的大型迭代优化要慢得多,因为它每次都会检查问题是否是 PSD,这就是为什么我希望使用 quad_prog,这已被证明是很多快点。 参考: https : //github.com/stephane-caron/qpsolvers
虽然有点超出范围,但我想让NLopt项目发挥作用。 正如首字母缩略词所暗示的那样,它处理非线性优化,但有大量全局/局部、无导数/显式导数算法。 我之所以要提及它的原因是,它有一个用于 MATLAB、Octave + Python(和 C/C++,...)的接口。 所以它可以很容易地以不同的语言重现解决方案(这就是我遇到它的原因); 此外,这些算法实际上比 MATLAB 原生算法要快(这是我自己的经验)。
对于您的问题,我会选择BOBYQA (二次优化或SLSQP (顺序最小二乘二次规划)的有界优化)。但是,您必须编写成本函数而不是交出矩阵
pip install nlopt
做一个小检查
import nlopt
# run quick test. Look for "Passed: optimizer interface test"
nlopt.test.test_nlopt()
关于如何使用优化的一些快速代码:
import numpy as np
import nlopt
obj = nlopt.opt(nlopt.LN_BOBYQA,5)
obj.set_min_objective(fnc)
obj.set_lower_bounds(lb)
obj.set_upper_bounds(ub)
def fnc(x, grad):
"""
The return value should be the value of the function at the point x,
where x is a NumPy array of length n of the optimization parameters
(the same as the dimension passed to the constructor).
In addition, if the argument grad is not empty, i.e. grad.size>0, then
grad is a NumPy array of length n which should (upon return) be set to
the gradient of the function with respect to the optimization parameters
at x. That is, grad[i] should upon return contain the partial derivative ,
for , if grad is non-empty.
"""
H = np.eye(len(x)) # extampe matrix
cost = 0.5*x.transpose().dot( H.dot(x) )
return float(cost) # make sure it is a number
xopt = obj.optimize(x0)
在 MATLAB 中,您只需要将 DLL 添加到您的路径中。 我为 BOBYQA 编写了一个简短的包装器来模仿 MATLAB 的界面(以防万一,你想用两种语言检查它=P——让我知道,我在 MATLAB 中更频繁地使用它......正如包装器可能显示的那样^^):
function [x_opt, fval, exitflag] = BOBYQA(fnc,x0,lb,ub, varargin)
% performes a constrained, derivative-free local optimization
%
% --- Syntax:
% x_opt = BOBYQA(fnc,x0,lb,ub)
% x_opt = BOBYQA(...,'MaxEval',10)
% x_opt = BOBYQA(...,'MaxTime',5)
% [x_opt, fval] = BOBYQA(...)
% [x_opt, fval, exitflag] = BOBYQA(...)
%
% --- Description:
% x_opt = BOBYQA(fnc,x0,lb,ub) takes a function handle 'func', an initial
% value 'x0' and lower and upper boundary constraints 'lb'
% and 'ub' as input. Performes a constrained local
% optimization using the algorithm BOBYQA from Powell
% http://www.damtp.cam.ac.uk/user/na/NA_papers/NA2009_06.pdf.
% Returns the optimal value 'x_opt'.
% x_opt = BOBYQA(...,'MaxEval',10)optional input parameter that defines the
% maximum number of evaluations.
% x_opt = BOBYQA(...,'MaxTime',5) optional input parameter that defines the
% maximum allowed time in seconds for the optimization. This
% is a soft constraint and may be (slightly) broken.
% [x_opt, fval] = BOBYQA(...) seconds return value is the optimal function
% value.
% [x_opt, fval, exitflag] = BOBYQA(...) third return value is the exitflag,
% see function NLoptExitFlag().
%
% ------------------------------------------------------------------- 2017
% NLOPT_LN_BOBYQA
% --- parse input
IN = inputParser;
addParameter(IN,'MaxEval',10000, @(x)validateattributes(x,{'numeric'},{'positive'}));
addParameter(IN,'MaxTime',60, @(x)validateattributes(x,{'numeric'},{'positive'}));
parse(IN,varargin{:});
% generic success code: +1
% stopval reached: +2
% ftol reached: +3
% xtol reached: +4
% maxeval reached: +5
% maxtime reached: +6
% generic failure code: -1
% invalid arguments: -2
% out of memory: -3
% roundoff-limited: -4
% set options
opt = struct();
opt.min_objective = fnc;
opt.lower_bounds = lb;
opt.upper_bounds = ub;
% stopping criteria
opt.maxtime = IN.Results.MaxTime; % s % status = +6
% opt.fc_tol = FncOpt.STOP_FNC_TOL*ones(size(ParInit)); % +3
% opt.xtol_rel = FncOpt.STOP_XTOL_REL; % +4
% opt.xtol_abs = FncOpt.STOP_XTOL_ABS*ones(size(ParInit)); % +4
opt.maxeval = IN.Results.MaxEval; % status = +5
% call function
opt.algorithm = 34;% eval('NLOPT_LN_BOBYQA');
t_start = tic;
[x_opt, fval, exitflag] = nlopt_optimize(opt,x0);
dt = toc(t_start);
fprintf('BOBYQA took %.5f seconds | exitflag: %d (%s)\n',dt,exitflag,NLoptExitFlag(exitflag))
end
function txt = NLoptExitFlag(exitflag)
% generic success code: +1
% stopval reached: +2
% ftol reached: +3
% xtol reached: +4
% maxeval reached: +5
% maxtime reached: +6
% generic failure code: -1
% invalid arguments: -2
% out of memory: -3
% roundoff-limited: -4
switch exitflag
case 1
txt = 'generic success code';
case 2
txt = 'stopval reached';
case 3
txt = 'ftol reached';
case 4
txt = 'xtol reached';
case 5
txt = 'maxeval reached';
case 6
txt = 'maxtime reached';
case -1
txt = 'generic failure code';
case -2
txt = 'invalid arguments';
case -3
txt = 'out of memory';
case -4
txt = 'roundoff-limited';
otherwise
txt = 'undefined exitflag!';
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.