Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.BinPacking/HeuristicLab.Problems.BinPacking/3.3/Decoders/3D/DBL/DeepestBottomLeftFunctions.cs @ 9563

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

#1966: Implemented additional Operator-Wrappers for PackingSequence and GroupingVector; Implemented additional problem-class for Rosenbauer-Problemstatement; Added marker-interfaces for decoder-types;

File size: 12.4 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.Encodings.PermutationEncoding;
11using HeuristicLab.Problems.BinPacking.Dimensions;
12using HeuristicLab.Problems.BinPacking.Interfaces;
13using HeuristicLab.Problems.BinPacking.PackingBin;
14using HeuristicLab.Problems.BinPacking.PackingItem;
15using HeuristicLab.Problems.BinPacking.Shapes;
16
17namespace HeuristicLab.Problems.BinPacking.Decoders {
18  public static class DeepestBottomLeftFunctions {
19
20    public static ObservableDictionary<int, ThreeDimensionalPacking> DeepestLeftBottomPacking(MultiComponentVectorEncoding solution, CuboidPackingBin binMeasures, ItemList<CuboidPackingItem> itemMeasures) {
21      int nrOfBins = solution.NrOfBins;
22
23      //Get all indexes of items for every bin according to grouping-vector
24      Dictionary<int, List<PackingInformation>> unpackedItemIndexesPerBin = new Dictionary<int, List<PackingInformation>>();
25
26      for (int i = 0; i < nrOfBins; i++) {
27        unpackedItemIndexesPerBin[i] = new List<PackingInformation>(solution.PackingInformations[i]);
28      }
29
30      ObservableDictionary<int, ThreeDimensionalPacking> packingPositions = new ObservableDictionary<int, ThreeDimensionalPacking>();
31      var remainingItems = new List<PackingInformation>();
32
33      //Iterate over all bin-lists
34      for (int binNr = 0; binNr < nrOfBins; binNr++) {
35        //Iterate over the current bin-item-list and find feasible positions in the current bin for each item
36        var unpackedItems = unpackedItemIndexesPerBin[binNr];
37        for (int i = 0; i < unpackedItems.Count; i++) {
38          var itemIndex = unpackedItems[i].ItemID;
39          var item = itemMeasures[itemIndex];
40          ThreeDimensionalPacking position = null;
41
42          position = DeepestBottomLeftFunctions.DeepestLeftBottomPosition(binMeasures, binNr, item, packingPositions, itemMeasures, unpackedItems[i].Rotated);
43
44          if (position == null) {
45            position = DeepestBottomLeftFunctions.DeepestLeftBottomPosition(binMeasures, binNr, item, packingPositions, itemMeasures, !unpackedItems[i].Rotated);
46          }
47          if (position == null) {
48            remainingItems.Add(unpackedItems[i]);
49            solution.PackingInformations[binNr].Remove(unpackedItems[i]);
50          } else {
51            packingPositions[itemIndex] = position;
52            solution.PackingInformations[binNr].Find(pi => pi.ItemID == itemIndex).Rotated = position.Rotated;
53          }
54        }
55      }
56
57      //Packing of remaining items
58      //Iterate over all bin-lists
59      for (int binNr = 0; binNr < nrOfBins && remainingItems.Count > 0; binNr++) {
60        var unpackedItems = new List<PackingInformation>(remainingItems);
61        for (int i = 0; i < unpackedItems.Count; i++) {
62          var itemIndex = unpackedItems[i].ItemID;
63          var item = itemMeasures[itemIndex];
64          ThreeDimensionalPacking position = null;
65
66          //Look for space in current bin
67          position = DeepestBottomLeftFunctions.DeepestLeftBottomPosition(binMeasures, binNr, item, packingPositions, itemMeasures, unpackedItems[i].Rotated);
68
69          if (position == null) {
70            position = DeepestBottomLeftFunctions.DeepestLeftBottomPosition(binMeasures, binNr, item, packingPositions, itemMeasures, !unpackedItems[i].Rotated);
71          }
72          if (position != null) {
73            packingPositions[itemIndex] = position;
74            remainingItems.Remove(unpackedItems[i]);
75            solution.PackingInformations[binNr].Add(unpackedItems[i]);
76            solution.PackingInformations[binNr].Find(pi => pi.ItemID == itemIndex).Rotated = position.Rotated;
77          }
78        }
79        if (remainingItems.Count > 0 && binNr + 1 >= nrOfBins) {
80          solution.PackingInformations[nrOfBins] = new ItemList<PackingInformation>();
81          nrOfBins++;
82        }
83      }
84
85      return packingPositions;
86    }
87
88    public static ObservableDictionary<int, ThreeDimensionalPacking> DeepestLeftBottomPacking(GroupingVectorEncoding solution, CuboidPackingBin binMeasures, ItemList<CuboidPackingItem> itemMeasures) {
89      int nrOfBins = solution.GroupingVector.Max() + 1;
90
91      //Get all indexes of items for every bin according to grouping-vector
92      //It is assumed, that at this point the item-indexes are sorted according to their item-size!
93      Dictionary<int, List<int>> unpackedItemIndexesPerBin = new Dictionary<int, List<int>>();
94
95      for (int i = 0; i < nrOfBins; i++) {
96        unpackedItemIndexesPerBin[i] = solution.GroupingVector
97          .Select((Value, Index) => new { Value, Index })
98          .Where(temp => temp.Value == i)
99          .Select(temp => temp.Index).ToList();
100      }
101
102      ObservableDictionary<int, ThreeDimensionalPacking> packingPositions = new ObservableDictionary<int, ThreeDimensionalPacking>();
103      var remainingItems = new List<int>();
104
105      //Iterate over all bin-lists
106      for (int binNr = 0; binNr < nrOfBins; binNr++) {
107        //Iterate over the current bin-item-list and find feasible positions in the current bin for each item
108        var unpackedItems = unpackedItemIndexesPerBin[binNr];
109        for (int i = 0; i < unpackedItems.Count; i++) {
110          var itemIndex = unpackedItems[i];
111          var item = itemMeasures[itemIndex];
112          ThreeDimensionalPacking position = null;
113
114          position = DeepestBottomLeftFunctions.DeepestLeftBottomPosition(binMeasures, binNr, item, packingPositions, itemMeasures);
115
116          if (position == null) {
117            remainingItems.Add(itemIndex);
118          } else
119            packingPositions[itemIndex] = position;
120        }
121      }
122
123      //Packing of remaining items
124      //Iterate over all bin-lists
125      for (int binNr = 0; binNr < nrOfBins && remainingItems.Count > 0; binNr++) {
126        var unpackedItems = new List<int>(remainingItems);
127        for (int i = 0; i < unpackedItems.Count; i++) {
128          var itemIndex = unpackedItems[i];
129          var item = itemMeasures[itemIndex];
130          ThreeDimensionalPacking position = null;
131
132          //Look for space in current bin
133          position = DeepestBottomLeftFunctions.DeepestLeftBottomPosition(binMeasures, binNr, item, packingPositions, itemMeasures);
134
135          if (position != null) {
136            packingPositions[itemIndex] = position;
137            remainingItems.Remove(itemIndex);
138            //solution.GroupingVector[itemIndex] = binNr;
139          }
140        }
141        if (remainingItems.Count > 0 && binNr + 1 >= nrOfBins) {
142          nrOfBins++;
143        }
144      }
145
146      return packingPositions;
147    }
148
149    public static ObservableDictionary<int, ThreeDimensionalPacking> DeepestLeftBottomPacking(PackingSequenceEncoding solution, CuboidPackingBin binMeasures, ItemList<CuboidPackingItem> itemMeasures) {
150      ObservableDictionary<int, ThreeDimensionalPacking> packingPositions = new ObservableDictionary<int, ThreeDimensionalPacking>();
151      int nrOfBins = 1;
152      for (int i = 0; i < solution.PackingSequence.Length; i++) {
153        var item = itemMeasures[solution.PackingSequence[i]];
154        ThreeDimensionalPacking position = null;
155        //Look for space in existing bins
156        for (int binNr = 0; binNr < nrOfBins; binNr++) {
157          position = DeepestBottomLeftFunctions.DeepestLeftBottomPosition(binMeasures, binNr, item, packingPositions, itemMeasures);
158          if (position != null)
159            break;
160        }
161        //Did not find enough space in any of the existing bins => create new bin
162        if (position == null) {
163          nrOfBins++;
164          position = DeepestBottomLeftFunctions.DeepestLeftBottomPosition(binMeasures, nrOfBins - 1, item, packingPositions, itemMeasures);
165        }
166
167        if (position == null)
168          position = new ThreeDimensionalPacking(-1, 0, 0, 0);
169
170        packingPositions[solution.PackingSequence[i]] = position;
171      }
172
173      return packingPositions;
174    }
175
176    public static ThreeDimensionalPacking DeepestLeftBottomPosition(CuboidPackingBin binMeasures, int binNr, CuboidPackingItem currentItem, ObservableDictionary<int, ThreeDimensionalPacking> itemPositions, ItemList<CuboidPackingItem> itemMeasures) {
177      return DeepestLeftBottomPosition(binMeasures, binNr, currentItem, itemPositions, itemMeasures, false);
178    }
179    public static ThreeDimensionalPacking DeepestLeftBottomPosition(CuboidPackingBin binMeasures, int binNr, CuboidPackingItem currentItem, ObservableDictionary<int, ThreeDimensionalPacking> itemPositions, ItemList<CuboidPackingItem> itemMeasures, bool rotated) {
180      //Starting-position at upper right corner (=left bottom point of item-rectangle is at position item.width,item.height)
181      ThreeDimensionalPacking currentPosition = new ThreeDimensionalPacking(binNr,
182        binMeasures.Width - (rotated ? currentItem.Depth : currentItem.Width),
183        binMeasures.Height - currentItem.Height,
184        binMeasures.Depth - (rotated ? currentItem.Width : currentItem.Depth), rotated);
185      //Slide the item as far as possible to the bottom
186      while (IsPositionFeasible(binMeasures, binNr, currentItem, MoveDown(currentPosition), itemPositions, itemMeasures)
187        || IsPositionFeasible(binMeasures, binNr, currentItem, MoveLeft(currentPosition), itemPositions, itemMeasures)
188        || IsPositionFeasible(binMeasures, binNr, currentItem, MoveBack(currentPosition), itemPositions, itemMeasures)) {
189        //Slide the item as far as possible to the left
190          while (IsPositionFeasible(binMeasures, binNr, currentItem, MoveLeft(currentPosition), itemPositions, itemMeasures)
191          || IsPositionFeasible(binMeasures, binNr, currentItem, MoveBack(currentPosition), itemPositions, itemMeasures)) {
192          //Slide the item as far as possible to the back
193            while (IsPositionFeasible(binMeasures, binNr, currentItem, MoveBack(currentPosition), itemPositions, itemMeasures)) {
194            currentPosition = MoveBack(currentPosition);
195          }
196            if (IsPositionFeasible(binMeasures, binNr, currentItem, MoveLeft(currentPosition), itemPositions, itemMeasures))
197            currentPosition = MoveLeft(currentPosition);
198        }
199          if (IsPositionFeasible(binMeasures, binNr, currentItem, MoveDown(currentPosition), itemPositions, itemMeasures))
200          currentPosition = MoveDown(currentPosition);
201      }
202
203      return IsPositionFeasible(binMeasures, binNr, currentItem, currentPosition, itemPositions, itemMeasures) ? currentPosition : null;
204    }
205
206    public static bool IsPositionFeasible(CuboidPackingBin binMeasures, int binNr, CuboidPackingItem currentItem,
207      ThreeDimensionalPacking currentPosition, ObservableDictionary<int, ThreeDimensionalPacking> itemPositions, ItemList<CuboidPackingItem> itemMeasures) {
208      //In this case feasability is defined as following: 1. the item fits into the bin-borders; 2. the item does not collide with another already packed item
209      if (!binMeasures.Encloses(currentPosition, currentItem))
210        return false;
211
212      var itemsWithPositions = itemMeasures.
213        Select((Value, Index) => new { Value, Index }).
214        Where(s => itemPositions.ContainsKey(s.Index)).
215        Select((s) => new { Measures = itemMeasures[s.Index], Position = itemPositions[s.Index] });
216
217      foreach (var itemWithPosition in itemsWithPositions) {
218        if (itemWithPosition.Position.AssignedBin == binNr && itemWithPosition.Measures.Overlaps(itemWithPosition.Position, currentPosition, currentItem))
219          return false;
220      }
221
222      return true;
223    }
224
225    private static ThreeDimensionalPacking MoveLeft(ThreeDimensionalPacking original) {
226      return new ThreeDimensionalPacking(original.AssignedBin, original.X - 1, original.Y, original.Z, original.Rotated);
227    }
228    private static ThreeDimensionalPacking MoveDown(ThreeDimensionalPacking original) {
229      return new ThreeDimensionalPacking(original.AssignedBin, original.X, original.Y - 1, original.Z, original.Rotated);
230    }
231    private static ThreeDimensionalPacking MoveBack(ThreeDimensionalPacking original) {
232      return new ThreeDimensionalPacking(original.AssignedBin, original.X, original.Y, original.Z - 1, original.Rotated);
233    }
234
235
236 
237  }
238}
Note: See TracBrowser for help on using the repository browser.