generate all binary matrix with given rows sum and columns sum - matrix

I'm trying to program an algoritmn with python which generate all the binary matrix (m row , n column) that we know sum of rows and sum of columns ... I tried few trials but I found that it was not valid . Someone can guide me please !
I tried to put all probabilities of each line with other lines and same for columns .. but it's unsuccesful way .

Related

Expression or Algorithm to get number of matrices with odd number occurrences of specific value in each row and column

I have to find total number of matrices that could be formed satisfying given condition.
Conditions -
Each matrix is filled with only 2 elements : (x) and (-x) where x is any
integer. [x is received from our web-app]
Now, such filled matrix is valid only if (-x) appears odd number of times in
each row and at the same time in each column.
Example -
Matrix (2x1) - valid matrices = 0
x
-x
Matrix (2x2) - valid matrices = 2
-x x x -x
x -x -x x
Matrix (3x3) - valid matrices = 22
6 combinations when -x appears once per row as well as once per column
3 combinations when -x appears trice per row but once per column
9 combinations when -x appears trice for 1 row and trice for 1 column (shape L,T,+ mirror images)
3 combinations when -x appears trice per column but once per row
1 combinations when -x appears at all positions
How should I calculate number of matrices satisfying given conditions - is there any algorithm or formula present for such cases?
Let us call n the number of rows and m the number of columns.
You get (n-1)(m-1) degrees of freedom, corresponding to the upper (n-1)(m-1) submatrix.
Then you have to calculate the last row and the last column, in such a way that the conditions are fulfilled.
You have a potential issue when calculating the last [n][m] value. If n and m have a different parity, no solution is possible.
Elsewhere, you get 2^{(n-1)(m-1)} combinations.
Edit
Please note that the parity constraints on rows and columns correspond to linear equations in Z/2Z. Therefore, the set of solutions in a vector space in Z/2Z, the size of which is 2^{something} or 0.

A greedy solution for a matrix rearrangment

I am working on something which I feel an NP-hard problem. So, I am not looking for the optimal solution but I am looking for a better heuristics. An integer input matrix (matrix A in the following example) is given as input and I have to produce an integer output matrix (matrix B in the following example) whose number of rows are smaller than the input matrix and should obey the following two conditions:
1) Each column of the output matrix should contain integers in the same order as they appear in the input matrix. (In the example below, first column of the matrix A and matrix B have the same integers 1,3 in the same order.)
2) Same integers must not appear in the same row (In the example below, first row of the matrix B contains the integers 1,3 and 2 which are different from each other.)
Note that the input matrix always obey the 2nd condition.
What a greedy algorithm looks like to solve this problem?
Example:
In this example the output matrix 'Matrix B' contains all the integers as they appear in the input matrix 'Matrix A" but the output matrix has 5 rows and the input matrix has 6 rows. So, the output 'Matrix B' is a valid solution of the input 'Matrix A'.
I would produce the output one row at a time. When working out what to put in the row I would consider the next number from each input column, starting from the input column which has the most numbers yet to be placed, and considering the columns in decreasing order of numbers yet to be placed. Where a column can put a number in the current output row when its turn comes up it should do so.
You could extend this to a branch and bound solution to find the exact best answer. Recursively try all possible rows at each stage, except when you can see that the current row cannot possibly improve on the best answer so far. You know that if you have a column with k entries yet to be placed, in the best possible case you will need at least k more rows.
In practice I would expect that this will be too expensive to be practical, so you will need to ignore some possible rows which you cannot rule out, and so cannot guarantee to find the best answer. You could try using a heuristic search such as Limited Discrepancy search.
Another non-exact speedup is to multiply the estimate for the number of rows that the best possible answer derived from a partial solution will require by some factor F > 1. This will allow you to rule out some solutions earlier than branch and bound. The answer you find can be no more than F times more expensive than the best possible answer, because you only discard possibilities that cannot improve on the current answer by more than a factor of F.
A greedy solution to this problem would involve placing the numbers column by column, top down, as they appear.
Pseudocode:
For each column c in A:
r = 0 // row index of next element in A
nextRow = 0 // row index of next element to be placed in B
while r < A.NumRows()
while r < A.NumRows() && A[r, c] is null:
r++ // increment row to check in A
if r < A.NumRows() // we found a non-null entry in A
while nextRow < A.NumRows() && ~CheckConstraints(A[r,c], B[nextRow, c]):
nextRow++ // increment output row in B
if 'nextRow' >= A.NumRows()
return unsolvable // couldn't find valid position in B
B[nextRow, c] = v // successfully found position in B
++nextRow // increment output row in B
If there are no conflicts you end up "packing" B as tightly as possible. Otherwise you greedily search for the next non-conflicting row position in B. If none can be found, the problem is unsolvable.
The helper function CheckConstraints checks backwards in columns for the same row value in B to ensure the same value hasn't already been placed in a row.
If the problem statement is relaxed such that the output row count in B is <= the row count in A, then if we are unable to pack B any tighter, then we can return A as a solution.

Maximize row-sameness given a binary MxN matrix and the ability to toggle columns?

If you have a binary matrix of 1s and 0s, and you are able to toggle columns (change all 1s to 0s in the column, and all 0s to 1s), how do you find the max number of "pure" rows for all possible combinations of column toggles?
"pure" meaning the row is all 0s, or all 1s.
Ex:
1 0
1 0
1 1
You can toggle either column to get 2 rows that are "pure", which is the best you can do (toggling both is not better), so you return 2 (the max number of "pure" rows).
I can't seem to figure out an efficient way to do this. The only way I've gotten so far is with a bunch of loops and brute force and checking for sameness by checking if the sum of a row is either 0 (all 0s) or N (the number of elements in a row).
Update
After clarification from the OP, the max-pure row problem is to find the max number of rows that become either 00...0 or 11...1 after toggling. I have updated my solution accordingly.
Note that we have the following facts:
If two rows ri and rj reduce to a pure row after toggling, then we must have ri = rj to start with.
If ri ≠ rj and ri overlaps rj (i.e. some of their corresponding column are the same), then both of them cannot map to a pure row.
Both of the facts above comes directly from the following observation:
Max number of "pure" rows is the same as the max number of identical rows
Proof
We claim that all the rows that constitute a solution of the max-pure problem must be identical in the matrix M.
Suppose we are given a m-by-n matrix M, and we have found a solution of the max-pure row problem. Let rows ri and rj be two arbitrary rows that get reduce to pure rows after toggling.
Observe that after all the necessary toggling operation on the columns (denote by σ1, σ2, ..., σk), ri and rj are both "pure" rows. i.e. We have the following:
σ1(σ2(...(σk(ri)...)) = σ1(σ2(...(σk(rj)...)) = 00...0
or
σ1(σ2(...(σk(ri)...)) = σ1(σ2(...(σk(rj)...)) = 11...1
So after applying all these toggling operations, ri and rj will equal each other. If we undo the very last toggling (i.e. we toggling the same column entry of these rows), it is obviously that both ri and rj will still map to the same output. i.e. We have the following:
σ2(σ3(...(σk(ri)...)) = σ2(σ3(...(σk(rj)...))
If we we continue undoing the toggling operations, we can conclude that ri = rj. In other words, if you pick any arbitrary rows from a solution of the max-pure problem, these rows must be identical in the beginning.
Idea
Given a row ri, if it can be reduce to the pure row, say 00...0, then we know that another row rj cannot be reduced to 11...1 if ri overlaps with rj (from fact 2 above). We can only hope that another row rk which does not overlap with ri to reduce to 11...1.
Algorithm
From the preceding idea, we can have the following simple algorithm to solve the max-pure row problem.
We first scan over the rows of matrix M, and then find all the unique rows of the matrix (denote by s1, s2, ..., sk). We let count(si) denotes the number of times si appears in M.
We then loop over all the pairs (si, sj) to determine the max-pure row number as below:
int maxCount = 0;
for each row si:
for each sj ≠ si:
if (sj overlaps si)
continue;
else
if (count(si) + count(sj) > maxCount)
// We have found a better pair
maxCount = count(si) + count(sj);
return maxCount;
We are doing O(n) works in the inner for loop (for entry-wise checking whether two rows overlap), and the loops are over O(m2) rows in the worst-case, so the running time of the algorithm is O(nm2).
Maybe I'm missing something, but a quick run down the rows should answer your question.
Start with the top row, and flip each column as needed until the top row is all T. Count the number of pure rows. Repeat for every other row, finding if the count is greater than any previous row.
You don't need to invert the whole matrix so each row is all F, the count will be the same.
The worst-case running time would be O(nm).

choosing row m from two matrices at random

I have two m*n matrices, A and P. I want to randomly choose the same 3 rows from both matrices, e.g. rows m, m+1, m+2 are picked from both matrices. I want to be able to make the calculation U=A-P on the selected subset (i.e. Usub-Psub), rather than before the selection. So far I have only been able to select rows from one matrix, without being able to match it to the other. The code I use for this is:
A=[0,1,1,3,2,4,4,5;0,2,1,1,3,3,5,5;0,3,1,1,4,4,2,5;0,1,1,1,2,2,5,5]
P=[0,0,0,0,0,0,0,0;0,0,0,0,0,0,0,0;0,0,0,0,0,0,0,0;0,0,0,0,0,0,0,0]
U=A-P
k = randperm(size(U,1));
Usub = U(k(1:3),:);
I would first create a function that returned a submatrix that had only three rows in it that takes an integer as the first of the three row. Then i'd do something like this:
m = number of rows;
randomRow = rand() % m;
U = A.sub(randomRow) - P.sub(randomRow);

help writing an algorithm

i need to write algo for this problem. i have never written an algo before . please correct me.
there is a list which contains four collumns each with numbers with upto 5 digits and about 10 rows in total. we have to remove the rows containng any number with less than 3 digits.
here is how i have tried
read list into multi-dimensional array
for each number in the array
if numdigits < 3
delete all numbers of that row
i know this is not the correct algorithm . can you help me correct it .
When creating your original list, rather check the individual values then, and not add it to that list if any of the numbers has less than 3 digits, that way reducing the original list size.
EDIT:
foreach row in original_document
{
bool allMoreThan3Digits = true
foreach cell in row
allMoreThan3Digits = allMoreThan3Digits && (ABS(cell.Value) >= 100)
if (allMoreThan3Digits)
add row to new list
}
Something like that.
With up to 5 digits in total in each column? If so here is what I would do.
For each row in list
For each column in row
if column number < 100 then
row delete

Resources