最優裝載問題_貪心


一、  問題描述

   有一批集裝箱要裝上一艘載重為C的輪船。其中集裝箱i的重量為Wi。最優裝載問題要去確定在裝載體積不受限制的情況下,將極可能多的集裝箱裝上輪船。

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

使用貪心算法。

問題描述為

    max∑Xi,∑WiXi<=C,Xi∈{0,1}   1<=i<=n

其中,變量Xi=0表示不裝入集裝箱i,Xi=1表示裝入集裝箱i。

貪心選擇性質

    設集裝箱已依其重量從小到大排序,(X1,X2,…,Xn)是最優裝問題的一個最優解。又設k=min{i|Xi=1}。易知,如果給定的最優裝載問題有解,則1<i<=n,i!=k,則

    ∑WiYi = Wi - Wk + ∑WiXi <= ∑WiXi <= C

因此,(Yz,Y2,…,Yn)是所給最優裝載問題的可行解。

    另一方面,由∑Yi = ∑Xi知,(Y1,Y2,…,Yn)是滿足貪心選擇性質的最優解。

最優子結構性質

    設(X1,X2,…,Xn)是最優裝載問題的滿足貪心選擇性質的最優解,則容易知道,X1=1,且(X2,…,Xn)是輪船載重量為C-W1,待裝載集裝箱為{2,3,…,n}時相應最優集裝箱問題的最優解。也及時說,最優集裝箱裝載問題具有最優子結構性質。

三、  代碼描述及復雜度分析

Loading(float c, float[]w, int[] x)

{

   創建集裝箱數組,存放每個集裝箱重量及其序號;

    按集裝箱重量從小到大排序;

    有小到大依次判斷是否可入箱;

    返回輪船上箱子總重量;

}

四、代碼實現

package 貪心算法;

import 分治法.dcPoint;

class Element implements Comparable{
	float w;
	int i;
	
	public Element(float ww, int ii) {
		w=ww;
		i=ii;
	}
	
	public int compareTo(Object x)
	{
		float xw=((Element)x).w;
		if(w<xw) return -1;
		if(w==xw) return 0;
		return 1;
	}
}

class MergeSort{
	public static void mergeSort(Element[] a){
		Element[] tempArray = new Element[a.length];
		mergeSort(a, tempArray, 0, a.length - 1);
	}
	
	private static void mergeSort(Element[] a, Element [] tempArray, int left, int right){
		if(left < right){
			int center = (left + right) >> 1;
			//分治
			mergeSort(a, tempArray, left, center);
			mergeSort(a, tempArray, center + 1, right);
			//合並
			merge(a, tempArray, left, center + 1, right);
		}
	}
	
	private static void merge(Element [] a, Element [] tempArray, int leftPos, int rightPos, int rightEnd){
		int leftEnd = rightPos - 1;
		int numOfElements = rightEnd - leftPos + 1;
		
		int tmpPos = leftPos;		//游標變量, 另兩個游標變量分別是leftPos 和 rightPos
		
		while(leftPos <= leftEnd && rightPos <= rightEnd){
				if(a[leftPos].w <= a[rightPos].w)
					tempArray[tmpPos++] = a[leftPos++];
				else
					tempArray[tmpPos++] = a[rightPos++];
		}
		
		while(leftPos <= leftEnd)
			tempArray[tmpPos++] = a[leftPos++];
		while(rightPos <= rightEnd)
			tempArray[tmpPos++] = a[rightPos++];
		
		//將排好序的段落拷貝到原數組中
		System.arraycopy(tempArray, rightEnd-numOfElements+1, a, rightEnd-numOfElements+1, numOfElements);
	}
}
public class 最優裝載{
	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;i++)
		{
			if(w[i]<=c){
				x[d[i].i]=1;
				opt+=d[i].w;
				c-=d[i].w;
			}else
				break;
		}
		return opt;
	}
	
	public static void main(String[] args)
	{
		float weight= (float) 100.00;
		float w[]={1,5,10,14,15,16,20,18,23,32,56,72,85};
		int x[]=new int[w.length];
		
		System.out.println("貨物總重量為:"+loading(weight, w, x));
		System.out.print("裝入集裝箱為:");
		for(int i=0; i<w.length; i++)
			if(x[i]==1) 
			System.out.print(i+1+" ");
	}
}

  

五、代碼運行結果截圖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM