How to solve this error when I use fmincon?
9 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Waseem AL Aqqad
il 30 Nov 2021
Commentato: Waseem AL Aqqad
il 1 Dic 2021
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 Commenti
Risposta accettata
Walter Roberson
il 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 Commenti
Walter Roberson
il 1 Dic 2021
Is it a situation that you want to reject as being unsuitable? If so return a value higher than any valid value.
If it is a situation that indicates that you have found a best-possible configuration, then return 0.
Do not return a random number: that would result in the situation being preferred to some (but not all) valid configurations.
Più risposte (0)
Vedere anche
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!