戰(zhàn):如何用 PHP 快速解決 4D 裝箱優(yōu)化問(wèn)題)
BoxPacker 實(shí)戰(zhàn)如何用 PHP 快速解決 4D 裝箱優(yōu)化問(wèn)題【免費(fèi)下載鏈接】BoxPacker4D bin packing / knapsack problem solver項(xiàng)目地址: https://gitcode.com/gh_mirrors/bo/BoxPackerBoxPacker 是一個(gè) PHP 庫(kù)解決4D 裝箱問(wèn)題給定一批帶長(zhǎng)寬高和重量的物品自動(dòng)算出最少需要幾個(gè)箱子、每件物品放進(jìn)哪個(gè)箱子。它面向需要做裝箱優(yōu)化的電商、物流和倉(cāng)儲(chǔ)開(kāi)發(fā)者。從一個(gè)真實(shí)問(wèn)題說(shuō)起訂單到底要幾個(gè)箱子電商場(chǎng)景里一張訂單該用幾個(gè)箱、每件商品放哪個(gè)箱人工判斷既慢又容易出錯(cuò)。全用大號(hào)箱浪費(fèi)成本不同箱型混搭又讓運(yùn)費(fèi)報(bào)價(jià)不穩(wěn)定。拆成多個(gè)包裹時(shí)還會(huì)出現(xiàn)第一個(gè)箱塞滿(mǎn)、最后一個(gè)箱幾乎空著的情況重量不均衡讓快遞和客戶(hù)都不舒服。這正是 BoxPacker 要做的把物品尺寸、箱型規(guī)格交給它返回一份完整可執(zhí)行的裝箱方案。5 分鐘快速上手安裝并跑通第一個(gè)裝箱示例環(huán)境要求是 PHP 8.2 及以上版本并安裝了 Composer。推薦用 Composer 安裝composer require dvdoug/boxpacker。如果無(wú)法使用 Composer也可以克隆倉(cāng)庫(kù)git clone https://gitcode.com/gh_mirrors/bo/BoxPacker。庫(kù)的核心是兩個(gè)接口Box箱子提供內(nèi)外尺寸和承重和Item物品提供尺寸、重量和旋轉(zhuǎn)規(guī)則。tests/ 目錄下提供了開(kāi)箱即用的TestBox和TestItem下面的示例會(huì)完整跑通一次裝箱?php use DVDoug\BoxPacker\Packer; use DVDoug\BoxPacker\Rotation; use DVDoug\BoxPacker\Test\TestBox; use DVDoug\BoxPacker\Test\TestItem; $packer new Packer(); $packer-addBox(new TestBox(標(biāo)準(zhǔn)箱, 300, 300, 100, 10, 296, 296, 96, 10000)); $packer-addItem(new TestItem(商品A, 250, 250, 12, 200, Rotation::KeepFlat), 1); $packer-addItem(new TestItem(商品B, 250, 250, 12, 200, Rotation::BestFit), 2); $packedBoxes $packer-pack(); echo 共裝入 . count($packedBoxes) . 個(gè)箱子 . PHP_EOL;運(yùn)行后你會(huì)得到所需箱子的數(shù)量遍歷$packedBoxes還能拿到每個(gè)箱子的箱型、含商品的總重量以及每件物品在箱內(nèi)的具體擺放坐標(biāo)。它到底能做什么4 個(gè)核心能力1. 一次調(diào)用確定箱型與擺放位置要解決的問(wèn)題是一批物品放進(jìn)多種不同尺寸的箱子怎么安排最合理。Packer::pack()會(huì)優(yōu)先嘗試小箱子發(fā)現(xiàn)物品能裝進(jìn)單個(gè)箱子時(shí)立即結(jié)束返回結(jié)果里每件物品都帶 x/y/z 坐標(biāo)。生成揀貨清單、打單或核對(duì)體積時(shí)直接用它即可。2. 多箱之間自動(dòng)均衡重量要解決的問(wèn)題是按體積裝完后先裝的箱很滿(mǎn)、后裝的箱很輕。庫(kù)內(nèi)的WeightRedistributor在體積裝箱完成后做第二輪把重箱里的物品挪到有空間且較輕的箱里。只要訂單拆出了多個(gè)箱子這一步會(huì)自動(dòng)執(zhí)行不需要額外代碼。3. 控制旋轉(zhuǎn)方向與堆疊約束要解決的問(wèn)題是部分商品必須平放或此面朝上部分商品不能疊放。物品上可以聲明BestFit任意方向、KeepFlat保持平放或Never禁止旋轉(zhuǎn)需要更細(xì)的規(guī)則時(shí)實(shí)現(xiàn)ConstrainedPlacementItem接口即可比如每箱最多放 2 節(jié)電池或電池不可互相堆疊。適合有易碎品、危險(xiǎn)品合規(guī)要求的業(yè)務(wù)。4. 限定箱子庫(kù)存數(shù)量要解決的問(wèn)題是箱型雖然可選但實(shí)際庫(kù)存有限。用LimitedSupplyBox聲明某箱型可用數(shù)量裝箱過(guò)程就不會(huì)超額使用。倉(cāng)庫(kù)箱型庫(kù)存緊張時(shí)用它。接入真實(shí)業(yè)務(wù)用訂單商品計(jì)算運(yùn)費(fèi)以電商運(yùn)費(fèi)計(jì)算為例。輸入端把示例里的TestBox、TestItem換成你自己的數(shù)據(jù)庫(kù)實(shí)體商品表提供長(zhǎng)寬高和重量箱型表提供外尺寸、自重和最大承重讓這兩個(gè)對(duì)象分別實(shí)現(xiàn)Item、Box接口。輸出端pack()返回的箱子列表里每個(gè)箱子的外尺寸和總重量正是快遞費(fèi)率接口需要的輸入據(jù)此就能算出運(yùn)費(fèi)。集成時(shí)主要改兩處一是給現(xiàn)有對(duì)象實(shí)現(xiàn)接口方法二是在返回結(jié)果上做后續(xù)處理。返回結(jié)果里的物品對(duì)象是你傳入的原始對(duì)象而非副本所以可以直接取商品價(jià)格做保價(jià)或核對(duì)。進(jìn)階技巧超時(shí)控制與邊界設(shè)置設(shè)置超時(shí)物品數(shù)量很大時(shí)計(jì)算時(shí)間會(huì)明顯增長(zhǎng)。用setTimeoutChecker()掛上超時(shí)檢查器超時(shí)后拋出TimeoutException由業(yè)務(wù)決定重試或降級(jí)。適合高并發(fā)的下單、詢(xún)價(jià)接口。調(diào)節(jié)重量均衡閾值默認(rèn)拆出的箱子超過(guò) 12 個(gè)時(shí)跳過(guò)重量均衡以節(jié)省時(shí)間。你的場(chǎng)景如果經(jīng)常出現(xiàn)箱數(shù)多但希望重量均勻可以用setMaxBoxesToBalanceWeight()調(diào)高或調(diào)低這個(gè)閾值。限定裝箱方向裝箱對(duì)象是卡車(chē)或側(cè)裝集裝箱時(shí)可用VolumePacker::packAcrossWidthOnly()強(qiáng)制沿單一方向擺放避免結(jié)果在真實(shí)裝卸時(shí)不可執(zhí)行。處理裝不下的物品默認(rèn)有物品超過(guò)所有箱子時(shí)會(huì)拋異常調(diào)用throwOnUnpackableItem(false)可讓裝箱繼續(xù)完成再用getUnpackedItems()取出沒(méi)裝下的物品單獨(dú)處理。常見(jiàn)問(wèn)題要求什么 PHP 版本v4 版本需要 PHP 8.2 及以上并啟用 ext-json 擴(kuò)展推薦通過(guò) Composer 安裝。某件物品比所有箱子都大怎么辦默認(rèn)拋出NoBoxesAvailableException改用throwOnUnpackableItem(false)后裝箱流程繼續(xù)通過(guò)getUnpackedItems()拿到剩余物品。只想判斷一批物品能否裝進(jìn)某個(gè)指定箱子可以。直接用單只箱子和物品列表構(gòu)造VolumePacker返回結(jié)果中已裝入物品的數(shù)量就是答案。BoxPacker 適合一切需要按尺寸和重量把物品分裝進(jìn)容器的場(chǎng)景包括電商發(fā)貨、倉(cāng)儲(chǔ)規(guī)劃乃至貼圖打包這類(lèi)二維排布問(wèn)題。下一步建議先把快速上手一節(jié)的示例跑一遍再閱讀 docs/ 下的官方文檔了解接口定義和約束機(jī)制的完整說(shuō)明。【免費(fèi)下載鏈接】BoxPacker4D bin packing / knapsack problem solver項(xiàng)目地址: https://gitcode.com/gh_mirrors/bo/BoxPacker創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考