基于Shapely的直角不规则多边形矩形细分快速算法咨询
正交直角多边形容器快速矩形放置方案(空间细分路线)
针对全直角边的不规则(正交)多边形装箱场景,不用走通用bin packing的高耗时启发式/回溯逻辑,基于正交空间细分的方案可以做到毫秒级出结果,以下是优先适配Shapely库的实现思路:
核心选型逻辑
放弃全局搜索式的装箱逻辑,全程维护轴对齐正交矩形的空闲空间列表,避免处理任意多边形的复杂相交、位置搜索计算,核心计算全部走Shapely的C层加速接口,速度比通用bin packing高1~2个数量级。
具体实现步骤
- 容器预处理
首先对输入的多边形做合法性校验:调用shapely.is_valid()排查自交问题,必要时用shapely.buffer(0)修正拓扑错误;初始空闲列表仅存入容器的最小外接轴对齐矩形。核心提速点:全程仅维护矩形形态的空闲空间,不存储任意多边形形态的空闲区,几何判断的复杂度直接从O(n²)降到O(n)。
- 待放物品预处理
所有待放小矩形按面积从大到小降序排列,优先放置大尺寸物品避免后期塞不下;每个物品预存两种尺寸:原始宽高、旋转90度后的宽高,放置时直接匹配即可。 - 空间细分放置循环
按排序依次取未放置的物品,遍历当前空闲列表,先做纯数值尺寸匹配(空位宽高大于等于物品/旋转后物品的宽高),找到第一个满足尺寸要求的空位后:- 将物品贴空位左下角放置,生成对应矩形对象,调用
container.contains(placed_rect)做边界校验,确认物品完全在容器内部 - 校验通过后将该空位从空闲列表移除,对剩余空间做正交拆分:固定物品贴左下角的位置后,剩余空间可拆为「物品右侧竖矩形+物品上方横矩形」,拆分时优先选拆分后大矩形面积更大的拆分方式,减少空间碎片
- 对新生成的空闲矩形做过滤:如果矩形尺寸小于所有未放置物品的最小宽高,直接丢弃;剩余矩形做合并判断,若和列表中已有矩形共边且可拼成更大矩形则合并,再加入空闲列表
- 标记物品为已放置,进入下一个物品的放置循环,直到所有物品放置完成
- 将物品贴空位左下角放置,生成对应矩形对象,调用
- 空闲空间标记
所有物品放置完成后,空闲列表中存储的就是可直接复用的矩形空闲区;如果需要和容器边界完全贴合的精确空闲多边形,仅需调用一次container.difference(shapely.unary_union(所有已放置矩形))即可,单次计算不影响整体速度。
关键优化点
- 尽量使用Shapely 2.0以上版本,所有几何计算优先调用内置矢量化接口,避免Python层逐点循环判断
- 空位匹配阶段先做纯数值的宽高比较,过滤掉尺寸不满足的空位后再调用Shapely做边界包含校验,可减少90%以上的无效几何运算
- 每次拆分空闲区后及时清理尺寸过小、不可能放下任何剩余物品的碎片矩形,压缩后续遍历的列表长度
适配说明
该方案完全满足约束:物品间无重叠、全部在容器边界内、支持90度旋转,在已知所有物品可放入容器的前提下,不会出现放置失败的情况。针对给出的这类凹形正交容器,常规几十到上百个物品的放置场景耗时基本在100ms以内,不会出现通用bin packing算法长时间计算的问题。

内容的提问来源于stack exchange,提问作者user1234
相关产品推荐
相关产品推荐

