java 盒子体积_于Java简要的箱子放盒子的问题

最近工作中需要处理一个实际问题就是大箱子装小盒子的问题,写这篇文章需要解决的实际问题 就是大容器装小东西的问题。例如仓库中货位装载SKU 车厢里面装载快递包裹。

以下代码实现比较粗糙,实际过程中就是为了计算一个箱子中能装多少东西

前提条件

1、自己校验完 最长比较,即 小东西的 L(length) 、W(width)、 H(height) 最大值不能超过 大容器的LWH, 本文只讨论 立体箱子问题 杠精 读到这里就可以去逛其他帖子了,避免浪费你宝贵的时间。

大箱子 小盒子 基本属性类

CountBox

@Data

@AllArgsConstructor

public class CountBox {

private Integer length;

private Integer width;

private Integer height;

public Double getVol()

{

return (double) this.length*this.width*this.height;

}

}

对于计算 结合前人的计算方法 计算了一个朴素的算法 得到的结果不一定对 后面读者有更好的方式 ,请留言 让鄙人改进 以更好的适应

具体的方法类(可能个人习惯了Java 或者Spring 的注入特性的习惯,公共的方法就抽象出来做某一类业务或者某一种方法)

@Slf4j

public class CountUtils {

/**

* 朴素计算(不计算之前已经装了的体积) 大箱子能装多少个小箱子

* @param maxBox

* @param minBox

* @return

* 原理是:

* nx < X

* ny < Y

* nz < Z

* 交换 XYZ 比较顺序来计算各种方法最多能放多少个 取整乘积最大值就是可放置的最多个数(朴素算法)

*/

public Integer toCount(CountBox maxBox,CountBox minBox)

{

int a = (

(maxBox.getLength() / minBox.getLength()) *

(maxBox.getWidth() / minBox.getWidth()) *

(maxBox.getHeight() / minBox.getHeight())

);

int b = (

(maxBox.getLength() / minBox.getLength()) *

(maxBox.getWidth() / minBox.getHeight()) *

(maxBox.getHeight() / minBox.getWidth())

);

int c = (

(maxBox.getLength() / minBox.getWidth()) *

(maxBox.getWidth() / minBox.getLength()) *

(maxBox.getHeight() / minBox.getHeight())

);

int d = (

(maxBox.getLength() / minBox.getWidth()) *

(maxBox.getWidth() / minBox.getHeight()) *

(maxBox.getHeight() / minBox.getLength())

);

int e = (

(maxBox.getLength() / minBox.getHeight()) *

(maxBox.getWidth() / minBox.getLength()) *

(maxBox.getHeight() / minBox.getWidth())

);

int f = (

(maxBox.getLength() / minBox.getHeight()) *

(maxBox.getWidth() / minBox.getWidth()) *

(maxBox.getHeight() / minBox.getLength())

);

ListcapacitiesList = new ArrayList<>();

Stream.of(a, b, c, d, e, f).forEach(x -> capacitiesList.add(x));

return PrimeSortUtils.getMaxNumberFromArray(capacitiesList);

}

/**

* 比较适用的现实的常规方法 计算前容器已完成了多少体积

* @param maxBox 大箱子

* @param minBox 小盒子

* @param occupyCapacity 已占用体积

* @return 所能承载的小盒子

*/

private Integer toCountComplex(CountBox maxBox,CountBox minBox,Double occupyCapacity)

{

Integer a=0,b=0,c=0;

//剔除所占空间的部分将该部分之外的体积分成若干个小的部分的box 进行朴素计算

Double totalCapacity = maxBox.getVol();

Double surplusCapacity = totalCapacity-occupyCapacity;

Double minNeedVolume = minBox.getVol();

int minValue = Math.min(minBox.getLength(),Math.min(minBox.getWidth(),minBox.getHeight()));

if(surplusCapacity>minNeedVolume)

{

double maxLength = (surplusCapacity/(maxBox.getWidth()*maxBox.getHeight()));

if(maxLength>minValue){

Integer lengthNew = (int)maxLength;

CountBox maxBoxNew = new CountBox(lengthNew,maxBox.getWidth(),maxBox.getHeight());

a = toCount(maxBoxNew,minBox);

}

double maxWidth = (surplusCapacity/(maxBox.getLength()*maxBox.getHeight()));

if(maxWidth>minValue){

Integer widthNew = (int)maxWidth;

CountBox maxBoxNew = new CountBox(maxBox.getLength(),widthNew,maxBox.getHeight());

b = toCount(maxBoxNew,minBox);

}

double maxHeight = (surplusCapacity/(maxBox.getLength()*maxBox.getWidth()));

if(maxHeight>minValue){

Integer heightNew = (int)maxHeight;

CountBox maxBoxNew = new CountBox(maxBox.getLength(),maxBox.getWidth(),heightNew);

c = toCount(maxBoxNew,minBox);

}

}

return Math.max(a,Math.max(b,c));

}

/**

* 无视空间放置的计算方法( 限用) 只能针对同一个槽所有规格都一样 并且条件比较苛刻 至于后面怎么改造,后面抽时间再研究

* @param maxBox 大箱子

* @param minBox 小盒子

* @param occupyCapacity 已占用的体积

* @return 小盒子个数

*/

public Integer toCountAll(CountBox maxBox,CountBox minBox,Double occupyCapacity)

{

Integer qty = 0;

Integer count = 0;

Double minBoxVolume = minBox.getVol();

while(true)

{

int tmp = toCountComplex(maxBox,minBox,(double)(occupyCapacity+qty*minBoxVolume));

if(tmp>0)

{

qty +=tmp;

count ++;

}

else

{

break;

}

}

log.info("First Recycle times is:{}",count);

int minValue = Math.min(minBox.getLength(),Math.min(minBox.getWidth(),minBox.getHeight()));

if(count>1) {

Integer a = maxBox.getLength() - (count - 1) * minValue;

Integer b = maxBox.getWidth() - (count - 1) * minValue;

Integer c = maxBox.getHeight() - (count - 1) * minValue;

int minSurplusVal = Math.min(a, Math.min(b, c));

Integer maxValue = Math.max(minBox.getLength(), Math.max(minBox.getWidth(), minBox.getHeight()));

if (maxValue <= minSurplusVal)//最长边 还小于最少递减值 即 理论上结合总体积比较还可以放得下

{

CountBox maxBoxNew = new CountBox(a, b, c);

Double theoreticalVol = maxBoxNew.getVol();

Double surplusVol = maxBox.getVol() - occupyCapacity - qty * minBoxVolume;

if (theoreticalVol > surplusVol) {

maxBoxNew.setLength(Math.max(minBox.getLength(), Math.max(minBox.getWidth(), minBox.getHeight())));

Double theoreticalVolNew = maxBoxNew.getVol();

if (theoreticalVolNew > surplusVol) {

maxBoxNew.setWidth(Math.max(minBox.getLength(), Math.min(minBox.getWidth(), minBox.getHeight())));

maxBoxNew.setHeight(Math.max(minBox.getLength(), Math.min(minBox.getWidth(), minBox.getHeight())));

Double theoreticalVolNew2 = maxBoxNew.getVol();

if (theoreticalVolNew2 > surplusVol) {

Double theoreticalVolNew3 = maxBoxNew.getVol();

if (theoreticalVolNew3 > surplusVol) {

maxBoxNew.setHeight(Math.min(minBox.getLength(), Math.min(minBox.getWidth(), minBox.getHeight())));

}

}

}

}

Integer qty2 = toCountComplex(maxBoxNew, minBox, 0D);

qty += qty2;

}

}

return qty;

}

public static void main(String[] args) {

CountUtils countUtils = new CountUtils();

CountBox maxBox = new CountBox(5,5,5);

CountBox minBox = new CountBox(1,2,3);

Integer firstQty = countUtils.toCountComplex(maxBox,minBox,0D);

System.out.println(firstQty);

Integer secondQty = countUtils.toCount(maxBox,minBox);

System.out.println(secondQty);

Integer thridQty = countUtils.toCountAll(maxBox,minBox2,0D);

System.out.println(thridQty);

}

}

自己测试过很多组数据 其中 对于解决实际问题的话 countComplex 话已经是比较好解决实际问题的,原因就是:理论计算方法对于实际生产的出入比较大,简单点说空间全部占满 当手都伸不进去了 小盒子怎么拿出来,当有容器包裹物体,空间装满 物体是无法拿出来的额。

1、toCount方法比较简易 也是默认算法 立体空间放置旋转九十度的原理

2、基于此类问题大都是NPL 问题,比较浪费时间,得出简易结果其实就能解决实际问题了

3、楼主不是专注于算法研究,所以该方法还有得改进,希望遇见贵人,能优化下计算过程。

有兴趣的技术大佬 帮忙想下 123 的盒子 和116 的盒子 在满足能够放下两种规格盒子的箱子里(就比如 654),能够放的数量是一样的吗??简化问题 已占空间 都设置成0 分析吧 。

实际生活中这种大箱子可能装的不是同一种规格的货,所以体积肯定不一样,只能每次减去已占用的体积重新分析计算

有建设性建议还可以留言,谢谢!

某些问题计算逻辑文库(外国仁的维基百科(We need to turn over the wall)):

https://en.wikipedia.org/wiki/Packing_problems

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值