Pseudorandom sequence with NO MORE than two consecutive numbers

Hi everyone.
I want to create an array of numbers from 1 to 4 with a pseudorandom order. A column has 100 rows, and each number must be five times in a subgroup of 20 rows. Additionally, the same number appears in two consecutive rows at the most.
The solution that I found here ( https://es.mathworks.com/matlabcentral/answers/743412-how-to-randomize-trials-without-presenting-the-same-trial-consecutively ), has the main problem that in a subset of 4 rows you can predict which number is the 4th.
Avoiding a while would be unbelievable so that my desired final matrix will be 100x10
Here I drop a short example what I need:
Correct pseudorandomization:
2 3 4 3 3 1 2 4 1 3 3 1 2 4 2 1 1 4 2 4...
Incorrect:
4 3 1 2 4 1 3 2 2 4 3 1 4 3 2 1 2 3 4 1...
any help will be welcome.

댓글 수: 2

"Additionally, the same number appears in two consecutive rows at the most."
Do you mean column instead of rows?
No, @Dyuman Joshi. I refer to having the same number repeated in more than two consecutive rows of the same column.

댓글을 달려면 로그인하십시오.

답변 (3개)

% Create the matrix
randomMatrix = createRandomMatrix();
% Display the first 20 rows of the matrix
disp(randomMatrix(1:20,:))
1 1 2 4 2 3 1 2 4 3 4 3 1 4 4 4 2 2 2 4 3 2 3 3 4 4 3 1 1 4 2 1 2 4 1 3 1 1 3 1 4 1 4 4 4 4 3 3 4 2 2 3 2 2 1 4 2 1 2 1 3 4 2 1 1 1 4 4 2 3 4 2 3 3 3 2 4 3 3 4 2 4 4 2 3 2 1 4 2 2 1 1 2 1 4 3 3 4 4 1 3 4 1 1 2 1 2 3 2 2 2 2 4 3 2 4 4 3 1 2 3 2 3 2 4 1 2 4 4 3 1 1 4 1 3 2 1 3 3 3 3 4 1 1 1 1 3 2 4 2 4 3 1 2 2 3 3 1 1 1 4 3 3 3 2 2 2 1 3 1 2 4 3 2 3 3 1 4 3 3 1 3 4 3 1 2 4 2 1 4 1 2 1 4 3 1 4 2 1 4
function matrix = createRandomMatrix()
numRows = 100;
numColumns = 10;
numGroups = 5;
values = 1:4;
% Preallocate the matrix
matrix = zeros(numRows, numColumns);
for col = 1:numColumns
% Repeat for each subgroup of rows
for group = 1:numGroups
isValid = false;
while ~isValid
% Generate a random permutation of the numbers for this subgroup
subgroup = repmat(values, 1, numRows/(numGroups*length(values)));
subgroup = subgroup(randperm(length(subgroup)));
% Check the no more than two consecutive numbers condition
for i = 3:length(subgroup)
if subgroup(i) == subgroup(i-1) && subgroup(i) == subgroup(i-2)
break;
end
end
% If we reached the end without breaking, the subgroup is valid
if i == length(subgroup)
isValid = true;
end
end
% Fill the subgroup into the matrix
matrix((group-1)*numRows/numGroups+1:group*numRows/numGroups, col) = subgroup;
end
end
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
Professional Interests
  • Technical Services and Consulting
  • Embedded Systems | Firmware Developement | Simulations
  • Electrical and Electronics Engineering
Feel free to contact me.

댓글 수: 1

Pablo
Pablo 2024년 1월 12일
편집: Pablo 2024년 1월 12일
Thank you for your answer. The function is high-speed and creates the matrix without taking many resources. However, checking the outputs, I found that sometimes it fails to control having the same number more than two times in a row (see the final four numbers of the third column). Here, I attach an example of an output I got. On this occasion, I asked the function for just five columns:
2 1 3 1 4
2 2 3 1 2
3 4 2 3 1
3 3 2 1 3
1 3 1 2 2
3 2 1 4 3
2 4 3 3 3
4 3 2 3 2
1 2 3 1 4
2 4 2 2 2
4 2 1 1 4
4 4 1 4 2
1 3 3 2 1
3 1 4 3 3
1 4 2 4 4
1 1 4 2 1
3 2 1 4 1
2 3 4 3 3
4 1 4 2 4
4 1 4 4 1

댓글을 달려면 로그인하십시오.

Hassaan
Hassaan 2024년 1월 12일
편집: Hassaan 2024년 1월 12일
@Pablo Check this out.
% Create the matrix
randomMatrix = createRandomMatrix();
% Display the first 20 rows of the matrix
disp(randomMatrix(1:20,:))
1 3 2 4 4 1 3 4 3 1 4 4 4 4 4 3 3 3 3 4 4 3 2 1 2 4 2 4 1 2 3 3 3 1 2 1 4 4 4 1 3 2 1 3 1 4 1 1 3 3 4 1 3 4 4 1 3 1 1 2 1 4 3 1 1 4 2 3 4 3 2 3 2 2 1 1 4 1 2 2 3 2 3 3 3 2 1 2 2 1 1 2 1 3 1 2 2 1 4 2 2 1 2 2 3 1 3 2 4 4 2 1 1 2 2 3 2 3 1 3 3 4 4 4 2 2 4 2 1 3 1 1 4 2 1 3 3 1 3 1 2 2 1 3 3 4 1 4 2 4 3 4 1 1 3 2 2 3 1 1 2 1 3 2 4 3 4 2 2 4 4 4 4 1 3 3 1 3 3 2 4 3 2 4 2 4 1 2 4 4 1 2 4 3 4 2 4 4 2 3
function matrix = createRandomMatrix()
numRows = 100;
numColumns = 10;
numGroups = 5;
values = 1:4;
% Preallocate the matrix
matrix = zeros(numRows, numColumns);
for col = 1:numColumns
for group = 1:numGroups
isValid = false;
while ~isValid
% Generate a random permutation of the numbers for this subgroup
subgroupSize = numRows/(numGroups*length(values));
subgroup = repmat(values, 1, subgroupSize);
subgroup = subgroup(randperm(length(subgroup)));
% Check that no more than two consecutive numbers are the same
isValid = true;
for i = 3:length(subgroup)
if subgroup(i) == subgroup(i-1) && subgroup(i) == subgroup(i-2)
isValid = false;
break;
end
end
end
% Fill the subgroup into the matrix
startRow = (group-1)*numRows/numGroups + 1;
endRow = group*numRows/numGroups;
matrix(startRow:endRow, col) = subgroup;
end
end
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
Professional Interests
  • Technical Services and Consulting
  • Embedded Systems | Firmware Developement | Simulations
  • Electrical and Electronics Engineering
Feel free to contact me.

댓글 수: 1

Thank you again, @Muhammad Hassaan Shah, but this code has the same problem as before. In the output, the same number can be found more than two times in consecutive rows. Apparently, the code controls not repeating the same number in two successive rows but only in the subgroup of 20 rows (where the four numbers must be five times each). Nevertheless, as I mentioned, the column has 100 rows, and this rule must work for the whole column.
The output I got with your last code (from row 40 to 62; see final numbers of the first column or first numbers of the sixth column):
1 3 4 4 1 4 1 2 1 4
3 1 4 4 1 4 1 4 1 3
4 1 3 1 4 4 4 4 2 4
3 3 1 2 2 1 1 3 3 1
4 1 3 4 2 2 3 3 1 1
2 4 4 3 3 4 4 2 2 3
4 2 2 4 4 3 3 1 4 1
1 2 1 3 3 1 2 4 2 2
1 3 2 1 4 2 1 2 1 3
2 1 3 1 4 2 3 1 1 4
1 4 1 2 1 4 2 2 4 2
4 4 3 4 4 2 4 3 4 4
2 3 4 2 1 4 2 1 3 3
1 3 1 3 3 1 1 3 2 4
3 2 2 4 1 3 1 4 4 3
4 2 4 3 2 3 4 3 4 2
3 4 3 1 3 1 3 1 3 1
2 2 1 1 2 3 2 1 3 2
2 1 2 2 1 1 4 2 1 1
1 4 4 3 3 3 2 2 2 4
3 3 2 2 2 2 3 4 3 2
3 3 3 2 3 4 4 4 3 1
3 1 4 2 4 3 2 3 3 3

댓글을 달려면 로그인하십시오.

Hassaan
Hassaan 2024년 1월 13일
편집: Hassaan 2024년 1월 13일
@Pablo Check this out.
% Create and display the matrix
randomMatrix = createRandomMatrix();
disp(randomMatrix(1:40,:));
1 3 1 2 1 2 4 1 4 2 3 4 2 1 4 4 2 3 2 4 2 2 4 4 2 1 1 4 1 1 4 1 3 3 3 3 3 2 3 3 4 2 4 2 1 1 4 4 2 1 3 4 1 3 4 2 3 2 1 3 2 3 2 4 2 3 1 1 3 2 1 1 3 1 3 4 2 3 4 4 2 4 2 3 1 1 1 3 1 4 1 3 4 1 4 2 2 2 2 2 4 2 1 2 3 3 4 1 4 1 3 1 3 4 2 4 3 4 3 3 3 1 2 4 3 3 3 4 3 1 1 4 3 2 1 2 4 3 1 3 4 3 1 1 4 1 2 2 2 2 2 2 4 3 2 4 1 1 4 4 3 1 4 4 1 4 4 3 2 1 1 4 2 2 2 3 1 4 1 2 2 2 1 3 3 1 3 2 4 3 4 3 3 1 4 2 2 1 3 4 1 4 2 2 4 4 2 4 1 3 4 1 3 3 1 1 4 1 4 4 3 2 1 1 2 3 1 2 3 2 2 3 4 4 3 2 3 3 2 1 3 1 3 1 1 3 1 2 4 2 1 3 4 2 3 4 4 4 1 3 2 2 1 4 4 1 3 3 3 4 4 4 2 3 2 2 2 1 2 1 4 3 4 4 3 3 1 2 2 2 2 4 3 1 4 4 2 1 3 1 3 1 2 2 2 1 3 4 1 3 1 2 1 3 1 2 4 3 4 4 2 1 4 3 4 1 4 4 1 4 3 2 3 2 2 3 3 1 4 2 4 3 2 1 3 4 1 3 2 3 1 4 1 4 1 2 2 2 3 1 4 3 2 2 3 2 2 4 1 2 2 4 4 4 1 4 1 3 2 4 3 2 1 3 4 1 3 1 4 1 1 1 3 1 2 3 4 2 3 3
function randomMatrix = createRandomMatrix()
numRows = 100;
numColumns = 10;
values = 1:4;
% Preallocate the matrix
randomMatrix = zeros(numRows, numColumns);
for col = 1:numColumns
% Initialize the column
col_data = [];
while length(col_data) < numRows
% Shuffle the values and add them to the column
shuffledValues = values(randperm(length(values)));
col_data = [col_data, shuffledValues];
% Check if the last three elements are the same, if so, remove them
if length(col_data) > 2 && col_data(end) == col_data(end-1) && col_data(end) == col_data(end-2)
col_data(end-2:end) = [];
end
end
% Assign the generated column data to the matrix
randomMatrix(:, col) = col_data(1:numRows).';
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
Professional Interests
  • Technical Services and Consulting
  • Embedded Systems | Firmware Developement | Simulations
  • Electrical and Electronics Engineering
Feel free to contact me.

카테고리

도움말 센터File Exchange에서 Resizing and Reshaping Matrices에 대해 자세히 알아보기

질문:

2024년 1월 12일

편집:

2024년 1월 13일

Community Treasure Hunt

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

Start Hunting!

Translated by