Algorithm 找到要携带的最大权重子集

Algorithm 找到要携带的最大权重子集,algorithm,Algorithm,一个人的物品重量低于他的重量 [10、10、12、15、16、20、45、65、120、140、150、178、198、200、210、233、298、306、307、310、375、400、420、411、501550、662、690、720、731、780、790] 他能带回家的最大重量是3公斤(3000克)。他想尽可能多地狂欢 注意,我尝试了回溯算法,但它给我的子集等于我正在寻找的和,但在我找不到相等匹配和的情况下,它失败了。我想找到接近总和的子集。这是可在中求解的子集-这基本上是回溯的一

一个人的物品重量低于他的重量

[10、10、12、15、16、20、45、65、120、140、150、178、198、200、210、233、298、306、307、310、375、400、420、411、501550、662、690、720、731、780、790]

他能带回家的最大重量是3公斤(3000克)。他想尽可能多地狂欢

注意,我尝试了回溯算法,但它给我的子集等于我正在寻找的和,但在我找不到相等匹配和的情况下,它失败了。我想找到接近总和的子集。

这是可在中求解的子集-这基本上是回溯的一个有效实现,通过以下递归公式:

D(0,n) = True
D(x,0) = False  | x > 0
D(x,n) = D(x-arr[i], n-1)           OR      D(x,n-1)
               ^                                ^
       item i is in subset         item i is not in subset
通过使用自下而上的动态规划(创建一个矩阵并从低到高填充)或自上而下的动态规划(记住每个结果并检查在递归之前是否已经计算过),这可以在
O(n*W)
中解决,其中
n
是元素的数量,
W
是子集的大小(你的情况是3000英镑)


如果运行自下而上的DP,则
x
的最大值为
D(x,n)=True
,是一个人可以携带的最大重量。要查找实际项目,应按照表格返回,检查在每个决策点添加的项目,并生成添加的项目。返回实际集在线程中有更多详细说明:(此线程正在处理背包问题,它是您问题的一个变体,重量=每件物品的成本)

使用回溯,我们可以像这样构建解决方案,
我们将尝试使用以下伪代码返回子集的最大权重,该权重最接近但也低于给定权重:

func(weight_till_now,curr_pos)
    if(weight_till_now > max_possible) return 0
    if(curr_pos >= N) return 0

    // Taking this weight in current subset
    weight =  max(weight_till_now,func(weight_till_now+wt[curr_pos],curr_pos+1))

    // Not taking in current subset
    weight =  max(weight_till_now,func(weight_till_now,curr_pos+1))

    return weight

使用初始参数0,0调用此函数将给出答案,因为这将生成每个子集,并尝试获取所有可能子集权重的最大权重,如果它大于最大可能权重,则返回0。

为什么不在遍历和更新该子集时记录当前最佳结果f当前值和目标值之间的差异小于之前的最佳结果?有趣的一点是你的回答:你是否有任何参考,其中递归与记忆一起被称为“自上而下的动态规划”?我多年来一直在讨论这是否真的被视为动态规划,或者“动态规划"表示根本不执行递归调用。@Codor虽然不是权威机构,但使用以下术语:
自上而下方法:这是任何问题的递归公式的直接结果。如果任何问题的解决方案可以使用其子问题的解决方案递归公式化,并且如果其子问题重叠这样,我们就可以轻松地将子问题的解决方案存储在一个表中。每当我们试图解决一个新的子问题时,我们首先检查该表是否已经解决。如果已记录解决方案,我们可以直接使用它,否则我们将解决子问题并将其解决方案添加到表中。
感谢您的澄清在上,我没有意识到!但是它有臭名昭著的
[引文需要]
标签。。。