1

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.

Adam
  • 2,726
  • 1
  • 9
  • 22
SimaGuanxing
  • 673
  • 2
  • 10
  • 29
  • The solver will find some problems trying to solve your problem. First, fminsearch is suitable for unconstrained optimization, but you said `interval` ranges from 1 to 30 and `factor` from 0.1 to 0.9. That suggest you should try another function (see [fmincon](https://www.mathworks.com/help/optim/ug/fmincon.html), for instance) – Thales Nov 22 '19 at 22:29
  • another problem is that usually an optimization algorithm will estimate/need the derivatives to look for the optimum. If your function has discontiniuties, the algorithm will not work properly. – Thales Nov 22 '19 at 22:32
  • @Thales Thanks for your reply. I am very new in the optimization field, would you be able to give me a demo using fmincon? – SimaGuanxing Nov 22 '19 at 22:35
  • Third, if some of your variables may assume only integer values, than you have another class of problems. As far as I am concerned, MATLAB currently cannot handle this problem with the usual optimization algorithms. You can set the problem with the [ga function](https://www.mathworks.com/help/gads/mixed-integer-optimization.html), if you have the global optimization toolbox. Or maybe, [this](https://www.mathworks.com/help/optim/examples/mixed-integer-quadratic-programming-portfolio-optimization.html) can help. – Thales Nov 22 '19 at 22:37
  • @Thales Would you be able to give me an example for using ga function on my case? I appreciate your help. – SimaGuanxing Nov 22 '19 at 22:48
  • Is the problem in the question an example, or the actual problem you want to optimize? Since the parameter space is quite small, you can easily check all combinations, and see the global minimum. Otherwise `ga` could be an option. – rinkert Nov 22 '19 at 22:51
  • @rinkert This is just an example so I can see whether it is correct. The actual problem is more complicated. It is even not a mathematical problem. – SimaGuanxing Nov 22 '19 at 22:56
  • Related question from OP: [Matlab use fminsearch to optimize a interval of numbers](https://stackoverflow.com/q/58984498/8239061) – SecretAgentMan Nov 22 '19 at 23:03
  • 1
    @SecretAgentMan Thanks for linking them. – SimaGuanxing Nov 25 '19 at 19:19
  • Answers go in answers, not the question itself, hence I rolled back the post to the state where it only contained a question. To let people know an existing answer works, accept and/or upvote that answer. If you want to show how you modified an existing answer to make it work for your case, post an answer yourself, this is perfectly acceptable on SO. Do make sure to reference the original answer, and, if it will be only a slight change, make it *community wiki*. – Adriaan Nov 26 '19 at 15:22

1 Answers1

3

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
Adam
  • 2,726
  • 1
  • 9
  • 22
  • 1
    Thanks for sharing the example for using GA. How can you handle variable in different steps? Say, I have one variable from 1 to 30 with step is 0.1 and another one is from 0.1 to 0.9 with step size is 0.1. Thanks! – SimaGuanxing Nov 25 '19 at 19:17
  • Please see my updated comment on the original thread. Thanks! – SimaGuanxing Nov 25 '19 at 21:41