how to use "randi" in specific case?

Hi!
i want to ask you if it is possible to use "randi" in this case:
i have a binary matrix A (m*n), each row has just "1" and other elements are set to "0", i want to put randomly in the "1" position a value from this range for example [10,15,20,25].
i'm asking how can i remove the case of seeing the same value in the same column or two same values in two successive columns.
for example:
0 0 10 0 0 0 0 0 0 0
0 0 10 0 0 0 0 0 0 0
0 0 0 15 0 0 0 0 0 0
0 0 0 20 0 0 0 0 0 0
0 0 0 10 0 0 0 0 0 0
0 0 0 0 25 0 0 0 0 0
0 0 0 0 0 0 20 0 0 0
0 0 0 0 0 0 0 15 0 0
0 0 0 0 0 0 0 0 10 0
0 0 0 0 0 0 0 0 10 0
0 0 0 0 0 0 0 0 0 15
0 0 0 0 0 0 0 0 0 25
as you see the third column i have the same value "10" ,also in the fourth i have the same value of previous column, i want to remove this case.
i'll appreciate any help, thank you very much.

4 Comments

Torsten
Torsten on 30 Nov 2022
Edited: Torsten on 30 Nov 2022
What means "random" in this case if you impose the above conditions on the "randomness" ?
could you please see the modification done above.
If your binary matrix had, e.g. (five 1's in some column) or (four 1's in some column and at least one 1 in the preceeding or next column), you couldn't do what you try to do. And then ?
@Torsten i want just a loop while, if the value exist in the column for more than one time or in just the previous or next column i will do another "randi"

Sign in to comment.

 Accepted Answer

Maybe something like this (the example A requires at least 5 values, e.g., [10 15 20 25 30]):
A = [ ...
0 0 1 0 0 0 0 0 0 0; ...
0 0 1 0 0 0 0 0 0 0; ...
0 0 0 1 0 0 0 0 0 0; ...
0 0 0 1 0 0 0 0 0 0; ...
0 0 0 1 0 0 0 0 0 0; ...
0 0 0 0 1 0 0 0 0 0; ...
0 0 0 0 0 0 1 0 0 0; ...
0 0 0 0 0 0 0 1 0 0; ...
0 0 0 0 0 0 0 0 1 0; ...
0 0 0 0 0 0 0 0 1 0; ...
0 0 0 0 0 0 0 0 0 1; ...
0 0 0 0 0 0 0 0 0 1];
vals = [10 15 20 25 30];
[m,n] = size(A);
n_vals = numel(vals);
is_used = false(1,n_vals);
is_used_previous = false(1,n_vals);
for jj = 1:n
idx = find(A(:,jj));
for ii = 1:numel(idx)
if all(is_used | is_used_previous)
continue
end
unused_val_idx = find(~is_used & ~is_used_previous);
new_val_idx = randi(numel(unused_val_idx));
A(idx(ii),jj) = vals(unused_val_idx(new_val_idx));
is_used(unused_val_idx(new_val_idx)) = true;
end
is_used_previous = is_used;
is_used(:) = false;
end
disp(A);
0 0 15 0 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 25 0 0 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0 0 0 30 0 0 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 15 0 0 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0 0 0 0 25 0 0 0 0 0 0 0 0 0 30

2 Comments

@Voss it works, thank you very much!
You're welcome!

Sign in to comment.

More Answers (1)

n=10;%length of matrix
l=[10 15 20 25];
m=zeros(length(l),n);
r1=randperm(length(l));r2=randperm(n,length(l));r3=randperm(length(l));
for k=1:length(l)
m(r1(k),r2(k))=l(r3(k));
end
m
m = 4×10
0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 0 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0 0 15 0 0

7 Comments

@David Hill thank you for your quick reply! but i forgot to put that i already have a binary matrix which has just "1" per row, so the values i want to generate should take the position of each "1" , i did some modification above.
m=20;n=10;
A=zeros(m,n);
for k=1:m
A(k,randi(n))=1;
end
l=[10 15 20 25];
A(A==1)=l(randi(length(l),1,nnz(A)))
A = 20×10
0 0 0 0 0 0 10 0 0 0 0 15 0 0 0 0 0 0 0 0 0 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 0 0 0 0 0 20 0 0 0 0 0 0 0 0 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 0 0 0 0 0 0 0 10 0 0 0 20 0 0 0 0 0 0 0 0 0 15 0 0 0 0 0 0 0 0 0
h=histc(A,l);
[r,c]=find(h>1);
[R,C]=find(movsum(h>=1,2,2,'endpoints','discard')>1);
C=C+1;
idx=[];
for k=1:length(r)
f=find(A(:,c(k))==l(r(k)));
idx=[idx;f(2:end)];
end
for k=1:length(R)
idx=[idx;find(A(:,C(k))==l(R(k)))];
end
idx=unique(idx);
A(idx,:)=[]
A = 9×10
0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 25 0 0 0 0 0 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 0 20 0 0 0 0 0 0 0 0 0 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 0 0 25 0 0 0 0 0 0 0 0 0 0 0 0 0 20 0 0 0 0
@David Hill the code you provided eliminate definitely the same value but i need to change it with other value.
You keep changing the problem. What are you trying to do? What is the big picture? I think you can figure it out from here.
@David Hill this is an eg when i did a sample "randi" exactly as you mentioned, but as you see the value "10" exists two times in column 3 also it exists in the next column so i want to change its value with another , its like another randi until having different values .
0 0 10 0 0 0
0 0 10 0 0 0
0 0 0 15 0 0
0 0 0 20 0 0
0 0 0 10 0 0
0 0 0 0 25 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
this is an e.g of required result:
0 0 10 0 0 0
0 0 25 0 0 0
0 0 0 15 0 0
0 0 0 20 0 0
0 0 0 25 0 0
0 0 0 0 10 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
@Majid: 25 exists in columns 3 and 4. Is that allowed?
@Voss no, because it is a e.g i just focus in one value"10", here just i take l=[10 15 20 25]; for my real case the range of values is large.

Sign in to comment.

Asked:

on 30 Nov 2022

Commented:

on 30 Nov 2022

Community Treasure Hunt

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

Start Hunting!