(1)搜索子集树
1.适用问题:求子集、0-1背包问题(实际上就是求组合的问题)
2.子集树
其中1表示选择,0表示不选。每一层各个节点其实表示的是集合中同一个元素的选择情况,如{1,3,5},A表示元素1选择或者不选的情况,B表示选择1之后,3选与不选的情况,C表示1不选之后3选与不选的情况
3.算法框架
void backtrack(int t){
if(t>=n)
Output(x);
else
for(i=0;i<1;i++){
x[t]=i;
if(Constraint(t) && Bound(t))
backtrack(t+1);
}
}
其中,x是01数组,x[t]=1表示集合中第t个元素在子集中,0表示 不在
Output(x):输出这个01数组,也就是对应的一个子集
Constraint(t):用来检验t是否能加入子集中,这和具体问题有关
原理:分别设置x[t]=0和x[t]=1,然后分别向下递归
4.例一:求集合的所有子集
private static void subset(int t, int[] a, int[] x)
{
if(t>=a.length)//表示所有元素都已经递归完毕
{
for(int i=0; i<x.length; i++)
{
if(x[i] != 0)
System.out.print(a[i]+" ");
}
System.out.println();
}
else
{
x[t] = 1;//搜索左子树
subset(t+1,a,x);
x[t] = 0;//搜索右子树
subset(t+1,a,x);
}
}
int[] a = {1,3,5};
int[] x = new int[a.length];
subset(0,a,x);//从第一个元素开始
结果为:
1 3 5
1 3
1 5
1
3 5
3
5
5.例二:0-1背包
int n = 3;
int v = 10;
int[] weight = {3,4,5};
int[] value = {4,5,6};
int[] x = new int[n];
int[] bestPlan = new int[n];
int curValue = 0;
int curWeight = 0;
oneZeroPackage(0,weight,value,x,curValue,curWeight,v,bestPlan);
System.out.println(maxValue);
for(int i=0;i<bestPlan.length;i++)
{
if(bestPlan[i] != 0)
System.out.print(value[i]+" ");
}
private static void oneZeroPackage(int t, int[] weight, int[] value,
int[] x, int curValue, int curWeight, int maxWeight, int[] bestPlan)
{
if(t>=weight.length)
{
if(curValue>maxValue)
{
for(int i=0; i<weight.length; i++)
bestPlan[i] = x[i];
maxValue = curValue;
}
}
else
{
x[t] = 1;
if(weight[t]+curWeight<=maxWeight)
oneZeroPackage(t+1, weight, value, x, curValue+value[t], curWeight+weight[t], maxWeight, bestPlan);
x[t] = 0;
oneZeroPackage(t+1, weight, value, x, curValue, curWeight, maxWeight, bestPlan);
}
}
结果为:
11
5 6
(2)求排列
@Test
public void tests() throws UnsupportedEncodingException
{
int[] a = {1,3,5};
pailie(a, 0, a.length-1);
}
private void pailie(int[] a, int begin, int end)
{
if (begin>end) {
for (int i : a) {
System.out.print(i+" ");
}
System.out.println();
}else {
for (int i = begin; i <= end; i++) {
swap(a,begin,i);
pailie(a, begin+1, end);
swap(a, begin, i);
}
}
}
private void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}