回溯法最优装载问题(java)
1.问题描述:
有一批共有 n 个集装箱要装上两艘载重量分别为 c1 和 c2 的轮船,其中集装箱 i 的重量为 w[i], 且重量之和小于(c1 + c2)。装载问题要求确定是否存在一个合理的装载方案可将这 n 个集装箱装上这两艘轮船。如果有,找出一种装载方案。
例如,当n=3,c1=c2=50,且w=[10,40,40]时,可将集装箱1和集装箱2装上一艘轮船,而将集装箱3装在第二艘轮船;如果w=[20,40,40],则无法将这3个集装箱都装上轮船。
容易证明,如果一个给定的装载问题有解,则采用如下的策略可以得到最优装载方案。
1.首先将第一艘轮船尽可能装满。
2.将剩余的集装箱装上第二艘轮船。
将第一艘轮船尽可能的装满等价于选取全体集装箱的子集,使该子集中集装箱的重量之和最接近 c1 。因此,等价于一个特殊的 0-1 背包问题。 因此是一棵子集树。
max(w1x1+w2x2+...+wixi)
(w1x1+w2x2+...+wixi)<= c1;
xi @{0,1},1<=i<=n
2 算法设计
用回溯法解装载问题时,用子集树表示其解空间显然是最合适的。可行性约束函数可剪去不满足约束条件(
(w1x1+w2x2+...+wixi)<= c1)的子树。在子集树的第j+1层的节点Z处,用cw记当前的装载重量,即cw=(w1x1+w2x2+...+wjxj),当cw>c1时,以节点Z为根的子树中所有节点都不满足约束条件,因而该子树中解均为不可行解,故可将该子树剪去。
package cn.cb.offer.backtrack; import javax.swing.*;
import java.util.Scanner; /**
* Created by IntelliJ IDEA.
* User: duanxx
* email:duanxx@staff.chinabyte.com
* Date: 13-10-16
* Time: 下午2:45
* 最优装载问题回溯法
*/
public class Loading {
private int n;//集装箱数
private int[] w;//集装箱重量数组
private int c;//第一艘轮船的载重量
private int cw;//当前载重量
private int bestw;//当前最优载重量
private int r;//剩余集装箱重量
private int[] x;//当前解
private int[] bestx;//当前最优解 /**
*
* @param i
*/
public void backtrace(int i) {
//1.到达叶节点
if (i > n-1) { //i此时的值=叶节点+1
if (cw > bestw) {
for (int j = 0; j < n; j++) {
bestx[j] = x[j];
bestw = cw;
}
return;
}
}
r -= w[i];
//2.搜索左子树
if (cw + w[i] < c) { //x[i =1
x[i] = 1;
cw += w[i];
backtrace(i + 1);
cw -= w[i];
}
//3.搜索右子树
if (cw + r > bestw) {
x[i] = 0;
backtrace(i + 1);
}
r += w[i];
} public static void main(String[] args) {
Loading X = new Loading();
/*String s1 = JOptionPane.showInputDialog(null, "输入货物数量:",
"最优装载问题", JOptionPane.QUESTION_MESSAGE);*/
Scanner scanner = new Scanner(System.in);
String s1 = scanner.nextLine();
X.n = Integer.parseInt(s1);
X.w = new int[X.n];
X.x = new int[X.n];
X.bestx= new int[X.n];
System.out.println("输出货物的重量数组:");
for (int i = 0; i < X.n; i++) {
X.w[i] = (int) (100 * Math.random());
System.out.println(X.w[i]);
}
/*String s2 = JOptionPane.showInputDialog(null, "输入第一艘轮船的载重量:",
"最优装载问题", JOptionPane.QUESTION_MESSAGE);*/ String s2 = scanner.nextLine();
X.c = Integer.parseInt(s2); for (int i = 0; i < X.n; i++)
X.r += X.w[i];
X.backtrace(0);
System.out.print("输出当前最优解:");
for (int i = 0; i < X.n; i++) System.out.print(X.bestx[i] + " ");
System.out.println();
System.out.println("最优解:" + X.bestw);
} }
回溯法最优装载问题(java)的更多相关文章
- Java算法——回溯法
回溯法一种选优搜索法,又称试探法.利用试探性的方法,在包含问题所有解的解空间树中,将可能的结果搜索一遍,从而获得满足条件的解.搜索过程采用深度遍历策略,并随时判定结点是否满足条件要求,满足要求就继续向 ...
- javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题
赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支 ...
- 算法java实现--回溯法--图的m着色问题
(转自:http://blog.csdn.net/lican19911221/article/details/26264471) 图的m着色问题的Java实现(回溯法) 具体问题描述以及C/C++实现 ...
- python 回溯法 子集树模板 系列 —— 3、0-1背包问题
问题 给定N个物品和一个背包.物品i的重量是Wi,其价值位Vi ,背包的容量为C.问应该如何选择装入背包的物品,使得放入背包的物品的总价值为最大? 分析 显然,放入背包的物品,是N个物品的所有子集的其 ...
- python 回溯法 记录
一直不是太理解回溯法,这几天集中学习了一下,记录如下. 回溯法有"通用的解题法"之称. 1.定义: 也叫试探法,它是一种系统地搜索问题的解的方法. 2.基本思想: 从一条路往前 ...
- 使用回溯法解批处理作业调度问题<算法分析>
一.实验内容及要求 1.要求用回溯法原理求解问题: 2.要求手工输入t1[10]及t2[10],t1[i]是任务i在机器1上的执行时间,t2[i]是任务i在机器2上的执行时间: 3.求出最优批处理作业 ...
- 01背包问题_回溯法&分支限界法
package 分支限界法; import java.util.LinkedList; import java.util.Scanner; /*01背包问题*/ public class ZOPack ...
- HDU 1016 Prime Ring Problem (回溯法)
Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- N-Queens And N-Queens II [LeetCode] + Generate Parentheses[LeetCode] + 回溯法
回溯法 百度百科:回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步又一次选择,这样的走不通就退回再走的技术为回溯法 ...
随机推荐
- Little Sub and Piggybank (杭师大第十二届校赛G题) DP
题目传送门 题意:每天能往存钱罐加任意实数的钱,每天不能多于起那一天放的钱数.如果某一天的钱数恰好等于那天的特价商品,则可以买,求最后的最大快乐值. 思路:先来一段来自出题人的题解: 显然的贪心:如果 ...
- 《Paxos Made Simple》翻译(转)
1 Introduction 可能是因为之前的描述对大多数读者来说太过Greek了,Paxos作为一种实现容错的分布式系统的算法被认为是难以理解的.但事实上,它可能是最简单,最显而易见的分布式算法了. ...
- 转如何检查数据库是否处于一致性的状态 以及 如果在DG 库上备份,恢复成一个主库
##sample 0 不完全恢复之后,open resetlogs之前,怎么快速的检查数据库是否处于一致性的状态?https://blog.csdn.net/msdnchina/article/det ...
- Bellman-Ford(BF)和Floyd算法
以下只是本人的笔记,想法我自己都怀疑,内容不作为参考, Floyd算法就比较暴力了,算法思想是三重循环,直接枚举所有的顶点,再两次for循环枚举所有点,验证以第一个点为中转点的两个点是否路径更短,具体 ...
- 更改kindeditor编辑器,改用支持h5的video标签替换原有embed标签
kindeditor是一款不错的可视化编辑器,不过最近几年似乎没在更新,现在h5趋于主流,正好有个业务需要编辑器支持mp4视频的播放,考虑到现在h5中的video标签的强大,于是决定将原来系统中的em ...
- 在vue中import()语法不能传入变量
解决办法: 一定要用变量的时候,可以通过字符串模板来提供部分信息给webpack:例如import(`./path/${myFile}`), 这样编译时会编译所有./path下的模块,但运行时确定my ...
- 【OpenCV-Python】-几何变换
涉及函数: cv2.getPerspectiveTransform()cv2.warpAffine() 接收的参数是2✖️3的变换矩阵cv2.warpPerspective() 接收的参数是3✖️3的 ...
- ubuntu系统复制到其他地方或克隆后,如何正确修改IP及MAC地址的解决方案(图文详解)
修改ip地址 永久修改MAC地址 方法一: 1)编辑“/etc/init.d/rc.local”文件(sudo gedit /etc/init.d/rc.local) 2)在此配置文件的最后面加上如( ...
- PyCharm鼠标右键不显示Run unittest方法
PyCharm鼠标右键不显示Run unittest方法 PyCharm是一个用来写python代码的IDE,很好用.在其中建立了unittest类后,鼠标点击某个test方法后,菜单中会显示Run ...
- spring自定义标签之 自我实现
引言: 最近心情比较难以平静,周末的两天就跑出去散心了,西湖边上走走,看日落,还是不错的.回来博客上发现,在自定义标签上,最后一步实现忘记加上了.其实,人生的路程中,我们总是实现着自我的价值,让自己 ...