Exemplo n.º 1
0
        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());
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        /// <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);
        }
Exemplo n.º 4
0
        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());
        }
Exemplo n.º 7
0
        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());
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
0
        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);
        }