概述
子集和问题
代码
#迭代回溯
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=" ")
结果
最小元素个数子集和问题
代码
#迭代回溯
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=" ")
结果
最后
以上就是清秀水壶为你收集整理的(最小元素个数)子集和问题--回溯法子集和问题最小元素个数子集和问题的全部内容,希望文章能够帮你解决(最小元素个数)子集和问题--回溯法子集和问题最小元素个数子集和问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复