这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战。
1.0-1背包问题
关于0-1背包问题是回溯算法的一个经典例子 就这个问题来记录一下自己对回溯算法的初步理解
因为自己对这个算法也只是入门阶段 所以有什么不正确的地方 欢迎大家指正
- 1.我个人理解(现目前阶段的理解):回溯算法 顾名思义就是不断往回算 举个例子:你要从A地点到B地点 在这个过程中有有限个路口任你选择 1.我对你加了约束条件 在从A到B的这个过程中你不能超过一个时间T 超过你就不能继续走这条路 你就必须要返回到上一个路口重新选择另一个路口,当你发现你重新选择的路口还是不行 那你就需要再返回到你上 上个路口继续试探 在这个过程中你是不是就在回溯了?再思考:我在不超过T中也有很多路径到达 但是我又提出了一个要求 我希望你能告诉我到达B的最少时间是多少 那么就是一个最优解问题 在这个过程中我们可以知道要使用回溯算法是有条件的 他得有约束条件(不符合条件的我们就不尝试了 这就是剪枝)也必须要有结束条件 ------解空间子集树
- 2.0-1背包问题 问题:给定n种物品和一背包。物品i的重量是wi,其价值为pi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
我根据这张图来分析这个0-1背包问题:Y代表取想x[i]的物品 N代表不去 (我在看了很多他们的解释 自己又想了想 我对 0-1背包问题可以看做是解空间树 我是假设把x[i]看成是一个结点 那么我们来看看如何来理解回溯算法)
a:假设我们第一件商品不取 第二件商品也不取 第三件商品也不取 我们就来到了1处 现在就得出一个价值(因为是第一个 就假设他是最优价值)
b.现在我们就又回溯到第二件商品处 换一个方向 第三件商品我们取 就到了2处 又得出一个价值 与最佳价值作比较(谁大谁留)
c.我们现在有回溯到第二件商品处 我们第二件商品又要取 那第三件商品可以取 也可以不取 又比较价值
d.我们又接着回溯到第一件商品处 我们又开始进行第二件商品取/不取 第三件商品取/不取
最后就回溯出了最佳价值 基本的思想就是这样的 但是在这中间需要加约束条件加以剪枝(不能超过背包重 ),这里就没有体现出来 到了叶子节点就要出来啦。来看一下代码
public class _05 {
static int BestValue = 0; // 最优值;当前的最大价值,初始化为0
static int[] BestX; // 最优解;BestX[i]=1代表物品i放入背包,0代表不放入
//
static int CurWeight = 0; // 当前放入背包的物品总重量
static int CurValue = 0; // 当前放入背包的物品总价值
static int N = 3;// 物品数量
static int C = 16;// 物品的总容量
static int W[] = { 10, 8, 5 }; // 每个物品的重量
static int v[] = { 5, 4, 1 };// 每个物品的价值
static int x[] = { 0, 0, 0 };// x[i]=1代表物品i放入背包,0代表不放入
public static int backtrack(int t) {
// 如果是子节点 当前价值和最佳价值做判断 保存最佳价值
if (t > N - 1) {
if (CurValue > BestValue) {
BestValue = CurValue;
}
return BestValue;
}
// 如果不是子节点 对子节点进行遍历
else {
// 就两种情况 取或不取 用0/1表示
for (int i = 0; i <= 1; i++) {
x[t] = i;
if (i == 0) {
// 如果是不取 就不需要进行判断 直接到下一个节点
backtrack(t + 1);
} else
// 放入背包就进行约束条件 判断放入背包的东西是否合法
{
if (CurWeight + W[t] <= C) {
CurWeight += W[t];
CurValue += v[t];
// 当东西装进入背包后你可以进行对下个商品的判断了
backtrack(t + 1);
//能执行以下两个语句就说明你回溯到了上一个节点 所以你就需要恢复现场 把你刚刚拿的东西退出来 我们要冲上一个节点又要重新来遍历 如果不减你就会多加一遍
CurWeight -= W[t];
CurValue -= v[t];
}
}
}
}
return BestValue;
}
public static void main(String[] args) {
backtrack(0);
System.out.println(BestValue);
for (int i = 0; i < 3; i++) {
// System.out.println(BestX[i]);
}
}
}`
