最优装载问题

最优装载问题

Description

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

Input

输入的第一个为测试样例的个数T,接下来有T个测试样例。每个测试样例的第一行是一个非负整数n( n ≤ 1000 )和一个非负整数C( C ≤ 10000 ),分别表示集装箱的个数以及轮船的载重量。接下来有n行,每行一个非负数,表示每个集装箱的重量。

Output

对应每个测试样例输出一行,格式为"Case #: D V",其中’#'表示第几个测试样例(从1开始计),D为轮船可以装载的集装箱数量的最大值,V为满足D最大时轮船的实际载重量。

最优装载可以用贪心算法求解。

贪心算法:

一般具有两个重要性质:贪心选择性质和最优子结构性质

贪心选择性质:所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解

最优子结构:当一个问题的最优解包括其子问题的最优解时,具有最优子结构。

代码(未测试)

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <algorithm>
 
using namespace std;
 
void _swap( int a[], int i, int j )
{
    a[i] = a[i]^a[j];
    a[j] = a[i]^a[j];
    a[i] = a[i]^a[j];
}
 
int random_position( int a[], int left, int right )
{
    srand((unsigned)time(NULL));
    int position = rand()%( right - left + 1) + left;
    int key = a[position];
    while( left < right )
    {
        while( left < right && a[left] < key ){ left++;}
        while( left < right && a[right] > key ){right--;}
        _swap(a, left, right);
    }
    a[left] = key;
    return left;
}
 
void qsort(int a[], int left, int right)
{
    if( left >= right )
        return ;
    int position = random_position(a, left, right);
    qsort( a, left, position-1 );
    qsort( a, position+1, right );
}
 
 
int main()
{
    int t,n,c;
    scanf("%d", &t);
    for( int i = 1; i <= t; i++ )
    {
        scanf("%d%d", &n, &c);
        int a[n];
        for( int k = 0; k < n; k++ )
        {
            scanf("%d", &a[k]);
        }
     //   sort(a, a+n);
        qsort(a, 0, n-1);
        int kk = 0, ans = 0;
        int after_c = c;
        while(a[kk] <= after_c)
        {
            ans++;
            after_c-=a[kk++];
        }
        printf("Case %d: %d %d\n", i, kk, c - after_c);
 
    }
 
    return 0;
}

实验课用

//#include "stdafx.h"  
#include <iostream>   
using namespace std;   
  
const int N = 4;  
  /*
template <class Type>    
void Swap(Type &x,Type &y);   
  
template<class Type>  
void Loading(int x[],  Type w[], Type c, int n);  
  
template<class Type>  
void SelectSort(Type w[],int *t,int n);  
 */ 
/*
int main()  
{  
    float c = 70;  
    float w[] = {0,20,10,26,15};//下标从1开始  
    int x[N+1];  
  int i;
    cout<<"轮船载重为:"<<c<<endl;  
    cout<<"待装物品的重量分别为:"<<endl;  
    for(i=1; i<=N; i++)  
    {  
        cout<<w[i]<<" ";  
    }  
    cout<<endl;  
    Loading(x,w,c,N);  
  
    cout<<"贪心选择结果为:"<<endl;  
    for( i=1; i<=N; i++)  
    {  
        cout<<x[i]<<" ";  
    }  
    cout<<endl;  
  
    return 0;  
}  
  */
template<class Type>  
void Loading(int x[],Type w[], Type c, int n)  
{  
    int i;
	int *t = new int [n+1];//存储排完序后w[]的原始索引  
    SelectSort(w, t, n);  
  
    for(i=1; i<=n; i++)  
    {  
        x[i] = 0;//初始化数组x[]  
    }  
    for( i=1; i<=n && w[t[i]]<=c; i++)  
    {  
        x[t[i]] = 1;  
        c -= w[t[i]];  
    }  
}  
  
template<class Type>  
void SelectSort(Type w[],int *t,int n)  
{  
    Type tempArray[N+1],temp;  
    memcpy(tempArray,w,(n+1)*sizeof(Type));//将w拷贝到临时数组tempArray中  
    int min;  
   int i,j;
    for(i=1;i<=n;i++)  
    {  
        t[i] = i;  
    }  
  
    for(i=1;i<n;i++)  
    {  
        min=i;  
        for( j=i+1;j<=n;j++)  
        {  
            if(tempArray[min]>tempArray[j])  
            {  
                min=j;  
            }  
        }  
        Swap(tempArray[i],tempArray[min]);  
        Swap(t[i],t[min]);  
    }  
}  
  
template <class Type>    
void Swap(Type &x,Type &y)  
{  
    Type temp = x;    
    x = y;    
    y = temp;    
} 

//new 
int main()  
{  
    float c = 70;  
    float w[] = {0,20,10,26,15};//下标从1开始  
    int x[N+1];  
  int i;
    cout<<"轮船载重为:"<<c<<endl;  
    cout<<"待装物品的重量分别为:"<<endl;  
    for(i=1; i<=N; i++)  
    {  
        cout<<w[i]<<" ";  
    }  
    cout<<endl;  
    Loading(x,w,c,N);  
  
    cout<<"贪心选择结果为:"<<endl;  
    for( i=1; i<=N; i++)  
    {  
        cout<<x[i]<<" ";  
    }  
    cout<<endl;  
  
    return 0;  
}   

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

最优子结构性质:设(x1,x2,……xn)是最优装载问题的满足贪心选择性质的最优解,则易知,x1=1,(x2,x3,……xn)是轮船载重量为c-w1,待装船集装箱为{2,3,……n}时相应最优装载问题的最优解。因此,最优装载问题具有最优子结构性质。

求解过程:最优装载问题可用贪心算法求解。采用重量最轻者先装的贪心选择策略,可产生最优装载问题的最优解。具体代码如下:

算法loading的主要计算量在于将集装箱依其重量从小到大排序,故算法所需的计算时间为 O(nlogn)。运行结果如下:

### 回答1: 最优装载问题是指在给定轮船载重量c和一批集装箱,每个集装箱的重量为wi,要求选择尽可能多的集装箱装上轮船。这个问题可以用贪心算法来解决。 具体实现方法如下: 1. 将所有集装箱按照重量从大到小排序。 2. 从重量最大的集装箱开始,依次尝试将其装入轮船,直到轮船的剩余载重量小于该集装箱的重量为止。 3. 将下一个重量次大的集装箱尝试装入轮船,重复步骤2,直到所有集装箱都被尝试过。 4. 统计成功装入轮船的集装箱数量,即为最优解。 这个贪心算法的正确性可以通过反证法证明。假设存在一种更优的装载方案,使得装入轮船的集装箱数量比上述算法得到的结果更多。那么在这个更优的方案中,一定存在一个集装箱,它的重量比上述算法中被尝试的第一个无法装入轮船的集装箱的重量更小。因此,如果按照上述算法的顺序尝试装载集装箱,这个更轻的集装箱一定能够被成功装入轮船,与假设矛盾。因此,上述算法得到的结果是最优解。 ### 回答2: 最优装载问题是一种经典的优化问题,用于求解在限制条件下选择最优解的问题。在此问题中,我们需要在轮船的载重量限制下,尽可能地装载更多的集装箱。 贪心法是解决最优装载问题的一种有效算法。贪心算法的基本思想是,在每一步中选择当前状态下最优的解,最终得到全局最优解。 在最优装载问题中,我们可以按照以下步骤实现贪心算法: 1. 将所有集装箱按照重量wi从大到小排序,表示尽可能选择重量大的集装箱来装载。 2. 从排序后的集装箱列表中按顺序选择集装箱,如果当前已经选择的集装箱总重量cw加上当前要选择的集装箱重量wi小于等于轮船载重量c,则选择该集装箱装入轮船,并将当前已经选择的集装箱总重量cw加上wi。 3. 如果当前已经选择的集装箱总重量cw加上当前要选择的集装箱重量wi大于轮船载重量c,则该集装箱无法装入轮船,继续选择下一个集装箱。 4. 重复步骤2和步骤3,直到所有集装箱都被考虑。 5. 输出已装载集装箱的数量。 通过这样的贪心策略,我们可以实现最优装载问题并得到最优解。 需要注意的是,贪心算法的局限性在于它只能得到局部最优解,不一定能得到全局最优解。在某些情况下,贪心算法可能会失效,例如,当集装箱的重量分布不均时,贪心算法可能无法得到最优解。因此,在实际应用中,需要根据具体情况选择合适的算法来求解。 ### 回答3: 最优装载问题,即在有限的载重量条件下最大化装箱数量的问题,可以采用贪心法进行求解。 首先,我们需要确定每个集装箱的单位重量价值,即按照每吨货物所占用的轮船空间的价值确定。这样,我们就能够依据集装箱单位重量的价值从高到低排序。 接下来,我们按照排序后的顺序依次选择集装箱进行装载。每次选择重量较小的集装箱放在尽量靠前的位置,直到轮船的载重量达到极限或全部集装箱都已经装载完毕。 贪心法的实现思路是在将集装箱按照单位重量价值排序后,依次选择重量较小的集装箱进行装载。因为重量较小的集装箱对于轮船的载重量贡献较小,可以给后续装载留出更多的余地,从而使得装载的集装箱数量更多。 同时,由于轮船的装载体积没有受到限制,因此不需要考虑集装箱的体积问题,只需按照重量排序即可。 通过贪心法,我们可以快速解决最优装载问题,并找出一种使得装入轮船的集装箱数量最多的装载方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值