有這樣一個需求, 須要對一組元素進行打包(裝箱),箱子的容積必定,可是至少能夠裝入一件物品,即便物品的體積大於箱子,求用最少的箱子裝載。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));