public void TestTop() { var box = Factory.CreateBox("Box", 10, 10, 10, 0, 10, 10, 10, 100); var itemA = Factory.CreateItem("Item A", 5, 10, 10, 10, true); var itemB = Factory.CreateItem("Item B", 5, 10, 10, 20, true); var packedItemA = new PackedItem(itemA, 0, 0, 0, 5, 10, 10); var packedItemB = new PackedItem(itemB, 0, 0, 0, 5, 10, 10); var packedItemListA = new PackedItemList(); packedItemListA.Insert(packedItemA); var packedBoxA = new PackedBox(box, packedItemListA); var packedItemListB = new PackedItemList(); packedItemListB.Insert(packedItemB); var packedBoxB = new PackedBox(box, packedItemListB); var pBoxArray = new PackedBox[] { packedBoxA, packedBoxB }; var packedBoxList = new PackedBoxList(); packedBoxList.Insert(packedBoxA); packedBoxList.Insert(packedBoxB); Assert.Equal(packedBoxA, packedBoxList.Top()); }
public void TestInsertAndCount() { var box = Factory.CreateBox("Box", 10, 10, 10, 0, 10, 10, 10, 100); var itemA = Factory.CreateItem("Item A", 5, 10, 10, 10, true); var itemB = Factory.CreateItem("Item B", 5, 10, 10, 20, true); var packedItemA = new PackedItem(itemA, 0, 0, 0, 5, 10, 10); var packedItemB = new PackedItem(itemB, 0, 0, 0, 5, 10, 10); var packedItemListA = new PackedItemList(); packedItemListA.Insert(packedItemA); var packedBoxA = new PackedBox(box, packedItemListA); var packedItemListB = new PackedItemList(); packedItemListB.Insert(packedItemB); var packedBoxB = new PackedBox(box, packedItemListB); var packedBoxList = new PackedBoxList(); packedBoxList.Insert(packedBoxA); packedBoxList.Insert(packedBoxB); Assert.Equal(2, packedBoxList.Count); }
/// <summary> /// Pack as many items as possible into specific given box. /// </summary> /// <returns></returns> public PackedBox Pack() { while (items.Count > 0) { var layerStartDepth = GetCurrentPackedDepth(); PackLayer(layerStartDepth, BoxWidth, BoxLength, box.InnerDepth - layerStartDepth); } if (BoxRotated) { RotateLayersNinetyDegrees(); } if (!LookAheadMode) { StabiliseLayers(); } var result = new PackedBox() { Box = box, PackedItems = GetPackedItemList() }; return(result); }
public void TestGetters() { var box = Factory.CreateBox("Box", 370, 375, 60, 140, 364, 374, 40, 3000); var oItem = new OrientatedItem( Factory.CreateItem("Item", 230, 330, 6, 320, true), 230, 330, 6 ); var packedItemList = new PackedItemList(); packedItemList.Insert(PackedItem.FromOrientatedItem(oItem, 0, 0, 0)); var pBox = new PackedBox(box, packedItemList); Assert.Equal(box.Reference, pBox.Box.Reference); Assert.Equal(460, pBox.TotalWeight); Assert.Equal(134, pBox.RemainingWidth); Assert.Equal(44, pBox.RemainingLength); Assert.Equal(34, pBox.RemainingDepth); Assert.Equal(2540, pBox.RemainingWeight); Assert.Equal(5445440, pBox.InnerVolume); }
/// <summary> /// Attempt to equalise weight distribution between 2 boxes /// </summary> /// <param name="boxA"></param> /// <param name="boxB"></param> /// <param name="targetWeight"></param> /// <returns>was the weight rebalanced?</returns> private bool EqualiseWeight(ref PackedBox boxA, ref PackedBox boxB, double targetWeight) { var anyIterationSuccessful = false; var overWeightBox = (boxA.TotalWeight > boxB.TotalWeight) ? boxA : boxB; var underWeightBox = (boxA.TotalWeight > boxB.TotalWeight) ? boxB : boxA; var overWeightBoxItems = overWeightBox.PackedItems.AsItemList(); var underWeightBoxItems = underWeightBox.PackedItems.AsItemList(); var key = overWeightBoxItems.Count; while (key - 1 >= 0) { key--; var overWeightItem = overWeightBoxItems[key]; //TODO: check algorithm logic - why there is direct boxB using instead of over/underWeightBox? if (overWeightItem.Weight + boxB.TotalWeight > targetWeight) { // moving this item would harm more than help continue; } var newLighterBoxes = DoVolumeRepack(underWeightBoxItems, overWeightItem); if (newLighterBoxes.Count != 1) { //only want to move this item if it still fits in a single box continue; } underWeightBoxItems.Add(overWeightItem); if (overWeightBoxItems.Count == 1) { //sometimes a repack can be efficient enough to eliminate a box boxB = newLighterBoxes.Top(); boxA = null; return(true); } overWeightBoxItems.RemoveAt(key); var newHeavierBoxes = DoVolumeRepack(overWeightBoxItems); if (newHeavierBoxes.Count != 1) { continue; } if (DidRepackActuallyHelp(boxA, boxB, newHeavierBoxes.Top(), newLighterBoxes.Top())) { boxB = newLighterBoxes.Top(); boxA = newHeavierBoxes.Top(); anyIterationSuccessful = true; } } return(anyIterationSuccessful); }
/// <summary> /// Not every attempted repack is actually helpful - sometimes moving an item between two /// otherwise identical boxes, or sometimes the box used for the now lighter set of items /// actually weighs more when empty causing an increase in total weight. /// </summary> /// <returns></returns> private bool DidRepackActuallyHelp(PackedBox oldBoxA, PackedBox oldBoxB, PackedBox newBoxA, PackedBox newBoxB) { PackedBoxList oldList = new PackedBoxList(); oldList.InsertFromArray(new PackedBox[] { oldBoxA, oldBoxB }); PackedBoxList newList = new PackedBoxList(); newList.InsertFromArray(new PackedBox[] { newBoxA, newBoxB }); return(newList.GetWeightVariance() < oldList.GetWeightVariance()); }
public void TestVolumeUtilisation() { var box = Factory.CreateBox("Box", 10, 10, 10, 0, 10, 10, 10, 10); var item = Factory.CreateItem("Item", 5, 10, 10, 10, true); var packedItem = new PackedItem(item, 0, 0, 0, 5, 10, 10); var packedItemList = new PackedItemList(); packedItemList.Insert(packedItem); var packedBox = new PackedBox(box, packedItemList); var packedBoxList = new PackedBoxList(); packedBoxList.Insert(packedBox); Assert.Equal(50f, packedBoxList.GetVolumeUtilisation()); }
public void TestVolumeUtilisation() { var box = Factory.CreateBox("Box", 10, 10, 20, 10, 10, 10, 20, 10); var oItem = new OrientatedItem( Factory.CreateItem("Item", 4, 10, 10, 10, true), 4, 10, 10 ); var packedItemList = new PackedItemList(); packedItemList.Insert(PackedItem.FromOrientatedItem(oItem, 0, 0, 0)); var pBox = new PackedBox(box, packedItemList); Assert.Equal(400, pBox.UsedVolume); Assert.Equal(1600, pBox.UnusedVolume); Assert.Equal(20, pBox.VolumeUtilizationPercent); }
private int Compare(PackedBox boxA, PackedBox boxB) { var itemsInThis = boxA.PackedItems.Count; var itemsInOther = boxB.PackedItems.Count; var choise = itemsInOther.CompareTo(itemsInThis); if (choise == 0) { choise = boxB.VolumeUtilizationPercent.CompareTo(boxA.VolumeUtilizationPercent); } if (choise == 0) { choise = boxB.UsedVolume.CompareTo(boxA.UsedVolume); } if (choise == 0) { choise = boxB.TotalWeight.CompareTo(boxA.TotalWeight); } return(choise); }