i wanted to know which algorithm should i apply here. Would a DFS do?
Given a 2–d matrix. Find the total number of connected sets in that matrix.
Connected set can be defined as group of cell(s) which has 1 mentioned on it and have at least one other cell in that set with which they share the neighbor relationship. A cell with 1 in it and no surrounding neighbor having 1 in it can be considered as a set with one cell in it. Neighbors can be defined as all the cells adjacent to the given cell in 8 possible directions (i.e. N, W, E, S, NE, NW, SE, SW direction). A cell is not a neighbor of itself.
For example:
1 0 0 1
0 0 1 0
0 0 1 0
1 0 0 1
number of connected sets is 3
0 0 1 0 0 1 0 0
1 0 0 0 0 0 0 1
0 0 1 0 0 1 0 1
0 1 0 0 0 1 0 0
1 0 0 0 0 0 0 0
0 0 1 1 0 1 1 0
1 0 1 1 0 1 1 0
0 0 0 0 0 0 0 0
number of connected set is 9.
Finding Connected Components We can use either DFS or BFS for this task. The variable Component_Count returns the number of connected components in the given graph. We start by initializing all the vertices to the flag not visited. We then choose any random vertex to start and check if we've visited the vertex or not.
The problem can be easily solved by applying DFS() on each component. In each DFS() call, a component or a sub-graph is visited. We will call DFS on the next un-visited component. The number of calls to DFS() gives the number of connected components.
A strongly connected component (SCC) of a directed graph is a maximal strongly connected subgraph. For example, there are 3 SCCs in the following graph. We can find all strongly connected components in O(V+E) time using Kosaraju's algorithm.
Pythonic Implementation, More understandable code:
# sea is 2 D array of 0 and 1s we have to find 1's group surrounded by 0's
def dfs(sea, i, j, b, h, visited):
surround = ((-1, -1), (0, -1), (1, -1),
(-1, 0), (1, 0),
(-1, 1), (0, 1), (1, 1)
)
if can_visit(sea, i, j, b, h, visited):
for s in surround:
visited[(i, j)] = 1
dfs(sea, i + s[0], j + s[1], b, h, visited)
def can_visit(sea, i, j, b, h, visited):
if i >= 0 and j >= 0 and i < b and j < h:
if (i, j) not in visited and sea[i][j] == 1:
return True
def find_island(sea):
visited = {}
h = len(sea)
count = 0
for i, row in enumerate(sea):
b = len(row)
for j, item in enumerate(row):
if can_visit(sea, i, j, b, h, visited):
count += 1
dfs(sea, i, j, b, h, visited)
return count
sea = [[1, 1, 0, 0, 0],
[0, 1, 0, 0, 1],
[1, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[1, 0, 1, 0, 1]
]
print find_island(sea)
I don't think you will need to think of it as a general graph problem and apply any algorithm such as BFS or DFS.
You will need to do three scans of the matrix.
scan 1:
start from the top
1 0 0 2
and your example should look like follows
1 0 0 2
0 0 2 0
0 0 2 0
3 0 0 2
scan 2:
start from the bottom check if each neighbor has the same number as the left most neighbor as well as the same number as the neighbor in the row below it
basically if you have a matrix like this
1 0 2
1 0 2
0 1 0
to check ensure that a set has really the same number
scan 3:
count the number of unique non-0 entries in the matrix
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With