找到具有给定边数的最大树子图,该子图是树的子图

时间:2013-05-24 10:49:09

标签: algorithm math graph-theory np

所以问题如下:给你一个图树,它是一棵树和你可以使用的边数。从v1开始,您可以选择已经访问过的任何顶点的边。

示例:graph

在这个例子中,最佳方法是:

for k==1 AC -> 5
for k==2 AB BH -> 11
for k==3 AC AB BH -> 16

起初我虽然从A开始找到长度为k的最大路径是个问题,但这一点很简单,但关键是你总是可以选择采用不同的方式,因此这种方法不起作用。 / p>

到目前为止我的意思是:

  1. 在k处砍伐树木,并强行摧毁所有可能性。

  2. 计算所有边缘的边缘成本。 成本将包括我们试图去的边缘之前的所有边缘的总和除以为了到达该边缘而需要添加的边缘量。 从那里挑选所有边缘的最大值,更新成本,并再次进行,直到达到k。

  3. 第二种方法似乎很好,但它让我想起了一些背包问题。

    所以我的问题是:有更好的方法吗?这个问题是NP吗?

    编辑:修剪答案的反例:

    enter image description here

1 个答案:

答案 0 :(得分:2)

此代码说明了基于计算来自以某个节点为根的树的最大权重的子问题的记忆方法。

我认为复杂度将是O(kE),其中E是图中边的数量(对于树,E = n-1)。

edges={}
edges['A']=('B',1),('C',5)
edges['B']=('G',3),('H',10)
edges['C']=('D',2),('E',1),('F',3)

cache={}
def max_weight_subgraph(node,k,used=0):
    """Compute the max weight from a subgraph rooted at node.
    Can use up to k edges.
    Not allowed to use the first used connections from the node."""
    if k==0:
        return 0
    key = node,k,used
    if key in cache:
        return cache[key]
    if node not in edges:
        return 0
    E=edges[node]
    best=0
    if used<len(E):
        child,weight = E[used]
        # Choose the amount r of edges to get from the subgraph at child
        for r in xrange(k):
            # We have k-1-r edges remaining to be used by the rest of the children
            best=max(best,weight+
                     max_weight_subgraph(node,k-1-r,used+1)+
                     max_weight_subgraph(child,r,0))
        # Also consider not using this child at all
        best=max(best,max_weight_subgraph(node,k,used+1))
    cache[key]=best
    return best

for k in range(1,4):
    print k,max_weight_subgraph('A',k)