How to maximize the weight of a tree by removing s

2020-02-11 17:33发布

问题:

Closed. This question needs to be more focused. It is not currently accepting answers.

Want to improve this question? Update the question so it focuses on one problem only by editing this post.

Closed 10 months ago.

There is a rooted tree with N nodes (numbered 1 through N); node '1' is the root. Each node has a value; let's denote the value of node i by A(i).

The following operation(s) can be performed any number of times (including zero):

1.choose any node which still exists in the tree and remove the whole sub- tree of this node including itself.

2.Let's define the profit as the sum of values of all nodes which currently exist in the tree minus X⋅k, where k denotes the number of times this operation was performed. Find the maximum possible profit.

How can we calculate 'k' value here?(means no. of time node is deleted to give optimum profit)

Example:-


3(number of nodes,N) ,

5(X)

1 -5 -10 (Values of corresponding nodes)

(edge(s) from 'x'->'y')

1 2

2 3

Output: -4

We remove the sub-tree of node : 2'.

Now,value of our tree is: 1.

Finals answer:- 1-(x)*k,
(k=1); as we have performed the operation of removing the sub-tree only '1' time 
:  1-(5)*1= -4.

NOTE:it's not given that tree should be binary it can be a general tree too.

回答1:

There's a straightforward recursive algorithm for this. The most profitable pruning you can perform on a tree is either to perform the most profitable pruning on all of its direct subtrees, or to just prune away the whole tree. This can be translated directly to code.

Assuming the tree has been processed into a data structure where every node has a value attribute representing the node's value and a children attribute storing a list of the node's child nodes, the following Python function would compute the max profit:

def max_profit(node):
    return max(
        -X,
        node.value + sum(map(max_profit, node.children)))

with the two options in the max call representing the choice to either prune the whole tree away at the root, or to keep the root and process the subtrees.



回答2:

The idea is to parse the tree, and see which subtree could be removed such that the profit will increase compared to its initial state. Do this analysis for every node before removing anything. Then, remove the subtrees that increases the most the profit. We can do it in two passes:

1) Doing a depth-first traversal of the tree (leaves first, then slowly going back towards the root), calculate the profit gain of each node as the G(i)=-A(i)+G(j)+G(k)+..., where i is the current node, and j,k,... are the children. In other words, the profit gain is the added value if we remove the current node.

During the same traversal, also compute the maximum profit gain of the node and its children. This will tell us if it is more profitable to remove a node or if it is more profitable to remove a subtree of this node. We compute the maximum profit gain as M(i) = max(G(i),M(j),M(k),...), where i,j,k,... are defined as above. If a child does not exist, just remove it from the max equation.

2) Doing a breadth-first traversal of the tree, we remove a node i (and its subtree) if G(i) == M(i) and G(i) >= X.

def compute_gain(node):
    map(compute_gain, node.children)
    node.gain = -node.value + sum([c.gain for c in node.children])
    node.max_gain = max(node.gain, max([c.max_gain for c in node.children]))

def prune_tree(node):
    if node.gain >= X and node.max_gain == node.gain:
        k += 1
        return False
    node.children = [c for c in node.children if prune_tree(c) == True]