Effective way to find rectangle coordinates in 0-1 networks

advertisements

Say I have an MxN matrix of 0's and 1's. It may or may not be sparse.

I want a function to efficiently find rectangles in the array, where by rectangle I mean:

a set of 4 elements that are all 1's that create the 4 corners of a rectangle, such that the sides of the rectangle are orthogonal to the array axes. In other words, a rectangle is a set of 4 1's elements with coordinates [row index, column index] like so: [r1,c1], [r1,c2], [r2,c2], [r2,c1].

E.g. this setup has one rectangle:

0 0 0 1 0 1 0
0 0 0 0 0 0 0
0 1 0 0 0 0 0
1 0 0 1 0 1 0
0 0 0 0 0 0 0
0 0 0 1 0 0 1

For a given MxN array, I want a Python function F(A) that returns an array L of subarrays, where each subarray is the coordinate pair of the corner of a rectangle (and includes all of the 4 corners of the rectangle). For the case where the same element of the array is the corner of multiple rectangles, it's ok to duplicate those coordinates.


My thinking so far is:

1) find the coordinates of the apex of each right triangle in the array

2) check each right triangle apex coordinate to see if it is part of a rectangle

Step 1) can be achieved by finding those elements that are 1's and are in a column with a column sum >=2, and in a row with a row sum >=2.

Step 2) would then iterate through each coordinate determined to be the apex of a right triangle. For a a given right triangle coordinate pair, it would iterate through that column, looking at every other right triangle coordinate from 1) that is in that column. For any pair of 2 right triangle points in a column, it would then check which row has a smaller row sum to know which row would be faster to iterate through. Then it would iterate through all of the right triangle column coordinates in that row and see if the other row also has a right triangle point in that column. If it does, those 4 points form a rectangle.

I think this will work, but there will be repetition, and overall this procedure seems like it would be reasonably computationally intensive. What are some better ways for detecting rectangle corners in 0-1 arrays?


This is from the top of my head and during 5 hrs layover at LAX. Following is my algorithm:

Step 1: Search all rows for at least two ones

 |  0 0 0 1 0 1 0
 |  0 0 0 0 0 0 0
 |  0 1 0 0 0 0 0
\|/ 1 0 0 1 0 1 0
    0 0 0 0 0 0 0
    0 0 0 1 0 0 1

Output:

 -> 0 0 0 1 0 1 0
    0 0 0 0 0 0 0
    0 1 0 0 0 0 0
 -> 1 0 0 1 0 1 0
    0 0 0 0 0 0 0
 -> 0 0 0 1 0 0 1

Step 2: For each pair of ones at each row get the index for one's in the column corresponding to the ones, lets say for the first row:

 -> 0 0 0 1 0 1 0

you check for ones in the following columns:

       |   |
      \|/ \|/

 0 0 0 1 0 1 0
 0 0 0 0 0 0 0
 0 1 0 0 0 0 0
 1 0 0 1 0 1 0
 0 0 0 0 0 0 0
 0 0 0 1 0 0 1

Step 3: If both index match; return the indices of all four. This can be easily accessed as you know the row and index of ones at all steps. In our case the search at columns 3, 5 are going to return 3 assuming you start index from 0. So we get the indicies for the following:

 0 0 0 ->1 0 ->1 0
 0 0 0 0 0 0 0
 0 1 0 0 0 0 0
 1 0 0 ->1 0 ->1 0
 0 0 0 0 0 0 0
 0 0 0 1 0 0 1

Step 4: Repeat for all pairs

Algorithm Complexity I know you need to search for columns * rows * number of pairs but you can always use hashmaps to optimize search O(1). Which will make over complexity bound to the number of pairs. Please feel free to comment with any questions.