- objective — Objective function
- x0 — Starting point
- lb — Lower bound for x
- ub — Upper bound for x
- solver — 'simulannealbnd'
- options — Options created with optimoptions or an options structure
- rngstate — Optional field to reset the state of the random number generator
Why Does My Custom SA not Work for Mixed-integer Problem?
3 views (last 30 days)
Show older comments
I have been trying to customize MATLAB's simulated annealing algorithm to my case, which is a mixed-integer optimization problem. Based on simulannealbnd documentation, I modified my code accordingly. However, it does not work as expected. That is, imagine we have N number of variables. I want to find a solution of which the first N / 2 number of variables are integer-valued and the rest of variables (N / 2 number of them) are float-valued. For demonstration I wrote this minimal reproducible example below:
rng(7, 'twister')
function y = objective(x)
y = abs(sum(x(1) .* (x(2:end - 3) .^ 2 + x(3:end - 2) - 11) .^ 2 - cos(x(2)) .* (x(4:end - 1) + x(5:end) .^ 2 - 7) .^ 2));
end
function newx = sahonorbounds(newx, optimValues, problem)
if ~problem.bounded
return
end
xin = newx;
newx = newx(:);
lb = problem.lb;
ub = problem.ub;
lbound = newx < lb;
ubound = newx > ub;
alpha = rand;
if any(lbound) || any(ubound)
projnewx = newx;
projnewx(lbound) = lb(lbound);
projnewx(ubound) = ub(ubound);
newx = alpha * projnewx + (1 - alpha) * optimValues.x(:);
newx = globaloptim.internal.validate.reshapeinput(xin, newx);
else
newx = xin;
end
% Round only integer variables
if isfield(problem, 'IntVars')
newx(problem.IntVars) = round(newx(problem.IntVars), 0);
end
end
function newx = mynewx(optimValues, problem)
currentx = optimValues.x;
nvar = numel(currentx);
newx = currentx;
newx(:) = currentx(:) + sqrt(optimValues.temperature) .* randn(nvar, 1);
newx = sahonorbounds(newx, optimValues, problem);
end
F = @(x) objective(x);
options = optimoptions('simulannealbnd', ...
'FunctionTolerance', 1e-9, ...
'AnnealingFcn', @mynewx, ...
'ReannealInterval', 10, ...
'InitialTemperature', 10);
N = 6; % NUMBER OF VARIABLES TO CHANGE
problem = struct('solver', 'simulannealbnd', ...
'objective', F, ...
'IntVars', 1:N / 2, ...
'x0', [round(100 .* rand(1, N / 2), 0), 100 .* rand(1, N / 2)], ...
'lb', zeros(1, N), ...
'ub', 100 .* ones(1, N), ...
'options', options);
[x, fval, exitflag, output] = simulannealbnd(problem);
fprintf('\nx* : ');
fprintf('%f ', x);
fprintf(' --- f(x*) : %f\n\n', fval);
When I set N equal to 4, it works, meaning the first two components of solution are integer and the other two are float. If I set it to 6, 8, etc., I get all-float solution. Can anyone explain what goes on here? How can I get what I wanted here, if I can?
0 Comments
Accepted Answer
Torsten
on 10 Jul 2024
Moved: Torsten
on 10 Jul 2024
This is the problem structure of "simulannealbnd". I cannot find "IntVars".
problem — Problem structure
structure
Problem structure, specified as a structure with the following fields:
Maybe you can tell us where you found that some variables can be defined as integers in the framework of "simulannealbnd".
3 Comments
Torsten
on 11 Jul 2024
Edited: Torsten
on 11 Jul 2024
So you have programmed a new version of "simulannealbnd" that can handle the option "IntVars" ? For this to be true, you would have had to rewrite the complete algorithm.
Why don't you use "ga" ? It has the software option to define variables as integers.
More Answers (0)
See Also
Categories
Find more on Simulated Annealing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!