random matrix with a minimum number difference for adjacent numbers accepted

5 vues (au cours des 30 derniers jours)
JdC
JdC le 19 Jan 2022
Commenté : JdC le 20 Jan 2022
Dear all,
I come to you with a problem I am facing right now. I am trying to make a random matrix with adjacent numbers that have to be at leat min_diff different from one another.
For now, I tried making the code below, but it seem to be flawed as I found 5.3268 5.2605 as adjacent numbers in my last try.
max=6;
min=3;
bounds=[min,max];
min_diff=0.1;
X=zeros(1,1250);
R=rand(1,size(X,2))*range(bounds)+bounds(1);
R1=zeros(size(R));
tcount=0;%just to know the number of itteration
for i=1:length(R)
R1(:,i)=ismembertol(R(:,i),R(:,i-1>0),min_diff);
while R1(:,i)==1
tcount=tcount+1;
R(:,i)=R(:,i)+min_diff;
R1(:,i)=ismembertol(R(:,i),R(:,i-1>0),min_diff);
end
end
Thank you in advance for your help,
JdC

Réponse acceptée

John D'Errico
John D'Errico le 20 Jan 2022
Modifié(e) : John D'Errico le 20 Jan 2022
Let me start out by saying it is a terrible idea to use max and min as variable names. Your next anguished question will be why do the FUNCTIONS min and max no longer work, or more likely, you will ee error messages that you don't understand.
As for your problem, do you want a random VECTOR? Or a MATRIX? Your code shows a vector. But you use the word matrix. A vector is surely simpler.
For a vector, the answer seems even trivial. Start with the first element.
minel = 3;
maxel = 6;
mindiff = 0.1;
nx = 1250;
X = NaN(1,nx); % preallocation for X.
X(1) = rand(1)*(maxel - minel) + minel; % X(1) can go anywhere
for ind = 2:nx
% choose x(ind) randomly, as long as it is not within mindiff of x(ind-1)
xinterval1 = [minel,max(minel,X(ind-1) - mindiff)];
xinterval2 = [min(maxel,X(ind-1) + mindiff),maxel];
% In the event that x(ind-1) was too close to either bound, the
% corresponding interval will have zero length. Since rand produces a
% random sequence that will never be exactly 0 or 1, there is no worry
% about a random point chosen below to lie in one of those zero length
% intervals.
% Finally, we sample randomly and uniformly from those two sub-intervals
% to find x(ind).
dx1 = diff(xinterval1);
dx2 = diff(xinterval2);
u = rand(1)*(dx1 + dx2);
if u < dx1
X(ind) = xinterval1(1) + u;
else
X(ind) = xinterval2(1) + u - dx1;
end
end
Did it work? Of course. Test my code. why bother? :) Anyway, what is the minimum difference? (See why it is a terrible idea to name a variable min? This next line would have failed!)
min(abs(diff(X)))
ans = 0.1002
So the minimum difference between successive elements was 0.1002, just slightly more than 0.1, as required.

Plus de réponses (1)

Matt J
Matt J le 19 Jan 2022
Modifié(e) : Matt J le 19 Jan 2022
Why not as follows?
min_diff=0.1;
R=rand(1,6);
R=R./min(abs(diff(R)))*min_diff;
abs(diff(R))
ans = 1×5
0.1000 0.3676 0.3966 0.2659 0.1198
  2 commentaires
JdC
JdC le 19 Jan 2022
Thank you, I think what was missing for me was just the abs(diff(R)).
I rearranged my code, and replaced ismembertol conditions by abs(diff(R)) and now it does work as I wish.
JdC
JdC le 20 Jan 2022
Modifié(e) : JdC le 20 Jan 2022
I thought it worked, but I realised today that it doesn't. If min_diff is changed, for example to 0.5, the diff will be higher than 1 so the result will be out of the bounds I put on R.
Thank you again but I have to find an other way.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Creating and Concatenating Matrices dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by