有这样一个需求, 须要对一组元素进行打包(装箱),箱子的容积必定,可是至少能够装入一件物品,即便物品的体积大于箱子,求用最少的箱子装载。php
该问题相似装箱。在对物体发货时候,能够达到最少的包裹数,挺有实际意义,借此研究一下装箱问题。下面代码是对与该问题的实现。因为是记录做用,文笔较为粗糙,后续修正加以详细说明。算法
该实现借鉴了装箱算法,关于装箱算法能够参考网络文章。以下:网络
http://blog.csdn.net/zhangnaigan/article/details/38352745测试
http://blog.csdn.net/x_i_y_u_e/article/details/46765093spa
具体实现代码以下:.net
$items = array( 0.1,0.3,0.8,0.4,0.5,0.2,1 ); //sort($items,SORT_DESC); defined('BOXSIZE') || define('BOXSIZE',1); function bestEncasement($items){ sort($items); $cnt = count($items,SORT_DESC);//更加有利于装箱 $box = array(); $dealArr = array(); for($j = 0;$j<$cnt;$j++){ $lastSize = intval(BOXSIZE); for($i = $cnt -1;$i>0;$i--){ if(in_array($i,$dealArr)){ continue;//若是该元素已经处理过则跳过 } //探测盒子是否为空 若是为空将元素加入 if(empty($box[$j])){ $box[$j][] = $items[$i]; $dealArr[] = $i; $lastSize -= $items[$i]; if($items[$i]>=BOXSIZE){ break;//空间已经存满直接跳出处理下一个盒子 } }else{ $tmpSize =$lastSize - $items[$i];//探测盒子是否够存放该元素 if($tmpSize == 0){ $box[$j][] = $items[$i]; $dealArr[] = $i; break;//存入空间剩余0 则跳出循环 处理下一个盒子 } if($tmpSize>0){//足够存入盒子 探测下一个元素 $box[$j][] = $items[$i]; $lastSize -= $items[$i]; $dealArr[] = $i; continue; }else{ //不足 处理下一个盒子 break; } } } } return $box; } print_r(bestEncasement($items));
上一个版本存在一些运算错误,读者能够自行发现,更正以下:code
<?php $items = array( 0.1,0.3,0.8,0.4,0.5,0.2,1,11,12 ); shuffle($items);//用于乱序测试 //sort($items,SORT_DESC); defined('BOXSIZE') || define('BOXSIZE',1); function bestEncasement($items){ sort($items,SORT_DESC);//排序更有利于装箱 $cnt = count($items); $box = array(); $dealArr = array(); for($j = 0;$j<$cnt;$j++){ $lastSize = intval(BOXSIZE); for($i = 0;$i<$cnt;$i++){ if(in_array($i,$dealArr)){ continue;//若是该元素已经处理过则跳过 } //探测盒子是否为空 若是为空将元素加入 if(empty($box[$j])){ $box[$j][] = $items[$i]; $dealArr[] = $i; $lastSize = bcsub($lastSize,$items[$i],2); if($items[$i]>=BOXSIZE){ break;//空间已经存满直接跳出处理下一个盒子 } }else{ $tmpSize =bcsub($lastSize,$items[$i],2);//探测盒子是否够存放该元素 if($tmpSize == 0){ $box[$j][] = $items[$i]; $dealArr[] = $i; break;//存入空间剩余0 则跳出循环 处理下一个盒子 } if($tmpSize>0){//足够存入盒子 探测下一个元素 $box[$j][] = $items[$i]; $lastSize = bcsub($lastSize,$items[$i],2); $dealArr[] = $i; continue; }else{ //不足 处理下一个盒子 break; } } } } return $box; } print_r(bestEncasement($items));