Reputation: 83
I am generating a sequence of equal number of 0's and 1's . A = [ 0 1 1 0 1 1 1 0 0 1 0 0] My goal is to not have either 0 or 1 be repeated more than 2 times consecutively. in the above array A, you can see that 1 1 1 appears so somehow I need to switch it around so that one of them becomes 0 and if there is something like 0 0 0 then switch one of them to 1. I have tried few algorithms which work for few iterations but then I get different number of 0's and 1's. Also, the result or the output should maintain the same number of 1's and 0's i.e. six 0's and six 1's.
nums = mod( reshape(randperm(1*12), 1, 12), 2)
for i = 1:length(nums)-2
if nums(i+1)==nums(i) & nums(i+2) ==nums(i)
if nums(i) == 1
nums(i+2) = 0;
else
nums(i+2) = 1;
end
end
end
Upvotes: 1
Views: 107
Reputation: 2303
This might be one way that does not require trying permutations until you find one:
A = [];
N = 100; %//number of elements you desire in A (must be even).
Initialize A to have equal number of alternating 0s
and 1s
:
%//initialize A = [1 0 1 0 1 0....] with equal numbers of 0 and 1.
for x=1:N/2
A = [A 1 0];
end
Iterate through A
:
for x=3:(N-1) %//iterate through A, and decide to swap or not at each iteration
if ( A(x) == A(x-1) && A(x) == A(x-2) ) %//must swap
temp = A(x);
A(x) = A(x+1);
A(x+1) = temp;
elseif ( A(x+1) == A(x-1) && A(x+1) == A(x-2) ) %//must not swap
else %//can choose to swap or not
if (randi([0 1])) %should I swap?
temp = A(x);
A(x) = A(x+1);
A(x+1) = temp;
end
end
end
Upvotes: 0
Reputation: 3511
As your constraints are too intricated in order to solve the problem a posteriori, I'd suggest you to iterate until you find a solution. (This approach being possible considering the small length of your output vector).
The code would look like :
out=0;
while ~out
nums = mod( reshape(randperm(1*12), 1, 12), 2);
diff1=diff(nums);
diff1(diff1~=0)=NaN;
diff2=diff(diff1);
if all(diff2~=0)
out=1;
end
end
It basically iterates over 2 steps :
1/ Generate a candidate :
nums = mod( reshape(randperm(1*12), 1, 12), 2);
2/ Check if the candidate respects the constraints
diff1=diff(nums);
diff1(diff1~=0)=NaN;
Here MATLAB's diff
function is used in order to check for repeated numbers. A 0 means that a number is repeated 2 times. In order to check if a number is repeated 3 times we need to use this function a second time.
diff2=diff(diff1);
Now, a 0 will appear if a number has been repeated 3 times or more consecutively, thus we check the presence of 0's in diff2
. If there isn't any the candidate is kept and we end the while loop.
if all(diff2~=0)
out=1;
end
Example run :
Upvotes: 3
Reputation: 502
You just need to make a counter.
nums = mod( reshape(randperm(1*12), 1, 12), 2)
idx=1;
counter_one=0;
counter_zero=0;
changedIndex=0;
while idx <= length(nums)
if (nums(idx) == 0)
counter_zero = counter_zero+1;
counter_one=0;
if (counter_zero == 3)
nums(idx)=1;
counter_zero=0;
changedIndex = 1;
end
else
counter_one= counter_one+1;
counter_zero=0;
if (counter_one== 3)
nums(idx)=0;
counter_one=0;
changedIndex =1;
end
end
if (changedIndex == 1)
if (idx < length(nums))
if (nums(idx+1)) == 1
counter_one = 1;
changedIndex = 0;
else
counter_zero=1;
changedIndex = 0;
end
else
if (nums(idx)) == 1
counter_one = 1;
changedIndex = 0;
else
counter_zero=1;
changedIndex = 0;
end
end
end
idx = idx+1;
end
I have tested it just now and it worked fine
New test, with a more difficult vector
Upvotes: 0