Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1966: Applied some heavy refactoring on the decoder-classes and cleaned up the code a bit;

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