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); }
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); }/*
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); }
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); }
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); }
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) { } } }
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); }
void RemovePatternFromDemands(Pattern2d pattern) { _patternDemands.RemoveAll(x => x.Pattern == pattern); }
void SetDemand(Pattern2d pattern, int demand) { _patternDemands.FirstOrDefault(x => x.Pattern == pattern).Demand = demand; }
void AddPatternDemand(Pattern2d pattern, int demand) { _patternDemands.Add(new PatternDemand2d { Pattern = pattern, Demand = demand }); }
}/* * 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); }
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); }