# pack3d
_Pack All~_
## 1. 属性
- 名称:pack3d
- 目标:提供一个高效的程序帮助用户优化三维装箱的效果
- 模块:采用模块化设计,输入输出、算法、约束,均可替换
## 2. 特点
- 简洁:Stay simple, stay young. 在保证好用和健壮的前提下,尽量简洁,便于维护和阅读
- 好用:经过我的精心设计,用起来非常方便
- 健壮:怎么折腾都不会崩
- 轻量:使用及拓展非常轻便和简单
- 高效:速度非常快,BR 测试数据统统一秒内解决
## 3. 用法
1. 按照下述输入格式准备 JSON 输入文件
2. 运行程序,通过参数指定输入文件路径
3. 程序将在 `result` 目录下生成 JSON 输出文件,并自动画图展示
## 4. 输入输出
### 坐标系定义
首先约定,程序统一采用右手坐标系,定义如下:
- X 轴:长度,向右为正方向。
- Y 轴:宽度,向后为正方向。
- Z 轴:高度,向上为正方向。
### 输入格式
输入文件为 JSON 格式,包含以下字段:
#### ContainerType (容器类型)
| `id` | string | 容器类型的唯一标识符 |
| `lx` | integer | 容器类型的长度 |
| `ly` | integer | 容器类型的宽度 |
| `lz` | integer | 容器类型的高度 |
| `payload` | number | 容器类型的最大载重(可选) |
| `quantity` | integer | 容器类型的可用数量(可选,默认无限制) |
#### BoxType(箱型)
| `id` | string | 箱型的唯一标识符 |
| `lx` | integer | 箱型的长度 |
| `ly` | integer | 箱型的宽度 |
| `lz` | integer | 箱型的高度 |
| `orients` | array | 箱型允许的放置方向(可选) |
##### Orients (允许的放置方向)
箱型的放置方向使用字符串表示,共有六种可能的放置方向:
- `"XYZ"`:长度 (lx) 沿 X 轴,宽度 (ly) 沿 Y 轴,高度 (lz) 沿 Z 轴(高度垂直)
- `"YXZ"`:宽度 (ly) 沿 X 轴,长度 (lx) 沿 Y 轴,高度 (lz) 沿 Z 轴(高度垂直)
- `"XZY"`:长度 (lx) 沿 X 轴,高度 (lz) 沿 Y 轴,宽度 (ly) 沿 Z 轴(宽度垂直)
- `"ZXY"`:高度 (lz) 沿 X 轴,长度 (lx) 沿 Y 轴,宽度 (ly) 沿 Z 轴(宽度垂直)
- `"YZX"`:宽度 (ly) 沿 X 轴,高度 (lz) 沿 Y 轴,长度 (lx) 沿 Z 轴(长度垂直)
- `"ZYX"`:高度 (lz) 沿 X 轴,宽度 (ly) 沿 Y 轴,长度 (lx) 沿 Z 轴(长度垂直)
比如 `"orients": ["XYZ", "YXZ"]` 表示该箱型的箱子只能平着放置,不能竖着放置。
如果未指定 `orients` 字段,默认是`["XYZ", "YXZ"]`,也就是只允许平着放置。
#### Box (箱子)
| `id` | string | 箱子的唯一标识符 |
| `type` | string | 箱子的类型 |
| `weight` | number | 箱子的重量(可选) |
#### Input (输入数据)
| `container_types` | array | 可用的容器类型列表 |
| `box_types` | array | 可用的箱型列表 |
| `boxes` | array | 待装载的箱子列表 |
示例输入请参考 [demo.json](data/demo.json)
### 输出格式
输出文件为 JSON 格式,包含以下字段:
#### Container (容器)
| `type` | object | 容器的类型 |
| `boxes` | array | 已装载的箱子列表 |
| `volume_rate` | number | 容器的体积利用率 |
| `weight_rate` | number | 容器的载重利用率 |
##### Box (箱子)
| `id` | string | 箱子的唯一标识符 |
| `type` | string | 箱型的唯一标识符 |
| `x` | integer | 装载的 X 轴坐标 |
| `y` | integer | 装载的 Y 轴坐标 |
| `z` | integer | 装载的 Z 轴坐标 |
| `orient` | string | 装载时的放置方向 |
#### Output (输出数据)
| `box_types` | array | 箱型列表 |
| `containers` | array | 容器列表 |
| `unpacked_boxes` | array | 未装载的箱子列表 |
完整的输出格式树状图如下:
```
output
├── box_types
│ ├── box_type#1
│ ├── box_type#2
│ └── ...
├── containers
│ ├── container#1
│ │ ├── type
│ │ └── boxes
│ │ │ ├── box#1
│ │ │ ├── box#2
│ │ │ └── ...
│ │ ├── volume_rate
│ │ └── weight_rate
│ ├── container#2
│ │ ├── type
│ │ └── boxes
│ │ │ ├── box#3
│ │ │ ├── box#4
│ │ │ └── ...
│ │ ├── volume_rate
│ │ └── weight_rate
│ └── ...
└── unpacked_boxes
├── box#5
├── box#6
└── ...
```
## 5. 开发
- 语言:Rust,要求 Rust 1.90+
- 构建:使用 [Cargo](https://doc.rust-lang.org/cargo/) 进行构建
- 画图:使用 [Python](https://www.python.org) 进行画图
- 文档:运行 `cargo doc` 生成文档
- 风格:运行 `cargo fmt` 格式化代码,遵循 Rust 官方代码风格
- 数据:使用 [OR-Library](https://people.brunel.ac.uk/~mastjjb/jeb/orlib/thpackinfo.html) 的测试数据以评估装箱效果