random matrix with a minimum number difference for adjacent numbers accepted

2 views (last 30 days)
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

Accepted Answer

John D'Errico
John D'Errico on 20 Jan 2022
Edited: John D'Errico on 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.

More Answers (1)

Matt J
Matt J on 19 Jan 2022
Edited: Matt J on 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 Comments
JdC
JdC on 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 on 20 Jan 2022
Edited: JdC on 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.

Sign in to comment.

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!