2013-05-24 1 views
2

문제는 다음과 같습니다. 트리와 사용 가능한 모서리 수를 그래프로 표시합니다. v1에서 시작하여 이미 방문한 vertifications에서 벗어나는 가장자리를 선택합니다.트리의 서브 그래프 인 주어진 수의 모서리를 가진 최대 트리 서브 그래프 찾기

예이 예에서 graph

최적의 방법은 : 우선

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

I 이것은부터 길이 k의 최대 경로를 찾는 문제 일 것이다 비록 하찮은 일이지만, 요점은 언제나 다른 방식으로 갈 수 있다는 것입니다. 그래서 접근 방식은 효과가 없습니다.

내가 뭘 지금까지의 생각 :

  1. 잘라 k에 나무와 무력 모든 possibilites.

  2. 모든 가장자리의 가장자리로가는 비용을 계산하십시오. 비용은 우리가 가고자하는 가장자리가 그 가장자리로 가기 위해 추가해야하는 가장자리의 양으로 나눠지기 전에 모든 가장자리의 합계를 포함합니다. 거기에서 최대를 선택하고 모든 가장자리에 대해 비용을 업데이트 한 다음 k에 도달 할 때까지 다시 수행하십시오.

두 번째 방법은 좋지만 나 배낭 문제를 상기시킵니다.

제 질문은 이렇습니다. 더 좋은 방법이 있습니까? 이 문제는 NP입니까?

EDIT : 트리밍 답변 이의 예 :

enter image description here

+0

이 결정 문제 버전은 분명 NP입니다. 루트는 항상 하위 그래프에 포함되어야합니까? 그렇지 않으면, BH는 k = 1에 대한 최적 해가 될 것이다. –

+1

문제는 "음수가 아닌 가중치가있는 트리가 주어진 경우 원본과 동일한 루트를 가진 트리이기도 한 정확히 * k * 노드의 최대 가중치 서브 그래프를 찾습니다"라고 다시 말할 수 있습니까? 그렇다면, 나는 이것을 해석하기 위해 * k * × # 노드 동적 프로그래밍 테이블을 사용할 수 있다고 생각한다. –

+0

예, 트리 루트가 항상 포함되어 있지만, 문제는 말한대로 다시 말할 수 있지만 k + 1 노드를 사용할 수 있습니다. 동적 프로그래밍 테이블 접근법에 대해 자세히 설명해 주시겠습니까? –

답변

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) 
+0

덕분에, 나는 그런 생각을하지 못했습니다. –

+0

힘든, 복잡성은 O (kE)가 아닙니다. 예를 들어, 첫 번째 그래프를 가져 와서'k = 4'를 시작하십시오. max_weight_subgraph ('B', *, *)가 k + 1 번만 호출 되더라도 max_weight_subgraph ('C', *, *)는 k + k-1 + k -2 + ... + 1' 번. 따라서 각 노드에서'k' 번만 호출하는 것은 아닙니다. 문제는 여전히 'NP'인 것처럼 보인다. 그리고이 솔루션은 실제로 ** bruteforce **라고 부릅니다. – Billiska

+0

캐시가 없으면이 알고리즘은 지수가되는 bruteforce가됩니다. 나는 캐시의 사용이 복잡성을 훨씬 더 잘 만들어야한다고 믿는다. 그러나, 나는 당신이 옳다고 생각하고 나는 함수의 for 루프로 인해 복잡성을 과소 평가했다. 현재의 추측은 O (k^2E) 복잡성과 더 비슷하다는 것입니다. –

관련 문제