Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.BinPacking/HeuristicLab.Problems.BinPacking/3.3/Decoders/2D/EP/ExtremePointsFunctions2D.cs @ 9495

Last change on this file since 9495 was 9495, checked in by jhelm, 11 years ago

#1966: Did some major refactoring in Decoder-classes; Added MoveEvaluator classes for different encodings and dimensions; Added new crossover-class for MCV encoding;

File size: 16.2 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Collections;
6using HeuristicLab.Core;
7using HeuristicLab.Encodings.PackingEncoding.GroupingVector;
8using HeuristicLab.Encodings.PackingEncoding.MultiComponentVector;
9using HeuristicLab.Encodings.PackingEncoding.PackingSequence;
10using HeuristicLab.Problems.BinPacking.Dimensions;
11using HeuristicLab.Problems.BinPacking.Interfaces;
12using HeuristicLab.Problems.BinPacking.PackingBin;
13using HeuristicLab.Problems.BinPacking.PackingItem;
14using HeuristicLab.Problems.BinPacking.Shapes;
15
16namespace HeuristicLab.Problems.BinPacking.Decoders {
17  public static class ExtremPointsFunctions2D {
18
19
20
21
22    public static ObservableDictionary<int, TwoDimensionalPacking> ExtremePointBasedPacking(MultiComponentVectorEncoding solution,
23        ItemList<RectangularPackingItem> itemMeasures, RectangularPackingBin binMeasures) {
24
25      #region Preperations
26          int nrOfBins = solution.NrOfBins;
27
28      //Get all indexes of items for every bin according to grouping-vector                     
29      Dictionary<int, List<PackingInformation>> unpackedItemIndexesPerBin = new Dictionary<int, List<PackingInformation>>();
30      Dictionary<int, HashSet<TwoDimensionalPacking>> extremePointsForBin = new Dictionary<int, HashSet<TwoDimensionalPacking>>();
31      var occupiedPoints = new List<int[,]>();
32
33      for (int i = 0; i < nrOfBins; i++) {       
34        unpackedItemIndexesPerBin[i] = new List<PackingInformation> (solution.PackingInformations[i]);
35
36        extremePointsForBin[i] = new HashSet<TwoDimensionalPacking>();
37        extremePointsForBin[i].Add(new TwoDimensionalPacking(i, 0, 0, false));
38        occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
39      }
40
41      ObservableDictionary<int, TwoDimensionalPacking> itemPositions = new ObservableDictionary<int, TwoDimensionalPacking>();
42      var remainingItems = new List<PackingInformation>();
43
44      #endregion Preperations
45
46
47      //Iterate over all bin-lists
48      for (int binNr = 0; binNr < nrOfBins; binNr++) {
49        //Iterate over the current bin-item-list and find feasible positions in the current bin for each item
50        var unpackedItems = unpackedItemIndexesPerBin[binNr];
51        for (int i = 0; i < unpackedItems.Count; i++) {
52          var itemIndex = unpackedItems[i].ItemID;
53          var item = itemMeasures[itemIndex];
54
55          extremePointsForBin[binNr] = OrderExtremePoints(extremePointsForBin[binNr], occupiedPoints, binMeasures);
56          var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePointsForBin[binNr], occupiedPoints, itemPositions, unpackedItems[i].Rotated);
57          if (positionFound != null) {
58            extremePointsForBin[binNr].Remove(positionFound);
59            itemPositions[itemIndex] = positionFound;
60            occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
61            extremePointsForBin[binNr] = GenerateNewExtremePointsForNewItem(extremePointsForBin[binNr], occupiedPoints, item, positionFound, binMeasures);
62          } else {
63            remainingItems.Add(unpackedItems[i]);
64            solution.PackingInformations[binNr].Remove(unpackedItems[i]);
65          }
66        }
67      }
68
69
70      //Packing of remaining items   
71      //Iterate over all bin-lists
72      for (int binNr = 0; binNr < nrOfBins && remainingItems.Count > 0; binNr++) {
73        var unpackedItems = new List<PackingInformation>(remainingItems);
74        //Iterate over all the remaining items
75        for (int i = 0; i < unpackedItems.Count; i++) {
76          var itemIndex = unpackedItems[i].ItemID;
77          var item = itemMeasures[itemIndex];
78
79          extremePointsForBin[binNr] = OrderExtremePoints(extremePointsForBin[binNr], occupiedPoints, binMeasures);
80          var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePointsForBin[binNr], occupiedPoints, itemPositions, unpackedItems[i].Rotated);
81          if (positionFound != null) {
82            extremePointsForBin[binNr].Remove(positionFound);
83            itemPositions[itemIndex] = positionFound;
84            occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
85            extremePointsForBin[binNr] = GenerateNewExtremePointsForNewItem(extremePointsForBin[binNr], occupiedPoints, item, positionFound, binMeasures);
86            remainingItems.Remove(unpackedItems[i]);
87            solution.PackingInformations[binNr].Add(unpackedItems[i]);
88          }
89        }
90        if (remainingItems.Count > 0 && binNr + 1 >= nrOfBins) {
91          extremePointsForBin[nrOfBins] = new HashSet<TwoDimensionalPacking>();
92          extremePointsForBin[nrOfBins].Add(new TwoDimensionalPacking(nrOfBins, 0, 0, false));
93          occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
94          solution.PackingInformations[nrOfBins] = new ItemList<PackingInformation>();
95          nrOfBins++;
96        }
97      }
98
99      return itemPositions;
100    }
101
102
103    public static ObservableDictionary<int, TwoDimensionalPacking> ExtremePointBasedPacking(GroupingVectorEncoding solution,
104        ItemList<RectangularPackingItem> itemMeasures, RectangularPackingBin binMeasures) {
105
106      #region Preperations
107      int nrOfBins = solution.GroupingVector.Max() + 1;
108
109      //Get all indexes of items for every bin according to grouping-vector
110      Dictionary<int, List<int>> unpackedItemIndexesPerBin = new Dictionary<int, List<int>>();   
111      Dictionary<int, HashSet<TwoDimensionalPacking>> extremePointsForBin = new Dictionary<int, HashSet<TwoDimensionalPacking>>();
112      var occupiedPoints = new List<int[,]>();
113
114      for (int i = 0; i < nrOfBins; i++) {
115        unpackedItemIndexesPerBin[i] = solution.GroupingVector
116          .Select((Value, Index) => new { Value, Index })
117          .Where(temp => temp.Value == i)
118          .Select(temp => temp.Index).ToList();
119
120        extremePointsForBin[i] = new HashSet<TwoDimensionalPacking>();
121        extremePointsForBin[i].Add(new TwoDimensionalPacking(i, 0, 0, false));   
122        occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
123      }
124
125      ObservableDictionary<int, TwoDimensionalPacking> itemPositions = new ObservableDictionary<int, TwoDimensionalPacking>();
126      var remainingItems = new List<int>();
127
128      #endregion Preperations
129
130             
131
132      //Iterate over all bin-lists
133      for (int binNr = 0; binNr < nrOfBins; binNr++) {
134        //Iterate over the current bin-item-list and find feasible positions in the current bin for each item
135        var unpackedItems = unpackedItemIndexesPerBin[binNr];
136        for (int i = 0; i < unpackedItems.Count; i++) {
137          var itemIndex = unpackedItems[i];
138          var item = itemMeasures[itemIndex];
139
140          extremePointsForBin[binNr] = OrderExtremePoints(extremePointsForBin[binNr], occupiedPoints, binMeasures);
141          var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePointsForBin[binNr], occupiedPoints, itemPositions);
142          if (positionFound != null) {
143            extremePointsForBin[binNr].Remove(positionFound);
144            itemPositions[itemIndex] = positionFound;
145            occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
146            extremePointsForBin[binNr] = GenerateNewExtremePointsForNewItem(extremePointsForBin[binNr], occupiedPoints, item, positionFound, binMeasures);
147          } else
148            remainingItems.Add(itemIndex);
149        }
150      }
151
152
153
154      //Packing of remaining items   
155      //Iterate over all bin-lists
156      for (int binNr = 0; binNr < nrOfBins && remainingItems.Count > 0; binNr++) {
157        var unpackedItems = new List<int>(remainingItems);
158        //Iterate over all the remaining items
159        for (int i = 0; i < unpackedItems.Count; i++) {
160          var itemIndex = unpackedItems[i];
161          var item = itemMeasures[itemIndex];
162
163          extremePointsForBin[binNr] = OrderExtremePoints(extremePointsForBin[binNr], occupiedPoints, binMeasures);
164          var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePointsForBin[binNr], occupiedPoints, itemPositions);
165          if (positionFound != null) {
166            extremePointsForBin[binNr].Remove(positionFound);
167            itemPositions[itemIndex] = positionFound;
168            occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
169            extremePointsForBin[binNr] = GenerateNewExtremePointsForNewItem(extremePointsForBin[binNr], occupiedPoints, item, positionFound, binMeasures);       
170            remainingItems.Remove(itemIndex);
171          }
172        }
173        if (remainingItems.Count > 0 && binNr + 1 >= nrOfBins) {
174          extremePointsForBin[nrOfBins] = new HashSet<TwoDimensionalPacking>();
175          extremePointsForBin[nrOfBins].Add(new TwoDimensionalPacking(nrOfBins, 0, 0, false));
176          occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
177          nrOfBins++;
178        }
179      }
180
181      return itemPositions;
182    }
183
184
185    public static ObservableDictionary<int, TwoDimensionalPacking> ExtremePointBasedPacking(PackingSequenceEncoding solution,
186        ItemList<RectangularPackingItem> itemMeasures, RectangularPackingBin binMeasures) {
187
188      #region Preperations
189      var itemPositions = new ObservableDictionary<int, TwoDimensionalPacking>(); 
190      int nrOfBins = 1;
191
192      var occupiedPoints = new List<int[,]>();
193      occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
194
195      HashSet<TwoDimensionalPacking> extremePoints = new HashSet<TwoDimensionalPacking>();
196      extremePoints.Add(new TwoDimensionalPacking(0, 0, 0, false));
197      #endregion
198
199      foreach (int itemIndex in solution.PackingSequence) {
200        var item = itemMeasures[itemIndex];
201        extremePoints = OrderExtremePoints(extremePoints, occupiedPoints, binMeasures);
202        var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePoints, occupiedPoints, itemPositions);
203        if (positionFound != null) {
204          extremePoints.Remove(positionFound);
205        }
206        else {
207          positionFound = new TwoDimensionalPacking(nrOfBins, 0, 0);
208          occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
209          nrOfBins++;
210        }
211        itemPositions[itemIndex] = positionFound;
212        occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
213        extremePoints = GenerateNewExtremePointsForNewItem(extremePoints, occupiedPoints, item, positionFound, binMeasures);
214      }
215
216      return itemPositions;
217    }
218
219
220    private static TwoDimensionalPacking FindExtremePointForItem(int itemIndex, ItemList<RectangularPackingItem> itemMeasures, RectangularPackingBin binMeasures,
221        HashSet<TwoDimensionalPacking> extremePoints, List<int[,]> occupiedPoints, ObservableDictionary<int, TwoDimensionalPacking> itemPositions) {
222          return FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePoints, occupiedPoints, itemPositions, false);
223    }
224    private static TwoDimensionalPacking FindExtremePointForItem(int itemIndex, ItemList<RectangularPackingItem> itemMeasures, RectangularPackingBin binMeasures,
225        HashSet<TwoDimensionalPacking> extremePoints, List<int[,]> occupiedPoints, ObservableDictionary<int, TwoDimensionalPacking> itemPositions, bool rotated) {
226
227      var itemFromList = itemMeasures[itemIndex];
228      RectangularPackingItem item = new RectangularPackingItem(
229        rotated ? itemFromList.Height : itemFromList.Width,
230        rotated ? itemFromList.Width : itemFromList.Height,
231        itemFromList.TargetBin);
232
233      int epIndex = 0;
234      while (epIndex < extremePoints.Count &&
235        (!BottomLeftFunctions.IsPositionFeasible(binMeasures, extremePoints.ElementAt(epIndex).AssignedBin, item, extremePoints.ElementAt(epIndex), itemPositions, itemMeasures)))
236      { epIndex++; }
237
238      if (epIndex < extremePoints.Count) {
239        var result = extremePoints.ElementAt(epIndex);
240        result.Rotated = rotated;
241        return result;
242      }
243      return null;
244    }
245    private static List<int[,]> IncreaseBinCountForOccupiedPoints(List<int[,]> occupiedPoints, RectangularPackingBin binMeasures) {
246      occupiedPoints.Add(new int[binMeasures.Width, binMeasures.Height]);
247      int lastIndex = occupiedPoints.Count - 1;
248      for (int w = 0; w < binMeasures.Width; w++) {
249        for (int h = 0; h < binMeasures.Height; h++) {
250            occupiedPoints[lastIndex][w, h] = -1;
251        }
252      }
253      return occupiedPoints;
254    }
255    private static List<int[,]>  OccupyPointsForNewItem(List<int[,]> occupiedPoints, RectangularPackingItem newItem, TwoDimensionalPacking position, int itemIndex) {
256      int width = position.Rotated ? newItem.Height : newItem.Width;
257      int height = position.Rotated ? newItem.Width : newItem.Height;
258      for (int w = position.X; w < position.X + width; w++) {
259        for (int h = position.Y; h < position.Y + height; h++) {
260            occupiedPoints[position.AssignedBin][w,h] = itemIndex;
261        }
262      }
263      return occupiedPoints;
264    }
265    private static HashSet<TwoDimensionalPacking> GenerateNewExtremePointsForNewItem(HashSet<TwoDimensionalPacking> extremePoints, List<int[,]> occupiedPoints,
266        RectangularPackingItem newItem, TwoDimensionalPacking position, RectangularPackingBin binMeasures) {
267      int currentBin = position.AssignedBin;
268
269      int newWidth = position.Rotated ? newItem.Height : newItem.Width;
270      int newHeight = position.Rotated ? newItem.Width : newItem.Height;
271
272      //Find ExtremePoints beginning from sourcepointX
273      var sourcePointX = new TwoDimensionalPacking(currentBin, position.X + newWidth, position.Y);
274      if (sourcePointX.X < binMeasures.Width && sourcePointX.Y < binMeasures.Height) {
275        //Traversing down the y-axis                                                                           
276        int currentYValue = sourcePointX.Y;
277        while (currentYValue > 0 && occupiedPoints[currentBin][sourcePointX.X, currentYValue] == -1) {
278          currentYValue--;
279        }
280        extremePoints.Add(new TwoDimensionalPacking(currentBin, sourcePointX.X, currentYValue));
281      }
282
283
284
285
286      //Find ExtremePoints beginning from sourcepointY
287      var sourcePointY = new TwoDimensionalPacking(currentBin, position.X, position.Y + newItem.Height);
288      if (sourcePointY.X < binMeasures.Width && sourcePointY.Y < binMeasures.Height) {
289        //Traversing down the x-axis 
290        int currentXValue = sourcePointY.X;
291        while (currentXValue > 0 && occupiedPoints[currentBin][currentXValue - 1, sourcePointY.Y] == -1) {
292          currentXValue--;
293        }
294        extremePoints.Add(new TwoDimensionalPacking(currentBin, currentXValue, sourcePointY.Y));
295      }
296
297
298      return extremePoints;
299    }
300
301    public static HashSet<TwoDimensionalPacking> OrderExtremePoints(HashSet<TwoDimensionalPacking> hashSet, List<int[,]> occupiedPoints, RectangularPackingBin binMeasures) {
302      return new HashSet<TwoDimensionalPacking>(hashSet.OrderBy(ep => ep.AssignedBin).ThenBy(ep => ep.X).ThenBy(ep => ep.Y).ThenBy(ep => ShortestPossibleSideFromEP(ep, occupiedPoints, binMeasures)));
303    }
304    private static int ShortestPossibleSideFromEP(TwoDimensionalPacking ep, List<int[,]> occupiedPoints, RectangularPackingBin binMeasures) {
305      int shortestSide = int.MaxValue;
306
307      if (ep.X >= binMeasures.Width || ep.Y >= binMeasures.Height)
308        return shortestSide;
309
310      int currentX = ep.X;
311      while (currentX < binMeasures.Width && occupiedPoints[ep.AssignedBin][currentX, ep.Y] == -1) { currentX++; }   
312      if (currentX - ep.X < shortestSide)
313        shortestSide = currentX - ep.X;
314
315      int currentY = ep.Y;
316      while (currentY < binMeasures.Height && occupiedPoints[ep.AssignedBin][ep.X, currentY] == -1) { currentY++;  }
317      if (currentY - ep.Y < shortestSide)
318        shortestSide = currentY - ep.Y;
319
320      return shortestSide;
321    }
322  }
323}
Note: See TracBrowser for help on using the repository browser.