子集和数问题
问题描述
已知(w1, w2, …, wn)和M,均为正数。要求找出wi的和数等于M的所有子集。
例如:若n=4,(w1,w2,w3,w4)=(11,13,24,7),M=31,则满足要求的子集是(11,13,7)和(24,7).
分析
子集和数问题解的一种表示方法
- 解由n-元组(x1, x2, …, xn)表示;
- 显式约束条件xi∈{0,1} ,1≤i≤n,如果没有选择Wi,则xi=0;如果选择了Wi,则xi=1。于是上面的解可以表示为(1,1,0,1)和(0,0,1,1);
- 隐式约束条件(xi× wi)的和数为M
- 解空间的大小为2n个元组
子集和数的递归回溯算法
//找W(1:n)中和数为M的所有子集。进入此过程时X(1),…,X(k-1)的值已确定。W(j)按非降次序排列。
|
global integer M,n; global real W(1:n); global boolean X(1:n) real r,s; integer k,j //生成左儿子// X(k)←1 if s+W(k)=M then print(X(j),j←1 to k) else if s+W(k)+W(k+1)<=M then call SUMOFSUB(S+W(k),k+1,r-W(k)) endif endif //生成右儿子和计算Bk的值// if s+r-W(k)>=M and s+W(k+1)<=M then X(k)←0 call SUMOFSUB(s,k+1,r-W(k)) endif end SUMOFSUB |
例子
n=6, M=30,W(1:6)=(5,10,12,13,15,18)
(当前和,当前处理的子数,剩余子数的和)
本文深入探讨了子集和数问题的解决方法,包括算法表示、递归回溯算法实现及具体实例解析。通过分析解的空间结构与生成左、右儿子节点的过程,读者将掌握如何寻找满足特定和数的子集。
3836

被折叠的 条评论
为什么被折叠?



