How can I form a matrix of all possible values of three variables?

조회 수: 14 (최근 30일)
Waseem AL Aqqad
Waseem AL Aqqad 2021년 12월 7일
편집: Waseem AL Aqqad 2021년 12월 8일
I have three variables (bgt, Trigger, alpha), and each one of it could take any value from the set of three values {0.1, 0.5, 0.9} . How can I form a matrix of size 27 by 3 that contains all the possible combinations? And then for the following Script, I want MATLAB to run each row of this newly formed matrix( 27 different runs in total) and save the results (Check % Save The Results Section ). Eventually, I want to pick any three rows easily and plot Mavg against its length (Three curves on the same plot. Nine plots in total)
Thanks!
Start_time = tic();
N = 5000;
p = 0.2;
% The three Variables
bgt = 0.9* N;
Trigger = 0.9 * N;
alpha = 0.9;
init_attack = 8; % no. of nodes attacked initially
mde = 0; %mode of attack
disturb = 350; % disturbance added to the loads
tol = 0.2; % tolerance parameter alpha C = L + a
iter = 1;
tmax = 120;
M_iter = zeros(iter, tmax);
for jj = 1:iter
N = numnodes(G);% number of nodes(components)
[G_dmg,attack,G_orig, needRemoveNode,LoadneedDist,M, tmax, lastIndex] = Load_initial(G,init_attack,mde,disturb,tol,Load, tmax); % initial attack (disruption)
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, tmax, lastIndex] = Load_Stages(G_dmg,needRemoveNode,LoadneedDist,M, tmax, lastIndex); % a cascade of failure will be triggered
end
if (M(tt) >= (Trigger)) && ~alreadyCalled % triggering level
% Calling for the very first time if we get here.
[G_dmg, Nodes_p, tmax] = Loads_decision(G_dmg, tmax);
[G_dmg, M, tmax, lastIndex] = Loads_implement(G_dmg, Nodes_p, M, tmax, lastIndex, 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, tmax] = Loads_decision(G_dmg, tmax); %decide which nodes to recover first
[G_dmg, M, tmax, lastIndex] = Loads_implement(G_dmg, Nodes_p, M, tmax, lastIndex, p, bgt, alpha); % implement recovery
end
end
M_iter(jj,:)=M;
S = std(M_iter);
SE = S/sqrt(size(M_iter,1));
end
% Save The Results
% if Trigger == 0.1 * N
save('M_iter.mat','M_iter');
Mavg = mean(M_iter,1);
save('Mavg.mat','Mavg');
save('SE.mat','SE')
% elseif Trigger == 0.5 * N
% save('M_iter2.mat','M_iter');
% Mavg = mean(M_iter,1);
% save('Mavg2.mat','Mavg');
% save('SE2.mat','SE')
% elseif Trigger == 0.9 * N
% save('M_iter3.mat','M_iter');
% Mavg = mean(M_iter,1);
% save('Mavg3.mat','Mavg');
% save('SE3.mat','SE')
% end
% Plotting
figure(1)
% errorbar(1:length(Mavg),Mavg,SE);hold on
plot(1:length(Mavg),Mavg); hold on
legend({'Triggering Level = 10%', 'Triggering Level = 50%', 'Triggering Level = 90%'}, 'Location', 'NorthWest');
xlabel('Time')
ylabel('No. of Inactive Nodes')
toc(Start_time)

채택된 답변

DGM
DGM 2021년 12월 7일
편집: DGM 2021년 12월 7일
This is what I did off the top of my head
v = [0.1 0.5 0.9];
k = 3;
combs = unique(nchoosek(repmat(v,[1 k]),k),'rows')
combs = 27×3
0.1000 0.1000 0.1000 0.1000 0.1000 0.5000 0.1000 0.1000 0.9000 0.1000 0.5000 0.1000 0.1000 0.5000 0.5000 0.1000 0.5000 0.9000 0.1000 0.9000 0.1000 0.1000 0.9000 0.5000 0.1000 0.9000 0.9000 0.5000 0.1000 0.1000
This can also be done using ndgrid and some reshaping. It's a bit faster, but the readability isn't remotely comparable. For the same reason, it's not something I find easy to remember either.
v = [0.1 0.5 0.9];
k = 3;
c = cell(1,k);
vc = repmat({v},[1 k]);
[c{:}] = ndgrid(vc{:});
n = length(c);
combs = reshape(cat(n+1,c{:}),[],n)
combs = 27×3
0.1000 0.1000 0.1000 0.5000 0.1000 0.1000 0.9000 0.1000 0.1000 0.1000 0.5000 0.1000 0.5000 0.5000 0.1000 0.9000 0.5000 0.1000 0.1000 0.9000 0.1000 0.5000 0.9000 0.1000 0.9000 0.9000 0.1000 0.1000 0.1000 0.5000
  댓글 수: 3
DGM
DGM 2021년 12월 8일
편집: DGM 2021년 12월 8일
Something like this might be a start
combs = % however you decide to generate the combination array
for k = 1:size(combs,1)
bgt = combs(k,1);
Trigger = combs(k,2);
alpha = combs(k,3);
% do the loop to calculate Miter
end
How you handle output collection is up to you. You could either collect the outputs in an N-D array or you can dump them to mat-files individually. Since I don't know what size they are intended to be, I'm going to leave that decision up to you.
Say you want Miter to be N-D. You might do the assignment like so:
M_iter(jj,:,k) = M;
or maybe you want to write each 2-D output to a unique file instead...
save(sprintf('M_iter%03d.mat',k),'M_iter');
If you want to plot the data for all 27 parameter combinations, you're probably going to be better off deciding on a way to collect the outputs into an ND array. Making a readable plot might be another challenge.
Waseem AL Aqqad
Waseem AL Aqqad 2021년 12월 8일
편집: Waseem AL Aqqad 2021년 12월 8일
Thank you so much. It's greatly appreciated.
To preallocate M_iter, I must do this (outside the two for loops) :
M_iter = zeros(iter, tmax, size(combs,1));
Instead of :
M_iter = zeros(iter, tmax);
Correct?

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by