[英]PHP Mysql Logic to loop through table and optimize output
不是100%肯定標題,隨意編輯,以更通用和有用的所有用戶
我有一個訂單捕獲'門戶',允許捕獲訂單。 訂單的一部分是數量或訂單。
我現在需要處理訂單,以便可以構建托盤,以便最佳地使用托盤。
例如,包裝托盤尺寸可以是1.62立方米(1x1.2x1.35)
然后,我在訂單上有以下項目
產品代碼,數量,總量
1,10,5.5立方米
2,3或0.2立方米
3,5,1.2立方米
4,1,0.15立方米
5,15,0.6立方米
我想處理這個,我假設使用mysql事務,以便實現以下輸出:
托盤1:產品1,2,5。 總容積= 1.3立方米
托盤2:產品3,4。 總容積= 1.35立方米
因此,為了澄清,腳本將采用0.5個立方體的第一個托盤,然后查找列表中最接近0.85的下一個訂單,以實現1.35立方米目標。 在這種情況下,它將是0.6。 現在總共1.1個立方體。 剩余空間現在是0.25立方體。 列表中最近的項目現在是產品2 @ 0.2 cube。 現在總共有1.3個立方體,沒有產品是0.05立方體或更少,所以托盤是完整的。 下一個可用產品現在是產品3 @ 1.2立方體。 所以需要0.15或更少的產品。 產品4是確切的體積,因此添加到托盤並關閉。
我希望這有助於澄清我的要求。
是否有一個mysql事務可以協助這個或這需要用PHP處理。
任何有關這方面的幫助將不勝感激,只是不知道如何構建這個邏輯。
感謝您一如既往的時光,
mysql表如下:
這是經典的裝箱問題 ,它是NP難的(也就是說,我們還沒有弄清楚問題是否可以在多項式時間內解決)。 找到最佳包裝等於嘗試每種可能的組合。
如果你不關心找到最優解,那么你在問題中描述的貪心啟發式(稱為首先適合遞減 )是一個合理的近似值; 還有其他啟發式方法可以保證整體的最佳結果,但它們變得相當復雜。
您可以按如下方式在PHP中實現FFD(使用PDO進行數據庫訪問):
define('PALLET_SIZE', 1 * 1.2 * 1.35);
$dbh = new PDO("mysql:dbname=$dbname", $username, $password);
$qry = $dbh->prepare('
SELECT code, qty, volume
FROM orders
WHERE order_id = :order
ORDER BY volume DESC
');
$qry->execute(array(':order' => 123));
$pallets = array();
while ($order = $qry->fetch()) {
if ($order['volume'] > PALLET_SIZE) die('item too big');
for ($i = 1; $i <= $order['qty']; $i++) { // remove this loop if not needed
$placed = false;
foreach ($pallets as &$pallet) {
if ($pallet['remaining'] >= $order['volume']) {
$pallet['remaining'] -= $order['volume'];
$pallet['items'][] = $order['code'];
$placed = true;
break;
}
}
if (!$placed) $pallets[] = array(
'remaining' => PALLET_SIZE - $order['volume'],
'items' => array($order['code'])
);
}
}
print_r($pallets);
有沒有mysql事務
我假設你的意思是一個mysql函數。
不,mysql中沒有任何東西可以幫助您解決這個問題。 這是一個NP難題。 解決問題的最有效方法可能是遺傳算法 ,但是數據中沒有足夠的信息來准確實現這一點 - 包裝取決於體積(即所有尺寸)和體積。
如果你確實有尺寸,那么允許人類設置包裝而不是嘗試在代碼中進行操作仍然要容易得多。
作為一個快速的解決方案,我將比較一組N個列表的副本,隨機排序,遍歷每個副本創建完整的托盤然后選擇最少托盤的列表(或其他所需的特征)。 為N選擇正確的值取決於大小的分布,以及您希望花費多少時間處理數據。
這類似於背包問題; 這是一個只能通過嘗試所有可能的組合才能完美解決的問題。 隨着可能組合的數量增加,這迅速成為問題。 在你的例子中,會有33個! 組合 - 相當大的數量。 所以這條路線可能不是我們想要的路線......
有沒有“開箱即用”的解決方案,雖然沒有為背包問題的示例代碼在這里 。 這可能有所幫助。
幾年前我寫了一個程序,在類似的問題上做了一個合理的工作; 偽代碼是這樣的:
for each order
while (unallocated items on order)
create new pallet
while not (pallet = full)
allocate largest remaining item smaller than remaining capacity to pallet
loop
loop
next order
這個算法做得不錯 - 船廠里的人喜歡它,因為最大的物品總是在包裝清單的頂部(因此最終位於堆棧的底部)。 該企業接受該算法不能保證是最優的; 在實踐中,這只會對巨大的訂單產生影響,因為算法的輕微改進可能會為我們節省一個托盤; 在大多數情況下,使算法更有效意味着貨物中的最后一個托盤幾乎是空的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.