How to solve this error when I use fmincon?

2 views (last 30 days)
In the script below, I try to optimize the resiliency of a complex network using fmincon. But after some time of running my script I got the following error:
Operands to the || and && operators must be convertible to logical scalar values.
Error in barrier
Error in fmincon (line 813)
[X,FVAL,EXITFLAG,OUTPUT,LAMBDA,GRAD,HESSIAN] = barrier(funfcn,X,A,B,Aeq,Beq,l,u,confcn,options.HessFcn, ...
Error in Resiliency_optimization (line 10)
[x,fval,exitflag,output] = fmincon(@objectivefun,x0,A,b,Aeq,beq,lb,ub,@nonlco);
A = [];
b = [];
Aeq = [];
beq = [];
lb =[];
ub = [];
t0 = [ 0.15, 0.2, 300, 0.3];
[x,fval,exitflag,output] = fmincon(@objectivefun,t0,A,b,Aeq,beq,lb,ub,@nonlco);
function f = objectivefun(t)
load('G.mat');
load('Load');
p = t(1);
Trigger = t(2);
bgt = t(3);
alpha = t(4);
N = numnodes(G);
iter = 1;
tmax = 80;
M_iter = zeros(iter, tmax);
for jj = 1:iter
[G_dmg,~,~, needRemoveNode,LoadneedDist,M] = Load_initial(G,8,0,350,0.2,Load);
alreadyCalled = false; % Say that decision and implement have not been called yet.
for tt = 3: tmax
if any(needRemoveNode)|| ~any(needRemoveNode)
[G_dmg,LoadneedDist,needRemoveNode,M] = Load_Stages(G_dmg,needRemoveNode,LoadneedDist,M);
end
if (M(end) >= (Trigger * N)) && ~alreadyCalled % triggering level
% Calling for the very first time if we get here.
[G_dmg, Nodes_p] = Loads_decision(G_dmg);
[G_dmg] = Loads_implement(G_dmg, Nodes_p, p, bgt, alpha);
alreadyCalled = true; % Set flag to indicate we've called it.
elseif alreadyCalled
% Once they've been called already, call them regardless of the "if" test.
[G_dmg, Nodes_p] = Loads_decision(G_dmg);
[G_dmg, M] = Loads_implement(G_dmg, Nodes_p, M, p, bgt, alpha);
end
end
M_iter(jj,:)=M;
% S = std(M_iter);
% SE = S/sqrt(size(M_iter,1));
end
Mavg = mean(M_iter,1);
[~, maxidx] = max(Mavg);
f = find( (Mavg <= 0.1 * N) & (maxidx <= 1:length(Mavg)), 1 );
end
function [c, ceq] = nonlco (t)
c = [];
ceq = [];
end
Thanks
  2 Comments
Waseem AL Aqqad
Waseem AL Aqqad on 1 Dec 2021
Thanks, Matt J. You are right, that is why Walter recommended ga(), particleswarm() or simannealbnd() instead of fmincon.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 30 Nov 2021
if (M(end) >= (Trigger * N)) && ~alreadyCalled % triggering level
% Calling for the very first time if we get here.
[G_dmg, Nodes_p] = Loads_decision(G_dmg);
[G_dmg] = Loads_implement(G_dmg, Nodes_p, p, bgt, alpha);
alreadyCalled = true; % Set flag to indicate we've called it.
elseif alreadyCalled
% Once they've been called already, call them regardless of the "if" test.
[G_dmg, Nodes_p] = Loads_decision(G_dmg);
[G_dmg, M] = Loads_implement(G_dmg, Nodes_p, M, p, bgt, alpha);
end
What if that condition is never true within a tt value? You would leave M unchanged. Is that appropriate? That is going to affect the mean()
f = find( (Mavg <= 0.1 * N) & (maxidx <= 1:length(Mavg)), 1 );
What if no entries match that condition? Then f would be empty, and that would cause problems in the optimization function.
You are returning an index. Indices are integers. fmincon() will typically give up easily when it sees integer values, deciding that the function is flat. Your function being minimized should be continuous, not discrete.
  7 Comments
Waseem AL Aqqad
Waseem AL Aqqad on 1 Dec 2021
Okay then its option 1 for my case.
Thank you so much for your help. I am really grateful.

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!