Iteratively and randomly adding ones to a binary vector in matlab

83 Views Asked by At

In each iteration I want to add 1 randomly to binary vector, Let say

iteration = 1,
  k = [0 0 0 0 0 0 0 0 0 0]
iteration = 2,
k = [0 0 0 0 1 0 0 0 0 0]
iteration = 3,
k = [0 0 1 0 0 0 0 1 0 0]

, that goes up to length(find(k)) = 5;

Am thinking of for loop but I don't have an idea how to start.

2

There are 2 best solutions below

2
On BEST ANSWER

If it's important to have the intermediate vectors (those with 1, 2, ... 4 ones) as well as the final one, you can generate a random permutation and, in your example, use the first 5 indices one at a time:

n = 9; %// number of elements in vector
m = 5; %// max number of 1's in vector
k = zeros(1, n);
disp(k); %// output vector of all 0's
idx = randperm(n);
for p = 1:m
   k(idx(p)) = 1;
   disp(k);
end

Here's a sample run:

   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   1
   1   0   0   0   0   0   0   0   1
   1   0   0   1   0   0   0   0   1
   1   0   0   1   1   0   0   0   1
   1   1   0   1   1   0   0   0   1
2
On

I wouldn't even use a loop. I would generate a random permutation of indices that sample from a vector going from 1 up to the length of k without replacement then just set these locations to 1. randperm suits the task well:

N = 10; %// Length 10 vector
num_vals = 5; %// 5 values to populate
ind = randperm(N, num_vals); %// Generate a vector from 1 to N and sample num_vals values from this vector
k = zeros(1, N); %// Initialize output vector k to zero
k(ind) = 1; %// Set the right values to 1

Here are some sample runs when I run this code a few times:

k =

     0     0     1     1     0     1     1     0     0     1


k =

     1     0     0     0     1     0     1     1     0     1


k =

     1     0     0     0     1     0     1     1     0     1


k =

     0     1     1     1     0     0     1     0     0     1

However, if you insist on using a loop, you can generate a vector from 1 up to the desired length, randomly choose an index in this vector then remove this value from the vector. You'd then use this index to set the location of the output:

N = 10; %// Length 10 vector
num_vals = 5; %// 5 values to populate

vec = 1 : N; %// Generate vector from 1 up to N
k = zeros(1, N); %// Initialize output k

%// Repeat the following for as many times as num_vals
for idx = 1 : num_vals
    %// Obtain a value from the vector
    ind = vec(randi(numel(vec), 1));
    %// Remove from the vector
    vec(ind) = [];
    %// Set location in output to 1
    k(ind) = 1;
end

The above code should still give you the desired effect, but I would argue that it's less efficient.