Example #1
0
        static void Main(string[] args)
        {
            var items      = new[] { 0.2, 0.5, 0.4, 0.7, 0.1, 0.3, 0.8 };
            var maxBinSize = 1.7;

            var bins = BinsPacker <double> .Pack(items, d => d, maxBinSize);

            bins.ToObservable().Subscribe(combination =>
            {
                foreach (var item in combination)
                {
                    Console.Write($"{item} ");
                }
                Console.WriteLine();
            }
                                          );
        }
Example #2
0
        private static IEnumerable<Area2DMap> SplitMapping(Area2DMap currentMap, int maxPointsPerProcess, byte patchSize)
        {
            // The input should be splitted smartly taking into account the input data and settings.

            var result = new List<Area2DMap>();

            if (currentMap.DestElementsCount > maxPointsPerProcess)
            {
                // Decide on how many parts we are going to divide input.
                var partsAmount = (double)currentMap.DestElementsCount / maxPointsPerProcess;
                if (partsAmount == 1) partsAmount++;

                // Let's calculate how many rows & columns we are going to have
                var rect = currentMap.DestBounds;
                var w = rect.Width;
                var h = rect.Height;
                var left = rect.X;
                var top = rect.Y;

                var sideSize = Math.Sqrt(maxPointsPerProcess);
                double cs, rs;

                if (w > h)
                {
                    cs = w / sideSize;
                    rs = partsAmount / cs;
                }
                else
                {
                    rs = h / sideSize;
                    cs = partsAmount / rs;
                }

                var csfloor = Math.Floor(cs);
                var columns = (int)(csfloor < cs ? csfloor + 1 : csfloor);

                var rsfloor = Math.Floor(rs);
                var rows = (int)(rsfloor < rs ? rsfloor + 1 : rsfloor);

                // Finally - what is the cell size?
                var cellWidth = w / columns;
                var rowHight = h / rows;

                // Split mapping
                var newMappings = new List<Area2DMap>();

                for (var y = top; y < top + h; y += rowHight)
                {
                    for (var x = left; x < left + w; x += cellWidth)
                    {
                        // we extend cell in all direction
                        // so that it overlaps with other cells

                        var cx = Math.Max(x - patchSize, 0);
                        var cy = Math.Max(y - patchSize, 0);
                        var cw = (x - cx) + cellWidth + patchSize;
                        var ch = (y - cy) + rowHight + patchSize;

                        var map = new Area2DMapBuilder()
                            .InitNewMap(currentMap)
                            .ReduceDestArea(Area2D.Create(cx, cy, cw, ch), true)
                            .Build();

                        if (map.DestElementsCount > 0)
                        {
                            newMappings.Add(map);
                        }
                    }
                }

                // Combine small mappings
                var bins = BinsPacker<Area2DMap>.Pack(newMappings, m => m.DestElementsCount, maxPointsPerProcess);
                newMappings.Clear();
                foreach (var bin in bins)
                {
                    var enumerable = bin as IList<Area2DMap> ?? bin.ToList();
                    if (enumerable.Count > 1)
                    {
                        newMappings.Add(
                            enumerable.Aggregate((m1, m2) => new Area2DMapBuilder()
                                .InitNewMap(m1)
                                .AddMapping(m2)
                                .Build()));
                    }
                    else
                    {
                        newMappings.Add(enumerable.First());
                    }
                }


                // Make a new input.
                for (int i = 0; i < newMappings.Count; i++)
                {
                    var map = newMappings[i];

                    if (map.DestElementsCount > 0)
                    {
                        result.Add(map);
                    }
                }
            }
            else
            {
                result.Add(currentMap);
            }

            return result;
        }