当前位置: 首页 > 知识库问答 >
问题:

一种将图划分为完全子图的算法

长孙兴德
2023-03-14

我需要一个算法来将无向图的顶点划分为一个或多个子图,这样每个子图都是一个完整的图(每个顶点与每个其他顶点相邻)。每个顶点都需要恰好位于其中一个子图中。

这里有一个例子:

input = [
    (A, B),
    (B, C),
    (A, C),
    (B, D),
    (D, E),
]
output = myalgo(input)  # [(A, B, C), (D, E)]

下面的图片更好地描述了这个问题:

Kosaraju算法:它只适用于有向图。

共有1个答案

上官锦
2023-03-14

这里有一个类,它实现了对完整子图的分段。它绝不是最优化的,可能会得到显著的改进,但这是一个起点

class SCCManager:
    def __init__(self, edges):
        self.clusters = []
        self.edges = edges

    def clusters_in(self, conn):
        first, second = conn
        f_clust = None
        s_clust = None
        for i, clust in enumerate(self.clusters):
            if first in clust:
                f_clust = i
            if second in clust:
                s_clust = i
            # break early if both already found
            if f_clust and s_clust:
                break
        return (f_clust, s_clust)

    def all_connected(self, cluster, vertex):
        for v in cluster:
            connected = (v, vertex) in self.edges or (vertex, v) in self.edges
            # break early if any element is not connected to the candidate
            if not connected:
                return False
        return True

    def get_scc(self):
        for edge in self.edges:
            c_first, c_second = self.clusters_in(edge)

            # case 1: none of the vertices are in an existing cluster
            # -> create new cluster containing the vertices
            if c_first == c_second == None:
                self.clusters.append([edge[0], edge[1]])
                continue

            # case 2: first is in a cluster, second isn't
            # -> add to cluster if eligible
            if c_first != None and c_second == None:
                # check if the second is connected to all cluster components
                okay = self.all_connected(self.clusters[c_first], edge[1])
                # add to cluster if eligible
                if okay:
                    self.clusters[c_first].append(edge[1])
                continue

            # case 3: other way round
            if c_first == None and c_second != None:
                okay = self.all_connected(self.clusters[c_second], edge[0])
                if okay:
                    self.clusters[c_second].append(edge[0])
                continue

            # case 4: both are in different clusters
            # -> merge clusters if allowed
            if c_first != c_second:
                # check if clusters can be merged
                for v in self.clusters[c_first]:
                    merge = self.all_connected(self.clusters[c_second], v)
                    # break if any elements are not connected
                    if not merge:
                        break
                # merge if allowed
                if merge:
                    self.clusters[c_first].extend(self.clusters[c_second])
                    self.clusters.remove(self.clusters[c_second])

            # case 5: both are in the same cluster
            # won't happen if input is sane, but doesn't require an action either way


        return self.clusters

...这里有一个工作示例:

inp = [
    ('A', 'B'),
    ('B', 'C'),
    ('A', 'C'),
    ('B', 'D'),
    ('D', 'E'),
    ('C', 'E')
]

test = SCCManager(inp)
print(test.get_scc())

[['A', 'B', 'C'], ['D', 'E']]
 类似资料:
  • 我有一个不连通的二分无向图。我想把图完全断开。我能执行的唯一操作是删除一个节点。删除节点将自动删除其边。任务是最小化要删除的节点数。图中的每个节点最多有4条边。 通过完全断开一个图的连接,我的意思是不应该通过一个链接连接两个节点。基本上是一个空边集。

  • 我目前正在学习动态编程,我无法解决这个问题。有人能给我一个算法吗?:考虑一个有向图G=(V,E),其中每个边都标有一个字母Sigma的字符,我们指定一个特殊的顶点s作为开始顶点,另一个f作为最后顶点。我们说G接受一个字符串a=a1a2。如果有一条从s到f的n条边的路径,其标号拼写为序列a。设计了一个O((V+E)n)动态规划算法来确定a是否被G接受。

  • 一个图形有 n 个顶点和 m 条边。图形开始连接,然后按边缘在列表中出现的顺序删除边缘。在该过程结束时,图形将断开连接。 因此,在边列表中有一个特定的边,因此在移除它之前,有一个连接的组件的顶点数超过 n/4 个顶点的底部。移除此边后,图中没有连接组件的顶点数超过 n/4 个顶点的底部。 我将如何设计找到这条边的最佳算法。我是否只是开始删除边,然后每次遍历图以检查最大的连通分量是否足够?这在O(n

  • 我必须使用Java将com.google.mlkit.vision.common.inputimage转换为android中等效的位图图像。现在我正在使用下面的代码。 上面的代码没有将输入转换为位图。谁能给我建议一下把输入转换成位图的有效方法。

  • 我不知道这是否会发生,但我会试试。 在过去的一个小时里,我研究了图像上传的安全性。我了解到有很多函数可以测试上传。 在我的项目中,我需要安全地上传图像。也有可能是一个非常大的数量,它可能需要大量的带宽,所以购买一个API不是一个选项。 所以我决定得到一个完整的PHP脚本,用于真正安全的图像上传。我也认为这对许多人有帮助,因为不可能找到真正安全的。但是我不是PHP的专家,所以添加一些功能对我来说真的

  • 我使用精明的边缘检测器来检测输入图像的边缘。 在每个输入图像中,可以有两个对象(主对象和其中的另一个对象),如示例图像所示。因此,在这种情况下,我应该检测两条边 我根据输入图像自动确定上下阈值(使用中值和西格玛)。大多数情况下,canny工作正常,但有时当图像对比度不太好时,边缘检测失败,如以下示例所示(注意:-外边缘始终正确检测,内边缘出现问题) Canny检测到外部边界的边缘,但内部对象的边缘