How do you randomize numbers but not have two consecutive numbers be the same?
4 ビュー (過去 30 日間)
古いコメントを表示
I have 25 different tones (5 frequencies, 5 amplitudes in combination) and I need to play them in a randomized order, but I do not want any tones with the same frequency or amplitude to be next to each other.
my script plays the tones according to my currently randomized order for example:
column 1 corresponding to frequency (1-5 for the 5 different frequencies) and column 2 corresponding to amplitude (1-5 for the different amplitudes)
1 4
2 4
4 2
5 5
4 4
4 5
3 5
5 2
1 3
4 3
3 4
4 1
2 3
5 1
1 1
3 2
1 2
1 5
5 4
2 2
2 5
3 3
5 3
3 1
2 1
How can I edit my script so that no sounds of the same frequency or amplitude are played consecutively?
3 件のコメント
bym
2011 年 1 月 25 日
If you want them in a random order,couldn't that include the possibility that the same frequency and amplitude is played consecutively?
回答 (8 件)
Matt Fig
2011 年 1 月 25 日
Use the RANDPERM function. Depending on what you want to do, pick one of these:
>> A = [1 2;3 4;5 6;7 8;9 10] % Sample Data
A =
1 2
3 4
5 6
7 8
9 10
>> A(randperm(5),:) % Keep rows the same, but different order
ans =
7 8
9 10
3 4
1 2
5 6
>> [A(randperm(5),1), A(randperm(5),2)] % Mix rows and cols separately
ans =
3 8
7 6
5 10
1 2
9 4
0 件のコメント
Paulo Silva
2011 年 1 月 25 日
function d=selpair(b,s)
%The input b is a column matrix with even values
%The input s is the number of pairs of values
%The output d is the a values but without being repeated
%by Paulo Silva
e=0;
for c=1:s
d(c,:)=b(1+e,:);
b(1+e,:)=[];e=0;
while(isempty(b) | d(c,:)==b(1+e,:))
e=e+1;
if ((e>=(s-1)) | (numel(b(:,1))<2))
return
end
end
end
To test the function use your data or this one
clc
clear
Pairs=25;
a=zeros(Pairs,2);
a(:,1)=round(0.5+abs(5*rand(Pairs,1)));
a(:,2)=round(0.5+abs(5*rand(Pairs,1)));
SortedData=selpair(a,Pairs);
6 件のコメント
Paulo Silva
2011 年 1 月 25 日
I made the function to detect same freq and tone, it was my mistake, I will change the code to do what you want
Paulo Silva
2011 年 1 月 25 日
Here's a better version, I included Matt Fig idea of the permutation, now my function can also randomize the rows of data and apply restrictions.
function d=selpair(b,at)
%The input at is the number of attempts that the function makes
%After the first attempt fails and if at>1 it will do a permutation of
%the rows of the data and try again, it will do permutations until all the
%data restrictions are satisfied or number attemps = at
%Made by Paulo Silva 25-01-2010
s=numel(b(:,1));
for atn=1:at
b=b(randperm(s),:); %randomize the rows
[d code]=selpairfind(b,s);
if (code==1)
break
else
%move the randperm line to this line if you don't want the data
%to be randomized at the first attempt
end
end
function [d code]=selpairfind(b,s)
%The input b is a (s,2) matrix
%The input s is the number of tones
%The output d is the matrix b but without consecutive rows with
%the same freq or amp, other detections are included
%just uncomment the line with the while you want and comment the others
%The returned value might not have the same size as the input
%(less lines), this is because the function can't satisfy the condition,
%it happens in the end of the data.
e=0;
for c=1:s
d(c,:)=b(1+e,:);
b(1+e,:)=[];e=0;
%detect same freq
%while((isempty(b)) | (d(c,1)==b(1+e,1)))
%detect same amp
%while((isempty(b)) | (d(c,2)==b(1+e,2)))
%detect same freq and amp
%while((isempty(b)) | (d(c,:)==b(1+e,:)))
%detect same freq or amp
while((isempty(b)) | ((d(c,1)==b(1+e,1))|(d(c,2)==b(1+e,2))))
e=e+1;
if ((e>=(numel(b(:,1))-1)) | (numel(b(:,1))<2))
%Sometimes the function cannot satisfy the condition very near
%the end of the data, some lines are ignore and the output size
%is smaller than the input, if you wish the size to be always the
%same just uncomment the next line (=no condition for that data)
%d=[d;b];
if (isempty(b))
code=1;
else
code=0;
end
return
end
end
end
end
end
Code to test and compare the data
clc
clear
clf
Pairs=25;
at=10; %number of attempts
a=zeros(Pairs,2);
a(:,1)=round(0.5+abs(5*rand(Pairs,1)));
a(:,2)=round(0.5+abs(5*rand(Pairs,1)));
SortedData=selpair(a,Pairs,at);
subplot(211)
plot(a)
xlabel('Original data, the horizontal lines are repeated values')
legend('Freq','Amp')
subplot(212)
plot(SortedData)
xlabel('Filtered data')
legend('Freq','Amp')
0 件のコメント
Bruno Luong
2011 年 1 月 25 日
Generate 100 pairs, no two consecutive pair has the same frequency OR the same amplitude:
% Data
f = (1:5)'
a = (1:5)'
Npairs = 100
% number of elements of f and a
nf = numel(f); % 5
na = numel(a); % 5
% Engine
indf = ceil((nf-1)*rand(Npairs,1)); % 0 excluded
indf = mod(cumsum(indf),nf)+1; % wrap around (0:nf)
inda = ceil((na-1)*rand(Npairs,1));
inda = mod(cumsum(inda),na)+1;
pairs = [f(indf) a(inda)] % two columns F and A
% Bruno
6 件のコメント
Matt Fig
2011 年 1 月 25 日
It should be pointed out, for clarity, that if the original row order is to be preserved, then only one of indf or inda is needed.
Paulo Silva
2011 年 1 月 25 日
function d=selpair(b,s)
%The input a is a column matrix with even values
%The input s is the number of pairs of values
%The output f is the a values but without consecutive rows with
%the same freq or amp
e=0;
for c=1:s
d(c,:)=b(1+e,:);
b(1+e,:)=[];e=0;
while((isempty(b)) | ((d(c,1)==b(1+e,1))|(d(c,2)==b(1+e,2))))
e=e+1;
if ((e>=(s-1)) | (numel(b(:,1))<2))
return
end
end
end
3 件のコメント
Walter Roberson
2011 年 1 月 25 日
Paulo, you could have just changed d(c,:)==b(1+e,:) to any(d(c,:)==b(1+e,:))
Paulo Silva
2011 年 1 月 25 日
function d=selpair(b,s)
%The input b is a (s,2) matrix
%The input s is the number of tones
%The output d is the matrix b but without consecutive rows with
%the same freq or amp, other detections are included
%just uncomment the line with the while you want and comment the others
%The returned value might not have the same size as the input
%(less lines), this is because the function can't satisfy the condition,
%it happens in the end of the data.
e=0;
for c=1:s
d(c,:)=b(1+e,:);
b(1+e,:)=[];e=0;
%detect same freq
%while((isempty(b)) | (d(c,1)==b(1+e,1)))
%detect same amp
%while((isempty(b)) | (d(c,2)==b(1+e,2)))
%detect same freq and amp
%while((isempty(b)) | (d(c,:)==b(1+e,:)))
%detect same freq or amp
while((isempty(b)) | ((d(c,1)==b(1+e,1))|(d(c,2)==b(1+e,2))))
e=e+1;
if ((e>=(numel(b(:,1))-1)) | (numel(b(:,1))<2)) % * error fixed *
%Sometimes the function cannot satisfy the condition very near
%the end of the data, some lines are ignore and the output size
%is smaller than the input, if you wish the size to be always the
%same just uncomment the next line (=no condition for that data)
%d=[d;b];
return
end
end
end
Code to test and compare the data
clc
clear
clf
Pairs=25;
a=zeros(Pairs,2);
a(:,1)=round(0.5+abs(5*rand(Pairs,1)));
a(:,2)=round(0.5+abs(5*rand(Pairs,1)));
SortedData=selpair(a,Pairs);
subplot(211)
plot(a)
xlabel('Original data, the horizontal lines are repeated values')
legend('Freq','Amp')
subplot(212)
plot(SortedData)
xlabel('Filtered data')
legend('Freq','Amp')
0 件のコメント
Paulo Silva
2011 年 1 月 25 日
Another implementation, please test it and report all possible errors
function d=selpair(b,at,Tdet,r1)
%The input at is the number of attempts that the function makes
%Tdet is the type of detection
%Tdet=1 detects same freq
%Tdet=2 detects same amp
%Tdet=3 detects same freq and amp
%Tdet=4 detects same freq or amp
%The input r1 enables the permutation of the data also in first attempt
%r1=1 yes do permutation at first
%r1~=1 no, try first without permutation
%it will do permutations until all the data restrictions are
%satisfied or number attemps = at
%Made by Paulo Silva 25-01-2010
s=numel(b(:,1));
for atn=1:at
[d code bres]=selpairfind(b,s,Tdet);
if (code==1)
disp('Success, data returned with all conditions satisfied')
break
else
if ((atn~=1) | ((r1==1) & (atn==1)))
b=b(randperm(s),:); %randomize the rows
end
end
end
if (code==0)
disp('Failed to satisfy all conditions, try again with more attempts')
message=sprintf('The last %d lines dont satisfy the conditions',numel(bres(:,1)));
disp(message)
userchoice=input('Do you still want to include those lines? y/n ','s');
if (strcmp(userchoice,'y') | strcmp(userchoice,'yes'))
disp('Success, data returned with all conditions satisfied exept last lines')
d=[d;bres];
end
end
function [d code b]=selpairfind(b,s,Tdet)
%The input b is a (s,2) matrix
%The input s is the number of tones
%Tdet is the type of detection
%Tdet=1 detects same freq
%Tdet=2 detects same amp
%Tdet=3 detects same freq and amp
%Tdet=4 detects same freq or amp
%The output d is the matrix b but without consecutive rows with
%the same freq or amp, other detections are included
%just uncomment the line with the while you want and comment the others
%The returned value might not have the same size as the input
%(less lines), this is because the function can't satisfy the condition,
%it happens in the end of the data.
e=0;
for c=1:s
d(c,:)=b(1+e,:);
b(1+e,:)=[];e=0;
if ((isempty(b)))
condwhile=1;
else
if (Tdet==1)
%detect same freq
condwhile=((d(c,1)==b(1+e,1)));
end
if (Tdet==2)
%detect same amp
condwhile=((d(c,2)==b(1+e,2)));
end
if (Tdet==3)
%detect same freq and amp
condwhile=((d(c,:)==b(1+e,:)));
end
if (Tdet==4)
%detect same freq or amp
condwhile=(((d(c,1)==b(1+e,1))|(d(c,2)==b(1+e,2))));
end
end
while(condwhile)
e=e+1;
if ((e>=(numel(b(:,1))-1)) | (numel(b(:,1))<2))
if (isempty(b))
code=1;
else
code=0;
end
return
end
end
end
end
end
0 件のコメント
J Richards
2012 年 4 月 18 日
Hi there,
Does anyone know of a way to stop elements from being repeated more than three times in a row? I have a 3 x 920 matrix consisting of the numbers 1 to 4, and wish to ensure that no number occurs more than 3 times consecutively in any column.
Thanks,
James
1 件のコメント
参考
カテゴリ
Help Center および File Exchange で Aerospace Applications についてさらに検索
製品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!