简体   繁体   English

python中的复杂bin包装2d

[英]Complex bin packing 2d in python

im having some trouble with 2d bin packing and cant seem to get the code to work.我在使用 2d bin 打包时遇到了一些问题,并且似乎无法让代码正常工作。 In this case im using the input:在这种情况下,我使用输入:

200x200x10 200x200x10

100x100x2 100x100x2

50x50x1 50x50x1

When starting the last piece in the sorted list of blocks (50x50) the packer identifies the correct node with a width of 100 and a height of 300, but it has the incorrect starting root at 700 instead of 600. I assume that it has something to do with the previous block being added at that root.当开始排序的块列表(50x50)中的最后一块时,打包器识别出宽度为 100,高度为 300 的正确节点,但它的起始根不正确,为 700 而不是 600。我假设它有一些东西与在该根中添加的前一个块有关。

Data of the last node being found:找到的最后一个节点的数据:

Width Root: 100宽度根:100

Height Root: 300高度根:300

X Root: 700 X 根:700

Y Root: 300 Y根:300

The image shows the outline of the node size in red and the X root value of the last node added.图像以红色显示节点大小的轮廓和添加的最后一个节点的 X 根值。

Would love some input if anyone can see some clear misstakes!如果有人能看到一些明显的错误,我会很乐意提供一些意见!

Image Output图像输出

The code is based on https://codeincomplete.com/articles/bin-packing/代码基于https://codeincomplete.com/articles/bin-packing/

class Block():
    def __init__(self, w : int, h : int) -> None:
        self.w = w
        self.h = h
        self.fit = None

class Node():
    def __init__(self, x : int, y : int, w : int, h : int) -> None:
        self.used = False
        self.x = x
        self.y = y
        self.h = h
        self.w = w
        self.down = None
        self.right = None

class Packer():
    def __init__(self) -> None:
        self.root = None
        self.blocks = None

    def fit(self, blocks : list[Block]) -> None:
        self.blocks = blocks
        self.root = Node(0, 0, self.blocks[0].w, self.blocks[0].h)
        for b in self.blocks:
            
            node = self.find_node(self.root, b.w, b.h)
            if node:
                
                b.fit = self.split_node(node, b.w, b.h)
            else:
                b.fit = self.grow_node(b.w, b.h)

    def find_node(self, root : Node, w : int, h : int) -> Node:
        if root.used:
            return self.find_node(root.right, w, h) or self.find_node(root.down, w, h)
        elif w <= root.w and h <= root.h:
            return root
        else:
            return None
    
    def split_node(self, node : Node, w : int, h : int) -> Node:
        node.used = True
        node.down = Node(node.x, node.y + h, node.w, node.h - h)
        node.right = Node(node.x + w, node.y, node.w - w, h)
        return node

    def grow_node(self, w : int, h : int) -> Node:
        can_grow_down = w <= self.root.w
        can_grow_right = w <= self.root.h

        should_grow_right = can_grow_right and self.root.h >= self.root.w + w
        should_grow_down = can_grow_down and self.root.w >= self.root.h + h

        if should_grow_right:
            return self.grow_right(w, h)
        elif should_grow_down:
            return self.grow_down(w, h)
        elif can_grow_right:
            return self.grow_right(w, h)
        elif can_grow_down:
            return self.grow_down(w, h)
        else:
            return None

    def grow_right(self, w : int, h : int) -> Node:
        new_node = Node(0, 0, self.root.w + w, self.root.h)
        new_node.used = True
        new_node.down = self.root
        new_node.right = Node(self.root.w, 0, w, self.root.h)
        self.root = new_node

        node = self.find_node(self.root, w, h)

        if node:
            return self.split_node(node, w, h)
        else:
            return None
    
    def grow_down(self, w : int, h : int) -> Node:
        new_node = Node(0, 0, self.root.w, self.root.h + h)
        new_node.used = True
        new_node.down = Node(0, self.root.h, self.root.w, h)
        new_node.right = self.root
        self.root = new_node

        node = self.find_node(self.root, w, h)

        if node:
            return self.split_node(node, w, h)
        else:
            return None

Solved by fixing a typo.通过修复错字解决。 Should work fine now for complex 2d bin packing!现在对于复杂的 2d bin 包装应该可以正常工作了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM