How to set bounds on fmincon manually

10 visualizaciones (últimos 30 días)
Jonathan Charron
Jonathan Charron el 3 de Dic. de 2020
Comentada: Jonathan Charron el 3 de Dic. de 2020
I have made a custom file for outputting fmincon solutions, the code below works for the supplied function and the bounds [0 5] in x1 and [0 5] in x2, but now if I want to go change bounds (eg. for Branch and Bound solving), say to [0 5] x1 and [3 5] in x2, it doesn't work as intended, it still finds the solution within the original bounds.
The problem is i'm not fluent with the function, and used the live version and converted it to code, the problem appears to be on this line in the for-loop (~67):
[solution,objectiveValue,exitflag,output] = fmincon(@objectiveFcn,x0(:,i),[],[],[],[],...
zeros(size(x0)),repmat(5,size(x0)),[],options2);
... what do I need to edit this line to so it will accept my boundaries when I change them? Thank you. Full code follows:
(There's no check atm on best-guess being inside the range, but it is not active for random start search)
% Mystery Function Minimizer. Minimize continuous surface f(XY) Using
% fmincon(SQP). Function defined at end of file (line ~137). Also set
% Function in 'myFun' for 3D surface plot. (line ~102)
% Written by Jon Charron (jcharro@clemson.edu | jon.charron@gmail.com)
close all
clear
clc
x1_bounds = [0 5];
x2_bounds = [0 5]; % WANT TO SET THIS TO [3 5] etc. without breaking, similar for x1
% Below, enable search mode: 1) Random 2) Uniform Grid 3) Best Guess
SearchMode = 1;
% Search Mode Parameters:
% 1
SearchPoints = 5; % No. of rand() searches
% 2
StepSize = 1; % x,y stepping for grid spacing
% 3
BestGuess = [2.5, 2.5];
if SearchMode == 1
% # Random start points within the range
% x0 = (feasible range)*rand()Coefficient + Lower limit
x0(1,:) = (x1_bounds(1,2)-x1_bounds(1,1)).*rand(1,SearchPoints) + x1_bounds(1,1);
x0(2,:) = (x2_bounds(1,2)-x2_bounds(1,1)).*rand(1,SearchPoints) + x2_bounds(1,1);
end
clear SearchPoints
if SearchMode == 2
% Fixed grid of start points
ndg = x1_bounds(1):StepSize:x1_bounds(2);
[X,Y] = ndgrid(ndg,ndg);
sizeX = size(X);
sizeY = size(Y);
x0(1,:) = reshape(X,[1,sizeX(1)*sizeX(2)]);
x0(2,:) = reshape(Y,[1,sizeY(1)*sizeY(2)]);
end
clear sizeX sizeY X Y ndg StepSize
if SearchMode == 3
% Fixed best guess point
x0 = BestGuess;
end
% Initialize solution handles
solutionSet = ones(2,length(x0))*999999999; % 2xN Matrix of massive values
fvalSet = ones(1,length(x0))*999999999; % Vector of massive values
iter_Total = 0; % Iterations
feval_Total = 0; % Function evaluations
% Set nondefault solver options
options2 = optimoptions('fmincon','MaxFunctionEvaluations',3500,'PlotFcn',...
{'optimplotx','optimplotfunccount','optimplotfvalconstr','optimplotfval',...
'optimplotconstrviolation','optimplotstepsize','optimplotfirstorderopt'},'Algorithm','sqp');
for i=1:1:length(x0)
% Fmincon()
% Solve
[solution,objectiveValue,exitflag,output] = fmincon(@objectiveFcn,x0(:,i),[],[],[],[],...
zeros(size(x0)),repmat(5,size(x0)),[],options2);
solutionSet(:,i) = solution;
fvalSet(1,i) = objectiveValue;
iter_Total = iter_Total + output.iterations;
feval_Total = feval_Total + output.funcCount;
end
clear solution i objectiveValue output exitfflag
clearvars options2
% Determine the minimum solution
[Minimum_F, index] = min(fvalSet);
X_star = [solutionSet(1,index) solutionSet(2,index)];
if SearchMode == 1 || SearchMode == 2
% plot search points
subplot(3,3,9)
scatter(x0(1,:),x0(2,:),'o','b')
hold on
scatter(X_star(1),X_star(2),'*','r') % and Optimum
hold off
hold on
scatter(x0(1,index),x0(2,index),'x','g') % and Winning Start
hold off
xlabel('x1')
ylabel('x2')
title('Search Points')
axis(horzcat(x1_bounds,x2_bounds))
end
% 3D Surface Plot
subplot (3,3,8)
meshDensity = 20; % Number of nodes to surface mesh plot
[X,Y] = ndgrid(linspace(x1_bounds(1),x1_bounds(2),meshDensity),...
linspace(x2_bounds(1),x2_bounds(2),meshDensity));
myFun = @(x,y) 2+0.01.*(y-x.^2).^2 + (1-x).^2 + 2.*(2-y).^2 + 7.*sin(0.5.*x).*sin(0.7.*x.*y);
s = meshc(X,Y,myFun(X,Y),'FaceAlpha','0.5');
s(1).FaceColor = 'flat';
s(2).FaceColor = 'flat';
s(2).Fill = 'on';
colorbar
xlabel('x1')
ylabel('x2')
zlabel('f(X'')')
title('Function Plot')
axis tight % Stop axis limits from shifting with rotation of view
camzoom(1) % Stop axes scaling from shifting with rotation of view*
%* Matlab calls it "Stretch-to-Fit" and claims it is a "Feature."
clear meshDensity s x_int y_int X Y myFun
hold on
% plot the found optimum
scatter3(X_star(1),X_star(2),Minimum_F,'*','r')
% plot the winning start point
hold on
f = objectiveFcn([x0(1,index);x0(2,index)]);
scatter3(x0(1,index),x0(2,index),f,'o','g')
hold off
clear f
% dirty-output for iteration and func eval totals:
iter_Total
feval_Total
function f = objectiveFcn(optimInput)
x = optimInput(1);
y = optimInput(2);
% Set problem function here:
f = 2+0.01*(y-x^2)^2 + (1-x)^2 + 2*(2-y)^2 + 7*sin(0.5*x)*sin(0.7*x*y);
end

Respuesta aceptada

Walter Roberson
Walter Roberson el 3 de Dic. de 2020
x0(1,:) = (x1_bounds(1,2)-x1_bounds(1,1)).*rand(1,SearchPoints) + x1_bounds(1,1);
x0(2,:) = (x2_bounds(1,2)-x2_bounds(1,1)).*rand(1,SearchPoints) + x2_bounds(1,1);
You are creating x0 as 2 rows and SearchPoints columns.
[solution,objectiveValue,exitflag,output] = fmincon(@objectiveFcn,x0(:,i),[],[],[],[],...
zeros(size(x0)),repmat(5,size(x0)),[],options2);
size(x0) would be [2, SearchPoints], so zeros(size(x0)) would be 2 x 5. But when you use lb and ub parameters, they must be empty [], or scalars (not recommended but permitted with a warning if x0 is not scalar), or vectors with the same number of elements that x0 has.
Your objective function is expecting a vector of exactly two values, so there is no good reason to set 2 * 5 = 10 lower bounds or upper bounds.
To run multiple searches, you need to loop over your columns of x0, passing one column in at a time (and your lb and ub should reflect the size of that column)
  1 comentario
Jonathan Charron
Jonathan Charron el 3 de Dic. de 2020
Thank you, I set the ub and lb before the loop now, instead of these calls to zeros and repmat left over from the .mlx version.
lb = [x1_bounds(1),x2_bounds(1)];
ub = [x1_bounds(2),x2_bounds(2)];

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Graphics Object Programming en Help Center y File Exchange.

Productos


Versión

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by