How to got about solving this loop question

∗ We would like to generate a (5 × 5) square matrix filled with random integers between 1 and 10 and with a particular number of 1’s in the top-left to bottom-right diagonal. Write a script that asks the user to input a number of 1’s he would like to have in this diagonal (checking that the value is not bigger than 5) and then using while and for loops, the script should generate a (5×5) matrix filled with random values in [1, 10] and check if this matrix is valid. When a solution matrix has been found, print it as well as the number of tries that were required to find it. For example, running this script might result in this output:
>> DiagonalMatrix
Enter the number of 1s you want in the diagonal: 4
1 6 4 4 7
3 10 8 6 5
4 7 1 5 10
8 3 1 1 2
6 9 3 7 1
844 matrices were generated to find a good one
Not sure how to start the question. Pls help? Thanks!

5 comentarios

Adam
Adam el 26 de Sept. de 2014
Editada: Adam el 26 de Sept. de 2014
Is there a reason why you require to produce 844 matrices?
The problem is entirely solvable with the creation of a single matrix unless I am missing some subtlety. Or is your aim purely to see how many attempts at creating a totally random matrix it takes before you get one that matches the criteria?
Strauss
Strauss el 26 de Sept. de 2014
Hi,
the 844 matrices is the example given inside the lab manual, when the input is 4. I believe according to the question, it is necessary to print out all the matrices (no. of tries) required to find the suitable matrix. Any I also couldn't grasp the 844 matrices, but maybe it's an example? it can be way less?
Adam
Adam el 26 de Sept. de 2014
Well, as I said, you can just create one straight away that fits the problem. Unless the entire purpose of what you are trying to do is to arrive at it by pure randomness.
If you just want to get straight there you simply create a random matrix and overwrite 4 (or however many chosen) of the elements of the leading diagonal (indices chosen at random) with 1s and you are guaranteed to have a valid matrix. Or am I missing some other condition on the matrix - e.g. rows must sum to a specific value, etc?
Hi the question wants the user to input a certain number of 1s along the diagonal. And the number of 1s must be an integer between 0 to 5. And the 1s appear randomly along the diagonals. For instance, it can appear in (1,1) and (3,3) when input is 2. However for another attempt, it can appear in (2,2) and (5,5) and so on.
Anyway this is my attempt:
x=input('Enter the number of 1s you want in the diagonal: ');
if mod(x,1)==0 && x>0 && x<=5
M=randi(10,5,5);
for n=1:x
i(n)=randi(5)
while i(n+1)~=i(n)
M(i(n),i(n))= 1
end
end
else
disp('You have entered an invalid response')
end
But it goes into infinite loop, maybe while loop is wrong?
Adam
Adam el 26 de Sept. de 2014
I still don't understand why you need to generate 844 matrices to get a good one instead of just defining it straight away, but I guess that doesn't matter!.
I added a comment about your infinite loop below.

Iniciar sesión para comentar.

Respuestas (3)

Image Analyst
Image Analyst el 26 de Sept. de 2014
I'd start by looking up help and examples for rand() to get random numbers, inputdlg() to ask for user input, randperm() to get a specified number of locations along the diagonal for the 1's, and fprintf() to display results. Here's a snippet to get you started:
% Ask user for a number.
defaultValue = 5;
titleBar = 'Enter a value';
userPrompt = 'Enter the integer';
caUserInput = inputdlg(userPrompt, titleBar, 1, {num2str(defaultValue)});
if isempty(caUserInput),return,end; % Bail out if they clicked Cancel.
% Round to nearest integer in case they entered a floating point number.
integerValue = round(str2double(cell2mat(caUserInput)));
% Check for a valid integer.
if isnan(integerValue)
% They didn't enter a number.
% They clicked Cancel, or entered a character, symbols, or something else not allowed.
integerValue = defaultValue;
message = sprintf('I said it had to be an integer.\nI will use %d and continue.', integerValue);
uiwait(warndlg(message));
end

1 comentario

Strauss
Strauss el 26 de Sept. de 2014
Editada: Strauss el 26 de Sept. de 2014
Hi,
I use the checking integer by the following commands:
x=input('Enter the number of 1s you want in the diagonal: ');
if mod(x,1)==0 && x>0 && x<=5
% checking integer and for x between 0 to 5
M=randi(10,5,5);
%generate random matrix 5,5 required size for question

Iniciar sesión para comentar.

Star Strider
Star Strider el 26 de Sept. de 2014

0 votos

The randi and diag functions are your friends here.
Note that you can also use randi to generate random subscripts if you want it to. (That would work in assigning the 1 values randomly on the diagonal, for instance.)

5 comentarios

This is my attempt thus far, but it goes into infinite loop
x=input('Enter the number of 1s you want in the diagonal: ');
if mod(x,1)==0 && x>0 && x<=5
M=randi(10,5,5);
for n=1:x
i(n)=randi(5)
while i(n+1)~=i(n)
M(i(n),i(n))= 1
end
end
else
disp('You have entered an invalid response')
end
The expression being checked in your while loop there never changes in the body of the while loop so it will be infinite.
I don't think you want to create a 5*5 matrix x times though do you?
I'm not quite sure what you are looking to do there, but did you maybe mean to put the
i(n) = randi(5)
line inside the while loop?
Then at least the condition evaluated by the while would change each iteration.
Ok this is a breakdown of what i've done
x=input('Enter the number of 1s you want in the diagonal: ');
% prompt user for input
if mod(x,1)==0 && x>0 && x<=5
% check x is an integer and between 0 to 5
M=randi(10,5,5);
%generate a random (5,5) matrix from 1 to 10
for n=1:x
%creating variable n for number of times it loops up to x
i(n)=randi(5)
%creating i(n) for the coordinate in the matrix determine by random 1 to 5
while i(n+1)~=i(n)
%coordinate cannot repeat, so doing a loop for the condition to be met
M(i(n),i(n))= 1
%output the matrix if and only if the while loop condition is met
end
end
else
disp('You have entered an invalid response')
% error message
end
Star Strider
Star Strider el 26 de Sept. de 2014
Editada: Star Strider el 26 de Sept. de 2014
I don’t understand the reason for the mod call. I’m also having problems understanding your code.
This is my approach, since you have to test for the number of ones on the diagonal and not simply set them. If this violates the conditions of the problem and so would not be a valid solution, I need to know:
DD1 = 3; % Desired # of Ones On Diagonal
k = 0; % Initialise Counter
DX = false; % DX == false -> Criterion Not Met
while ~DX
k = k+1; % Increment Counter
M = randi(10, 5, 5); % Create Matrix
DM = diag(M); % Get Diagonal
DM1 = length(find(DM == 1)); % Find # of Ones on Diagonal
if DM1 == DD1 % Check If Criterion Reached
R = M; % If So, Output Result As ‘R’
DX = true; % Criterion Met
end
end
fprintf(1,'\n\tMatrix = [%2d %2d %2d %2d %2d\n\t\t\t %2d %2d %2d %2d %2d\n\t\t\t %2d %2d %2d %2d %2d\n\t\t\t %2d %2d %2d %2d %2d\n\t\t\t %2d %2d %2d %2d %2d]\n\n', R')
fprintf(1,'\n\tRequired %d Iterations\n\n',k)
There might be better and more efficient approaches, but this seems to work.
Strauss
Strauss el 26 de Sept. de 2014
Ok thanks. I will try it out.

Iniciar sesión para comentar.

Thorsten
Thorsten el 26 de Sept. de 2014
Useful function are
help rand
diag
find
numel

1 comentario

This is my attempt thus far, but it goes into infinite loop
x=input('Enter the number of 1s you want in the diagonal: ');
if mod(x,1)==0 && x>0 && x<=5
M=randi(10,5,5);
for n=1:x
i(n)=randi(5)
while i(n+1)~=i(n)
M(i(n),i(n))= 1
end
end
else
disp('You have entered an invalid response')
end

Iniciar sesión para comentar.

Categorías

Más información sobre Creating and Concatenating Matrices en Centro de ayuda y File Exchange.

Preguntada:

el 26 de Sept. de 2014

Comentada:

el 26 de Sept. de 2014

Community Treasure Hunt

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

Start Hunting!

Translated by