Example #1
0
        public List <ContainerPackingResult> Pack(Container container, List <Item> itemsToPack)
        {
            var result = new List <ContainerPackingResult>();
            var containerPackingResult = new ContainerPackingResult();

            containerPackingResult.ContainerID = container.ID;
            var algorithm = GetPackingAlgorithmFromTypeID(1); //magic # // only enum avail in this 3rd party tool

            // Until I rewrite the algorithm with no side effects, we need to clone the item list
            // so the parallel updates don't interfere with each other.
            var items = new List <Item>();

            itemsToPack.ForEach(item =>
            {
                items.Add(new Item(item.ID, item.Dim1, item.Dim2, item.Dim3, item.Quantity));
            });

            var algorithmResult = algorithm.Run(container, items);

            var containerVolume    = container.Length * container.Width * container.Height;
            var itemVolumePacked   = algorithmResult.PackedItems.Sum(i => i.Volume);
            var itemVolumeUnpacked = algorithmResult.UnpackedItems.Sum(i => i.Volume);

            algorithmResult.PercentContainerVolumePacked = Math.Round(itemVolumePacked / containerVolume * 100, 2);
            algorithmResult.PercentItemVolumePacked      =
                Math.Round(itemVolumePacked / (itemVolumePacked + itemVolumeUnpacked) * 100, 2);

            lock (sync)
            {
                containerPackingResult.AlgorithmPackingResults.Add(algorithmResult);
            }

            return(result);
        }
        /// <summary>
        /// Attempts to pack the specified containers with the specified items using the specified algorithms.
        /// </summary>
        /// <param name="containers">The list of containers to pack.</param>
        /// <param name="itemsToPack">The items to pack.</param>
        /// <param name="algorithmTypeIDs">The list of algorithm type IDs to use for packing.</param>
        /// <returns>A container packing result with lists of the packed and unpacked items.</returns>
        public static List <ContainerPackingResult> Pack(List <Container> containers, List <Item> itemsToPack, List <int> algorithmTypeIDs)
        {
            Object sync = new Object {
            };
            List <ContainerPackingResult> result = new List <ContainerPackingResult>();

            Parallel.ForEach(containers, container =>
            {
                ContainerPackingResult containerPackingResult = new ContainerPackingResult();
                containerPackingResult.ContainerID            = container.ID;

                Parallel.ForEach(algorithmTypeIDs, algorithmTypeID =>
                {
                    IPackingAlgorithm algorithm = PackingService.GetPackingAlgorithmFromTypeID(algorithmTypeID);

                    // Until I rewrite the algorithm with no side effects, we need to clone the item list
                    // so the parallel updates don't interfere with each other.
                    List <Item> items = new List <Item>();

                    itemsToPack.ForEach(item =>
                    {
                        items.Add(new Item(item.ID, item.Length, item.Width, item.Height, item.Quantity));
                    });

                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    AlgorithmPackingResult algorithmResult = algorithm.Run(container, items);
                    stopwatch.Stop();

                    algorithmResult.PackTimeInMilliseconds = stopwatch.ElapsedMilliseconds;

                    decimal containerVolume = container.Length * container.Width * container.Height;
                    decimal volumePacked    = 0;

                    algorithmResult.PackedItems.ForEach(item =>
                    {
                        volumePacked += item.Volume;
                    });

                    algorithmResult.PercentContainerVolumePacked = (int)Math.Ceiling(volumePacked / containerVolume * 100);

                    lock (sync)
                    {
                        containerPackingResult.AlgorithmPackingResults.Add(algorithmResult);
                    }
                });

                containerPackingResult.AlgorithmPackingResults = containerPackingResult.AlgorithmPackingResults.OrderBy(r => r.AlgorithmName).ToList();

                lock (sync)
                {
                    result.Add(containerPackingResult);
                }
            });

            return(result);
        }
Example #3
0
        /// <summary>
        ///     Attempts to pack the specified containers with the specified items using the specified algorithms.
        /// </summary>
        /// <param name="containers">The list of containers to pack.</param>
        /// <param name="itemsToPack">The items to pack.</param>
        /// <param name="algorithmTypeIDs">The list of algorithm type IDs to use for packing.</param>
        /// <returns>A container packing result with lists of the packed and unpacked items.</returns>
        public List <ContainerPackingResult> Pack(List <Container> containers, List <Item> itemsToPack,
                                                  List <int> algorithmTypeIDs)
        {
            var sync   = new object();
            var result = new List <ContainerPackingResult>();

            Parallel.ForEach(containers, container =>
            {
                var containerPackingResult         = new ContainerPackingResult();
                containerPackingResult.ContainerID = container.ID;

                Parallel.ForEach(algorithmTypeIDs, algorithmTypeID =>
                {
                    var algorithm = GetPackingAlgorithmFromTypeID(algorithmTypeID);

                    // Until I rewrite the algorithm with no side effects, we need to clone the item list
                    // so the parallel updates don't interfere with each other.
                    var items = new List <Item>();

                    itemsToPack.ForEach(item =>
                    {
                        items.Add(new Item(item.ID, item.Dim1, item.Dim2, item.Dim3, item.Quantity));
                    });

                    var stopwatch = new Stopwatch();
                    stopwatch.Start();
                    var algorithmResult = algorithm.Run(container, items);
                    stopwatch.Stop();

                    algorithmResult.PackTimeInMilliseconds = stopwatch.ElapsedMilliseconds;

                    var containerVolume    = container.Length * container.Width * container.Height;
                    var itemVolumePacked   = algorithmResult.PackedItems.Sum(i => i.Volume);
                    var itemVolumeUnpacked = algorithmResult.UnpackedItems.Sum(i => i.Volume);

                    algorithmResult.PercentContainerVolumePacked =
                        Math.Round(itemVolumePacked / containerVolume * 100, 2);
                    algorithmResult.PercentItemVolumePacked =
                        Math.Round(itemVolumePacked / (itemVolumePacked + itemVolumeUnpacked) * 100, 2);

                    lock (sync)
                    {
                        containerPackingResult.AlgorithmPackingResults.Add(algorithmResult);
                    }
                });

                containerPackingResult.AlgorithmPackingResults = containerPackingResult.AlgorithmPackingResults
                                                                 .OrderBy(r => r.AlgorithmName).ToList();

                lock (sync)
                {
                    result.Add(containerPackingResult);
                }
            });

            return(result);
        }
Example #4
0
        /// <summary>
        /// Attempts to pack the specified containers with the specified items using the specified algorithms.
        /// </summary>
        /// <param name="containers">The list of containers to pack.</param>
        /// <param name="itemsToPack">The items to pack.</param>
        /// <param name="algorithmTypeIDs">The list of algorithm type IDs to use for packing.</param>
        /// <returns>A container packing result with lists of the packed and unpacked items.</returns>
        public static List <ContainerPackingResult> Pack(Container containers, List <Item> itemsToPack, List <int> algorithmTypeIDs)
        {
            Object sync = new Object {
            };
            List <ContainerPackingResult> result = new List <ContainerPackingResult>();

            //Parallel.ForEach(containers, container =>
            //{
            ContainerPackingResult containerPackingResult = new ContainerPackingResult();

            containerPackingResult.ContainerID   = containers.Id;
            containerPackingResult.ContainerName = containers.Name;
            containerPackingResult.Weight        = containers.Weight;

            Parallel.ForEach(algorithmTypeIDs, algorithmTypeID =>
            {
                IPackingAlgorithm algorithm = PackingService.GetPackingAlgorithmFromTypeID(algorithmTypeID);

                // Until I rewrite the algorithm with no side effects, we need to clone the item list
                // so the parallel updates don't interfere with each other.
                List <Item> items = new List <Item>();

                itemsToPack.ForEach(item =>
                {
                    items.Add(new Item(item.Name, item.Dim1, item.Dim2, item.Dim3, item.Quantity));
                });

                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                AlgorithmPackingResult algorithmResult = algorithm.Run(containers, items);
                stopwatch.Stop();

                algorithmResult.PackTimeInMilliseconds = stopwatch.ElapsedMilliseconds;

                decimal containerVolume    = containers.Length * containers.Width * containers.Height;
                decimal itemVolumePacked   = algorithmResult.PackedItems.Sum(i => i.Volume);
                decimal itemVolumeUnpacked = algorithmResult.UnpackedItems.Sum(i => i.Volume);

                algorithmResult.PercentContainerVolumePacked = Math.Round(itemVolumePacked / containerVolume * 100, 2);
                algorithmResult.PercentItemVolumePacked      = Math.Round(itemVolumePacked / (itemVolumePacked + itemVolumeUnpacked) * 100, 2);

                lock (sync)
                {
                    containerPackingResult.AlgorithmPackingResults.Add(algorithmResult);
                }
            });

            containerPackingResult.AlgorithmPackingResults = containerPackingResult.AlgorithmPackingResults.OrderBy(r => r.AlgorithmName).ToList();

            lock (sync)
            {
                result.Add(containerPackingResult);
            }
            //});

            return(result);
        }
Example #5
0
        public static Dictionary <string, object> Pack3D(
            Cuboid bin,
            List <Cuboid> items)
        {
            decimal          length    = Convert.ToDecimal(bin.Length);
            decimal          width     = Convert.ToDecimal(bin.Width);
            decimal          height    = Convert.ToDecimal(bin.Height);
            List <Container> container = new List <Container> {
                new Container(1, length, width, height)
            };

            List <Item> itemsToPack = ItemsFromCuboids(items);

            //Dictionary to map Item Id with Cuboid index
            Dictionary <int, int> idDict = IdFromItem(itemsToPack).Zip(Enumerable.Range(0, itemsToPack.Count), (k, v) => new { Key = k, Value = v }).ToDictionary(x => x.Key, x => x.Value);

            List <int> algorithm = new List <int> {
                1
            };

            ContainerPackingResult packingResult          = CromulentBisgetti.ContainerPacking.PackingService.Pack(container, itemsToPack, algorithm).FirstOrDefault();
            AlgorithmPackingResult algorithmPackingResult = packingResult.AlgorithmPackingResults.FirstOrDefault();

            List <Item>   packedItems   = algorithmPackingResult.PackedItems;
            List <Cuboid> packedCuboids = CuboidsFromItems(packedItems);

            List <Item>   unpackedItems   = algorithmPackingResult.UnpackedItems;
            List <Cuboid> unpackedCuboids = CuboidsFromItems(unpackedItems);

            List <int> packedIndices = IdFromItem(packedItems).Where(idDict.ContainsKey)
                                       .Select(x => idDict[x])
                                       .ToList();

            Dictionary <string, object> newOutput;

            newOutput = new Dictionary <string, object>
            {
                { packedItemsOutputPort3D, packedCuboids },
                { indicesOutputPort3D, packedIndices },
                { remainingItemsOutputPort3D, unpackedCuboids }
            };

            return(newOutput);
        }
Example #6
0
        /// <summary>
        /// Initializes everything.
        /// </summary>
        private void Initialize(Container container, List <Item> items)
        {
            itemsToPack        = new List <Item>();
            itemsPackedInOrder = new List <Item>();
            result             = new ContainerPackingResult();

            // The original code uses 1-based indexing everywhere. This fake entry is added to the beginning
            // of the list to make that possible.
            itemsToPack.Add(new Item(0, 0, 0, 0, 0));

            layers           = new List <Layer>();
            itemsToPackCount = 0;

            foreach (Item item in items)
            {
                for (int i = 1; i <= item.Quantity; i++)
                {
                    Item newItem = new Item(item.ID, item.Dim1, item.Dim2, item.Dim3, item.Quantity);
                    itemsToPack.Add(newItem);
                }

                itemsToPackCount += item.Quantity;
            }

            itemsToPack.Add(new Item(0, 0, 0, 0, 0));

            totalContainerVolume = container.Length * container.Height * container.Width;
            totalItemVolume      = 0.0M;

            for (x = 1; x <= itemsToPackCount; x++)
            {
                totalItemVolume = totalItemVolume + itemsToPack[x].Volume;
            }

            scrapfirst = new ScrapPad();

            scrapfirst.Pre       = null;
            scrapfirst.Post      = null;
            packingBest          = false;
            hundredPercentPacked = false;
            quit = false;
        }
        public static Dictionary <string, object> PackContainersWithGroupsContinuously(List <Miscellany.ContainerPacking.Entities.Container> containers, List <List <Miscellany.ContainerPacking.Entities.Item> > itemsToPack, int algorithm = 1, int minimumItems = 20)
        {
            //Select algorithm using integer
            List <int> algorithms = new List <int> {
                algorithm
            };

            //Create CromulentBisgetti Items, retaining the nested structure
            List <List <Item> > items = new List <List <Item> >();

            foreach (List <Miscellany.ContainerPacking.Entities.Item> l in itemsToPack)
            {
                List <Item> subList = new List <Item>();
                foreach (Miscellany.ContainerPacking.Entities.Item i in l)
                {
                    Item cbItem = ItemToCB(i);
                    subList.Add(cbItem);
                }
                items.Add(subList);
            }

            //Reverse List to start from back so removals don't cause problems to indexing
            items.Reverse();

            //Output lists
            List <List <Miscellany.ContainerPacking.Entities.Item> > itemsPacked = new List <List <Miscellany.ContainerPacking.Entities.Item> >();
            bool          IsCompletePack               = false;
            List <int>    PackTimeInMilliseconds       = new List <int>();
            int           TotalPackTimeInMilliseconds  = 0;
            List <double> PercentContainerVolumePacked = new List <double>();
            List <double> PercentItemVolumePacked      = new List <double>();

            //Items Count
            int currentPackGroup = items.Count - 1; //Set to last index

            //Temporary group of Items to pack
            List <Item> tempItemsToPack = new List <Item>();

            //Loop through the containers
            foreach (Miscellany.ContainerPacking.Entities.Container container in containers)
            {
                //No more pack groups to consider
                if (currentPackGroup < 0)
                {
                    break;
                }

                //How many Items in temp list?
                int tempCount = tempItemsToPack.Count;

                //Ensure count matches the number of groups remaining
                currentPackGroup = items.Count - 1;

                if (tempCount >= minimumItems)
                {
                    //There are more Items than the minimum or the same
                }
                else if (currentPackGroup < 0 || (currentPackGroup == 0 && items[currentPackGroup].Count == 0))
                {
                    //There are fewer Items than the minimum but there are no more Items to draw on
                    if (tempCount == 0)
                    {
                        //No Items left so break the loop
                        break;
                    }
                }
                else
                {
                    //There are fewer Items than the minimum but there are further Items to use
                    int whileCount = 0;
                    while (tempCount < minimumItems)
                    {
                        whileCount++;
                        if (whileCount > 10)
                        {
                            continue; //temp
                        }
                        if (currentPackGroup < 0)
                        {
                            break;
                        }
                        if (items[currentPackGroup].Count == 0)
                        {
                            //No items left, move onto next group for next loop
                            items.RemoveAt(currentPackGroup);
                            currentPackGroup--;
                        }
                        else if (items[currentPackGroup].Count <= (minimumItems - tempCount))
                        {
                            //Fewer Items are available than desired
                            tempItemsToPack.AddRange(items[currentPackGroup]); //Add all Items
                            items.RemoveAt(currentPackGroup);                  //Remove all items from the group
                            currentPackGroup--;                                //Move to the next group index for the next loop
                            tempCount = tempItemsToPack.Count;                 //Set the cou/*
                        }
                        else if (items[currentPackGroup].Count > (minimumItems - tempCount))
                        {
                            //The desired number or greater are available
                            int numberToTake = minimumItems - tempCount;
                            if (numberToTake < 1)
                            {
                                continue;
                            }
                            for (int i = numberToTake - 1; i >= 0; i--)
                            {
                                //Take each required Item and remove from list
                                tempItemsToPack.Add(items[currentPackGroup][i]);
                                items[currentPackGroup].RemoveAt(i);
                            }
                            tempCount = tempItemsToPack.Count; //Report the current size of the temporary group
                        }
                        //tempCount++;
                    }
                }

                //Create CromulentBisgetti Container
                Container        con  = ContainerToCB(container);
                List <Container> cons = new List <Container> {
                    con
                };

                //Get container packing result
                ContainerPackingResult containerPackingResult = CromulentBisgetti.ContainerPacking.PackingService.Pack(cons, tempItemsToPack, algorithms).FirstOrDefault();

                //Get the single algorthim packing result from the container packing result
                AlgorithmPackingResult algorithmPackingResult = containerPackingResult.AlgorithmPackingResults.FirstOrDefault();

                //Packed Items
                List <Miscellany.ContainerPacking.Entities.Item> itemsPackedPass = new List <Miscellany.ContainerPacking.Entities.Item>();
                foreach (Item i in algorithmPackingResult.PackedItems)
                {
                    Miscellany.ContainerPacking.Entities.Item mItem = ItemToMiscellany(i);
                    itemsPackedPass.Add(mItem);
                }
                itemsPacked.Add(itemsPackedPass);
                IsCompletePack = algorithmPackingResult.IsCompletePack;
                if (IsCompletePack)          //If all the items from that group are packed
                {
                    tempItemsToPack.Clear(); //Clear all Items from temp list
                }
                else
                {
                    tempItemsToPack = algorithmPackingResult.UnpackedItems; //items is set to unpacked items for next loop
                }
                PackTimeInMilliseconds.Add(Convert.ToInt32(algorithmPackingResult.PackTimeInMilliseconds));
                TotalPackTimeInMilliseconds += Convert.ToInt32(algorithmPackingResult.PackTimeInMilliseconds);
                PercentContainerVolumePacked.Add(Miscellany.Math.Functions.ToDouble(algorithmPackingResult.PercentContainerVolumePacked));
                PercentItemVolumePacked.Add(Miscellany.Math.Functions.ToDouble(algorithmPackingResult.PercentItemVolumePacked));
            }

            //Convert CromulentBisgetti items to Miscellany Items for Unpacked Items
            List <Miscellany.ContainerPacking.Entities.Item> itemsUnpacked = new List <Miscellany.ContainerPacking.Entities.Item>();

            foreach (List <Item> l in items)
            {
                foreach (Item i in l)
                {
                    Miscellany.ContainerPacking.Entities.Item mItem = ItemToMiscellany(i);
                    itemsUnpacked.Add(mItem);
                }
            }

            //Return values
            var d = new Dictionary <string, object>();

            d.Add("packedItems", itemsPacked);
            d.Add("unpackedItems", itemsUnpacked);
            d.Add("isCompletePack", IsCompletePack);
            d.Add("packTimeInMilliseconds", PackTimeInMilliseconds);
            d.Add("totalPackTimeInMilliseconds", TotalPackTimeInMilliseconds);
            d.Add("percentContainerVolumePacked", PercentContainerVolumePacked);
            d.Add("percentItemVolumePacked", PercentItemVolumePacked);
            return(d);
        }
Example #8
0
        public static Dictionary <string, object> PackContainer(Miscellany.ContainerPacking.Entities.Container container, List <Miscellany.ContainerPacking.Entities.Item> itemsToPack, int algorithm = 1)
        {
            //Create CromulentBisgetti Container
            Container con = ContainerToCB(container);

            //Create CromulentBisgetti Items
            List <Item> items = new List <Item>();

            foreach (Miscellany.ContainerPacking.Entities.Item i in itemsToPack)
            {
                Item cbItem = ItemToCB(i);
                items.Add(cbItem);
            }

            //Create list with single container
            List <Container> containers = new List <Container> {
                con
            };

            //Select algorithm using integer
            List <int> algorithms = new List <int> {
                algorithm
            };

            //Get container packing result
            ContainerPackingResult containerPackingResult = CromulentBisgetti.ContainerPacking.PackingService.Pack(containers, items, algorithms).FirstOrDefault();

            //Get the single algorthim packing result from the container packing result
            AlgorithmPackingResult algorithmPackingResult = containerPackingResult.AlgorithmPackingResults.FirstOrDefault();
            bool   IsCompletePack               = algorithmPackingResult.IsCompletePack;
            int    PackTimeInMilliseconds       = Convert.ToInt32(algorithmPackingResult.PackTimeInMilliseconds); //Max limit of int32 for milliseconds is596 hours
            double PercentContainerVolumePacked = Miscellany.Math.Functions.ToDouble(algorithmPackingResult.PercentContainerVolumePacked);
            double PercentItemVolumePacked      = Miscellany.Math.Functions.ToDouble(algorithmPackingResult.PercentItemVolumePacked);
            //int BestFitOrientation = algorithmPackingResult.best

            //Convert CromulentBisgetti items to Miscellany Items
            //Packed Items
            List <Miscellany.ContainerPacking.Entities.Item> itemsPacked = new List <Miscellany.ContainerPacking.Entities.Item>();

            foreach (Item i in algorithmPackingResult.PackedItems)
            {
                Miscellany.ContainerPacking.Entities.Item mItem = ItemToMiscellany(i);
                itemsPacked.Add(mItem);
            }
            //Unpacked Items
            List <Miscellany.ContainerPacking.Entities.Item> itemsUnpacked = new List <Miscellany.ContainerPacking.Entities.Item>();

            foreach (Item i in algorithmPackingResult.UnpackedItems)
            {
                Miscellany.ContainerPacking.Entities.Item mItem = ItemToMiscellany(i);
                itemsUnpacked.Add(mItem);
            }

            //Return values
            var d = new Dictionary <string, object>();

            d.Add("packedItems", itemsPacked);
            d.Add("unpackedItems", itemsUnpacked);
            d.Add("isCompletePack", IsCompletePack);
            d.Add("packTimeInMilliseconds", PackTimeInMilliseconds);
            d.Add("percentContainerVolumePacked", PercentContainerVolumePacked);
            d.Add("percentItemVolumePacked", PercentItemVolumePacked);
            d.Add("orientation", PercentItemVolumePacked);
            return(d);
        }
        public static Dictionary <string, object> PackContainersWithGroups(List <Miscellany.ContainerPacking.Entities.Container> containers, List <List <Miscellany.ContainerPacking.Entities.Item> > itemsToPack, int algorithm = 1)
        {
            //Select algorithm using integer
            List <int> algorithms = new List <int> {
                algorithm
            };
            //Create CromulentBisgetti Items
            List <List <Item> > items = new List <List <Item> >();

            foreach (List <Miscellany.ContainerPacking.Entities.Item> l in itemsToPack)
            {
                List <Item> subList = new List <Item>();
                foreach (Miscellany.ContainerPacking.Entities.Item i in l)
                {
                    Item cbItem = ItemToCB(i);
                    subList.Add(cbItem);
                }
                items.Add(subList);
            }

            //Reverse List to start from back so removals don't cause problems to indexing
            items.Reverse();

            //Output lists
            List <List <Miscellany.ContainerPacking.Entities.Item> > itemsPacked = new List <List <Miscellany.ContainerPacking.Entities.Item> >();
            bool          IsCompletePack               = false;
            List <int>    PackTimeInMilliseconds       = new List <int>();
            int           TotalPackTimeInMilliseconds  = 0;
            List <double> PercentContainerVolumePacked = new List <double>();
            List <double> PercentItemVolumePacked      = new List <double>();

            //Items Count
            int currentPackGroup = items.Count - 1;

            //Loop through the containers
            foreach (Miscellany.ContainerPacking.Entities.Container container in containers)
            {
                if (items.Count == 0)
                {
                    break;
                }
                if (items[currentPackGroup].Count == 0)
                {
                    items.RemoveAt(currentPackGroup); //Remove empty list
                    currentPackGroup--;               //move to next group
                }

                //Create list of items to pack
                List <Item> itemsToPackGroup = items[currentPackGroup];

                //Create CromulentBisgetti Container
                Container        con  = ContainerToCB(container);
                List <Container> cons = new List <Container> {
                    con
                };

                //Get container packing result
                ContainerPackingResult containerPackingResult = CromulentBisgetti.ContainerPacking.PackingService.Pack(cons, itemsToPackGroup, algorithms).FirstOrDefault();

                //Get the single algorthim packing result from the container packing result
                AlgorithmPackingResult algorithmPackingResult = containerPackingResult.AlgorithmPackingResults.FirstOrDefault();

                //Packed Items
                List <Miscellany.ContainerPacking.Entities.Item> itemsPackedPass = new List <Miscellany.ContainerPacking.Entities.Item>();
                foreach (Item i in algorithmPackingResult.PackedItems)
                {
                    Miscellany.ContainerPacking.Entities.Item mItem = ItemToMiscellany(i);
                    itemsPackedPass.Add(mItem);
                }
                itemsPacked.Add(itemsPackedPass);
                IsCompletePack = algorithmPackingResult.IsCompletePack;
                if (IsCompletePack)                   //If all the items from that group are packed
                {
                    items.RemoveAt(currentPackGroup); //Remove group from list to pack
                    currentPackGroup--;               //Move on to the next group
                }
                else
                {
                    items[currentPackGroup] = algorithmPackingResult.UnpackedItems; //items is set to unpacked items for next loop
                }
                PackTimeInMilliseconds.Add(Convert.ToInt32(algorithmPackingResult.PackTimeInMilliseconds));
                TotalPackTimeInMilliseconds += Convert.ToInt32(algorithmPackingResult.PackTimeInMilliseconds);
                PercentContainerVolumePacked.Add(Miscellany.Math.Functions.ToDouble(algorithmPackingResult.PercentContainerVolumePacked));
                PercentItemVolumePacked.Add(Miscellany.Math.Functions.ToDouble(algorithmPackingResult.PercentItemVolumePacked));
                if (items.Count == 0) //No more groups to pack
                {
                    break;
                }
            }

            //Convert CromulentBisgetti items to Miscellany Items for Unpacked Items
            List <Miscellany.ContainerPacking.Entities.Item> itemsUnpacked = new List <Miscellany.ContainerPacking.Entities.Item>();

            foreach (List <Item> l in items)
            {
                foreach (Item i in l)
                {
                    Miscellany.ContainerPacking.Entities.Item mItem = ItemToMiscellany(i);
                    itemsUnpacked.Add(mItem);
                }
            }

            //Return values
            var d = new Dictionary <string, object>();

            d.Add("packedItems", itemsPacked);
            d.Add("unpackedItems", itemsUnpacked);
            d.Add("isCompletePack", IsCompletePack);
            d.Add("packTimeInMilliseconds", PackTimeInMilliseconds);
            d.Add("totalPackTimeInMilliseconds", TotalPackTimeInMilliseconds);
            d.Add("percentContainerVolumePacked", PercentContainerVolumePacked);
            d.Add("percentItemVolumePacked", PercentItemVolumePacked);
            return(d);
        }
Example #10
0
        public static Dictionary <string, object> PackContainers(List <Miscellany.ContainerPacking.Entities.Container> containers, List <Miscellany.ContainerPacking.Entities.Item> itemsToPack, int algorithm = 1)
        {
            //Select algorithm using integer
            List <int> algorithms = new List <int> {
                algorithm
            };

            //Create CromulentBisgetti Items
            List <Item> items = new List <Item>();

            foreach (Miscellany.ContainerPacking.Entities.Item i in itemsToPack)
            {
                Item cbItem = ItemToCB(i);
                items.Add(cbItem);
            }

            //Output lists
            List <List <Miscellany.ContainerPacking.Entities.Item> > itemsPacked = new List <List <Miscellany.ContainerPacking.Entities.Item> >();
            bool          IsCompletePack               = false;
            List <int>    PackTimeInMilliseconds       = new List <int>();
            int           TotalPackTimeInMilliseconds  = 0;
            List <double> PercentContainerVolumePacked = new List <double>();
            List <double> PercentItemVolumePacked      = new List <double>();

            //Loop through the containers
            foreach (Miscellany.ContainerPacking.Entities.Container container in containers)
            {
                //Create CromulentBisgetti Container
                Container        con  = ContainerToCB(container);
                List <Container> cons = new List <Container> {
                    con
                };
                //Get container packing result
                ContainerPackingResult containerPackingResult = CromulentBisgetti.ContainerPacking.PackingService.Pack(cons, items, algorithms).FirstOrDefault();
                //Get the single algorthim packing result from the container packing result
                AlgorithmPackingResult algorithmPackingResult = containerPackingResult.AlgorithmPackingResults.FirstOrDefault();
                //Packed Items
                List <Miscellany.ContainerPacking.Entities.Item> itemsPackedPass = new List <Miscellany.ContainerPacking.Entities.Item>();
                foreach (Item i in algorithmPackingResult.PackedItems)
                {
                    Miscellany.ContainerPacking.Entities.Item mItem = ItemToMiscellany(i);
                    itemsPackedPass.Add(mItem);
                }
                itemsPacked.Add(itemsPackedPass);
                items          = algorithmPackingResult.UnpackedItems; //items is set to unpacked items for next loop
                IsCompletePack = algorithmPackingResult.IsCompletePack;
                PackTimeInMilliseconds.Add(Convert.ToInt32(algorithmPackingResult.PackTimeInMilliseconds));
                TotalPackTimeInMilliseconds += Convert.ToInt32(algorithmPackingResult.PackTimeInMilliseconds);
                PercentContainerVolumePacked.Add(Miscellany.Math.Functions.ToDouble(algorithmPackingResult.PercentContainerVolumePacked));
                PercentItemVolumePacked.Add(Miscellany.Math.Functions.ToDouble(algorithmPackingResult.PercentItemVolumePacked));
                if (algorithmPackingResult.IsCompletePack == true)
                {
                    break;
                }
            }

            //Convert CromulentBisgetti items to Miscellany Items for Unpacked Items
            List <Miscellany.ContainerPacking.Entities.Item> itemsUnpacked = new List <Miscellany.ContainerPacking.Entities.Item>();

            foreach (Item i in items)
            {
                Miscellany.ContainerPacking.Entities.Item mItem = ItemToMiscellany(i);
                itemsUnpacked.Add(mItem);
            }

            //Return values
            var d = new Dictionary <string, object>();

            d.Add("packedItems", itemsPacked);
            d.Add("unpackedItems", itemsUnpacked);
            d.Add("isCompletePack", IsCompletePack);
            d.Add("packTimeInMilliseconds", PackTimeInMilliseconds);
            d.Add("totalPackTimeInMilliseconds", TotalPackTimeInMilliseconds);
            d.Add("percentContainerVolumePacked", PercentContainerVolumePacked);
            d.Add("percentItemVolumePacked", PercentItemVolumePacked);
            return(d);
        }
Example #11
0
        /// <summary>
        /// Attempts to pack the specified containers with the specified items using the specified algorithms.
        /// </summary>
        /// <param name="containers">The list of containers to pack.</param>
        /// <param name="itemsToPack">The items to pack.</param>
        /// <param name="algorithmTypeIDs">The list of algorithm type IDs to use for packing.</param>
        /// <returns>A container packing result with lists of the packed and unpacked items.</returns>
        public static List <ContainerPackingResult> Pack(List <Container> containers, List <Item> itemsToPack, List <int> algorithmTypeIDs)
        {
            Object sync = new Object {
            };
            List <ContainerPackingResult> result = new List <ContainerPackingResult>();

            Parallel.ForEach(containers, container =>
            {
                ContainerPackingResult containerPackingResult = new ContainerPackingResult();
                containerPackingResult.ContainerID            = container.ID;

                Parallel.ForEach(algorithmTypeIDs, algorithmTypeID =>
                {
                    var jsonDefinition = new
                    {
                        Height = new Decimal(),
                        Length = new Decimal(),
                        Volume = new Decimal(),
                        Width  = new Decimal(),
                        Items  = new List <Item>()
                    };

                    var onlineContainerJsonSource = "{\"Height\":9.0,\"Length\":15.0,\"Volume\":1755.0,\"Width\":13.0,\"Items\":[{\"ID\":0,\"PesoMaximo\":0,\"Peso\":0,\"EmpilhamentoDisponivel\":true,\"ItensEmpilhados\":[],\"TipoDeItemId\":1,\"IsPacked\":true,\"Dim1\":3.0,\"Dim2\":3.0,\"Dim3\":3.0,\"CoordX\":0.0,\"CoordY\":0.0,\"CoordZ\":0.0,\"PackDimX\":3.0,\"PackDimY\":3.0,\"PackDimZ\":3.0,\"Volume\":27.000},{\"ID\":0,\"PesoMaximo\":0,\"Peso\":0,\"EmpilhamentoDisponivel\":true,\"ItensEmpilhados\":[],\"TipoDeItemId\":1,\"IsPacked\":true,\"Dim1\":3.0,\"Dim2\":3.0,\"Dim3\":3.0,\"CoordX\":3.0,\"CoordY\":0.0,\"CoordZ\":0.0,\"PackDimX\":3.0,\"PackDimY\":3.0,\"PackDimZ\":3.0,\"Volume\":27.000},{\"ID\":0,\"PesoMaximo\":0,\"Peso\":0,\"EmpilhamentoDisponivel\":true,\"ItensEmpilhados\":[],\"TipoDeItemId\":1,\"IsPacked\":true,\"Dim1\":3.0,\"Dim2\":3.0,\"Dim3\":3.0,\"CoordX\":6.0,\"CoordY\":0.0,\"CoordZ\":0.0,\"PackDimX\":3.0,\"PackDimY\":3.0,\"PackDimZ\":3.0,\"Volume\":27.000},{\"ID\":0,\"PesoMaximo\":0,\"Peso\":0,\"EmpilhamentoDisponivel\":true,\"ItensEmpilhados\":[],\"TipoDeItemId\":2,\"IsPacked\":true,\"Dim1\":2.0,\"Dim2\":2.0,\"Dim3\":2.0,\"CoordX\":9.0,\"CoordY\":0.0,\"CoordZ\":0.0,\"PackDimX\":2.0,\"PackDimY\":2.0,\"PackDimZ\":2.0,\"Volume\":8.0},{\"ID\":0,\"PesoMaximo\":0,\"Peso\":0,\"EmpilhamentoDisponivel\":true,\"ItensEmpilhados\":[],\"TipoDeItemId\":2,\"IsPacked\":true,\"Dim1\":2.0,\"Dim2\":2.0,\"Dim3\":2.0,\"CoordX\":11.0,\"CoordY\":0.0,\"CoordZ\":0.0,\"PackDimX\":2.0,\"PackDimY\":2.0,\"PackDimZ\":2.0,\"Volume\":8.0},{\"ID\":0,\"PesoMaximo\":0,\"Peso\":0,\"EmpilhamentoDisponivel\":true,\"ItensEmpilhados\":[],\"TipoDeItemId\":2,\"IsPacked\":true,\"Dim1\":2.0,\"Dim2\":2.0,\"Dim3\":2.0,\"CoordX\":13.0,\"CoordY\":0.0,\"CoordZ\":0.0,\"PackDimX\":2.0,\"PackDimY\":2.0,\"PackDimZ\":2.0,\"Volume\":8.0},{\"ID\":0,\"PesoMaximo\":0,\"Peso\":0,\"EmpilhamentoDisponivel\":true,\"ItensEmpilhados\":[],\"TipoDeItemId\":2,\"IsPacked\":true,\"Dim1\":2.0,\"Dim2\":2.0,\"Dim3\":2.0,\"CoordX\":9.0,\"CoordY\":0.0,\"CoordZ\":2.0,\"PackDimX\":2.0,\"PackDimY\":2.0,\"PackDimZ\":2.0,\"Volume\":8.0},{\"ID\":0,\"PesoMaximo\":0,\"Peso\":0,\"EmpilhamentoDisponivel\":true,\"ItensEmpilhados\":[],\"TipoDeItemId\":2,\"IsPacked\":true,\"Dim1\":2.0,\"Dim2\":2.0,\"Dim3\":2.0,\"CoordX\":11.0,\"CoordY\":0.0,\"CoordZ\":2.0,\"PackDimX\":2.0,\"PackDimY\":2.0,\"PackDimZ\":2.0,\"Volume\":8.0},{\"ID\":0,\"PesoMaximo\":0,\"Peso\":0,\"EmpilhamentoDisponivel\":true,\"ItensEmpilhados\":[],\"TipoDeItemId\":2,\"IsPacked\":true,\"Dim1\":2.0,\"Dim2\":2.0,\"Dim3\":2.0,\"CoordX\":13.0,\"CoordY\":0.0,\"CoordZ\":2.0,\"PackDimX\":2.0,\"PackDimY\":2.0,\"PackDimZ\":2.0,\"Volume\":8.0},{\"ID\":0,\"PesoMaximo\":0,\"Peso\":0,\"EmpilhamentoDisponivel\":true,\"ItensEmpilhados\":[],\"TipoDeItemId\":2,\"IsPacked\":true,\"Dim1\":2.0,\"Dim2\":2.0,\"Dim3\":2.0,\"CoordX\":7.0,\"CoordY\":0.0,\"CoordZ\":3.0,\"PackDimX\":2.0,\"PackDimY\":2.0,\"PackDimZ\":2.0,\"Volume\":8.0},{\"ID\":0,\"PesoMaximo\":0,\"Peso\":0,\"EmpilhamentoDisponivel\":true,\"ItensEmpilhados\":[],\"TipoDeItemId\":2,\"IsPacked\":true,\"Dim1\":2.0,\"Dim2\":2.0,\"Dim3\":2.0,\"CoordX\":5.0,\"CoordY\":0.0,\"CoordZ\":3.0,\"PackDimX\":2.0,\"PackDimY\":2.0,\"PackDimZ\":2.0,\"Volume\":8.0}]}";

                    var onlineContainerSource = JsonConvert.DeserializeAnonymousType(onlineContainerJsonSource, jsonDefinition);

                    // Until I rewrite the algorithm with no side effects, we need to clone the item list
                    // so the parallel updates don't interfere with each other.
                    List <Item> items = new List <Item>();

                    onlineContainerSource.Items.ForEach(item =>
                    {
                        item.Quantity = 1;
                        //item.IsPacked = false;
                        items.Add(item);

                        item.ItensEmpilhados.ForEach(itemEmpilhado => items.Add(itemEmpilhado));
                    });

                    itemsToPack.ForEach(item =>
                    {
                        for (int i = 0; i < item.Quantity; i++)
                        {
                            items.Add(new Item(item.ID, item.Dim1, item.Dim2, item.Dim3, 1, item.TipoDeItemId));
                        }
                    });

                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    //AlgorithmPackingResult algorithmResult = algorithm.Run(container, items);
                    AlgorithmPackingResult algorithmResult = new OnlineContainerPacking().OnlineRun(container, items);
                    stopwatch.Stop();

                    algorithmResult.PackTimeInMilliseconds = stopwatch.ElapsedMilliseconds;

                    decimal containerVolume    = container.Length * container.Width * container.Height;
                    decimal itemVolumePacked   = algorithmResult.PackedItems.Sum(i => i.Volume);
                    decimal itemVolumeUnpacked = algorithmResult.UnpackedItems.Sum(i => i.Volume);

                    algorithmResult.PercentContainerVolumePacked = Math.Round(itemVolumePacked / containerVolume * 100, 2);
                    algorithmResult.PercentItemVolumePacked      = Math.Round(itemVolumePacked / (itemVolumePacked + itemVolumeUnpacked) * 100, 2);

                    var onlineContainer = new
                    {
                        Height = container.Height,
                        Length = container.Length,
                        Volume = container.Volume,
                        Width  = container.Width,
                        Items  = algorithmResult.PackedItems
                    };

                    var onlineContainerJson = JsonConvert.SerializeObject(onlineContainer);

                    lock (sync)
                    {
                        containerPackingResult.AlgorithmPackingResults.Add(algorithmResult);
                    }
                });

                containerPackingResult.AlgorithmPackingResults = containerPackingResult.AlgorithmPackingResults.OrderBy(r => r.AlgorithmName).ToList();

                lock (sync)
                {
                    result.Add(containerPackingResult);
                }
            });

            return(result);
        }