算法设计-回溯法——装载问题

算法介绍

回溯法:

回溯法又称试探法。回溯法的基本做法是深度优先搜索,是一种组织得井井有条的、能避免不必要重复搜索的穷举式搜索算法。
回溯算法的基本思想:从一条路往前走,能进则进,不能进则退回来,换一条路再试。

问题实例

问题描述:

题目:
用回溯法编写一个递归程序解决如下装载问题:有 n 个集装箱要装上 2 艘载重分别为 c1 和 c2的轮船,其中集装箱 i 的重量为 wi(1≤ i ≤ n),且∑ 𝑤𝑖 ≤ 𝑐1 + 𝑐2 𝑛 𝑖=1 。问是否有一个合理 的装载方案可以将这 n 个集装箱装上这 2 艘轮船?如果有,请给出装载方案。
举例:当 n=3,c1=c2=50,且 w=[10,40,40]时,可以将集装箱 1 和 2 装到第一艘轮船上, 集装箱 3 装到第二艘轮船上;如果 w=[20,40,40]时,无法将这 3 个集装箱都装上轮船。

问题分析

对于该问题可以拆分成两部分来看,第一部分是轮船一的最大载重问题,相当于背包问题
第二部分就是判断轮船一装剩下的是否可以装载的问题

对于问题1需要通过判断节点i(集装箱i)的装与不装形成一个二叉树,一条到叶子节点的通路就是一种方案。
再利用一变量存储此时重量,以此来记录最优的装载方案。
设 bestw : 当前最优载重量,
cw : 当前扩展结点Z的载重量 ;
r : 剩余集装箱的重量;
w[i] : i节点(i集装箱)的重量;
当 cw+w[i]<=c1时 可以放
当 cw + r (限界函数) <= bestw时,可将Z的右子树剪去。(此时右子树的所有方案一定大于轮船1的载重量)
当 cw + r (限界函数) > bestw时,可以讨论i节点不放的情况。

伪代码:
①用i记录第几个集装箱,判断该集装箱是否装入
②如果剩余载重量大于该集装箱的重量,先不装入,否则装入。
③再判断如果先不放该集装箱,再放剩下的集装箱是否可以达成最优装载。
④利用回溯法,逐一判断集装箱,直到结束。

代码:

#include <iostream>

using namespace std;

//定义全局变量
int x[100]; //表示当前解,0代不表放,1代表放
int bestx[100];//表示最优解
int w[100];// 表示集装箱i的重量
int bestw;//当前最优装载重量
int r;//剩余集装箱的重量
int n; //集装箱的数量
int c1;//轮船1的载重量
int c2;//轮船2的载重量
int cw;
  • 34
    点赞
  • 333
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值