pseudorandomize using brute force
9 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hi,
I have a vector consisted of 79 ones and 316 zeros. I would like to randomly order my vector so that a "1" can only occur after 3 or more zeros occur consecutively. So, my codes is as following:
A = [zeros(316,1); ones(79,1)];
%shuffle randomly
nTrials = size(A,1);
RandTrials = randperm(nTrials)';
A(:,2)=RandTrials(:,1);
A=sortrows(A,2);
for t=RandTrials %runs A vector by vector
if A(t,1)==1 & A(t-1,1)==0 & A(t-2,1)==0 & A(t-3,1)==0
; %do nothing
elseif A(t,1)==1 & A(t-1,1)==1;
RandTrials = randperm(nTrials)';
A(:,2)=RandTrials(:,1);
A=sortrows(A,2);
elseif A(t,1)==1 & A(t-1,1)==1 & A(t-1,2)==1;
RandTrials = randperm(nTrials)';
A(:,2)=RandTrials(:,1);
A=sortrows(A,2);
elseif A(t,1)==1 & A(t-1,1)==1 & A(t-1,2)==1 & A(t-1,3)==1;
RandTrials = randperm(nTrials)';
A(:,2)=RandTrials(:,1);
A=sortrows(A,2);
end
end
I was wondering what I am doing wrong in this code. Hope someone can help me on this.
Thanks in advance,
Nil
2 commentaires
Réponses (2)
Walter Roberson
le 7 Juin 2016
If a 1 can only occur after 3 or more zeros, then you need at least 3 times as many 0 as you have 1. As you have 315 ones, you would need at least 945 zeros.
Note: your code accidentally reverses the number of 0's and 1's.
2 commentaires
Walter Roberson
le 7 Juin 2016
You might want to have a look at http://www.mathworks.com/matlabcentral/answers/282617-how-to-do-this-operation-on-a-random-matrix#comment_364318 and grab my partitions routine there and modify it to have a minimum number of items per partition. The idea would be that you would partition (total length minus number of ones) into (number of ones) pieces, each of minimum length 3, and then you would take [zeros(1, number_in_partition), 1] as the substructure.
John D'Errico
le 8 Juin 2016
Modifié(e) : John D'Errico
le 8 Juin 2016
Even after the repair, correcting the number of zeros and ones...
You have 79 ones, and 316 zeros. The requirement is that a one may ONLY appear after 3 zeros have appeared.
So at the very best, a 1 may appear at position 4, then 8, then 12, etc. You see the pattern. The indexes of the ones elements appear at locations:
(1:79)*4
Ok, that is a COMPLETELY non-random sequence. But is it the shortest possible such sequence. It would account for
3*79
ans =
237
Thus 237 zeros.
316 - 3*79
ans =
79
You wish to always have 316 zeros. So there must be 79 more zeros.
The solution is now trivial. Just start with the NON-random sequence.
S = zeros(1,316);
S(4:4:316) = 1;
Now, choose random insertion points, and add a zero at that location. You can do it using a loop if you wish, one zero at a time. This is the simplest solution.
for i = 1:79
ns = numel(S);
% New location of a zero,
% after the newind location in S
newind = randi(ns+1,1) - 1;
S = [S(1:newind),0,S((newind+1):end);
end
I'm feeling too lazy to do it more intelligently, but that would be entirely possible too. Since it is hardly worthwhile to optimize code that is not yet asking to be optimized...
3 commentaires
Alan Weiss
le 9 Juin 2016
I believe that you misunderstood John's suggestion. He says the following:
- Create a nonrandom sequence of 0 and 1 having the property that you want, using all but 79 of your zeros
- Insert the 79 other zeros into the nonrandom sequence in a random way.
I believe that this is a fine idea, satisfying your requirements in all respects, and is an efficient computational scheme.
Alan Weiss
MATLAB mathematical toolbox documentation
John D'Errico
le 9 Juin 2016
Modifié(e) : John D'Errico
le 9 Juin 2016
Alan is completely correct. While it starts out as non-random, once you are done inserting randomly placed zeros, it is exactly that, and it has the property that you want to see, AND it is quite efficient.
The virtue of the scheme that I have proposed is in the end, you do have a fully random sequence that fits all of your requirements. Were you to try instead to choose how many zeros to place between the ones, then you would have a serious problem of assuring both that the total number of zeros is what was specified, and that every one has at least 3 zeros.
In fact, this is a fairly tightly constrained problem. You don't have that many spare zeros to insert there. On average, you will have 4 zeros between every one, but since you know that you MUST have at least 3 zeros, then there will be very few cases where you can have too many zeros separating a pair of ones.
Voir également
Catégories
En savoir plus sur Surrogate Optimization 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!