Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.BinPacking/HeuristicLab.Problems.BinPacking/3.3/Encodings/PackingPlans/BinPacking3D.cs @ 9598

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

#1966: Fixed a bug which caused the stacking-contraint to be wrongly enforced; Did some cleanup;

File size: 16.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Text;
26using HeuristicLab.Problems.BinPacking.Interfaces;
27using HeuristicLab.Problems.BinPacking.PackingItem;
28using HeuristicLab.Problems.BinPacking.Shapes;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30using HeuristicLab.Core;
31using HeuristicLab.Common;
32using HeuristicLab.Parameters;
33using HeuristicLab.Data;
34using HeuristicLab.Collections;
35using HeuristicLab.Problems.BinPacking.Dimensions;
36using HeuristicLab.Problems.BinPacking.PackingBin;
37
38namespace HeuristicLab.Encodings.PackingEncoding.PackingPlan {
39  [Item("BinPacking3D", "Represents a single-bin packing for a 3D bin-packing problem.")]
40  [StorableClass]
41  public class BinPacking3D : BinPacking<ThreeDimensionalPacking, CuboidPackingBin, CuboidPackingItem> {
42
43    public BinPacking3D(CuboidPackingBin binMeasures) : base(binMeasures) {
44      //OccupiedPoints = new OccupiedPoints3D(binMeasures);
45    }
46    [StorableConstructor]
47    protected BinPacking3D(bool deserializing) : base(deserializing) { }
48    protected BinPacking3D(BinPacking3D original, Cloner cloner)
49      : base(original, cloner) {
50        this.depthWasDoubled = original.depthWasDoubled;
51    }
52    public override IDeepCloneable Clone(Cloner cloner) {
53      return new BinPacking3D(this, cloner);
54    }
55                                       
56    protected override void GenerateNewExtremePointsForNewItem(CuboidPackingItem newItem, ThreeDimensionalPacking position) {
57      int newWidth = position.Rotated ? newItem.Depth : newItem.Width;
58      int newDepth = position.Rotated ? newItem.Width : newItem.Depth;
59
60      //Find ExtremePoints beginning from sourcepointX
61      var sourcePointX = new ThreeDimensionalPacking(0, position.X + newWidth, position.Y, position.Z);
62      if (sourcePointX.X < BinMeasures.Width && sourcePointX.Y < BinMeasures.Height && sourcePointX.Z < BinMeasures.Depth) {
63        //Traversing down the y-axis           
64        ThreeDimensionalPacking current = new ThreeDimensionalPacking(0, sourcePointX.X, sourcePointX.Y, sourcePointX.Z);
65        while (current.Y > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveDown (current))) {
66          current = ThreeDimensionalPacking.MoveDown(current);
67        }
68        ExtremePoints.Add((ThreeDimensionalPacking)current.Clone());
69        while (current.X > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveLeft(current))) {
70          current = ThreeDimensionalPacking.MoveLeft(current);
71        }
72        ExtremePoints.Add(current);
73
74        //Traversing down the z-axis                 
75        current = new ThreeDimensionalPacking(0, sourcePointX.X, sourcePointX.Y, sourcePointX.Z);
76        while (current.Z > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveBack (current))) {
77          current = ThreeDimensionalPacking.MoveBack(current);
78        }
79        ExtremePoints.Add((ThreeDimensionalPacking)current.Clone());
80        while (current.Y > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveDown(current))) {
81          current = ThreeDimensionalPacking.MoveDown(current);
82        }
83        ExtremePoints.Add(current);
84      }
85
86
87
88
89      //Find ExtremePoints beginning from sourcepointY
90      var sourcePointY = new ThreeDimensionalPacking(0, position.X, position.Y + newItem.Height, position.Z);
91      if (sourcePointY.X < BinMeasures.Width && sourcePointY.Y < BinMeasures.Height && sourcePointY.Z < BinMeasures.Depth) {
92        //Traversing down the x-axis         
93        ThreeDimensionalPacking current = new ThreeDimensionalPacking(0, sourcePointY.X, sourcePointY.Y, sourcePointY.Z);
94        while (current.X > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveLeft(current))) {
95          current = ThreeDimensionalPacking.MoveLeft(current);
96        }
97        ExtremePoints.Add((ThreeDimensionalPacking)current.Clone());
98        while (current.Y > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveDown(current))) {
99          current = ThreeDimensionalPacking.MoveDown(current);
100        }
101        ExtremePoints.Add(current);
102
103        //Traversing down the z-axis                                                                   
104        current = new ThreeDimensionalPacking(0, sourcePointY.X, sourcePointY.Y, sourcePointY.Z);
105        while (current.Z > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveBack(current))) {
106          current = ThreeDimensionalPacking.MoveBack(current);
107        }
108        ExtremePoints.Add((ThreeDimensionalPacking)current.Clone());
109        while (current.Y > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveDown(current))) {
110          current = ThreeDimensionalPacking.MoveDown(current);
111        }
112        ExtremePoints.Add(current);
113      }
114
115
116
117
118
119      //Find ExtremePoints beginning from sourcepointZ
120      var sourcePointZ = new ThreeDimensionalPacking(0, position.X, position.Y, position.Z + newDepth);
121      if (sourcePointZ.X < BinMeasures.Width && sourcePointZ.Y < BinMeasures.Height && sourcePointZ.Z < BinMeasures.Depth) {
122        //Traversing down the x-axis                                                                             
123        ThreeDimensionalPacking current = new ThreeDimensionalPacking(0, sourcePointZ.X, sourcePointZ.Y, sourcePointZ.Z);
124        while (current.X > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveLeft(current))) {
125          current = ThreeDimensionalPacking.MoveLeft(current);
126        }
127        ExtremePoints.Add((ThreeDimensionalPacking)current.Clone());
128        while (current.Y > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveDown(current))) {
129          current = ThreeDimensionalPacking.MoveDown(current);
130        }
131        ExtremePoints.Add(current);
132
133        //Traversing down the y-axis                                                                     
134        current = new ThreeDimensionalPacking(0, sourcePointZ.X, sourcePointZ.Y, sourcePointZ.Z);
135        while (current.Y > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveDown(current))) {
136          current = ThreeDimensionalPacking.MoveDown(current);
137        }
138        ExtremePoints.Add((ThreeDimensionalPacking)current.Clone());
139        while (current.X > 0 && IsPointOccupied(ThreeDimensionalPacking.MoveLeft(current))) {
140          current = ThreeDimensionalPacking.MoveLeft(current);
141        }
142        ExtremePoints.Add(current);
143      }
144
145      ExtremePoints = new HashSet<ThreeDimensionalPacking>(ExtremePoints.
146        OrderBy(ep => ep.Z).
147        ThenBy(ep => ep.X).
148        ThenBy(ep => ep.Y)//.ThenBy(ep => ShortestPossibleSideFromPoint(ep))
149        );
150    }
151
152    public override ThreeDimensionalPacking FindExtremePointForItem(CuboidPackingItem measures, bool rotated, bool stackingConstraints) {
153
154      CuboidPackingItem item = new CuboidPackingItem(
155        rotated ? measures.Depth : measures.Width,
156        measures.Height,
157        rotated ? measures.Width : measures.Depth,
158        measures.TargetBin);
159
160      int epIndex = 0;
161      while (epIndex < ExtremePoints.Count && (
162        !IsPositionFeasible(item, ExtremePoints.ElementAt(epIndex))
163        || !IsSupportedByAtLeastOnePoint(item, ExtremePoints.ElementAt(epIndex))
164        || (stackingConstraints && !IsStaticStable(item, ExtremePoints.ElementAt(epIndex)))
165        || (stackingConstraints && !IsWeightSupported(item, ExtremePoints.ElementAt(epIndex)))
166      )) { epIndex++; }
167
168      if (epIndex < ExtremePoints.Count) {
169        var result = ExtremePoints.ElementAt(epIndex);
170        result.Rotated = rotated;
171        return result;
172      }
173      return null;
174    }
175
176    public override ThreeDimensionalPacking FindPositionBySliding(CuboidPackingItem measures, bool rotated) {
177      //Starting-position at upper right corner (=left bottom point of item-rectangle is at position item.width,item.height)
178      ThreeDimensionalPacking currentPosition = new ThreeDimensionalPacking(0,
179        BinMeasures.Width - (rotated ? measures.Depth : measures.Width),
180        BinMeasures.Height - measures.Height,
181        BinMeasures.Depth - (rotated ? measures.Width : measures.Depth), rotated);
182      //Slide the item as far as possible to the bottom
183      while (IsPositionFeasible(measures, ThreeDimensionalPacking.MoveDown(currentPosition))
184        || IsPositionFeasible(measures, ThreeDimensionalPacking.MoveLeft(currentPosition))
185        || IsPositionFeasible(measures, ThreeDimensionalPacking.MoveBack(currentPosition))) {
186        //Slide the item as far as possible to the left
187          while (IsPositionFeasible(measures, ThreeDimensionalPacking.MoveLeft(currentPosition))
188        || IsPositionFeasible(measures, ThreeDimensionalPacking.MoveBack(currentPosition))) {
189          //Slide the item as far as possible to the back
190          while (IsPositionFeasible(measures, ThreeDimensionalPacking.MoveBack(currentPosition))) {
191            currentPosition = ThreeDimensionalPacking.MoveBack(currentPosition);
192          }
193          if (IsPositionFeasible(measures, ThreeDimensionalPacking.MoveLeft(currentPosition)))
194            currentPosition = ThreeDimensionalPacking.MoveLeft(currentPosition);
195        }
196          if (IsPositionFeasible(measures, ThreeDimensionalPacking.MoveDown(currentPosition)))
197            currentPosition = ThreeDimensionalPacking.MoveDown(currentPosition);
198      }
199
200      return IsPositionFeasible(measures, currentPosition) ? currentPosition : null;
201    }
202   
203    public override void SlidingBasedPacking(ref List<int> sequence, ItemList<CuboidPackingItem> itemMeasures) {
204      var temp = new List<int>(sequence);
205      for (int i = 0; i < temp.Count; i++) {
206        var item = itemMeasures[temp[i]];
207        var position = FindPositionBySliding(item, false);
208        if (position != null) {
209          PackItem(temp[i], item, position);
210          sequence.Remove(temp[i]);
211        }
212      }
213    }
214    public override void SlidingBasedPacking(ref List<int> sequence, ItemList<CuboidPackingItem> itemMeasures, Dictionary<int, bool> rotationArray) {
215      var temp = new List<int>(sequence);
216      for (int i = 0; i < temp.Count; i++) {
217        var item = itemMeasures[temp[i]];
218        var position = FindPositionBySliding(item, rotationArray[i]);
219        if (position != null) {
220          PackItem(temp[i], item, position);
221          sequence.Remove(temp[i]);
222        }
223      }
224    }
225    public override void ExtremePointBasedPacking(ref List<int> sequence, ItemList<CuboidPackingItem> itemMeasures, bool stackingConstraints) {
226      var temp = new List<int>(sequence);
227      foreach (int itemID in temp) {
228        var item = itemMeasures[itemID];
229        var positionFound = FindExtremePointForItem(item, false, stackingConstraints);
230        if (positionFound != null) {
231          PackItem(itemID, item, positionFound);
232          sequence.Remove(itemID);
233        }
234      }
235    }
236    public override void ExtremePointBasedPacking(ref List<int> sequence, ItemList<CuboidPackingItem> itemMeasures, bool stackingConstraints, Dictionary<int, bool> rotationArray) {
237      var temp = new List<int>(sequence);
238      foreach (int itemID in temp) {
239        var item = itemMeasures[itemID];
240        var positionFound = FindExtremePointForItem(item, rotationArray[itemID], stackingConstraints);
241        if (positionFound != null) {
242          PackItem(itemID, item, positionFound);
243          sequence.Remove(itemID);
244        }
245      }
246    }
247                                                   
248    public override int ShortestPossibleSideFromPoint(ThreeDimensionalPacking position) {
249
250      int shortestSide = int.MaxValue;
251      int width = BinMeasures.Width;
252      int height = BinMeasures.Height;
253      int depth = BinMeasures.Depth;
254
255      if (position.X >= width || position.Y >= height || position.Z >= depth)
256        return shortestSide;
257
258      ThreeDimensionalPacking current = new ThreeDimensionalPacking (0, position.X, position.Y, position.Z);
259      while (current.X < width && IsPointOccupied(current)) { current = ThreeDimensionalPacking.MoveRight(current); }
260      if (current.X - position.X < shortestSide)
261        shortestSide = current.X - position.X;
262
263
264      current = new ThreeDimensionalPacking(0, position.X, position.Y, position.Z);
265      while (current.Y < height && IsPointOccupied(current)) { current = ThreeDimensionalPacking.MoveUp (current); }
266      if (current.Y - position.Y < shortestSide)
267        shortestSide = current.Y - position.Y;
268
269
270      current = new ThreeDimensionalPacking(0, position.X, position.Y, position.Z);
271      while (current.Z < depth && IsPointOccupied(current)) { current = ThreeDimensionalPacking.MoveFront(current); }
272      if (current.Z - position.Z < shortestSide)
273        shortestSide = current.Z - position.Z;
274
275      return shortestSide;
276    }
277    public override bool IsStaticStable(CuboidPackingItem item, ThreeDimensionalPacking position) {
278      //Static stability is given, if item is placed on the ground
279      if (position.Y == 0)
280        return true;
281
282      if (IsPointOccupied (new ThreeDimensionalPacking (0, position.X, position.Y - 1, position.Z))
283        && IsPointOccupied (new ThreeDimensionalPacking (0, position.X + item.Width, position.Y - 1, position.Z))
284        && IsPointOccupied (new ThreeDimensionalPacking (0, position.X, position.Y - 1, position.Z + item.Depth))
285        && IsPointOccupied (new ThreeDimensionalPacking (0, position.X + item.Width, position.Y - 1, position.Z + item.Depth)))
286        return true;
287
288
289      //if (occupiedPoints[position.X, position.Y - 1, position.Z] != -1
290      //  && occupiedPoints[position.X + item.Width - 1, position.Y - 1, position.Z] != -1
291      //  && occupiedPoints[position.X, position.Y - 1, position.Z + item.Depth - 1] != -1
292      //  && occupiedPoints[position.X + item.Width - 1, position.Y - 1, position.Z + item.Depth - 1] != -1)
293      //  return true;
294
295      //int groundCount = 0;
296      //for (int x = ep.X; x < ep.X + item.Width - 1; x++) {
297      //  for (int z = ep.Z; z < ep.Z + item.Depth - 1; z++) {
298      //    if (occupiedPoints[x,ep.Y-1, z] != -1)                                                     
299      //      groundCount++;
300      //  }
301      //}
302      //double stableGround = (double)(groundCount) / (double)(item.Width * item.Depth);
303      //if (stableGround > 0.75)
304      //  return true;
305
306      return false;
307    }
308
309
310    [Storable]
311    private bool depthWasDoubled = false;
312    public void DoubleDepth() {
313      if (!depthWasDoubled) {
314        var oldDepth = BinMeasures.Depth;
315        BinMeasures.Depth = BinMeasures.Depth * 2;
316        //OccupiedPoints.ChangeBinMeasures(BinMeasures);
317        depthWasDoubled = true;
318      }
319    }
320         
321    public bool IsSupportedByAtLeastOnePoint(CuboidPackingItem item, ThreeDimensionalPacking position) {
322      if (position.Y == 0)
323        return true;
324
325      int y = position.Y - 1;
326      for (int x = position.X; x < position.X + item.Width; x++)
327        for (int z = position.Z; z < position.Z + item.Depth; z++)
328          if (IsPointOccupied(new ThreeDimensionalPacking(0, x, y, z)))
329            return true;
330     
331      return false;
332    }
333    public bool IsWeightSupported(CuboidPackingItem item, ThreeDimensionalPacking ep) {
334      if (ep.Y == 0)
335        return true;
336
337      if (ItemMeasures[PointOccupation(new ThreeDimensionalPacking(0, ep.X, ep.Y - 1, ep.Z))].SupportsStacking(item)
338        && ItemMeasures[PointOccupation(new ThreeDimensionalPacking(0, ep.X + item.Width, ep.Y - 1, ep.Z))].SupportsStacking(item)
339        && ItemMeasures[PointOccupation(new ThreeDimensionalPacking(0, ep.X, ep.Y - 1, ep.Z + item.Depth))].SupportsStacking(item)
340        && ItemMeasures[PointOccupation(new ThreeDimensionalPacking(0, ep.X + item.Width, ep.Y - 1, ep.Z + item.Depth))].SupportsStacking(item))
341        return true;
342
343      return false;
344    }
345  }
346}
Note: See TracBrowser for help on using the repository browser.