子集和问题
代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70#迭代回溯 def MaxAdd(n,c,value,bestx): #n:数据个数 #c:上界 #value[]:数据列表 #bestx[]:当前最优解 i=1#从根节点出发 x=[0 for i in range(n+1)]#x[1:i]是当前子集 bestw=0#当前最优子集和 cw=0#当前子集和 r=0#剩余数的总和 for j in range(1,n+1): r+=value[j] print("r",r) while True: while i<=n and cw+value[i]<=c:#左子树 r-=value[i] cw+=value[i] x[i]=1 i+=1 print("第{}层".format(i-1)) print("←添加",value[i-1]) print("cw",cw) print("r",r) if i>n: print("第{}层".format(i)) print("到达左叶子") for j in range(1,n+1): bestx[j]=x[j] bestw=cw else:#剪掉value[i]的左子树,搜索右子树 r-=value[i] i+=1 print("向右,不加",value[i-1]) print("r",r) print("到第{}层".format(i)) while cw+r<=bestw:#剪掉value[i-1]的右子树 i-=1 print("回退到",value[i]) print("第{}层".format(i)) print("cw",cw) print("r",r) while i>0 and (not x[i]): r+=value[i] i-=1 print("一直回退到",value[i]) if i==0: return bestw,bestx x[i]=0 cw-=value[i]#不加入value[i] i+=1 n=5 c=10 value=[0,4,5,6,2,2] bestx=[0 for i in range(n+1)] r=0#剩余数的总和 for j in range(1,n+1): r+=value[j] bestw,bestx=MaxAdd(n,c,value,bestx) print("最大子集和为",bestw) print("构成最大子集和的子集为:",end="") for i in range(n+1): if bestx[i]: print(value[i],end=" ")
结果
最小元素个数子集和问题
代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82#迭代回溯 def MaxAdd(n,c,value,bestx): #n:数据个数 #c:上界 #value[]:数据列表 #bestx[]:当前最优解 i=1#从根节点出发 number=100#初始化最优子集元素个数为一个足够大的数100 x=[0 for i in range(n+1)]#x[1:i]是当前子集 bestw=0#最优子集和 cw=0#当前子集和 r=0#剩余数的总和 for j in range(1,n+1): r+=value[j] while True: #cw+value[i]<=c是约束函数 #x.count(1)+1<=number是其中一个上界函数 while i<=n and cw+value[i]<=c and x.count(1)+1<=number:#搜索左子树 r-=value[i] cw+=value[i] x[i]=1 i+=1 print("第{}层".format(i-1)) print("←添加",value[i-1]) print("cw",cw) print("r",r) print() if i<=n and (cw+value[i]>c or x.count(1)+1>number): #约束条件剪掉value[i]的左子树或者上界函数剪掉value[i]的左子树 #搜索右子树 r-=value[i] i+=1 print("向右,不加",value[i-1]) print("r",r) print("cw",cw) print("到第{}层".format(i)) print() while cw+r<bestw or r==0:#上界函数剪掉value[i-1]的右子树 #搜索到达叶子结点 if cw>=bestw: print("第{}层".format(i)) print("到达叶子") for j in range(1,n+1): bestx[j]=x[j] #计算当前子集的元素个数 number=bestx.count(1) print("元素个数number",number) bestw=cw print("最大子集和bestw",bestw) print() i-=1 print("回退到",value[i]) print("第{}层".format(i)) print("cw",cw) print("r",r) while i>0 and (not x[i]): r+=value[i] i-=1 print("一直回退到",value[i]) if i==0: return bestw,bestx,number x[i]=0 cw-=value[i]#不加入value[i] i+=1 print("cw",cw) print("r",r) print() c=10 value=[0,2,2,6,5,4] #value=[0,4,6,5,2,2] n=len(value)-1 bestx=[0 for i in range(n+1)] bestw,bestx,number=MaxAdd(n,c,value,bestx) print("最大子集和为",bestw) print("构成最大子集和的子集元素个数为",number) print("构成最大子集和的子集为:",end="") for i in range(n+1): if bestx[i]: print(value[i],end=" ")
结果
最后
以上就是清秀水壶最近收集整理的关于(最小元素个数)子集和问题--回溯法子集和问题最小元素个数子集和问题的全部内容,更多相关(最小元素个数)子集和问题--回溯法子集和问题最小元素个数子集和问题内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复