Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1966: Did some major refactoring in Decoder-classes; Added MoveEvaluator classes for different encodings and dimensions; Added new crossover-class for MCV encoding;

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