最优装载问题_贪心

一、  问题描述

   有一批集装箱要装上一艘载重为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+" ");
	}
}

  

五、代码运行结果截图

六、问题总结

常用排序算法还得再好好看看。

原文地址:https://www.cnblogs.com/LieYanAnYing/p/11829319.html

时间: 2024-10-14 00:32:42

最优装载问题_贪心的相关文章

贪心算法之最优装载

贪心算法通过一系列的选择来得到问题的解.它所做的每一个选择都是当前状态下局部最好选择.从许多的贪心算法求解的问题可以看到可用贪心算法求解的问题一般具有两个重要的性质:贪心选择性质和最优子结构性质. 1.贪心选择性质 贪心选择性质是 指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到.与动态规划算法的不同之处是贪心算法只依赖在当前状态下做出最优选择,然后再去解做出这个选择后产生的相应的子问题.贪心算法依赖于以往做出的选择,但是绝不依赖未来做出的选择.所以贪心算法是自顶向下解决问题

贪心算法:最优装载问题

/*----------------------------------------------------- 给出n个物体,第i个物体的重量为wi. 选择尽量多的物体,使得总重量不超过C. 输入: n和C以及n个整数表示的wi. 输出: 按照输入物体的顺序输出n个用空格分隔的Y或N. Y表示该物体被选中,N表示不被选中. 最后一行输出所选中的物体的个数num和总重量w,用空格分隔. 注意:这个地方每个物体是不可再分割的整体. 思路: 先把所有物体按重量排序(从小到大排序) , 然后贪心选择重量

贪心算法一:最优装载问题

1.基本思想: 贪心算法是通过一系列的选择来得到问题的解,它所做的选择都是当前情况下最优的选择,即贪心算法并不考虑整体最优,而考虑的是当前情况下的局部最优,即贪心选择. 2.贪心算法的两个性质: 1)贪心选择性质:所求解的问题的整体最优解可以通过一系列局部最优的选择来,即贪心选择达到.贪心选择所依赖的是以前所做过的选择,而对以后所做的选择没有关系. 2)最优子结构性质:一个问题的最优解包含其子问题的最优解. 3.贪心算法与动态规划的区别: 动态规划是通过自底向上的方式解决子问题,贪心算法是通过自

贪心算法之最优装载问题

问题描述: 给出n个物体,第i个物体的重量是Wi,选择尽量多的物体,使得总重量不超过C. 问题分析: 这是一个很典型的用贪心算法的题目.要想让装的物体越多,自然装的最轻的物体就越多.因此可以对物体的重量由小到大进行排序,然后依次装载即可.这就体现了贪心算法只顾眼前,但却可以得到最优解. 解决问题:  代码如下 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> //为了引入memcpy 4 /

最优装载(贪心)

描述:有一批集装箱要装上一艘载重量为C的轮船.其中集装箱i的重量为wi.最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船. 贪心算法之最优装载 给出n个物体,第i个物体的重量为wi. 选择尽量多的物体,使得总重量不超过C. 注意:这个地方每个物体是不可再分割的整体. 思路: 先把所有物体按重量排序(从小到大排序) , 然后贪心选择重量比较小的物体直到所选物体的总重量超过所允许的最大重量C .一般选择是从最小的开始,所以先要排序 第一种方法(容器) #include <i

0-1 背包问题、背包问题、最优装载问题、哈夫曼编码,这几个问题的思想是什么?

0-1背包问题: 给定n种物品和一个背包.物品i的重量是Wi,其价值为Vi,背包的容量为C.应如何选择装入背包的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i只有2种选择,即装入背包或不装入背包.不能将物品i装入背包多次,也不能只装入部分的物品i. 背包问题: 与0-1背包问题类似,所不同的是在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n. 解决方法:求每个物品的价值重量比,即价值/重量.然后添加价值重量比最大的物品,添加结束如果

最优装载

最优装载 贪心算法 一问题描述 二问题分析 三代码实现 package loading; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.Arrays; import java.util.Comparator; public class bin { public static void main(String[] args) throws

回溯法--无优化 最优装载问题

//#include "stdafx.h" // 回溯法,解空间分为排列数和子集树,前者是不同节点顺序的排列,后者是一个(0,1,...)的向量子集// 最大装载问题,是一个NP问题,目前只计算第一艘船,属于子集树// 有几个货物,子集树就有几层,当前题目为5层// 我感觉递归还是太过于精巧和经凑,很难挖空心思自己写出来,多熟悉别人现有的程序是一个好办法. #include<iostream>using namespace std; template<class T&

单源最短路径_贪心算法

问题描述 给定带权有向图G =(V,E),其中每条边的权是非负实数.另外,还给定V中的一个顶点,称为源.现在要计算从源到所有其它各顶点的最短路长度.这里路的长度是指路上各边权之和. 策略与数据结构 其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合.一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知. 相关解释 观测域:假设起点为v点,观测域便为v点的四周,即v的所有邻接点: 点集 V:图中所有点的集合: 点集 S:已经找到最短路径的终点集合: 数组 D:存储观测域内能观测到的最