贪心法——最优装载问题

贪心法——最优装载问题

问题:

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

0-1背包在价值相同时的特例。

分析:

直管思路:先装最轻的。

将所有物品从轻到重排序。

贪心选择:选择第一个待选物品。

父问题:给出待选物品的一个最优选择。子问题:给出选了第一个待选物品后的最优选择。

贪心选择性质证明:利用数学归纳法,证明两点:1.原问题以贪心选择开始,也就是证明数学归纳法的归纳基础成立;2.对于任意规模的以贪心选择开始的问题,若其取最优解,那么贪心选择之后生成的子问题仍然具有以贪心选择开始的最优解,也就是证明数学归纳法的归纳步骤成立。

  1. 若要装尽可能多的集装箱,那么一定要装第一个(最轻的货物),否则最轻的货物替换掉选中的某个货物一定能得到更优的解。
  2. 对于剩下的一部分集装箱,同理还是要选最轻的,选中这个最轻的后,剩下的所有货物还是要选最轻的(这一点就是最优子结构性质)

最优子结构性质:剩下的一部分集装箱,选择最轻的使得其得到最优解,剩下的货物中选出的最优解加上这个货物就是父问题的最优解。

代码:

// 最优装载问题
// 输入:物品数量n,最大载重c,物品重量序列w,是否选择某物品x
void Loading(int n,float c,float w[],int x[]){
    sort(w,w+n);
    for(int i = 0;i < n;i++){
        if(c>=w[i]){
            x[i] = 1;
            c -= w[i];
        }else{
            x[i] = 0;
        }
    }
}

复杂度:

时间复杂度:排序O(nlogn)+迭代O(n)

空间复杂度:O(n)

一些思考:

贪心选择性质侧重贪心选择可以得到一个局部的最优解,重点在于递推

最优子结构性质侧重每个局部最优解都是由每一步的贪心选择组成的,重点在于组合

目前认为贪心是一种特殊的较为简单的动态规划递推式

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
贪心算法是一种常用的解决最优装载问题的算法。在Java中,可以使用贪心算法来解决最优装载问题最优装载问题是指在给定一组物品和一个容量限制的背包时,如何选择物品放入背包中,使得背包的总价值最大化。贪心算法的思想是每次选择当前最优的物品放入背包中,直到背包无法再放入更多物品为止。 以下是Java中贪心算法解决最优装载问题的基本步骤: 1. 定义一个物品类,包含物品的重量和价值属性。 2. 根据物品的价值重量比进行排序,从大到小排序。 3. 初始化背包的容量和总价值为0。 4. 遍历排序后的物品列表,依次将物品放入背包中,直到背包无法再放入更多物品或者所有物品都已经放入背包为止。 5. 返回背包的总价值作为最优解。 下面是一个简单的Java代码示例: ```java import java.util.Arrays; class Item implements Comparable<Item> { int weight; int value; public Item(int weight, int value) { this.weight = weight; this.value = value; } @Override public int compareTo(Item other) { double ratio1 = (double) this.value / this.weight; double ratio2 = (double) other.value / other.weight; if (ratio1 > ratio2) { return -1; } else if (ratio1 < ratio2) { return 1; } else { return 0; } } } public class GreedyAlgorithm { public static int knapsack(Item[] items, int capacity) { Arrays.sort(items); int totalValue = 0; int currentWeight = 0; for (Item item : items) { if (currentWeight + item.weight <= capacity) { currentWeight += item.weight; totalValue += item.value; } else { int remainingCapacity = capacity - currentWeight; totalValue += item.value * ((double) remainingCapacity / item.weight); break; } } return totalValue; } public static void main(String[] args) { Item[] items = {new Item(10, 60), new Item(20, 100), new Item(30, 120)}; int capacity = 50; int maxValue = knapsack(items, capacity); System.out.println("最优装载问题的最大价值为:" + maxValue); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值