Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.BinPacking/HeuristicLab.Problems.BinPacking/3.3/Decoders/3D/EP/ExtremePointsFunctions3D.cs @ 9473

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

#1966: Fixed some problems in MCV-move operators; Added parts of potvin-encoding implementation;

File size: 27.7 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Collections;
6using HeuristicLab.Core;
7using HeuristicLab.Encodings.IntegerVectorEncoding;
8using HeuristicLab.Encodings.PackingEncoding.GroupingVector;
9using HeuristicLab.Encodings.PackingEncoding.MultiComponentVector;
10using HeuristicLab.Encodings.PackingEncoding.PackingSequence;
11using HeuristicLab.Encodings.PackingEncoding.Potvin;
12using HeuristicLab.Problems.BinPacking.Dimensions;
13using HeuristicLab.Problems.BinPacking.Interfaces;
14using HeuristicLab.Problems.BinPacking.PackingBin;
15using HeuristicLab.Problems.BinPacking.PackingItem;
16using HeuristicLab.Problems.BinPacking.Shapes;
17
18namespace HeuristicLab.Problems.BinPacking.Decoders {
19  public static class ExtremePointsFunctions3D {
20
21
22
23    public static ObservableDictionary<int, ThreeDimensionalPacking> ExtremePointBasedPacking(ref PotvinEncoding solution,
24      ItemList<CuboidPackingItem> itemMeasures, CuboidPackingBin binMeasures) {
25        if (!solution.DelimiterInitialized) {
26          #region Preperations
27          var itemPositions = new ObservableDictionary<int, ThreeDimensionalPacking>();
28          int nrOfBins = 1;
29
30          var occupiedPoints = new List<int[, ,]>();
31          occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
32
33          HashSet<ThreeDimensionalPacking> extremePoints = new HashSet<ThreeDimensionalPacking>();
34          extremePoints.Add(new ThreeDimensionalPacking(0, 0, 0, 0, false));
35          #endregion
36
37          Dictionary<int, List<int>> itemIndexesForBin = new Dictionary<int, List<int>>();
38          itemIndexesForBin[0] = new List<int>();
39
40          foreach (int itemIndex in solution.IntVector) {
41            var item = itemMeasures[itemIndex];
42            extremePoints = OrderExtremePoints(extremePoints, occupiedPoints, binMeasures);
43            var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePoints, occupiedPoints, itemPositions);
44            if (positionFound != null) {
45              extremePoints.Remove(positionFound);
46            } else {
47              positionFound = new ThreeDimensionalPacking(nrOfBins, 0, 0, 0);
48              occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
49              itemIndexesForBin[nrOfBins] = new List<int>();
50              nrOfBins++;
51            }
52            itemPositions[itemIndex] = positionFound;
53            itemIndexesForBin[positionFound.AssignedBin].Add(itemIndex);
54            occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
55            extremePoints = GenerateNewExtremePointsForNewItem(extremePoints, occupiedPoints, item, positionFound, binMeasures);
56          }
57          List<int> intVector = new List<int>();
58          foreach (var indexes in itemIndexesForBin) {
59            foreach (var index in indexes.Value) {
60              intVector.Add(index);
61            }
62            intVector.Add(-1);
63          }
64          intVector.RemoveAt(intVector.Count - 1);
65          solution.IntVector = new IntegerVector (intVector.ToArray());
66
67          return itemPositions;
68        } else {
69          #region Preperations
70          int nrOfBins = solution.IntVector.Count(i => i.Equals (-1)) + 1;
71
72          //Get all indexes of items for every bin according to int vector
73          Dictionary<int, List<int>> unpackedItemIndexesPerBin = new Dictionary<int, List<int>>();
74          Dictionary<int, HashSet<ThreeDimensionalPacking>> extremePointsForBin = new Dictionary<int, HashSet<ThreeDimensionalPacking>>();
75          var occupiedPoints = new List<int[, ,]>();
76
77          int binCounter = 0;
78          unpackedItemIndexesPerBin[binCounter] = new List<int>();
79          for (int i = 0; i < solution.IntVector.Length; i++) {
80            if (solution.IntVector[i].Equals(-1)) {
81              unpackedItemIndexesPerBin[binCounter++] = new List<int>();
82              extremePointsForBin[i] = new HashSet<ThreeDimensionalPacking>();
83              extremePointsForBin[i].Add(new ThreeDimensionalPacking(i, 0, 0, 0, false));
84              occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
85            } else {
86              unpackedItemIndexesPerBin[binCounter].Add(solution.IntVector[i]);
87            }
88
89          }
90
91
92          ObservableDictionary<int, ThreeDimensionalPacking> itemPositions = new ObservableDictionary<int, ThreeDimensionalPacking>();
93          var remainingItems = new List<int>();
94
95          #endregion Preperations
96
97
98
99          //Iterate over all bin-lists
100          for (int binNr = 0; binNr < nrOfBins; binNr++) {
101            //Iterate over the current bin-item-list and find feasible positions in the current bin for each item
102            var unpackedItems = unpackedItemIndexesPerBin[binNr];
103            for (int i = 0; i < unpackedItems.Count; i++) {
104              var itemIndex = unpackedItems[i];
105              var item = itemMeasures[itemIndex];
106
107              extremePointsForBin[binNr] = OrderExtremePoints(extremePointsForBin[binNr], occupiedPoints, binMeasures);
108              var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePointsForBin[binNr], occupiedPoints, itemPositions);
109              if (positionFound != null) {
110                extremePointsForBin[binNr].Remove(positionFound);
111                itemPositions[itemIndex] = positionFound;
112                occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
113                extremePointsForBin[binNr] = GenerateNewExtremePointsForNewItem(extremePointsForBin[binNr], occupiedPoints, item, positionFound, binMeasures);
114              } else
115                remainingItems.Add(itemIndex);
116            }
117          }
118
119
120
121          //Packing of remaining items   
122          //Iterate over all bin-lists
123          for (int binNr = 0; binNr < nrOfBins && remainingItems.Count > 0; binNr++) {
124            var unpackedItems = new List<int>(remainingItems);
125            //Iterate over all the remaining items
126            for (int i = 0; i < unpackedItems.Count; i++) {
127              var itemIndex = unpackedItems[i];
128              var item = itemMeasures[itemIndex];
129
130              extremePointsForBin[binNr] = OrderExtremePoints(extremePointsForBin[binNr], occupiedPoints, binMeasures);
131              var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePointsForBin[binNr], occupiedPoints, itemPositions);
132              if (positionFound != null) {
133                extremePointsForBin[binNr].Remove(positionFound);
134                InsertItemgeneAfterLastItemgeneOfUsedBin(ref solution, itemIndex, binNr);
135                itemPositions[itemIndex] = positionFound;
136                occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
137                extremePointsForBin[binNr] = GenerateNewExtremePointsForNewItem(extremePointsForBin[binNr], occupiedPoints, item, positionFound, binMeasures);
138                remainingItems.Remove(itemIndex);
139              }
140            }
141            if (remainingItems.Count > 0 && binNr + 1 >= nrOfBins) {
142              extremePointsForBin[nrOfBins] = new HashSet<ThreeDimensionalPacking>();
143              extremePointsForBin[nrOfBins].Add(new ThreeDimensionalPacking(nrOfBins, 0, 0, 0, false));
144              occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
145              nrOfBins++;
146            }
147          }
148
149          return itemPositions;
150        }
151    }
152    private static void InsertItemgeneAfterLastItemgeneOfUsedBin(ref PotvinEncoding solution, int itemIndex, int binNr) {
153      List<int> temp = new List<int> (solution.IntVector);
154      temp.Remove(itemIndex);
155      var delimiterIndexes = temp.Select((value, index) => value == -1).Select((value, index) => index);
156      int insertionIndex = temp.Count;
157      if (binNr < delimiterIndexes.Count()) {
158        insertionIndex = delimiterIndexes.ElementAt(binNr);
159      }
160      temp.Insert(insertionIndex, itemIndex);
161      solution.IntVector = new IntegerVector (temp.ToArray());
162    }
163
164
165    public static ObservableDictionary<int, ThreeDimensionalPacking> ExtremePointBasedPacking(ref MultiComponentVectorEncoding solution,
166        ItemList<CuboidPackingItem> itemMeasures, CuboidPackingBin binMeasures) {
167
168      #region Preperations
169      int lowerBound = solution.PackingInformations.Max(x => x.AssignedBin);
170      int nrOfBins = lowerBound + 1;
171
172      //Get all indexes of items for every bin according to grouping-vector                     
173      Dictionary<int, List<PackingInformation>> unpackedItemIndexesPerBin = new Dictionary<int, List<PackingInformation>>();
174      Dictionary<int, HashSet<ThreeDimensionalPacking>> extremePointsForBin = new Dictionary<int, HashSet<ThreeDimensionalPacking>>();
175      var occupiedPoints = new List<int[, ,]>();
176
177      for (int i = 0; i < nrOfBins; i++) {       
178        unpackedItemIndexesPerBin[i] = solution.PackingInformations
179          .Where(pi => pi.AssignedBin == i)
180          .ToList();
181
182        extremePointsForBin[i] = new HashSet<ThreeDimensionalPacking>();
183        extremePointsForBin[i].Add(new ThreeDimensionalPacking(i, 0, 0, 0, false));
184        occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
185      }
186
187      ObservableDictionary<int, ThreeDimensionalPacking> itemPositions = new ObservableDictionary<int, ThreeDimensionalPacking>();
188      var remainingItems = new List<PackingInformation>();
189
190      #endregion Preperations
191
192
193      //Iterate over all bin-lists
194      for (int binNr = 0; binNr < nrOfBins; binNr++) {
195        //Iterate over the current bin-item-list and find feasible positions in the current bin for each item
196        var unpackedItems = unpackedItemIndexesPerBin[binNr];
197        for (int i = 0; i < unpackedItems.Count; i++) {
198          var itemIndex = unpackedItems[i].ItemIndex;
199          var item = itemMeasures[itemIndex];
200
201          extremePointsForBin[binNr] = OrderExtremePoints(extremePointsForBin[binNr], occupiedPoints, binMeasures);
202          var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePointsForBin[binNr], occupiedPoints, itemPositions, unpackedItems[i].Rotated);
203          if (positionFound != null) {
204            extremePointsForBin[binNr].Remove(positionFound);
205            itemPositions[itemIndex] = positionFound;
206            occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
207            extremePointsForBin[binNr] = GenerateNewExtremePointsForNewItem(extremePointsForBin[binNr], occupiedPoints, item, positionFound, binMeasures);
208          } else
209            remainingItems.Add(unpackedItems[i]);
210        }
211      }
212
213
214      //Packing of remaining items   
215      //Iterate over all bin-lists
216      for (int binNr = 0; binNr < nrOfBins && remainingItems.Count > 0; binNr++) {
217        var unpackedItems = new List<PackingInformation>(remainingItems);
218        //Iterate over all the remaining items
219        for (int i = 0; i < unpackedItems.Count; i++) {
220          var itemIndex = unpackedItems[i].ItemIndex;
221          var item = itemMeasures[itemIndex];
222
223          extremePointsForBin[binNr] = OrderExtremePoints(extremePointsForBin[binNr], occupiedPoints, binMeasures);
224          var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePointsForBin[binNr], occupiedPoints, itemPositions, unpackedItems[i].Rotated);
225          if (positionFound != null) {
226            extremePointsForBin[binNr].Remove(positionFound);
227            itemPositions[itemIndex] = positionFound;
228            occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
229            extremePointsForBin[binNr] = GenerateNewExtremePointsForNewItem(extremePointsForBin[binNr], occupiedPoints, item, positionFound, binMeasures);
230            remainingItems.Remove(unpackedItems[i]);
231            if (binNr <= lowerBound) {
232              InsertItemgeneAfterLastItemgeneOfUsedBin(ref solution, itemIndex, binNr);
233            }
234          }
235        }
236        if (remainingItems.Count > 0 && binNr + 1 >= nrOfBins) {
237          extremePointsForBin[nrOfBins] = new HashSet<ThreeDimensionalPacking>();
238          extremePointsForBin[nrOfBins].Add(new ThreeDimensionalPacking(nrOfBins, 0, 0, 0, false));
239          occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
240          nrOfBins++;
241        }
242      }
243
244      return itemPositions;
245    }
246    private static void InsertItemgeneAfterLastItemgeneOfUsedBin(ref MultiComponentVectorEncoding solution, int itemIndex, int binNr) {
247      var itemgene = solution.PackingInformations.Find(pi => pi.ItemIndex == itemIndex);
248      solution.PackingInformations.Remove (itemgene);
249      itemgene.AssignedBin = binNr;
250      int targetIndex = solution.PackingInformations.FindLastIndex(pi => pi.AssignedBin == binNr);
251      solution.PackingInformations.Insert(targetIndex + 1, itemgene);
252    }
253
254
255    public static ObservableDictionary<int, ThreeDimensionalPacking> ExtremePointBasedPacking(GroupingVectorEncoding solution,
256        ItemList<CuboidPackingItem> itemMeasures, CuboidPackingBin binMeasures) {
257
258      #region Preperations
259      int nrOfBins = solution.GroupingVector.Max() + 1;
260
261      //Get all indexes of items for every bin according to grouping-vector
262      Dictionary<int, List<int>> unpackedItemIndexesPerBin = new Dictionary<int, List<int>>();   
263      Dictionary<int, HashSet<ThreeDimensionalPacking>> extremePointsForBin = new Dictionary<int, HashSet<ThreeDimensionalPacking>>();
264      var occupiedPoints = new List<int[, ,]>();
265
266      for (int i = 0; i < nrOfBins; i++) {
267        unpackedItemIndexesPerBin[i] = solution.GroupingVector
268          .Select((Value, Index) => new { Value, Index })
269          .Where(temp => temp.Value == i)
270          .Select(temp => temp.Index).ToList();
271
272        extremePointsForBin[i] = new HashSet<ThreeDimensionalPacking>();
273        extremePointsForBin[i].Add(new ThreeDimensionalPacking(i, 0, 0, 0, false));   
274        occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
275      }
276
277      ObservableDictionary<int, ThreeDimensionalPacking> itemPositions = new ObservableDictionary<int, ThreeDimensionalPacking>();
278      var remainingItems = new List<int>();
279
280      #endregion Preperations
281
282             
283
284      //Iterate over all bin-lists
285      for (int binNr = 0; binNr < nrOfBins; binNr++) {
286        //Iterate over the current bin-item-list and find feasible positions in the current bin for each item
287        var unpackedItems = unpackedItemIndexesPerBin[binNr];
288        for (int i = 0; i < unpackedItems.Count; i++) {
289          var itemIndex = unpackedItems[i];
290          var item = itemMeasures[itemIndex];
291
292          extremePointsForBin[binNr] = OrderExtremePoints(extremePointsForBin[binNr], occupiedPoints, binMeasures);
293          var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePointsForBin[binNr], occupiedPoints, itemPositions);
294          if (positionFound != null) {
295            extremePointsForBin[binNr].Remove(positionFound);
296            itemPositions[itemIndex] = positionFound;
297            occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
298            extremePointsForBin[binNr] = GenerateNewExtremePointsForNewItem(extremePointsForBin[binNr], occupiedPoints, item, positionFound, binMeasures);
299          } else
300            remainingItems.Add(itemIndex);
301        }
302      }
303
304
305
306      //Packing of remaining items   
307      //Iterate over all bin-lists
308      for (int binNr = 0; binNr < nrOfBins && remainingItems.Count > 0; binNr++) {
309        var unpackedItems = new List<int>(remainingItems);
310        //Iterate over all the remaining items
311        for (int i = 0; i < unpackedItems.Count; i++) {
312          var itemIndex = unpackedItems[i];
313          var item = itemMeasures[itemIndex];
314
315          extremePointsForBin[binNr] = OrderExtremePoints(extremePointsForBin[binNr], occupiedPoints, binMeasures);
316          var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePointsForBin[binNr], occupiedPoints, itemPositions);
317          if (positionFound != null) {
318            extremePointsForBin[binNr].Remove(positionFound);
319            itemPositions[itemIndex] = positionFound;
320            occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
321            extremePointsForBin[binNr] = GenerateNewExtremePointsForNewItem(extremePointsForBin[binNr], occupiedPoints, item, positionFound, binMeasures);       
322            remainingItems.Remove(itemIndex);
323          }
324        }
325        if (remainingItems.Count > 0 && binNr + 1 >= nrOfBins) {
326          extremePointsForBin[nrOfBins] = new HashSet<ThreeDimensionalPacking>();
327          extremePointsForBin[nrOfBins].Add(new ThreeDimensionalPacking(nrOfBins, 0, 0, 0, false));
328          occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
329          nrOfBins++;
330        }
331      }
332
333      return itemPositions;
334    }
335
336
337    public static ObservableDictionary<int, ThreeDimensionalPacking> ExtremePointBasedPacking(PackingSequenceEncoding solution,
338        ItemList<CuboidPackingItem> itemMeasures, CuboidPackingBin binMeasures) {
339
340      #region Preperations
341      var itemPositions = new ObservableDictionary<int, ThreeDimensionalPacking>(); 
342      int nrOfBins = 1;
343
344      var occupiedPoints = new List<int[, ,]>();
345      occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
346
347      HashSet<ThreeDimensionalPacking> extremePoints = new HashSet<ThreeDimensionalPacking>();
348      extremePoints.Add(new ThreeDimensionalPacking(0, 0, 0, 0, false));
349      #endregion
350
351      foreach (int itemIndex in solution.PackingSequence) {
352        var item = itemMeasures[itemIndex];
353        extremePoints = OrderExtremePoints(extremePoints, occupiedPoints, binMeasures);
354        var positionFound = FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePoints, occupiedPoints, itemPositions);
355        if (positionFound != null) {
356          extremePoints.Remove(positionFound);
357        }
358        else {
359          positionFound = new ThreeDimensionalPacking(nrOfBins, 0, 0, 0);
360          occupiedPoints = IncreaseBinCountForOccupiedPoints(occupiedPoints, binMeasures);
361          nrOfBins++;
362        }
363        itemPositions[itemIndex] = positionFound;
364        occupiedPoints = OccupyPointsForNewItem(occupiedPoints, item, positionFound, itemIndex);
365        extremePoints = GenerateNewExtremePointsForNewItem(extremePoints, occupiedPoints, item, positionFound, binMeasures);
366      }
367
368      return itemPositions;
369    }
370
371
372    private static ThreeDimensionalPacking FindExtremePointForItem(int itemIndex, ItemList<CuboidPackingItem> itemMeasures, CuboidPackingBin binMeasures,
373        HashSet<ThreeDimensionalPacking> extremePoints, List<int[, ,]> occupiedPoints, ObservableDictionary<int, ThreeDimensionalPacking> itemPositions) {
374          return FindExtremePointForItem(itemIndex, itemMeasures, binMeasures, extremePoints, occupiedPoints, itemPositions, false);
375    }
376    private static ThreeDimensionalPacking FindExtremePointForItem(int itemIndex, ItemList<CuboidPackingItem> itemMeasures, CuboidPackingBin binMeasures,
377        HashSet<ThreeDimensionalPacking> extremePoints, List<int[,,]> occupiedPoints, ObservableDictionary<int, ThreeDimensionalPacking> itemPositions, bool rotated) {
378
379      var itemFromList = itemMeasures[itemIndex];
380      CuboidPackingItem item = new CuboidPackingItem(
381        rotated ? itemFromList.Depth : itemFromList.Width,
382        itemFromList.Height,
383        rotated ? itemFromList.Width : itemFromList.Depth,
384        itemFromList.TargetBin);
385
386      int epIndex = 0;
387      while (epIndex < extremePoints.Count &&
388        (!DeepestBottomLeftFunctions.IsPositionFeasible(binMeasures, extremePoints.ElementAt(epIndex).AssignedBin, item, extremePoints.ElementAt(epIndex), itemPositions, itemMeasures) ||
389        !IsStaticStable(occupiedPoints[extremePoints.ElementAt(epIndex).AssignedBin], item, extremePoints.ElementAt(epIndex))))
390      { epIndex++; }
391
392      if (epIndex < extremePoints.Count) {
393        var result = extremePoints.ElementAt(epIndex);
394        result.Rotated = rotated;
395        return result;
396      }
397      return null;
398    }
399    private static List<int[, ,]> IncreaseBinCountForOccupiedPoints(List<int[, ,]> occupiedPoints, CuboidPackingBin binMeasures) {
400      occupiedPoints.Add(new int[binMeasures.Width, binMeasures.Height, binMeasures.Depth]);
401      int lastIndex = occupiedPoints.Count - 1;
402      for (int w = 0; w < binMeasures.Width; w++) {
403        for (int h = 0; h < binMeasures.Height; h++) {
404          for (int d = 0; d < binMeasures.Depth; d++) {
405            occupiedPoints[lastIndex][w, h, d] = -1;
406          }
407        }
408      }
409      return occupiedPoints;
410    }
411    private static bool IsStaticStable(int[, ,] occupiedPoints, CuboidPackingItem item, ThreeDimensionalPacking ep) {
412      //Static stability is given, if item is placed on the ground
413      if (ep.Y == 0)
414        return true;
415
416      if (occupiedPoints[ep.X, ep.Y - 1, ep.Z] != -1
417        && occupiedPoints[ep.X + item.Width - 1, ep.Y - 1, ep.Z] != -1
418        && occupiedPoints[ep.X, ep.Y - 1, ep.Z + item.Depth - 1] != -1
419        && occupiedPoints[ep.X + item.Width - 1, ep.Y - 1, ep.Z + item.Depth - 1] != -1)
420        return true;
421
422      //int groundCount = 0;
423      //for (int x = ep.X; x < ep.X + item.Width - 1; x++) {
424      //  for (int z = ep.Z; z < ep.Z + item.Depth - 1; z++) {
425      //    if (occupiedPoints[x,ep.Y-1, z] != -1)                                                     
426      //      groundCount++;
427      //  }
428      //}
429      //double stableGround = (double)(groundCount) / (double)(item.Width * item.Depth);
430      //if (stableGround > 0.75)
431      //  return true;
432
433      return false;
434    }
435    private static List<int[, ,]>  OccupyPointsForNewItem(List<int[, ,]> occupiedPoints, CuboidPackingItem newItem, ThreeDimensionalPacking position, int itemIndex) {
436      int width = position.Rotated ? newItem.Depth : newItem.Width;
437      int depth = position.Rotated ? newItem.Width : newItem.Depth;
438      for (int w = position.X; w < position.X + width; w++) {
439        for (int h = position.Y; h < position.Y + newItem.Height; h++) {
440          for (int d = position.Z; d < position.Z + depth; d++) {
441            occupiedPoints[position.AssignedBin][w,h,d] = itemIndex;
442          }
443        }
444      }
445      return occupiedPoints;
446    }
447    private static HashSet<ThreeDimensionalPacking> GenerateNewExtremePointsForNewItem(HashSet<ThreeDimensionalPacking> extremePoints, List<int[, ,]> occupiedPoints,
448        CuboidPackingItem newItem, ThreeDimensionalPacking position, CuboidPackingBin binMeasures) {
449      int currentBin = position.AssignedBin;
450
451      int newWidth = position.Rotated ? newItem.Depth : newItem.Width;
452      int newDepth = position.Rotated ? newItem.Width : newItem.Depth;
453
454      //Find ExtremePoints beginning from sourcepointX
455      var sourcePointX = new ThreeDimensionalPacking(currentBin, position.X + newWidth, position.Y, position.Z);
456      if (sourcePointX.X < binMeasures.Width && sourcePointX.Y < binMeasures.Height && sourcePointX.Z < binMeasures.Depth) {
457        //Traversing down the y-axis                                                                           
458        int currentYValue = sourcePointX.Y;
459        while (currentYValue > 0 && occupiedPoints[currentBin][sourcePointX.X, currentYValue, sourcePointX.Z] == -1) {
460          currentYValue--;
461        }
462        extremePoints.Add(new ThreeDimensionalPacking(currentBin, sourcePointX.X, currentYValue, sourcePointX.Z));
463
464        //Traversing down the z-axis
465        int currentZValue = sourcePointX.Z;
466        while (currentZValue > 0 && occupiedPoints[currentBin][sourcePointX.X, sourcePointX.Y, currentZValue - 1] == -1) {
467          currentZValue--;
468        }
469        extremePoints.Add(new ThreeDimensionalPacking(currentBin, sourcePointX.X, sourcePointX.Y, currentZValue));
470      }
471
472
473
474
475      //Find ExtremePoints beginning from sourcepointY
476      var sourcePointY = new ThreeDimensionalPacking(currentBin, position.X, position.Y + newItem.Height, position.Z);
477      if (sourcePointY.X < binMeasures.Width && sourcePointY.Y < binMeasures.Height && sourcePointY.Z < binMeasures.Depth) {
478        //Traversing down the x-axis 
479        int currentXValue = sourcePointY.X;
480        while (currentXValue > 0 && occupiedPoints[currentBin][currentXValue - 1, sourcePointY.Y, sourcePointY.Z] == -1) {
481          currentXValue--;
482        }
483        extremePoints.Add(new ThreeDimensionalPacking(currentBin, currentXValue, sourcePointY.Y, sourcePointY.Z));
484
485        //Traversing down the z-axis
486        int currentZValue = sourcePointY.Z;
487        while (currentZValue > 0 && occupiedPoints[currentBin][sourcePointY.X, sourcePointY.Y, currentZValue - 1] == -1) {
488          currentZValue--;
489        }
490        extremePoints.Add(new ThreeDimensionalPacking(currentBin, sourcePointY.X, sourcePointY.Y, currentZValue));
491      }
492
493
494
495
496
497      //Find ExtremePoints beginning from sourcepointZ
498      var sourcePointZ = new ThreeDimensionalPacking(currentBin, position.X, position.Y, position.Z + newDepth);
499      if (sourcePointZ.X < binMeasures.Width && sourcePointZ.Y < binMeasures.Height && sourcePointZ.Z < binMeasures.Depth) {
500        //Traversing down the x-axis 
501        int currentXValue = sourcePointZ.X;
502        while (currentXValue > 0 && occupiedPoints[currentBin][currentXValue - 1, sourcePointZ.Y, sourcePointZ.Z] == -1) {
503          currentXValue--;
504        }
505        extremePoints.Add(new ThreeDimensionalPacking(currentBin, currentXValue, sourcePointZ.Y, sourcePointZ.Z));
506
507        //Traversing down the y-axis                                                                           
508        int currentYValue = sourcePointZ.Y;
509        while (currentYValue > 0 && occupiedPoints[currentBin][sourcePointZ.X, currentYValue, sourcePointZ.Z] == -1) {
510          currentYValue--;
511        }
512        extremePoints.Add(new ThreeDimensionalPacking(currentBin, sourcePointZ.X, currentYValue, sourcePointZ.Z));
513      }
514
515
516      return extremePoints;
517    }
518
519
520    private static HashSet<ThreeDimensionalPacking> OrderExtremePoints(HashSet<ThreeDimensionalPacking> hashSet, List<int[, ,]> occupiedPoints, CuboidPackingBin binMeasures) {
521      return new HashSet<ThreeDimensionalPacking>(hashSet.OrderBy(ep => ep.AssignedBin).ThenBy(ep => ep.Z).ThenBy(ep => ep.X).ThenBy(ep => ep.Y).ThenBy(ep => ShortestPossibleSideFromEP(ep, occupiedPoints, binMeasures)));
522    }
523    private static int ShortestPossibleSideFromEP(ThreeDimensionalPacking ep, List<int[, ,]> occupiedPoints, CuboidPackingBin binMeasures) {
524      int shortestSide = int.MaxValue;
525
526      if (ep.X >= binMeasures.Width || ep.Y >= binMeasures.Height || ep.Z >= binMeasures.Depth)
527        return shortestSide;
528
529      int currentX = ep.X;
530      while (currentX < binMeasures.Width && occupiedPoints[ep.AssignedBin][currentX, ep.Y, ep.Z] == -1) { currentX++; }   
531      if (currentX - ep.X < shortestSide)
532        shortestSide = currentX - ep.X;
533
534      int currentY = ep.Y;
535      while (currentY < binMeasures.Height && occupiedPoints[ep.AssignedBin][ep.X, currentY, ep.Z] == -1) { currentY++;  }
536      if (currentY - ep.Y < shortestSide)
537        shortestSide = currentY - ep.Y;
538
539      int currentZ = ep.Z;
540      while (currentZ < binMeasures.Depth && occupiedPoints[ep.AssignedBin][ep.X, ep.Y, currentZ] == -1) { currentZ++; }
541      if (currentZ - ep.Z < shortestSide)
542        shortestSide = currentZ - ep.Z;
543
544      return shortestSide;
545    }
546  }
547}
Note: See TracBrowser for help on using the repository browser.