一、问题描述
有一批集装箱要装上一艘载重量为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]+" ");
}
}