예제 #1
0
        int MaxPatterns(Pattern2d pattern, Dictionary <Rect, int> residualDemand)
        {
            int max = int.MaxValue;

            foreach (var item in pattern.Blanks)
            {
                var demRef  = residualDemand.Where(x => x.Key.Equals(item)).FirstOrDefault().Key;
                var count   = pattern.Blanks.Count(x => x.Width == item.Width && x.Height == item.Height);
                var demand  = residualDemand[demRef];
                var thisMax = demand / count;
                if (thisMax < max)
                {
                    max = thisMax;
                }
            }
            return(max);
        }
예제 #2
0
 bool DoAnyBlanksFit(Pattern2d pattern, List <Rect> blanks)
 {
     foreach (var space in pattern.Spaces)
     {
         foreach (var blank in blanks)
         {
             if (_algservice.FitsWidthToHeight(blank, space))
             {
                 return(true);
             }
             if (_algservice.FitsWidthToWidth(blank, space))
             {
                 return(true);
             }
         }
     }
     return(false);
 }/*
예제 #3
0
        public int MaxPatterns(Pattern2d pattern, Dictionary <Rect, int> residualDemand, List <Rect> demandReference)
        {
            int max = int.MaxValue;

            foreach (var item in demandReference)
            {
                var count = pattern.Blanks.Count(x => x.Equals(item));


                var demand  = residualDemand[item];
                var thisMax = demand / count;
                if (thisMax < max)
                {
                    max = thisMax;
                }
            }

            return(max);
        }
예제 #4
0
        public void ProcessOld()
        {
            _master        = new Rect();
            _master.Width  = 96;
            _master.Height = 48;
            Pattern2d pattern = new Pattern2d();
            var       rect1   = new Rect();

            rect1.X      = 0;
            rect1.Y      = 0;
            rect1.Height = 10;
            rect1.Width  = 20;
            var rect2 = new Rect();

            rect2.X      = 20;
            rect2.Y      = 0;
            rect2.Height = 10;
            rect2.Width  = 20;
            var rect3 = new Rect();

            rect3.X      = 20;
            rect3.Y      = 20;
            rect3.Height = 27;
            rect3.Width  = 55;
            var rect4 = new Rect();

            rect4.X        = 77;
            rect4.Y        = 20;
            rect4.Height   = 10;
            rect4.Width    = 10;
            pattern.Blanks = new List <Rect>();
            pattern.Blanks.Add(rect1);
            pattern.Blanks.Add(rect2);
            pattern.Blanks.Add(rect3);
            pattern.Blanks.Add(rect4);
            SetSpaces(pattern, _master);
        }
예제 #5
0
        public List <PatternDemand2d> Process()
        {
            _patternDemands = new List <PatternDemand2d>();
            var  addedBlanks       = new List <Rect>();
            var  residualDemand    = new Dictionary <Rect, int>(_demand);
            bool allDemandComplete = false;
            Rect newBlank          = null;

            while (!allDemandComplete)
            {
                //var orderedSizes = residualDemand.Where(x => x.Value > 0).Select(x => x.Key).OrderBy(x => x.Height * x.Width).ToList(); //ordered by area
                var orderedSizes = _sort(residualDemand.Where(x => x.Value > 0).Select(x => x.Key).ToList()).ToList();

                var stack = new Stack <Rect>(orderedSizes);
                stack.Reverse();

                var pattern = new Pattern2d();
                addedBlanks    = new List <Rect>();
                pattern.Master = _master;
                pattern.SetMasterSpace();
                bool masterIsComplete = false;
                while (!masterIsComplete)
                {
                    if (stack.Count == 0)
                    {
                        masterIsComplete = true;
                    }
                    else
                    {
                        newBlank = stack.Pop();
                        var tempDemand = residualDemand[newBlank];
                        if (tempDemand == 0)
                        {
                            continue;
                        }
                        bool blankFits = true;


                        while (blankFits)
                        {
                            var blankCopy = new Rect(newBlank);
                            if (pattern.Blanks.Count > 0)
                            {
                                SetSpaces(pattern, _master);
                            }

                            blankFits = false;
                            var longSide  = blankCopy.Width >= blankCopy.Width ? blankCopy.Width : blankCopy.Y;
                            var shortSide = longSide == blankCopy.Width ? blankCopy.Height : blankCopy.Width;

                            var orderedSpaces = pattern.Spaces.OrderBy(x => x.Y).ThenBy(x => x.X);
                            foreach (var space in orderedSpaces)
                            {
                                if (FitsLongToHeight(blankCopy, space, longSide, shortSide)) //
                                {
                                    blankFits = true;
                                }
                                else if (FitsShortToHeight(blankCopy, space, longSide, shortSide))
                                {
                                    blankFits = true;
                                }

                                if (blankFits == true)
                                {
                                    blankCopy.X = space.X;
                                    blankCopy.Y = space.Y;
                                    pattern.Blanks.Add(blankCopy);
                                    if (!addedBlanks.Contains(newBlank))
                                    {
                                        addedBlanks.Add(newBlank);
                                    }
                                    tempDemand--;
                                    break;
                                }
                            }
                            if (tempDemand == 0)
                            {
                                break;
                            }
                        }
                    }
                    if (masterIsComplete)
                    {
                        if (pattern.Blanks.Count > 0)
                        {
                            SetSpaces(pattern, _master);
                        }
                        var max = MaxPatterns(pattern, residualDemand, addedBlanks);
                        foreach (var i in addedBlanks)
                        {
                            var sub = max * pattern.Blanks.Count(x => x.Equals(i));
                            residualDemand[i] -= sub;
                        }
                        _patternDemands.Add(new PatternDemand2d {
                            Pattern = pattern, Demand = max
                        });
                        if (residualDemand.Count(x => x.Value > 0) == 0)
                        {
                            allDemandComplete = true;
                        }
                    }
                }
            }
            return(_patternDemands);
        }
예제 #6
0
        public void SetSpaces(Pattern2d pattern, Rect master)
        {
            var spaces       = pattern.Spaces = new List <Rect>();
            var blanks       = pattern.Blanks;
            var sortedBlanks = blanks.OrderBy(blank => blank.X).ThenBy(blank => blank.Y);


            if (blanks.Exists(x => x.Height == 1))
            {
            }

            if (blanks.Count == 0)
            {
                var space = new Rect();
                space.X      = 0;
                space.Y      = 0;
                space.Width  = master.Width;
                space.Height = master.Height;
                spaces.Add(space);
            }
            var rotate = false;

            foreach (var blank in sortedBlanks)
            {
                if (blank.Height > blank.Width)
                {
                    blank.Rotate();
                    rotate = true;
                }
                var space = new Rect();
                space.X = blank.X;
                space.Y = blank.Y + blank.Height;
                var firstBlankAbove = GetFirstBlockGoingUp(blank, blanks);
                if (firstBlankAbove == null)
                {
                    space.Height = master.Height - space.Y;
                }
                else
                {
                    space.Height = firstBlankAbove.Y - space.Y;
                }
                var firstBlankRight = GetFirstBlockGoingRight(space, blanks);
                if (firstBlankRight == null)
                {
                    space.Width = master.Width - space.X;
                }
                else
                {
                    space.Width = firstBlankRight.X - space.X;
                }
                if (space.Height > 0 && space.Width > 0)
                {
                    spaces.Add(space);
                }

                space           = new Rect();
                space.X         = blank.X + blank.Width;
                space.Y         = blank.Y;
                firstBlankRight = GetFirstBlockGoingRight(blank, blanks);
                if (firstBlankRight == null)
                {
                    space.Width = master.Width - space.X;
                }
                else
                {
                    space.Width = firstBlankRight.X - space.X;
                }
                if (space.Height > 0 && space.Width > 0)
                {
                    spaces.Add(space);
                }

                firstBlankAbove = GetFirstBlockGoingUp(space, blanks);
                if (firstBlankAbove == null)
                {
                    space.Height = master.Height - space.Y;
                }
                else
                {
                    space.Height = firstBlankAbove.Y - space.Y;
                }
                if (space.Height > 0 && space.Width > 0)
                {
                    spaces.Add(space);
                }

                if (rotate)
                {
                    blank.Rotate();
                }
            }

            foreach (var blank in pattern.Blanks)
            {
                if (pattern.Spaces.Count(x => x.X == blank.X && x.Y == blank.Y) > 0)
                {
                }
            }
        }
예제 #7
0
        public Pattern2d Shuffle(Pattern2d pattern)
        {
            //demand should be set to the removed pattern
            Pattern2d shuffled = new Pattern2d();

            shuffled.Master = _master;

            List <Rect> randBlanks = new List <Rect>(pattern.Blanks);
            List <Func <Rect, Rect, double, double, bool> > fitFns = new List <Func <Rect, Rect, double, double, bool> >();

            fitFns.Add(FitsLongToHeight);
            fitFns.Add(FitsShortToHeight);

            Random ran       = new Random();
            var    ranBlanks = randBlanks.Shuffle();
            bool   added     = true;

            for (int i = 0; i < ranBlanks.Length; ++i)
            {
                List <int> fitFunHelper = new List <int> {
                    0, 1
                };
                var blank     = ranBlanks[i];
                var longSide  = blank.Width >= blank.Width ? blank.Width : blank.Y;
                var shortSide = longSide == blank.Width ? blank.Height : blank.Width;

                if (added == true)
                {
                    SetSpaces(shuffled, _master);
                }
                added = false;
                var shuSpaces = shuffled.Spaces.Shuffle();
                if (shuSpaces.Length == 0)
                {
                    break;
                }
                var spaceIndex = ran.Next(0, shuSpaces.Length);
                var space      = shuSpaces[spaceIndex];
                var fitnum     = ran.Next(0, 2);
                if (fitFns[fitnum](blank, space, longSide, shortSide))
                {
                    var newBlank = new Rect(blank);
                    newBlank.X = space.X;
                    newBlank.Y = space.Y;
                    shuffled.Blanks.Add(newBlank);
                    added = true;
                }
                else
                {
                    fitFunHelper.Remove(fitnum);
                    if ((fitFns[fitFunHelper.First()](blank, space, longSide, shortSide)))
                    {
                        var newBlank = new Rect(blank);
                        newBlank.X = space.X;
                        newBlank.Y = space.Y;
                        shuffled.Blanks.Add(newBlank);
                        added = true;
                    }
                }
            }
            SetSpaces(shuffled, _master);
            return(shuffled);
        }
예제 #8
0
 void RemovePatternFromDemands(Pattern2d pattern)
 {
     _patternDemands.RemoveAll(x => x.Pattern == pattern);
 }
예제 #9
0
 void SetDemand(Pattern2d pattern, int demand)
 {
     _patternDemands.FirstOrDefault(x => x.Pattern == pattern).Demand = demand;
 }
예제 #10
0
 void AddPatternDemand(Pattern2d pattern, int demand)
 {
     _patternDemands.Add(new PatternDemand2d {
         Pattern = pattern, Demand = demand
     });
 }
예제 #11
0
        }/*
          * void SubtractDemand(Pattern2d oldPattern, Pattern2d newPattern, Rect newBlank, Dictionary<Rect, int> residualDemand)
          * {
          * var maxNew = residualDemand[newBlank];
          * var maxOld = GetDemand(oldPattern);
          * var needKeepOldPattern = maxNew < maxOld ? true : false;
          *
          * if (oldPattern.Blanks.Count == 0) //if new pattern
          * {
          *     _patternComplete.Remove(oldPattern);
          *     RemovePatternFromDemands(oldPattern);
          *     AddPatternDemand(newPattern, int.MaxValue);
          *     residualDemand[newBlank]--;
          *     _patternComplete.Add(newPattern, false);
          *     _lastPatternAdded = newPattern;
          *     _lastBlankAdded = newBlank;
          *     return;
          * }
          * if (maxOld == int.MaxValue)
          * {
          *     if (_lastPatternAdded == oldPattern && _lastBlankAdded.Equals(newBlank))
          *     {
          *         _patternComplete.Remove(oldPattern);
          *         RemovePatternFromDemands(oldPattern);
          *         AddPatternDemand(newPattern, maxOld);
          *     }
          *     else //maxvalue and not the same
          *     {
          *
          *     }
          * }
          *
          * if (needKeepOldPattern) //using up all of new blank
          * {
          *     _patternDemands.Add(new PatternDemand2d { Pattern = newPattern, Demand = maxNew });
          *     _patternComplete.Add(newPattern, false);
          *
          *     _lastPatternAdded = newPattern;
          *     _lastBlankAdded = newBlank;
          * }
          * else //max of new >= to the old count, never if the pattern was empty
          * {
          *     _patternComplete.Remove(oldPattern);
          *     RemovePatternFromDemands(oldPattern);
          *     AddPatternDemand(newPattern, maxOld);
          * }
          * residualDemand[newBlank] -= maxNew;
          * }
          */

        int GetDemand(Pattern2d pattern)
        {
            return(_patternDemands.FirstOrDefault(x => x.Pattern == pattern).Demand);
        }
예제 #12
0
        public List <PatternDemand2d> Process(Dictionary <Rect, int> demand, Func <List <Rect>, List <Rect> > sort, Rect master, Predicate <int> rotate)
        {
            _patternComplete = new Dictionary <Pattern2d, bool>();
            _patternDemands  = new List <PatternDemand2d>(); //return this
            var  addedBlanks       = new List <Rect>();
            var  residualDemand    = new Dictionary <Rect, int>(demand);
            bool allDemandComplete = false;
            Rect newBlank          = null;

            while (!allDemandComplete)
            {
                if (residualDemand.Sum(x => x.Value) == 0)
                {
                    break;
                }
                //var orderedSizes = residualDemand.Where(x => x.Value > 0).Select(x => x.Key).OrderBy(x => x.Height * x.Width).ToList(); //ordered by area
                var orderedSizes = sort(residualDemand.Where(x => x.Value > 0).Select(x => x.Key).ToList()).ToList(); //sort blanks, remove demand = 0

                var stack = new Stack <Rect>(orderedSizes);

                //choose pattern to fill based on largest space

                if (_patternDemands.Count(x => x.Pattern.Blanks.Count == 16) > 0)
                {
                }
                foreach (var pat in _patternDemands)
                {
                    if (!_patternComplete.ContainsKey(pat.Pattern))
                    {
                    }
                }

                var patsBySumOfUsedArea = _patternDemands.OrderBy(x => x.Pattern.Blanks.Sum(z => z.Height * z.Width));
                var parentPatterns      = patsBySumOfUsedArea
                                          .Where(x => !_patternComplete[x.Pattern])
                                          .Select(x => x.Pattern).ToList();//order by largest area of space that's not complete

                var parentPattern = parentPatterns.FirstOrDefault();
                var isNewPattern  = false;
                if (parentPattern == null)
                {
                    parentPattern = new Pattern2d();
                    //_patternDemands.Add(new PatternDemand2d { Pattern = parentPattern, Demand = int.MaxValue });
                    //_patternComplete.Add(parentPattern, false);
                    parentPattern.Master = master;
                    parentPattern.SetMasterSpace();
                    isNewPattern = true;

                    parentPatterns.Add(parentPattern);
                }



                //_patternMaxCount.Add(pattern, int.MaxValue);


                var newPattern = parentPattern.GetCopy();
                addedBlanks = new List <Rect>();

                bool masterIsComplete = false;


                bool blankFits = false;
                var  tryCount  = 0; //used in rotate, rotate first, rotate first 2 etc


                if (stack.Count == 0)
                {
                    masterIsComplete = true;
                }
                else
                {
                    foreach (var p in parentPatterns)
                    {
                        foreach (var size in orderedSizes)
                        {
                            newBlank      = size;
                            parentPattern = p;
                            newPattern    = parentPattern.GetCopy();

                            blankFits = false;
                            if (stack.Count == 0)
                            {
                            }

                            if (newBlank.Width == 48)
                            {
                            }
                            var tempDemand = residualDemand[newBlank];
                            if (tempDemand == 0)
                            {
                                continue; //pop next blank
                            }
                            var blankCopy = new Rect(size);
                            if (rotate(tryCount))
                            {
                                blankCopy.Rotate();
                            }

                            //if (pattern.Blanks.Count > 0)
                            //_algservice.SetSpaces(pattern, master);

                            var longSide  = blankCopy.Width >= blankCopy.Width ? blankCopy.Width : blankCopy.Y;
                            var shortSide = longSide == blankCopy.Width ? blankCopy.Height : blankCopy.Width;


                            var orderedSpaces = parentPattern.Spaces.OrderBy(x => x.Y).ThenBy(x => x.X);
                            foreach (var space in orderedSpaces)
                            {
                                if (_algservice.FitsWidthToWidth(blankCopy, space)) //
                                {
                                    blankFits = true;
                                }
                                else if (_algservice.FitsWidthToHeight(blankCopy, space))
                                {
                                    blankCopy.Rotate();
                                    blankFits = true;
                                }

                                if (blankFits == true)
                                {
                                    blankCopy.X = space.X;
                                    blankCopy.Y = space.Y;

                                    newPattern.Blanks.Add(blankCopy);

                                    //if (!addedBlanks.Contains(newBlank))
                                    addedBlanks.Add(newBlank);
                                    tempDemand--;
                                    break;
                                }
                            }
                            if (blankFits)
                            {
                                break;
                            }
                        }
                    }
                    if (!blankFits && !isNewPattern)
                    {
                        newPattern = new Pattern2d();
                        //_patternDemands.Add(new PatternDemand2d { Pattern = parentPattern, Demand = int.MaxValue });
                        //_patternComplete.Add(parentPattern, false);
                        newPattern.Master = master;
                        newPattern.SetMasterSpace();
                        isNewPattern = true;
                        _patternComplete.Add(newPattern, false);
                        AddPatternDemand(newPattern, 1);
                        continue;
                    }
                    if (newPattern.Blanks.Count(x => x.Height == 48 && x.Width == 48) == 1)
                    {
                    }
                    var samePattern     = _patternDemands.FirstOrDefault(x => x.Pattern.Equals(newPattern));
                    var parentPatDemand = _patternDemands.FirstOrDefault(x => x.Pattern.Equals(parentPattern));

                    if (samePattern != null)
                    {
                        samePattern.Demand++;
                        residualDemand[newBlank]--;
                        if (!isNewPattern)
                        {
                            parentPatDemand.Demand--;
                        }
                    }
                    else
                    {
                        if (!isNewPattern)
                        {
                            parentPatDemand.Demand--;

                            AddPatternDemand(newPattern, 1);
                            residualDemand[newBlank]--;
                        }
                        else //new pattern without any same already added
                        {
                            //RemovePatternFromDemands(parentPattern);
                            //_patternComplete.Remove(parentPattern);
                            AddPatternDemand(newPattern, 1);
                            residualDemand[newBlank]--;
                        }

                        _patternComplete.Add(newPattern, false);
                    }
                    if (!isNewPattern && parentPatDemand.Demand == 0)
                    {
                        RemovePatternFromDemands(parentPattern);
                        _patternComplete.Remove(parentPattern);
                    }


                    //SubtractDemand(parentPattern, newPattern, newBlank, residualDemand);


                    _algservice.SetSpaces(parentPattern, master);
                    _algservice.SetSpaces(newPattern, master);

                    var completedPat = new List <Pattern2d>();
                    foreach (var pd in _patternComplete.Where(x => x.Value == false))
                    {
                        if (!DoAnyBlanksFit(pd.Key, residualDemand.Where(x => x.Value > 0).Select(x => x.Key).ToList()))
                        {
                            completedPat.Add(pd.Key);
                        }
                    }
                    completedPat.ForEach(x => _patternComplete[x] = true);
                }

                _algservice.SetSpaces(parentPattern, master);
                _algservice.SetSpaces(newPattern, master);

                //if (blankFits == true)
                {
                    /*
                     * if (masterIsComplete)
                     * {
                     *  if (pattern.Blanks.Count > 0)
                     *      _algservice.SetSpaces(pattern, master);
                     *  var max = _algservice.MaxPatterns(pattern, residualDemand, addedBlanks);
                     *  foreach (var i in addedBlanks)
                     *  {
                     *      var sub = max * pattern.Blanks.Count(x => x.Equals(i));
                     *      residualDemand[i] -= sub;
                     *
                     *  }
                     *  _patternDemands.Add(new PatternDemand2d { Pattern = pattern, Demand = max });
                     *  if (residualDemand.Count(x => x.Value > 0) == 0)
                     *      allDemandComplete = true;
                     * }*/
                }
            }

            return(_patternDemands);
        }