最优装载(贪心)

一、问题描述

有一批集装箱要装上一艘载重量为C的轮船。其中集装箱i的重量为Wi。最优装载问题要求确定在装载体积不受限制的情况下,尽可能多的集装箱装上轮船。

二、解题思路及所选算法策略的可行性分析

最优装载问题可用贪心算法求解。因为不限体积,尽可能多的装载。所以采用重量最轻者先装的贪心选择策略,可产生最优解。

三、结果

在这里插入图片描述

四、代码实现

package cn;

import java.util.Scanner;

public class Test {
	/**
	 * 静态集装箱类
	 * @author PC214
	 *
	 */
	public static class Element implements Comparable{
		float w;
		int i;
		public Element(float ww,int ii) {
			w = ww;//重量
			i = ii;//序号
		}

		@Override
		public int compareTo(Object X) {
			// TODO Auto-generated method stub
			float xw = ((Element)X).w;
			if(w<xw) return -1;
			if(w==xw) return 0;
			return 1;
		}
		
	}
	/**
	 * 贪心算法
	 * @param c 最大装载重量
	 * @param w 集装箱重量数组
	 * @param x	记录集装箱序号
	 * @return 返回最大重量
	 */
	public static float loading(float c,float[] w,int[] x) {
		int n=w.length;
		Element[] d = new Element[n];
		for(int i = 0;i < n;i++)
			d[i] = new Element(w[i],i);
		MergeSort.mergeSort(d);
		float opt = 0;
		for(int i=0;i<n;i++)
			x[i]=0;
		for(int i=0;i<n&&d[i].w<=c;i++) {
			x[d[i].i]=1;
			opt+=d[i].w;
			c-=d[i].w;
		}
		return opt;
	}
	/**
	 * 归并排序
	 * @author PC214
	 *
	 */
	public static class MergeSort{
		public static void mergeSort(Comparable a[]){
			Comparable b[] = new Comparable[a.length];
			int s = 1;
			while(s < a.length){
				mergePass(a,b,s);//合并到数组b
				s += s;
				mergePass(b,a,s);//合并到数组a
				s += s;
			}
		}
		//合并大小为s的相邻子数组
		public static void mergePass(Comparable x[],Comparable y[],int s){
			int i = 0;
			while(i <= x.length - 2 * s){
				//合并大小为s的相邻2段子数组
				merge(x,y,i,i + s - 1,i + 2 * s - 1);
				i = i + 2 * s;
			}
			if(i + s < x.length)
				merge(x,y,i,i + s - 1,x.length - 1);
			else
				//复制到y
				for(int j = i;j < x.length;j ++)
					y[j] = x[j];
		}
		public static void merge(Comparable c[],Comparable d[],int l,int m,int r){
			//合并 c[l:m]和c[m+1:r]到d[l:r]
			int i = l,j = m + 1,k = l;
			while((i <= m) && (j <= r))
				if(c[i].compareTo(c[j]) <= 0){
					d[k ++] = c[i ++];
				}
				else
					d[k ++] = c[j ++];
			if(i > m)
				for(int q = j;q <= r;q ++)
					d[k ++] = c[q];
			else
				for(int q = i;q <= m;q ++)
					d[k ++] = c[q];
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("请输入最大装载重量和集装箱数目:");
		Scanner readr = new Scanner(System.in);
		float c = readr.nextFloat();
		int n = readr.nextInt();
		
		float[] w = new float[n];
		int[] x = new int[n];
		System.out.println("集装箱数组:");
		for(int i=0;i<n;i++)
			w[i] = readr.nextFloat();
		float opt;//最大装载
		opt=loading(c,w,x);
		
		System.out.println("最大装载:"+opt);
		System.out.println("最优装载序列:");
		for(int i=0;i<n;i++)
			System.out.print(x[i]+" ");

		
	}

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Ma.01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值