Dear,
I have these initial parameters :
numRows = 216;
numCols = 432;
A = zeros(numRows,numCols);
numOnesPerCol = randi(([2,3]),[1,numCols]);
numOnesPerRow = randi(([5,6]),[numRows,1]);
and I want to create a binary matrix with dimensions (numRows*numCols) that has numOnesPerCol and numOnesPerRow.
How can I do that please

4 commentaires

Hi there ! Can you be a liitle clear?Do you want all the rows of first col have the numonesperrow data or do you want the first col of all the row have numonepercoldata ??
You cant merge your parameter in any way but you can try
numRows = 216;
numCols = 432;
A = zeros(numRows,numCols);
numOnesPerCol = randi(([2,3]),[215,numCols]);
numOnesPerRow = randi(([5,6]),[1,numCols]);
a=[numOnesPerRow ;numOnesPerCol ]
a = 216×432
5 6 6 5 5 6 6 5 5 6 5 5 5 5 6 5 6 6 5 5 5 6 6 5 6 6 5 6 6 6 3 2 3 2 2 2 2 3 2 3 3 3 2 3 3 2 3 3 2 2 2 3 3 2 2 2 3 2 2 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 3 3 3 2 2 2 3 2 2 2 3 2 3 2 3 2 2 3 3 3 2 2 2 2 3 2 3 3 2 2 3 2 3 3 2 2 3 2 3 3 2 3 2 3 3 3 3 3 2 2 3 2 2 2 2 3 3 2 3 3 3 3 3 2 3 2 2 2 3 3 3 3 2 2 3 3 2 3 3 2 2 2 2 3 2 2 3 2 2 2 2 2 3 2 2 3 3 2 3 2 2 2 3 2 2 2 3 2 3 3 2 3 3 2 2 2 2 2 2 3 3 2 2 2 2 2 2 2 3 3 2 3 3 3 3 3 2 3 2 2 3 3 3 2 3 2 3 3 3 3 2 3 2 3 3 3 2 3 3 2 2 3 3 3 2 3 3 2 2 3 2 3 2 3 2 2 2 2 3 2 3 2 3 3 3 3 2 3 3 3 2 2 3 3 2 3 2 3 2 3 2 3 2 2 3 3 2 3 2 3 2 3 2 2 2 2 3 2 2 2 2 2 3
or vice versa
Torsten
Torsten le 15 Jan 2022
numOnesPerCol is a row vector (1x432) with only 2's and 3's.
numOnesPerRow is a row vector (1x216) with only 5's and 6's.
So what do you mean by
"I want to create a matrix with dimensions (numRows*numCols) that has numOnesPerCol and numOnesPerRow"
@Tina I will give you a small example to understand the idea
numRows = 5;
numCols = 10;
A = zeros(numRows,numCols);
numOnesPerCol = randi(([2,3]),[1,numCols]); % Number of ones in each column
numOnesPerRow = randi(([5,6]),[numRows,1]); % Number of ones in each Row
I obtain for example this binary matrix
which contain 5 rows and 10 columns, in each column I have 2 or 3 ones. And in each row I have 5 or 6 ones.
@Torsten I will give you a small example to understand the idea
numRows = 5;
numCols = 10;
A = zeros(numRows,numCols);
numOnesPerCol = randi(([2,3]),[1,numCols]); % Number of ones in each column
numOnesPerRow = randi(([5,6]),[numRows,1]); % Number of ones in each Row
I obtain for example this binary matrix
which contain 5 rows and 10 columns, in each column I have 2 or 3 ones. And in each row I have 5 or 6 ones.

Connectez-vous pour commenter.

 Réponse acceptée

Torsten
Torsten le 15 Jan 2022
Modifié(e) : Torsten le 20 Jan 2022

0 votes

Use intlinprog for the program
min: sum_{i=1}^{numRows} (e1_i+ + e1_i-) + sum_{j=1}^{numCols} (e2_j+ + e2_j-)
under the constraints
e1_j+ - e1_j- - sum_{i=1}^{numRows} A(i,j) = -numOnesPerCol(j) (j=1,...,numCols)
e2_i+ - e2_i- - sum_{j=1}^{numCols} A(i,j) = -numOnesPerRow(i) (i=1,...,numRows)
e1_j+, e1_j- >= 0 (j=1,...,numCols)
e2_i+, e2_i- >= 0 (i=1,...,numRows)
A(i,j) in {0,1} for all i,j

6 commentaires

high speed
high speed le 15 Jan 2022
@Torsten Sorry I didn't understand
Torsten
Torsten le 15 Jan 2022
Use the optimizer "intlinprog" and solve the system I defined above for the matrix elements A(i,j).
Image Analyst
Image Analyst le 15 Jan 2022
Modifié(e) : Image Analyst le 15 Jan 2022
A solution may not exist. For example if you wanted, in a 5x10 matrix to have 9 or more in each row but only 1 or 2 in each column. There is no solution for that. Solutions exist only for certain combinations.
Torsten
Torsten le 15 Jan 2022
Modifié(e) : Torsten le 15 Jan 2022
Yes, the solver will show up that the problem is not feasible (hopefully).
Torsten
Torsten le 20 Jan 2022
Modifié(e) : Torsten le 20 Jan 2022
Test whether this code works for your purpose.
If fopt as output from intlinprog is equal to zero, a matrix with the desired properties exists and is written to console.
If you want to run the program for larger values of numRows and numCols, you should construct Aeq as a sparse matrix.
numRows = 5;
numCols = 10;
%numOnesPerCol = randi(([2,3]),[1,numCols]); % Number of ones in each column
%numOnesPerRow = randi(([5,6]),[numRows,1]); % Number of ones in each Row
numOnesPerCol = [3 2 3 3 2 3 2 3 3 2];
numOnesPerRow = [5;6;5;5;5];
%Usually, nothing needs to be changed after this line
f = [ones(2*numCols,1);ones(2*numRows,1);zeros(numRows*numCols,1)];
intcon = 2*numCols+2*numRows+1:2*numRows+2*numCols+numRows*numCols;
Aeq11 = [eye(numCols,numCols),-eye(numCols,numCols),zeros(numCols,numRows),zeros(numCols,numRows)];
Aeq12 = -repmat(eye(numCols,numCols),1,numRows);
Aeq21 = [zeros(numRows,numCols),zeros(numRows,numCols),eye(numRows,numRows),-eye(numRows,numRows)];
Aeq22 = [];
for i=1:numRows
Aeq22 = [Aeq22;zeros(1,(i-1)*numCols),ones(1,numCols),zeros(1,(numRows-i)*numCols)];
end
Aeq22 = -Aeq22;
Aeq = [Aeq11,Aeq12;Aeq21,Aeq22];
beq = [-numOnesPerCol.';-numOnesPerRow];
Aineq = [];
bineq = [];
lb = [zeros(2*numCols,1);zeros(2*numRows,1);zeros(numCols*numRows,1)];
ub = [Inf(2*numCols,1);Inf(2*numRows,1);ones(numCols*numRows,1)];
[xopt,fopt,status,output] = intlinprog(f,intcon,Aineq,bineq,Aeq,beq,lb,ub);
disp(xopt)
disp(fopt)
disp(status)
disp(output)
if abs(fopt) < eps
for i = 1:numRows
for j = 1:numCols
A(i,j) = xopt(2*numRows+2*numCols+(i-1)*numCols+j);
end
end
disp(A)
end
high speed
high speed le 20 Jan 2022
@Torsten It works with your code. Thank you so much
I really appreciate your help

Connectez-vous pour commenter.

Plus de réponses (1)

Image Analyst
Image Analyst le 15 Jan 2022

0 votes

@high speed I think what you need to do is to first construct a Latin Rectangle:
Then mask it with two numbers like
output = latinRectangle == 1 | latinRectangle == 2;
Sorry I don't have Latin Rectangle code but there is Latin Square, and maybe Latin Rectangle, code in the File Exchange.

1 commentaire

high speed
high speed le 15 Jan 2022
@Image Analyst Thank you for your response, but I think that I don't need to work with Latin Rectangle.
Because the idea here is to obtain binary matrix that contains a variety of ones between 2 and 3 in each column and a variety of ones between 5 and 6 in each row as in this example

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by