JavaScript实现利用回溯法解决0-1背包问题

本文介绍了如何利用回溯法解决0-1背包问题,详细阐述了0-1背包问题的定义,并通过一个实例展示了如何构建解空间树。接着,解释了回溯法的基本思想和何时使用,以及解空间树中的活结点、死结点概念。最后,给出了JavaScript的代码实现,通过递归搜索解空间树找到最优解。
摘要由CSDN通过智能技术生成

题记:

这几天都在学习算法遇到了比较典型的0-1背包问题,下面就0-1背包的问题利用回溯法来解决。但是,在网上看到较多的都是java或者c实现的,那么我就来用JavaScript来实现一下基于回溯法解决的0-1背包问题

正文:

0-1背包问题:

有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
举个例子:
现在有3个物品,重量分别为16,15,15。价值分别为45,25,25。我有一个能装30的背包,怎么装能达到背包内价值最多?
注意:物品只能选择拿或者不拿,不能装部分

回溯法:

什么是回溯法呢?
回溯法的基本做法是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法。这种方法适用于解一些组合数相当大的问题。
什么时候使用呢?
有许多问题,当需要找出它的解集或者要求回答什么解是满足某些约束条件的最佳解时,往往要使用回溯法。
解空间树:
既然说了,回溯法是一种组织的井井有条的,避免不必要搜索的穷举式搜索法,那么我们就要构造一个解空间树。
回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。
生成问题的基本状态:
扩展结点:一个正在产生儿子的结点称为扩展结点
活结点:一个自身已生成但其儿子还没有全部生成的节点称做活结点
死结点:一个所有儿子已经产生的结点称做死结点

0-1背包与回溯法:

简单介绍了0-1背包问题与回溯法的概念,接下来我们来看看怎么利用回溯法实现0-1背包问题的解。
我们来想一想对于这个数量为3的0-1背包问题,解一共有8种:(1代

回溯法解0_1背包问题时,会用到状态空间树。在搜索状态空间树时,只要其左儿子结点是一个可行结点,搜索就进入其左子树。当右子树有可能包含最优解时才进入右子树搜索,否则将右子树剪去。设r是当前剩余物品价值总和;cp是当前价值;bestp是当前最优价值。当cp+r≤bestp时,可剪去右子树。计算右子树中解的上界可以用的方法是将剩余物品依其单位重量价值排序,然后依次装入物品,直至装不下时,再装入该物品的一部分而装满背包。由此得到的价值是右子树中解的上界,用此值来剪枝。 为了便于计算上界,可先将物品依其单位重量价值从大到小排序,此后只要顺序考察各物品即可。在实现时,由MaxBoundary函数计算当前结点处的上界。它是类Knap的私有成员。Knap的其他成员记录了解空间树种的节点信息,以减少函数参数的传递以及递归调用时所需要的栈空间。在解空间树的当前扩展结点处,仅当要进入右子树时才计算上界函数MaxBoundary,以判断是否可以将右子树减去。进入左子树时不需要计算上界,因为其上界与父结点的上界相同。 在调用函数Knapsack之前,需要先将各物品依其单位重量价值从达到小排序。为此目的,我们定义了类Objiect。其中,运算符与通常的定义相反,其目的是为了方便调用已有的排序算法。在通常情况下,排序算法将待排序元素从小到大排序。 在搜索状态空间树时,由函数Backtrack控制。在函数中是利用递归调用的方法实现了空间树的搜索
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值