Example #1
0
        private void Insert(
            Cuboid cuboid,
            FreeCuboidChoiceHeuristic cuboidChoice,
            GuillotineSplitHeuristic splitMethod)
        {
            // Check is overweight
            if (cuboid.Weight + _usedCuboids.Sum(x => x.Weight) > _parameter.BinWeight)
            {
                return;
            }

            // Find where to put the new cuboid
            var freeNodeIndex = 0;

            FindPositionForNewNode(cuboid, cuboidChoice, out freeNodeIndex);

            // Abort if we didn't have enough space in the bin
            if (!cuboid.IsPlaced)
            {
                return;
            }

            // Remove the space that was just consumed by the new cuboid
            if (freeNodeIndex < 0)
            {
                throw new ArithmeticException("freeNodeIndex < 0");
            }
            SplitFreeCuboidByHeuristic(_freeCuboids[freeNodeIndex], cuboid, splitMethod);
            _freeCuboids.RemoveAt(freeNodeIndex);

            // Remember the new used cuboid
            _usedCuboids.Add(cuboid);
        }
Example #2
0
 public BinPackGuillotineAlgorithm(
     BinPackParameter parameter,
     FreeCuboidChoiceHeuristic cuboidChoice,
     GuillotineSplitHeuristic splitMethod)
 {
     _parameter    = parameter;
     _cuboidChoice = cuboidChoice;
     _splitMethod  = splitMethod;
     _usedCuboids  = new List <Cuboid>();
     _freeCuboids  = new List <Cuboid>();
     AddFreeCuboid(new Cuboid(parameter.BinWidth, parameter.BinHeight, parameter.BinDepth));
 }
Example #3
0
        private static decimal ScoreByHeuristic(
            Cuboid cuboid,
            Cuboid freeCuboid,
            FreeCuboidChoiceHeuristic cuboidChoice)
        {
            switch (cuboidChoice)
            {
            case FreeCuboidChoiceHeuristic.CuboidMinHeight:
                return(freeCuboid.Y + cuboid.Height);

            default:
                throw new NotSupportedException($"cuboid choice is unsupported: {cuboidChoice}");
            }
        }
Example #4
0
 public BinPackGuillotineAlgorithm(
     decimal binWidth,
     decimal binHeight,
     decimal binDepth,
     FreeCuboidChoiceHeuristic cuboidChoice,
     GuillotineSplitHeuristic splitMethod)
 {
     _binWidth     = binWidth;
     _binHeight    = binHeight;
     _binDepth     = binDepth;
     _cuboidChoice = cuboidChoice;
     _splitMethod  = splitMethod;
     _usedCuboids  = new List <Cuboid>();
     _freeCuboids  = new List <Cuboid>();
     AddFreeCuboid(new Cuboid(_binWidth, _binHeight, _binDepth));
 }
Example #5
0
        private void FindPositionForNewNode(
            Cuboid cuboid,
            FreeCuboidChoiceHeuristic cuboidChoice,
            out int freeCuboidIndex)
        {
            var width     = cuboid.Width;
            var height    = cuboid.Height;
            var depth     = cuboid.Depth;
            var bestScore = decimal.MaxValue;

            freeCuboidIndex = -1;

            // Try each free cuboid to find the best one for placement a given cuboid.
            // Rotate a cuboid in every possible way and find which choice is the best.
            for (int index = 0; index < _freeCuboids.Count; ++index)
            {
                var freeCuboid = _freeCuboids[index];

                // Width x Height x Depth (no rotate)
                if (width <= freeCuboid.Width &&
                    height <= freeCuboid.Height &&
                    depth <= freeCuboid.Depth)
                {
                    var score = ScoreByHeuristic(cuboid, freeCuboid, cuboidChoice);
                    if (score < bestScore && cuboid.AllowOrientZ)
                    {
                        cuboid.IsPlaced = true;
                        cuboid.X        = freeCuboid.X;
                        cuboid.Y        = freeCuboid.Y;
                        cuboid.Z        = freeCuboid.Z;
                        cuboid.Width    = width;
                        cuboid.Height   = height;
                        cuboid.Depth    = depth;
                        bestScore       = score;
                        freeCuboidIndex = index;
                    }
                }

                // Width x Depth x Height (rotate vertically)
                if (width <= freeCuboid.Width &&
                    depth <= freeCuboid.Height &&
                    height <= freeCuboid.Depth &&
                    _parameter.AllowRotateVertically)
                {
                    var score = ScoreByHeuristic(cuboid, freeCuboid, cuboidChoice);
                    if (score < bestScore && cuboid.AllowOrientY)
                    {
                        cuboid.IsPlaced = true;
                        cuboid.X        = freeCuboid.X;
                        cuboid.Y        = freeCuboid.Y;
                        cuboid.Z        = freeCuboid.Z;
                        cuboid.Width    = width;
                        cuboid.Height   = depth;
                        cuboid.Depth    = height;
                        bestScore       = score;
                        freeCuboidIndex = index;
                    }
                }

                // Depth x Height x Width (rotate horizontally)
                if (depth <= freeCuboid.Width &&
                    height <= freeCuboid.Height &&
                    width <= freeCuboid.Depth)
                {
                    var score = ScoreByHeuristic(cuboid, freeCuboid, cuboidChoice);
                    if (score < bestScore && cuboid.AllowOrientX)
                    {
                        cuboid.IsPlaced = true;
                        cuboid.X        = freeCuboid.X;
                        cuboid.Y        = freeCuboid.Y;
                        cuboid.Z        = freeCuboid.Z;
                        cuboid.Width    = depth;
                        cuboid.Height   = height;
                        cuboid.Depth    = width;
                        bestScore       = score;
                        freeCuboidIndex = index;
                    }
                }

                // Depth x Width x Height (rotate horizontally and vertically)
                if (depth <= freeCuboid.Width &&
                    width <= freeCuboid.Height &&
                    height <= freeCuboid.Depth &&
                    _parameter.AllowRotateVertically)
                {
                    var score = ScoreByHeuristic(cuboid, freeCuboid, cuboidChoice);
                    if (score < bestScore && cuboid.AllowOrientY)
                    {
                        cuboid.IsPlaced = true;
                        cuboid.X        = freeCuboid.X;
                        cuboid.Y        = freeCuboid.Y;
                        cuboid.Z        = freeCuboid.Z;
                        cuboid.Width    = depth;
                        cuboid.Height   = width;
                        cuboid.Depth    = height;
                        bestScore       = score;
                        freeCuboidIndex = index;
                    }
                }

                // Height x Width x Depth (rotate vertically)
                if (height <= freeCuboid.Width &&
                    width <= freeCuboid.Height &&
                    depth <= freeCuboid.Depth &&
                    _parameter.AllowRotateVertically)
                {
                    var score = ScoreByHeuristic(cuboid, freeCuboid, cuboidChoice);
                    if (score < bestScore && cuboid.AllowOrientZ)
                    {
                        cuboid.IsPlaced = true;
                        cuboid.X        = freeCuboid.X;
                        cuboid.Y        = freeCuboid.Y;
                        cuboid.Z        = freeCuboid.Z;
                        cuboid.Width    = height;
                        cuboid.Height   = width;
                        cuboid.Depth    = depth;
                        bestScore       = score;
                        freeCuboidIndex = index;
                    }
                }

                // Height x Depth x Width (rotate horizontally and vertically)
                if (height <= freeCuboid.Width &&
                    depth <= freeCuboid.Height &&
                    width <= freeCuboid.Depth &&
                    _parameter.AllowRotateVertically)
                {
                    var score = ScoreByHeuristic(cuboid, freeCuboid, cuboidChoice);
                    if (score < bestScore && cuboid.AllowOrientX)
                    {
                        cuboid.IsPlaced = true;
                        cuboid.X        = freeCuboid.X;
                        cuboid.Y        = freeCuboid.Y;
                        cuboid.Z        = freeCuboid.Z;
                        cuboid.Width    = height;
                        cuboid.Height   = depth;
                        cuboid.Depth    = width;
                        bestScore       = score;
                        freeCuboidIndex = index;
                    }
                }
            }
        }