Matlab中的Frank - Wolfe算法

时间:2015-04-28 21:50:17

标签: matlab mathematical-optimization

我正在尝试解决以下问题:

  maximize  x^2-5x+y^2-3y  

 x+y <=  8 
 x<=2  
 x,y>= 0  

使用Frank Wolf算法(根据http://web.mit.edu/15.053/www/AMP-Chapter-13.pdf)。

但在运行以下程序后:

    syms x y t;

    f = x^2-5*x+y^2-3*y; 

    fdx = diff(f,1,x); % f'x
    fdy = diff(f,1,y); % y'x

    x0 = [0 0];      %initial point

    A = [1 1;1 0];    %constrains matrix
    b = [8;2];   
    lb = zeros(1,2); 



    eps = 0.00001; 
    i = 1;
    X = [inf inf];
    Z = zeros(2,200); %result for end points (x1,x2) 

    rr = zeros(1,200);
    options = optimset('Display','none');

    while( all(abs(X-x0)>[eps,eps]) && i < 200)

        %f'x(x0) 
        c1 = subs(fdx,x,x0(1));
        c1 = subs(c1,y,x0(2));

        %f'y(x0) 
        c2 = subs(fdy,x,x0(1));
        c2 = subs(c2,y,x0(2));

        %optimization point of linear taylor function
        ys = linprog((-[c1;c2]),A,b,[],[],lb,[],[],options); 


        %parametric representation of line
        xt = (1-t)*x0(1)+t*ys(1,1);
        yt = (1-t)*x0(2)+t*ys(2,1);

        %f(x=xt,y=yt)
        ft = subs(f,x,xt);
        ft = subs(ft,y,yt);

        %f't(x=xt,y=yt)
        ftd = diff(ft,t,1);

         %f't(x=xt,y=yt)=0 -> for max point 
        [t1] = solve(ftd); % (t==theta)


        X = double(x0);%%%%%%%%%%%%%%%%%

        %  [ xt(t=t1)  yt(t=t1)]
        xnext(1) = subs(xt,t,t1) ;
        xnext(2) =  subs(yt,t,t1) ;

        x0 = double(xnext);
        Z(1,i) = x0(1);
        Z(2,i) = x0(2);


        i = i + 1;
    end





    x_point = Z(1,:);
    y_point = Z(2,:);



% Draw result
scatter(x_point,y_point);
hold on;

% Print results
fprintf('The answer is:\n');

fprintf('x = %.3f \n',x0(1));
fprintf('y = %.3f \n',x0(2));


res = x0(1)^2 - 5*x0(1) + x0(2)^2 - 3*x0(2);
fprintf('f(x0) = %.3f\n',res);

我得到以下结果:

    x = 3.020 
    y = 0.571 
    f(x0) = -7.367

这不管我运行这个程序多少次迭代(1,50或200)。

即使我选择了不同的起点(例如,x0 =(1,6)),我也得到了大多数的否定答案。

我知道这是一个近似值,但结果应该是正数(对于x0 final,在这种情况下)。

我的问题是:我的实施有什么问题?

提前致谢。

1 个答案:

答案 0 :(得分:1)

i changed a few things, it still doesn't look right but hopefully this is getting you in the right direction. It looks like the intial x0 points make a difference to how the algorithm converges.

Also make sure to check what i is after running the program, to determine if it ran to completion or exceeded the maximum iterations

lb = zeros(1,2); 
ub = [2,8]; %if x+y<=8 and x,y>0 than both x,y < 8



eps = 0.00001; 
i_max = 100;
i = 1;
X = [inf inf];
Z = zeros(2,i_max); %result for end points (x1,x2) 

rr = zeros(1,200);
options = optimset('Display','none');

while( all(abs(X-x0)>[eps,eps]) && i < i_max)

    %f'x(x0) 
    c1 = subs(fdx,x,x0(1));
    c1 = subs(c1,y,x0(2));

    %f'y(x0) 
    c2 = subs(fdy,x,x0(1));
    c2 = subs(c2,y,x0(2));

    %optimization point of linear taylor function
    [ys, ~ , exit_flag] = linprog((-[c1;c2]),A,b,[],[],lb,ub,x0,options); 

so here is the explanation of the changes

ub, uses our upper bound. After i added a ub, the result immediately changed

x0, start this iteration from the previous point

exit_flag this allows you to check exit_flag after execution (it always seems to be 1 indicating it solved the problem correctly)