[英]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!如果有人能看到一些明显的错误,我会很乐意提供一些意见!
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.