Algorithm “计算”;节点闭合";带删除的图的性质

Algorithm “计算”;节点闭合";带删除的图的性质,algorithm,graph-theory,Algorithm,Graph Theory,给定一个有向图,目标是将节点与其所指向的节点组合起来,并得出这些[让我们给出名称]超级节点的最小数量 问题是,一旦合并了节点,就不能再次使用这些节点。[第一个节点以及所有组合节点-即一个超级节点的所有成员] 贪婪的方法是选择出度最大的节点,并将该节点与它所指向的节点组合,然后移除所有节点。每次对尚未从图中删除的节点执行此操作 贪婪是O(V),但这不一定会输出最小数量的超级节点。 那么最好的算法是什么呢?我将尝试以不同的方式描述这个问题。要将顶点分成两组。第一组由“根节点”组成,第二组由“从属节点

给定一个有向图,目标是将节点与其所指向的节点组合起来,并得出这些[让我们给出名称]超级节点的最小数量

问题是,一旦合并了节点,就不能再次使用这些节点。[第一个节点以及所有组合节点-即一个超级节点的所有成员]

贪婪的方法是选择出度最大的节点,并将该节点与它所指向的节点组合,然后移除所有节点。每次对尚未从图中删除的节点执行此操作

贪婪是O(V),但这不一定会输出最小数量的超级节点。
那么最好的算法是什么呢?

我将尝试以不同的方式描述这个问题。要将顶点分成两组。第一组由“根节点”组成,第二组由“从属节点”组成,即直接连接到根节点的节点

root dependent B A < C E D < F 根相关 B A< C E D< F 图0:可能的结果图

您希望最小化根节点的数量。这与最大化依赖节点的数量相同,与最大化结果图中的边的数量相同,与最小化从开始图构造过程中移除的边的数量相同

让我们首先看一下暴力:对于每个节点分成根和依赖集的二分体,首先检查它是否满足问题陈述的标准,最后采取可能的最佳方法。二分体的数量是指数级的,因此必须对其进行改进

如果我们将每条边视为具有可能的状态“未知”、“获取”或“移除”,则获取一条边将移除源自其结束节点的所有边,以及终止于该节点的所有边(见图1)。但是,无论如何,我们最多可以保留一条以特定节点结尾的边

A B C \|/ D /|\ E F G A、B、C \|/ D /|\ E F G 图1:获取边A-D将删除此处显示的所有其他边

有许多“贪婪”的启发法:

  • 将具有最多传出边的节点放入根集中,并将其所有连接的节点放入从属集中(我认为这是您的建议)
这存在一个问题,即一些连接的节点最好放在根集中,这就带来了第一个优化:

  • 将具有最多传出连接的节点放入根集中,并将其所有连接的节点标记为“可访问”。然后循环,但只计算到每个点上不“可到达”的节点的连接数。当所有节点都在根集中或“可访问”时停止。最后,将所有不在根集中的“可到达”节点放入依赖集中,并将它们任意分布在可连接的根节点之间
这看起来很好,但仍然不一定是最优的。也许你可以从另一边开始:

  • 将传出连接数最少的节点放入依赖集中。“删除”其所有输出边缘。“获取”来自具有最多传出连接数的节点的传入边缘,并将该节点放入根集中。循环,直到所有节点都在根集中或从属集中

我仍然无法证明这是否是最优的,但至少我不能直接想到一个打破它的情况。

20!相当大,大于2^61。幸运的是,有更好的方法来解决小实例:(编辑)动态规划。通过保存每个子问题的最优解,我们需要花费一些内存来节省大量时间

下面是Python中的一些示例代码。在用另一种语言实现下面的代码时,您可能需要对顶点0、…、n-1进行编号,并将集合实现为位向量

# find a smallest node closure of G
# G is a graph in adjacency-list format: G[v] is the set of neighbors of v
def node_closure(G):
    # maps subsets of vertices to their smallest node closure
    smallest = {frozenset(): []}
    def find_smallest(S):
        if S in smallest:
            return smallest[S]
        else:
            candidates = [[v] + find_smallest(S - frozenset([v]) - G[v]) for v in S]
            return min(candidates, key=len)
    return find_smallest(frozenset(G))

这个问题有一个NP硬度降低,从集合覆盖保持目标值。这意味着,除非P=NP,否则多项式时间算法所能获得的最佳保证是,它始终输出的解最多是最优解的
O(logn)

如果
x1,…,xm
是要覆盖的元素,
S1,…,Sn
是集合,那么集合覆盖的目标是选择其并集为
{x1,…,xm}
的集合的最小数目。假设每个元素至少出现在一个集合中,用节点
x1,…,xm,S1,…,Sn,R
绘制一个图,其中存在从
R
到所有
Si
的弧,并且对于所有
i,j
,从
Si
xj
的弧,当且仅当
xj
属于
Si
。节点闭包和集合覆盖之间有一个简单的对应关系:要从集合覆盖中获得节点闭包,请删除与所选集合对应的顶点,然后
R
;要从节点闭包中获取集合覆盖,请获取所有已选择顶点的集合,以及包含已选择顶点的每个
xj
的集合


(注意,对于集合覆盖,贪婪算法达到了最佳近似比!对于您的问题,类似的情况可能是正确的。)

这难道不等于找到一个图的最小着色(其中一种颜色基本上代表一个超级节点)?@直接:我看不到与最小着色有任何相似之处。我将组合节点称为超级节点。着色问题状态相邻节点不能具有相同的颜色。你能详细说明一下吗?你需要找到超级节点的最小数量。将超级节点视为特定颜色。然后放弃其所有相邻节点的相同颜色。等等…谢谢算法专家!是的,在我看来它甚至不像NP完全[给出一个答案,我们如何验证它是多项式时间内的最优解?]。它看起来确实像你