Free cookie consent management tool by TermsFeed Policy Generator

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