前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >回溯法最优装载问题(Java实现)

回溯法最优装载问题(Java实现)

原创
作者头像
ruochen
修改2021-05-17 10:20:40
1K0
修改2021-05-17 10:20:40
举报

最优装载问题

问题描述

  • 有一批共n个集装箱要装上2艘载重量分别为c1和c2的轮船,其中集装箱i的重量为wi,装载问题要求确定是否有一个合理的装载方案可将这些集装箱装上这2艘轮船。如果有,找出一种装载方案。例如:当n=3,c1=c2=50,且w=10,40,40时,则可以将集装箱1和2装到第一艘轮船上

Java源代码

注释很详细

代码语言:txt
复制
 /*
 * 若尘
 */
package loading2;

/**
 * 装载问题
 * @author ruochen
 * @version 1.0
 */
public class Loading {
	/** 集装箱数 */
	static int n;
	/** 集装箱重量数组 */
	static int[] w;
	/** 第一艘轮船的载重量 */
	static int c1;
	/** 第二艘轮船的载重量 */
	static int c2;
	/** 当前载重量 */
	static int cw;
	/** 当前最优载重量 */
	static int bestw;
	/** 剩余集装箱重量 */
	static int r;
	/** 当前解 */
	static int[] x;
	/** 当前最优解 */
	static int[] bestx;

	public static void main(String[] args) {
		// 下标从1开始,所以第一个元素为0
		int[] ww = {0, 10, 40, 40};
		int cc1 = 50;
		int cc2 = 50;
		System.out.println(maxLoading(ww, cc1, cc2));
		outPut();
	}
	
	/** 返回不超过c 的最大子集和 */
	public static int maxLoading(int[] ww, int cc1, int cc2) {
		n = ww.length - 1;
		w = ww;
		c1 = cc1;
		c2 = cc2;
		cw = 0;
		bestw = 0;
		x = new int[n + 1];
		bestx = new int[n + 1];
		r = 0;
		// r 初始值为全部集装箱总重
		for (int i= 1; i <= n; i++) {
			r += w[i];
		}
		// 计算最优载重量
		backTrack(1);
		return bestw;
	}

	/** 回溯算法 */
	public static void backTrack(int i) {
		// 搜索第 i 层节点
		if (i > n) {
			// 到达叶节点
			if (cw > bestw) {
				for (int j = 1; j <= n; j++) {
					bestx[j] = x[j];
				}
				bestw = cw;
			}
			return ;
		}
		// 搜索子树
		r -= w[i];
		if (cw + w[i] <= c1) {
			// 重量不超过 c
			// 搜索左子树
			x[i] = 1;
			cw += w[i];
			backTrack(i + 1);
			// 还原
			x[i] = 1;
			cw -= w[i];
		}
		// 只在右子树进行上界函数判断是因为其对左子树无影响
		// 左子树是选择放,上界函数 = cw(当前重量) + r(剩余重量)
		if (cw + r > bestw) {
			x[i] = 0;
			// 搜素右子树
			backTrack(i + 1);
		}
		r += w[i];
	}
	
	static void outPut() {
		int weight = 0;
		for (int i = 1; i <= n; i++) {
			if (bestx[i] == 0) {
				// 第一艘轮船装完后的剩余重量
				weight += w[i];
			}
		}
		if (weight > c2) {
			System.out.println("不能装入 ");
		} else {
			System.out.print("轮船一装入的货物为: ");
			for (int i = 1; i <= n; i++) {
				if (bestx[i] == 1) {
					System.out.print(i + " ");
				}
			}
			System.out.println();
			System.out.print("轮船二装入的货物为: ");
			for (int i = 1; i <= n; i++) {
				if (bestx[i] != 1) {
					System.out.print(i + " ");
				}
			}
		}
	}

}
代码语言:txt
复制
50
代码语言:txt
复制
轮船一装入的货物为: 1 2 
代码语言:txt
复制
轮船二装入的货物为: 3 

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 最优装载问题
    • 问题描述
      • Java源代码
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档