MATLAB Answers

How to set bounds on fmincon manually

16 views (last 30 days)
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),[],[],[],[],...
... 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 ( |
close all
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);
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)]);
clear sizeX sizeY X Y ndg StepSize
if SearchMode == 3
% Fixed best guess point
x0 = BestGuess;
% 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',...
for i=1:1:length(x0)
% Fmincon()
% Solve
[solution,objectiveValue,exitflag,output] = fmincon(@objectiveFcn,x0(:,i),[],[],[],[],...
solutionSet(:,i) = solution;
fvalSet(1,i) = objectiveValue;
iter_Total = iter_Total + output.iterations;
feval_Total = feval_Total + output.funcCount;
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
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
title('Search Points')
% 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),...
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';
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
% plot the winning start point
hold on
f = objectiveFcn([x0(1,index);x0(2,index)]);
hold off
clear f
% dirty-output for iteration and func eval totals:
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);


Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 3 Dec 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),[],[],[],[],...
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 Comment

Jonathan Charron
Jonathan Charron on 3 Dec 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)];

Sign in to comment.

More Answers (0)




Community Treasure Hunt

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

Start Hunting!

Translated by