Create random matrix (MATLAB)

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 个评论

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
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.

请先登录,再进行评论。

 采纳的回答

Torsten
Torsten 2022-1-15
编辑:Torsten 2022-1-20
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 个评论

@Torsten Sorry I didn't understand
Use the optimizer "intlinprog" and solve the system I defined above for the matrix elements A(i,j).
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 2022-1-15
编辑:Torsten 2022-1-15
Yes, the solver will show up that the problem is not feasible (hopefully).
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
@Torsten It works with your code. Thank you so much
I really appreciate your help

请先登录,再进行评论。

更多回答(1 个)

@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 个评论

@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

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Surrogate Optimization 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by