算法/贪心算法/BinPacking一维装箱问题

问题描述

We have a number of bins each with a capacity of 1, and we have a set of objects all with different sizes, s1,s2,…,sn between 0 and 1. What is the fewest number of bins that would be needed to store all of the objects?

Instance: 0.5, 0.7, 0.3, 0.9, 0.6, 0.8, 0.1, 0.4, 0.2, 0.5

一维装箱问题只考虑一个因素,比如重量、体积、长度等。


思路一

要求解箱子数目,也就是说不能确定会占用多少个箱子,因此采用链表的形式来存储箱子信息。
我们先将物品由大到小进行排序,每次拿出一个物品从第一个箱子开始遍历:如果可以放下,那么重新拿出一个物品在从第一个开始遍历;如果放不下,就开一个新箱子,将这个物品放在里面。


思路二

还是先将物品由大到小进行排序,每次拿出一个箱子遍历物品,遍历完一次物品就表示一个箱子装满了,然后再开下一个箱子,直到所有的物品装完为止。对于上述题目,既然只需要求出所需箱子的数量,个人认为就没必要用更复杂的数据结构了。
初学算法,这个完全是自己写的,感觉还有待优化,思路一的代码也会尽快完成,出现问题望指正。

//箱子类
class Box {
    static int MAX_SIZE = 10;
    int id = 0;
    int size;
    int[] store;//记录箱子里装入的物品

    Box(int n) {
        store = new int[n];
    }
}


public class BinPacking {

    private int[] goods;

    private BinPacking(int[] goods) {
        this.goods = goods;
    }


//    将Good按照size由大到小排序
    private void sort(int[] goods) {
        for (int i = 0; i < goods.length; i++) {
            for (int j = 1; j < goods.length - i; j++) {
                if (goods[j - 1] < goods[j]) {
                    int temp = goods[j];
                    goods[j] = goods[j - 1];
                    goods[j - 1] = temp;
                }
            }
        }
    }


//    用于判断是否全部物品已经装完
    private int sum(int[] goods) {
        int sum = 0;
        for (int good : goods) {
            sum += good;
        }
        return sum;
    }


//    装箱过程
    private void binPacking() {
        sort(goods);

        Box box = new Box(goods.length);

        while (sum(goods) != 0) {
            box.id++;//箱子id从1开始
            box.size = Box.MAX_SIZE;
            for (int j = 0; j < goods.length; j++) {
                box.store[j] = 0;
            }//存储清零,相当于开一个新箱子

            for (int i = 0; i < goods.length; i++) {
                while (goods[i] == 0) {
                    if (i == goods.length - 1)
                        break;
                    i++;
                }//跳过已经装入的物品

                if (goods[i] <= box.size) {
                    box.size -= goods[i];
                    box.store[i] = goods[i];//将已装入的物品存在Box类的store[]中
                    goods[i] = 0;
                    if (box.size == 0)
                        break;
                }
            }

//            一次遍历结束,打印结果
            System.out.println("第" + box.id + "个箱子装入质量为:");
            for (int j = 0; j < goods.length; j++) {
                if (box.store[j] != 0) {
                    System.out.print(box.store[j] + " ");
                }
            }
            System.out.println();

        }
        System.out.println("最少需要" + box.id + "个箱子");
    }


    public static void main(String[] args) {
        int[] goods = {5,  7,  3,  9,  6,  8,  1,  4,  2,  5};
        BinPacking b = new BinPacking(goods);
        b.binPacking();
    }

}
  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值