二维装箱怎么能装最多

问题描述:
在这里插入图片描述
上面的描述是一个三维的装箱问题,但是题目说大箱子的长度和小箱子的长度相同,所以可以转换为一个二维空间上的装箱问题,只考虑宽和高。
思考:

  1. 怎么装才能保证装的最多?从最小的开始装,装到装不下了就是最多的情况。(背包问题)
  2. 但是小方块不规则,会有很多空隙存在,那么在计算剩余空间的时候,用剩余总空间减去当前小方块的空间这样的做法是有问题的,因为小方块不可能像理想的那样紧凑的在一起。

解决方法:

  1. 要装下最多,首先能确定的是空间小的优先是能保证装的最多。
  2. 要能充分的利用空间,但是又不能以理想的方式直接用总的减去当前的。其实用二分的方法可以充分的利用空间,就是将第一个矩形放入盒子后,将盒子分为右、下两个盒子,然后继续在右和下两个盒子中装第二个矩形,然后装下了又划分。(参考
  3. 上面解决了装最多,和充分利用空间的问题,但是充分利用空间的方法是从大开始装,因为这样划分的空间才有可能装下后面比它小的矩形。要是从最小的开始装,那么划分后剩余的空间是装不下还比它大的矩形的。所以1和2两个思路分别解决了问题,但是矛盾了。
  4. 那么又要优先装小的,又要从大的开始装。怎么解决? 我的思路是:从大的开始装,装到装不下了,看是否有剩余的小矩形,如果有!那么把最大的一个矩形剔除,从第二大的开始装,重复上面步骤,知道最小的一个装到盒子里面,那么这样的情况一定是最多而且最紧凑的。

代码的实现:

节点类 Node.java

public class Node {
    public Integer x;
    public Integer y;
    public Integer w;
    public Integer h;
    public boolean isUsed;
    public Node right;
    public Node down;
    public Rectangle rec;


    public Node() {
    }

    public Node(Integer x, Integer y, Integer w, Integer h) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
    }

    public Integer getX() {
        return x;
    }

    public void setX(Integer x) {
        this.x = x;
    }

    public Integer getY() {
        return y;
    }

    public void setY(Integer y) {
        this.y = y;
    }

    public Integer getW() {
        return w;
    }

    public void setW(Integer w) {
        this.w = w;
    }

    public Integer getH() {
        return h;
    }

    public void setH(Integer h) {
        this.h = h;
    }

    public boolean isUsed() {
        return isUsed;
    }

    public void setUsed(boolean used) {
        isUsed = used;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    public Node getDown() {
        return down;
    }

    public void setDown(Node down) {
        this.down = down;
    }

    public Rectangle getRec() {
        return rec;
    }

    public void setRec(Rectangle rec) {
        this.rec = rec;
    }
}

核心类 Core.java

public class Core {

    private Node root;
    private Integer templateWidth;
    private Integer templateHeight;
    public List<Rectangle> datas;

    public Core(List<Rectangle> datas,Integer templateWidth, Integer templateHeight) {
        this.templateWidth = templateWidth;
        this.templateHeight = templateHeight;
        this.datas = datas;
    }

    public Node paking(){
        this.root = new Node(0,0,templateWidth,templateHeight);
        for (Rectangle item : datas){
            if(!item.isUsed){//没有装入
                Node currentNode = this.findNode(root,item);
                if (currentNode != null){//装下去了
                    this.splitPlate(currentNode,item);//划分
                    item.isUsed = true;
                }
                else {
                    return  this.root;
                }
            }
        }
        return this.root;
    }

    private Node findNode(Node root,Rectangle rectangle){
        if (root.isUsed){//已经划分成两块(右  下)
            Node node = findNode(root.right,rectangle);
            if (node == null){//左边装不下
                node = findNode(root.down,rectangle);//从右边装
            }
            return node;
        } else if (rectangle.w <= root.w && rectangle.h <= root.h){//区间能装下小矩形
            root.setRec(rectangle);
            return root;
        }else {//装不下了
            return null;
        }
    }

    private Node splitPlate(Node node,Rectangle rectangle){//划分容器
        node.isUsed = true;//s说明容器已经划分了
        node.down = new Node(node.x,rectangle.h,node.w,node.h-rectangle.h);//x,y,w,h
        node.right = new Node(node.y,rectangle.w,node.w-rectangle.w,rectangle.h);
        return node;
    }
}

欢迎评论留言交流
留个群,嘻嘻嘻
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
二维装箱算法,也称为二维空间中的物品堆叠或二维容器载问题,是一个经典的优化问题,通常用于解决如何在给定的二维容器(如托盘、箱子或网格)中高效地放置多个不同尺寸的物品,使得空间利用最大化。在Python中,你可以使用一些数据结构和算法来实现这个功能,例如列表、元组、集合或者自定义的二维数据结构。 以下是一个简单的二维装箱算法实现思路: 1. 使用列表或数组表示二维容器,每个元素代表一个可分配的空间。 2. 对于每个待载的物品,存储其尺寸(宽度和高度)。 3. 使用回溯或深度优先搜索(DFS)等方法,尝试将物品放入容器的不同位置,确保不超出容器边界且不覆盖已放置的物品。 4. 每次尝试放一个新物品时,计算剩余空间,记录下当前布局的最大填充度或总容量。 5. 当所有物品都尝试放置过或者无法找到合适的放置位置时,返回当前最佳解决方案。 为了实现这个算法,你可以创建一个类,比如`BoxPacker`,包含方法来添加物品、检查放置和递归尝试。这里提供一个简化版的伪代码示例: ```python class BoxPacker: def __init__(self, container_size): self.container = list(container_size) self.items = [] def add_item(self, item_size): # 添加物品到物品列表 ... def pack(self): self._pack_helper(0, 0) # 从左上角开始 def _pack_helper(self, x, y): # 递归函数,尝试在(x, y)位置放置物品 ... if no_more_space: # 如果没有空间了,回溯并尝试下一个位置 return # 使用示例 packer = BoxPacker((10, 10)) # 假设容器是10x10 for item in items: packer.add_item(item.size) packer.pack() ``` 要了解更多细节,你可能需要查阅一些资料或者参考已有的开源库,如`packing-layers`或者`bin-packing-lab`这样的库。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值