Create random matrix (MATLAB)
2 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
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
2022-1-20
编辑:Torsten
2022-1-20
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
更多回答(1 个)
Image Analyst
2022-1-15
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.
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!