Introduction
I didn't have access to a CPP compiler or java runtime. Wrote this using my browser using ES2017. At least it runs in your browser! If you need I can write it in other languages (cpp, java, php, python).
And I must add that I don't know anything about Hungarian Algorithm
and I just created an algorithm to find the best minimum optimized lines!
I'm pushing this code and tests in a Github repo. So you can fire more Info, Codes, Documentations here
In matrix data presentation I used:
index 0
represents rows and index 1
represents columns.
Step 1
Go through input
array and count the zeros and store it in a 2 dimensional array.
The #matrixPower
indicates number of zeros in each column or row.
Step 2
In the next step we check row by row. Each row which have a value greater than 0
in #matrixPower[0]
is a row contains zeros and we call them powered
from now on.
Loop through powered row and check every column which crosses the current powered
row on 0
! If there was any column with power of 1
so we draw the line on the row! And decrease the power of every crossed column by 1
. Because it is covered by current row!
Count the lines in the progress.
Do this for all rows!
Notice: When a column crosses a row on a zero
the power would be at least 1
because of the zero
in the cross!
Step 3
If any powered
column remains we should draw the line on them!
That's it! now we have a map of lines and a number of minimum lines!
Note: inputMatrix
is the variable which contains your matrix!
let colLength = inputMatrix[0].length;
let rowLength = inputMatrix.length;
let matrixPower = [Array(rowLength).fill(0), Array(colLength).fill(0)];
let matrixLine = [Array(rowLength).fill(0), Array(colLength).fill(0)];
for (let row = 0; row < rowLength; row++) {
for (let col = 0; col < colLength; col++) {
if (inputMatrix[row][col] == 0) {
matrixPower[0][row]++;
matrixPower[1][col]++;
}
}
}
let minimum = 0;
let len = [matrixPower[0].length, matrixPower[1].length], cross;
for (let row = 0; row < len[0]; row++) {
cross = [];
for (let col = 0; col < len[0]; col++) {
if (inputMatrix[row][col] == 0) {
cross.push(col);
if (matrixPower[1][col] < 2) {
matrixLine[0][row] = 1;
}
}
}
if (matrixLine[0][row] == 1) {
minimum++;
for (let i = 0; i < cross.length; i++)
matrixPower[1][cross[i]]--;
}
}
for (let col = 0; col < len[1]; col++) {
if (matrixPower[1][col] > 0) {
matrixLine[1][col] = 1;
minimum++;
}
}
console.log(minimum);
I tested the algorithm against an optimized brute force function 100 times with random 12*10
matrixes. The result was 100% OK!
average time of brute force: 0.036653s
average time of Optimized algorithm: 0.000019s
total time of brute force: 3.9180s
total time of Optimized algorithm: 0.0025s
I hundred tests brute force took ~4seconds but the algorithm took only 2.5milliseconds
I'm sure this can be more optimized through more work.