關於近似裝箱問題的思考。

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