在Matlab 2016b与2017b上运行脚本时,优化结果不同

时间:2018-03-14 12:13:05

标签: matlab optimization constraint-programming nonlinear-optimization

我有一个约束优化问题,我试图在Matlab中解决。

  • 然而,我发现当我使用Matlab 2016b运行求解器时,结果与使用Matlab 2017b在另一台计算机上运行时的结果不同。

  • 我发现使用非随机优化器sqp时,解算器不会收敛到相同的值,这很奇怪。事实上,2016b未达到可行点,而2017b找到了当地最低点。

  • 我已100%确定以下功能的输入完全相同。

  • 我也试过修理种子(给Twister)。

这些差异来自哪里?如何查看2016b与2017年的不同之处?我在release notes中的fmincon找不到任何内容。

或者差异来自不同的东西?我该怎么做才能检查和理解这个?

这是核心功能:

function customOptimization(ymu, Sigma, upperTarget, maxWeight)
% ymu: 1 x M vector
% Sigma: M x M matrix
% upperTarget: double constant
% maxWeight: double constant

options = optimoptions(...
    'fmincon','Algorithm','sqp',...
    'MaxFunctionEvaluations',1e+5,'MaxIterations',1e+5, ...
    'OptimalityTolerance',1e-12,'ConstraintTolerance',1e-12, ...
    'StepTolerance',1e-6, ...
    'Display', 'off');

% Problem definition
fnhandle                 = @(x)in_objectfun(x, ymu);
nonlcon                  = @(x)in_nonlconstr(x, Sigma);
[A, b, Aeq, beq, lb, ub] =     in_linconstr(ymu);
x0                       =     in_startvalue(ymu, Sigma);

% Optimization & scaling
    [weights,fval,exitflag,output] = fmincon(fnhandle, x0, A, b, Aeq, beq, lb, ub, nonlcon, options); 


% -------------------------------------------------------------------------
% CONSTRAINTS AND OTHER

% objective function
    function  f = in_objectfun(w, imu)

        f = abs(imu) * log(abs(w))';
        f = -f;

    end

% linear constraints
    function [A, b, Aeq, beq, lb, ub] = in_linconstr(imu)

        temp = ones(0,nbAssets);
        temp(imu >= 0) = -1;
        temp(imu < 0) = 1;

        % (b) and (c)
        % Ax <= b
        A = diag(temp);
        b = zeros(nbAssets,1);

        % other
        Aeq = [];
        beq = [];
        lb = [];
        ub = [];

    end

% nonlinear constraints
    function [c,ceq] = in_nonlconstr(w, S)

        % (a)
        c(1) = sqrt(w*S*w') - upperTarget;
        c(2) = max(abs(w))/sum(abs(w)) - maxWeight;

        % (d)
        ceq = [];

    end

% starting values
    function x0 = in_startvalue(imu)

        x0 = imu/2;

    end

end

0 个答案:

没有答案