Search code examples
matlabmathematical-optimizationfminsearch

Matlab use fminsearch to optimize multi variables


I am using Matlab fminsearch to minimize a equation with two variables sum((interval-5).^2, 2)*factor The interval is a vector contains 5 values. They can be only picked sequentially from value 1 to 30 with step size is 1. The factor is a value from 0.1 to 0.9.

The code is below. I think the interval values are correct but factor value is wrong.

Interval value: [3 4 5 6 7] factor value: 0.6 Final Output: 6

I think the factor value should be 0.1 and final output should be 1 as global minimum.

%% initialization of problem parameters
minval = 1;
maxval = 30;
step = 1;
count = 5;

minFactor = 0.1;
maxFactor = 0.9;

%% the objective function
fun = @(interval, factor) sum((interval-5).^2, 2)*factor;

%% a function that generates an interval from its initial value
getinterval = @(start) floor(start) + (0:(count-1)) * step;
getfactor =@(start2) floor(start2 * 10)/10;

%% a modified objective function that handles constraints
objective = @(start, start2) f(start, fun, getinterval, minval, maxval, getfactor, minFactor, maxFactor);

%% finding the interval that minimizes the objective function
start = [(minval+maxval)/2 (minFactor+maxFactor)/2];
y = fminsearch(objective, start);
bestvals = getinterval(y(1));
bestfactor = getfactor(y(2));

eval = fun(bestvals,bestfactor);
disp(bestvals)
disp(bestfactor)
disp(eval)

The code uses the following function f.

function y = f(start, fun, getinterval, minval, maxval, getfactor, minFactor, maxFactor)
   interval = getinterval(start(1));
   factor = getfactor(start(2));
   if (min(interval) < minval) || (max(interval) > maxval) || (factor<minFactor) || (factor>maxFactor)
       y = Inf;
       else
          y = fun(interval, factor);
       end
   end

I tried the GA function as Adam suggested. I changed it to two different sets given the fact that my variables are from different ranges and steps. Here are my changes.

step1 = 1;
set1 = 1:step1:30;

step2 = 0.1;
set2 = 0.1:step2:0.9;

% upper bound depends on how many integer used for mapping
ub = zeros(1, nvar);
ub(1) = length(set1);      
ub(2) = length(set2); 

Then, I changed the objective function

% objective function
function y = f(x,set1, set2)
    % mapping
    xmap1 = set1(x(1));
    xmap2 = set2(x(2));

    y = (40 - xmap1)^xmap2;

end

After I run the code, I think I get the answer I want.


Solution

  • Illustration of ga() optimizing over a set

    objective function

    f = xmap(1) -2*xmap(2)^2  + 3*xmap(3)^3 - 4*xmap(4)^4 + 5*xmap(5)^5;
    

    set

    set = {1, 5, 10, 15, 20, 25, 30}
    

    The set contains 7 elements:

    • index 1 is equivalent to 1 set(1)
    • index 2 to 5...
    • index 7 to 30 set(7)

    The input to ga will be in the range 1 to 7.
    The lower bound is 1, and the upper bound is 7.

    ga optimization is done by computing the fitness function: evaluate f over the input variable.
    The tips here will be using integer as input and later while evaluating f use the mapping discussed above.


    The code is as follows

    % settting option for ga
    opts = optimoptions(@ga, ...
                        'PopulationSize', 150, ...
                        'MaxGenerations', 200, ...
                        'EliteCount', 10, ...
                        'FunctionTolerance', 1e-8, ...
                        'PlotFcn', @gaplotbestf);
    
    % number of variable
    nvar = 5;   
    
    % lower bound is 1
    lb = ones(1, nvar);
    
    step = 2.3;
    set = 1:step:30;
    limit = length(set);
    
    % upper bound depends on how many integers are used for mapping
    ub = limit.*lb;      
    
    % maximization used the opposite of f as ga only does minimization
    % asking ga to minimize -f is equivalent to maximizing f
    fitness = @(x)-1*f(x, step, set);
    [xbest, fbest, exitflag] = ga(fitness,nvar, [], [], [], [], lb, ub, [], 1:nvar, opts);  
    
    % get the discrete integer value and find their corresponding value in the set
    mapx = set(xbest)
    
    
    
    % objective function
    function y = f(x, step, set)
    l = length(x);
    
    % mapping
    xmap = zeros(1, l);
    for i = 1:l
        xmap(i) = set(x(i));
    end
    
    
    
    y = xmap(1) -2*xmap(2)^2  + 3*xmap(3)^3 - 4*xmap(4)^4 + 5*xmap(5)^5;
    
    end