子集求和问题
给定正数wi(1≤i≤n)和m,要求寻找wi的所有子集,它们的和
为m。例如,如果n=4、(w1,w2,w3,w4)=(11,13,24,7)且m=31,那么想得到的子集为(11,13,7)和(24,7)。与其通过和为m的wi来表示解向量,不如先为wi指定索引,然后利用索引来表示解向量。一般来说,所有的解都表示为k元祖(x1,x2,…,xk)(1≤k≤n)的形式,不同的解对应着不同大小的元祖。显示约束要求xi∈{j|j为整数,1≤j≤n }。隐式约束要求任何两个wi都不相同,且对应的wi的和为m。由于期望避免生成同一子集的多个实例,所以必须增加一个隐式约束xj
子集求和问题还有另外一种表示方法:每一个解子集都用一个n元祖(x1,x2,…,xn), xi∈{0,1}(1≤i≤n)来表示。如果没有选中wi,那么xi=0;如果选中wi,那么xi=1。
动态结构图
静态结构图
控制抽象:
void Backtrack(int t) {
if (t > n) Output(x);
else {
for (int i = f(n,t); i <= g(n,t); i ++) {
x[t] = h(i);
if (Constraint(t) && Bound(t))
Backtrack(t+1);
}
}
}
t表示递归深度
for循环中f(n,t)和g(n,t)分别表示在当前扩展节点处未搜索过的子数的起始编号和终止编号。
h(i)表示在当前扩展节点处x[t]的第i个可选值。Constraint(t)和Bound(t)表示在当前扩展节点处的约束方程和接线函数。
本文来源:https://www.2haoxitong.net/k/doc/549fb049767f5acfa1c7cd94.html
文档为doc格式