Python 识别矩阵中的最大连通分量

Python 识别矩阵中的最大连通分量,python,algorithm,matrix,depth-first-search,connected-components,Python,Algorithm,Matrix,Depth First Search,Connected Components,我有一个包含1和0的python numpy矩阵,我需要确定矩阵中最大的1集合: 矩阵最多可以有960000个元素,因此我希望避免暴力解决方案 解决这个问题最明智的方法是什么?您可以使用一个名为“是python实现”的数据结构。此数据结构是为此类任务而设计的 如果当前元素为1,则遍历行,检查是否有任何已遍历的邻居为1。如果是,则将此元素添加到其集合中。如果有1个以上的并集,则为这些集合。如果没有邻居为1,则创建一个新集合。最后输出最大的一组 这项工作如下: def MakeSet(x):

我有一个包含1和0的python numpy矩阵,我需要确定矩阵中最大的1集合:

矩阵最多可以有960000个元素,因此我希望避免暴力解决方案


解决这个问题最明智的方法是什么?

您可以使用一个名为“是python实现”的数据结构。此数据结构是为此类任务而设计的

如果当前元素为1,则遍历行,检查是否有任何已遍历的邻居为1。如果是,则将此元素添加到其集合中。如果有1个以上的并集,则为这些集合。如果没有邻居为1,则创建一个新集合。最后输出最大的一组

这项工作如下:

def MakeSet(x):
  x.parent = x
  x.rank   = 0
  x.size = 1

def Union(x, y):
  xRoot = Find(x)
  yRoot = Find(y)
  if xRoot.rank > yRoot.rank:
    yRoot.parent = xRoot
  elif xRoot.rank < yRoot.rank:
    xRoot.parent = yRoot
  elif xRoot != yRoot: # Unless x and y are already in same set, merge them
    yRoot.parent = xRoot
    xRoot.rank = xRoot.rank + 1
  x.size += y.size
  y.size = x.size

def Find(x):
  if x.parent == x:
    return x
  else:
    x.parent = Find(x.parent)
    return x.parent

""""""""""""""""""""""""""""""""""""""""""

class Node:
  def __init__ (self, label):
    self.label = label
  def __str__(self):
    return self.label

rows = [[1, 0, 0], [1, 1, 0], [1, 0, 0]]
setDict = {}
for i, row in enumerate(rows):
  for j, val in enumerate(row):
    if row[j] == 0:
      continue
    node = Node((i, j))
    MakeSet(node)
    if i > 0:
      if rows[i-1][j] == 1:
        disjointSet = setDict[(i-1, j)]
        Union(disjointSet, node)
    if j > 0:
      if row[j-1] == 1:
      disjointSet = setDict[(i, j-1)]
      Union(disjointSet, node)
    setDict[(i, j)] = node
print max([l.size for l in setDict.values()])

>> 4

这是一个完整的工作示例,其中不相交集的代码取自上面的链接。

您可以使用一个名为is-python实现的数据结构。此数据结构是为此类任务而设计的

如果当前元素为1,则遍历行,检查是否有任何已遍历的邻居为1。如果是,则将此元素添加到其集合中。如果有1个以上的并集,则为这些集合。如果没有邻居为1,则创建一个新集合。最后输出最大的一组

这项工作如下:

def MakeSet(x):
  x.parent = x
  x.rank   = 0
  x.size = 1

def Union(x, y):
  xRoot = Find(x)
  yRoot = Find(y)
  if xRoot.rank > yRoot.rank:
    yRoot.parent = xRoot
  elif xRoot.rank < yRoot.rank:
    xRoot.parent = yRoot
  elif xRoot != yRoot: # Unless x and y are already in same set, merge them
    yRoot.parent = xRoot
    xRoot.rank = xRoot.rank + 1
  x.size += y.size
  y.size = x.size

def Find(x):
  if x.parent == x:
    return x
  else:
    x.parent = Find(x.parent)
    return x.parent

""""""""""""""""""""""""""""""""""""""""""

class Node:
  def __init__ (self, label):
    self.label = label
  def __str__(self):
    return self.label

rows = [[1, 0, 0], [1, 1, 0], [1, 0, 0]]
setDict = {}
for i, row in enumerate(rows):
  for j, val in enumerate(row):
    if row[j] == 0:
      continue
    node = Node((i, j))
    MakeSet(node)
    if i > 0:
      if rows[i-1][j] == 1:
        disjointSet = setDict[(i-1, j)]
        Union(disjointSet, node)
    if j > 0:
      if row[j-1] == 1:
      disjointSet = setDict[(i, j-1)]
      Union(disjointSet, node)
    setDict[(i, j)] = node
print max([l.size for l in setDict.values()])

>> 4

这是一个完整的工作示例,其中不相交集的代码取自上面的链接。

我认为计数将在下一步关闭。例如,如果将行更改为行=[[1,0,0],[1,1,1],[1,0,0]],则仍然得到4,尽管它应该是5。将工会改为

def Union(x, y):
  xRoot = Find(x)
  yRoot = Find(y)
  if xRoot.rank > yRoot.rank:
    yRoot.parent = xRoot
    xRoot.size += yRoot.size
  elif xRoot.rank < yRoot.rank:
    xRoot.parent = yRoot
    yRoot.size += xRoot.size
  elif xRoot != yRoot:  # Unless x and y are already in same set, merge them
    yRoot.parent = xRoot
    xRoot.rank = xRoot.rank + 1
    xRoot.size += yRoot.size

似乎已经解决了。

我想未来几天会停止计数。例如,如果将行更改为行=[[1,0,0],[1,1,1],[1,0,0]],则仍然得到4,尽管它应该是5。将工会改为

def Union(x, y):
  xRoot = Find(x)
  yRoot = Find(y)
  if xRoot.rank > yRoot.rank:
    yRoot.parent = xRoot
    xRoot.size += yRoot.size
  elif xRoot.rank < yRoot.rank:
    xRoot.parent = yRoot
    yRoot.size += xRoot.size
  elif xRoot != yRoot:  # Unless x and y are already in same set, merge them
    yRoot.parent = xRoot
    xRoot.rank = xRoot.rank + 1
    xRoot.size += yRoot.size

似乎可以解决问题。

您已经尝试过了吗?我有一个实现,我把矩阵分成子矩阵,然后取这些子矩阵的和,找到最大的一个,我这样做了两次,然后通过检查相邻字段并将组件添加到集群来强制解决方案。如果您不需要自己的实现(如果它是家庭作业),例如,请查看NetworkX的python模块和此处的相关问题:谢谢。我来看看!你已经试过了吗?我有一个实现,我把矩阵分成子矩阵,然后取这些子矩阵的和,找到最大的一个,我这样做了两次,然后通过检查相邻字段并将组件添加到集群来强制解决方案。如果您不需要自己的实现(如果它是家庭作业),例如,请查看NetworkX的python模块和此处的相关问题:谢谢。我来看看!实际上,如果你事先知道边的不相交集有点过分了。如果事先知道不相交集的边有点太多,那么可以直接进行图遍历。您可以只进行图形遍历