Free cookie consent management tool by TermsFeed Policy Generator

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