JAVA实现回溯算法

350 阅读4分钟

这是我参与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]);
		}
	}
 
}`

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ba2ab96bc77642218190eb348f8432fe~tplv-k3u1fbpfcp-watermark.image)