您的位置:首页 > 其它

DP26树的最大独立子集问题 Largest Independent Set Problem @geeksforgeeks

2013-12-29 00:27 471 查看


Given a Binary Tree, find size of the Largest Independent Set(LIS) in it. A subset of all tree nodes is an independent set if there is no edge between any two nodes of the subset.

For example, consider the following binary tree. The largest independent set(LIS) is {10, 40, 60, 70, 80} and size of the LIS is 5.





A Dynamic Programming solution solves a given problem using solutions of subproblems in bottom up manner. Can the given problem be solved using solutions to subproblems? If yes, then what are the subproblems? Can we find largest independent set size (LISS)
for a node X if we know LISS for all descendants of X? If a node is considered as part of LIS, then its children cannot be part of LIS, but its grandchildren can be. Following is optimal substructure property.

1) Optimal Substructure:

Let LISS(X) indicates size of largest independent set of a tree with root X.
LISS(X) = MAX { (1 + sum of LISS for all grandchildren of X),
(sum of LISS for all children of X) }


The idea is simple, there are two possibilities for every node X, either X is a member of the set or not a member. If X is a member, then the value of LISS(X) is 1 plus LISS of all grandchildren. If X is not a member, then the value is sum of LISS of all children.

2) Overlapping Subproblems

Following is recursive implementation that simply follows the recursive structure mentioned above.

遇到树的结构可以改变节点的结构,在节点里面增加一个memo值用来存储

package DP;

public class LargestIndependentSet {

public static void main(String[] args) {
Node root = new Node(20);
root.left = new Node(8);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
root.right = new Node(22);
root.right.right = new Node(25);

System.out.println("Size of the Largest Independent Set is " + LISS_Rec(root));

NodeMemo root2 = new NodeMemo(20);
root2.left = new NodeMemo(8);
root2.left.left = new NodeMemo(4);
root2.left.right = new NodeMemo(12);
root2.left.right.left = new NodeMemo(10);
root2.left.right.right = new NodeMemo(14);
root2.right = new NodeMemo(22);
root2.right.right = new NodeMemo(25);

System.out.println("Size of the Largest Independent Set is " + LISS_Memo(root2));
}

public static int LISS_Rec(Node root){
if(root == null){
return 0;
}

// 计算不包含当前节点的size,即为左右孩子的LISS size
int sizeExcl = LISS_Rec(root.left) + LISS_Rec(root.right);

// 计算包含当前节点的size,即为1+孙子的LISS size
int sizeIncl = 1;
if(root.left != null){
sizeIncl += LISS_Rec(root.left.left) + LISS_Rec(root.left.right);
}
if(root.right != null){
sizeIncl += LISS_Rec(root.right.left) + LISS_Rec(root.right.right);
}

return Math.max(sizeExcl, sizeIncl);
}

public static int LISS_Memo(NodeMemo root){
if(root == null){
return 0;
}
if(root.liss != 0){
return root.liss;
}
if(root.left==null && root.right==null){
root.liss = 1;
return root.liss;
}

int sizeExcl = LISS_Memo(root.left) + LISS_Memo(root.right);

int sizeIncl = 1;
if(root.left != null){
sizeIncl += LISS_Memo(root.left.left) + LISS_Memo(root.left.right);
}
if(root.right != null){
sizeIncl += LISS_Memo(root.right.left) + LISS_Memo(root.right.right);
}

root.liss = Math.max(sizeExcl, sizeIncl);		// 保存结果
return root.liss;
}

public static class Node{
int data;
Node left, right;

public Node(int data){
this.data = data;
}
}

public static class NodeMemo{
int data;
NodeMemo left, right;
int liss;

public NodeMemo(int data){
this.data = data;
}
}
}

http://www.geeksforgeeks.org/largest-independent-set-problem/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: