BIN Packing 3D Item Most Efficiently Given Pack Quantity
Posting this solution because I found all other options out there except this one. In this particular case, I have 1 item that can be packed a # of times and the goal is to pack it in the most efficient manner not to exceed UPS/FedEX LxWxH limitations, not providing box dimensions to fit the item in
BIN Packing Item given LxWxH Number of Times
I was able to find a bunch of solutions out there, but for example to get a UPS/FedEx shipping quote, my items can be packed provided a specified pack quantity. Packing same items in NON defined boxes is not something I found out there. So this method will: provided LxWxH
and Quantity
, return the best way to pack it with smallest area and least amount of empty space.
Using the Code
The code is fairly simple. This is a brute force approach to finding the first most adequate package size to provide to UPS/FedEx to get a quote. For example: suppose you have an item 22" x 8" x 8" and you want to pack 10 of them together to have a single package. Adequate packed dimensions are: 22x40x16, 44x40x8... Below recursive method will return the result in a decimal[3]
array where [0] = Length
, [1] = Width
and [2] = Height
of the newly packed box. Please note that in my code, any given dimension was set not to exceed 108
".
protected decimal[] PackItemsInBin(decimal[] PackingDimensions, decimal Length,
decimal Width, decimal Height, decimal Quantity )
{
decimal[] dimensions_l;
decimal[] dimensions_w;
decimal[] dimensions_h;
decimal LengthPackingQuantity, WidthPackingQuantity,
HeightPackingQuantity, LengthArea, WidthArea, HeightArea = 0;
try
{
if (Math.Floor(PackingDimensions[0] / Length) * Math.Floor(PackingDimensions[1] / Width) *
Math.Floor(PackingDimensions[2] / Height) >= Quantity)
{
return PackingDimensions;
}
else
{
//HAVE NOT FOUND THE SOLUTION
//so lets go in all directions until we get a solution.
dimensions_l = new decimal[3] { PackingDimensions[0],
PackingDimensions[1], PackingDimensions[2] };
dimensions_w = new decimal[3] { PackingDimensions[0],
PackingDimensions[1], PackingDimensions[2] };
dimensions_h = new decimal[3] { PackingDimensions[0],
PackingDimensions[1], PackingDimensions[2] };
dimensions_l[0] += Length;//go with length
dimensions_w[1] += Width;//go with width
dimensions_h[2] += Height;//go with height
//get the results from each direciton
dimensions_l = PackItemsInBin(dimensions_l, Length, Width, Height, Quantity);
dimensions_w = PackItemsInBin(dimensions_w, Length, Width, Height, Quantity);
dimensions_h = PackItemsInBin(dimensions_h, Length, Width, Height, Quantity);
//calculate some of the measurements to use to determine the best packed choice
LengthPackingQuantity = Math.Floor(dimensions_l[0] / Length) *
Math.Floor(dimensions_l[1] / Width) * Math.Floor(dimensions_l[2] / Height);
WidthPackingQuantity = Math.Floor(dimensions_w[0] / Length) *
Math.Floor(dimensions_w[1] / Width) * Math.Floor(dimensions_w[2] / Height);
HeightPackingQuantity = Math.Floor(dimensions_h[0] / Length) *
Math.Floor(dimensions_h[1] / Width) * Math.Floor(dimensions_h[2] / Height);
LengthArea = dimensions_l[0] + dimensions_l[1] + dimensions_l[2];
WidthArea = dimensions_w[0] + dimensions_w[1] + dimensions_w[2];
HeightArea = dimensions_h[0] + dimensions_h[1] + dimensions_h[2];
//GB. determine if the best solution is here based on several decisions,
//for example if there is empty space or not and what the area is
//GB. best decision is made on the packed box that takes the least amount of space
//and has the least amount of empty space considering the area
if (LengthPackingQuantity + LengthArea <= WidthArea + WidthPackingQuantity &&
LengthPackingQuantity + LengthArea <= HeightArea +
HeightPackingQuantity && dimensions_l[0] < 108)
{
return dimensions_l;
}
else if (WidthArea + WidthPackingQuantity <= LengthPackingQuantity +
LengthArea && WidthArea + WidthPackingQuantity <= HeightArea +
HeightPackingQuantity && dimensions_l[0] < 108)
{
return dimensions_w;
}
else
return dimensions_h;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
}