回溯法求解简单装载问题

问题描述:有一批集装箱要装上一艘载重量为W的轮船,其中编号为i(0<= i<=n-1)的集装箱的重量为wi。现要从n个集装箱中选出若干个装上轮船,使得他们的重量之和恰好为W。如果找到任何一种解,返回true,否则返回false。

思路:其实这道题运用了回溯法一个非常明显的特点,就是剪枝法。也就是狭义回溯法定义“回溯法=DFS+剪枝法”;另一种广义定义就是递归喽。

#include<iostream>
using namespace std;
int w[] = { 0,5,2,6,4,3 };
int x[100];    //这个x[]是用来判断是否选择装载,存放最优解向量的
int n = 5,W=10;
int maxw = 0;
void dfs(int i, int tw, int rw, int op[]) //求解简单装载问题
{  //tw表示选择的集装箱重量和,rw代表剩下集装箱重量和,op表示一种装载方案
	if (i > n)  //这个代表它把所有的集装箱都判断了是否装载,是走出递归的条件
	{
		if (tw > maxw)
		{
			maxw = tw;
			for (int j = 1;j <= n;j++)
			{
				x[j] = op[j];    //这个x[]是用来判断是否选择装载,存放最优解向量的
			}
		}
	}
	else
	{
		if (tw + w[i] <= W)   //左孩子结点剪枝
		{
			op[i] = 1;               //选取第i个集装箱
			dfs(i + 1, tw + w[i], rw - w[i], op);
		}
		if (tw + rw - w[i] > maxw)    //虽然这步我有点小蒙,但是确实是如此
		{
			op[i] = 0;
			dfs(i + 1, tw, rw - w[i], op);
		}
	}
}
void displaySolution(int n) 
{
	for (int i = 1;i <= n;i++) 
	{
		if (x[i] == 1) {
			printf("选择第%d个集装箱\n", i);
		}
	}        //当然不仅把要求写了,顺便还把选择哪几个集装箱输出了
	if (maxw == W)
		cout << "ture";   
	else
		cout << "false";

}
int main()
{
	int tw = 0, rw = 20;
	int op[100];
	dfs(1, tw, rw, op);
	displaySolution(n);
	return 0;
}

在这里插入图片描述
自己懒得画这个解空间树,找了个课本的,(0,20)0代表tw,20代表rw
在这里插入图片描述

  • 6
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
最优装载问题是指在给定一些货物和一些集装箱的容量限制下,如何选择并装载货物使得装载的总重量最大。这是一个经典的组合优化问题,可以使用回溯法进行求解回溯法的基本思想是将问题的解空间表示成一个树形结构,从根节点开始递归搜索所有可能的解,当搜索到叶子节点时,判断该叶子节点是否满足问题的约束条件,如果满足则记录该解,并回溯到上一层继续搜索,如果不满足则直接回溯到上一层。 具体来说,对于最优装载问题,可以将每个货物看作一个节点,每个节点有两种状态,即选中和不选中。从根节点开始,依次选择每个节点的状态,计算当前装载的总重量,如果超出了集装箱的容量限制则回溯到上一层,否则继续递归搜索下一层节点。当搜索到叶子节点时,记录当前的最优解,并回溯到上一层继续搜索。最终,所有可能的解都会被搜索到,从中选取最优解即可。 需要注意的是,使用回溯法求解最优装载问题的时间复杂度很高,因为需要搜索所有可能的解。为了提高效率,可以使用剪枝策略,即在搜索过程中根据当前装载的总重量和集装箱的容量限制,预测当前节点的子树中可能出现的最大总重量,如果该值小于当前的最优解,则可以剪枝,直接回溯到上一层。这样可以避免搜索无用的子树,减少搜索时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值