Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1966: More refactoring; Added more sophisticated structures for packing-plan and bin-packing representation; Transferred parts of the decoding-algorithms to these structures; Did some more refactoring and cleanup;

File size: 13.7 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        int currentYValue = sourcePointX.Y;
65        while (currentYValue > 0 && !IsPointOccupied(new ThreeDimensionalPacking (0, sourcePointX.X, currentYValue, sourcePointX.Z))) {
66          currentYValue--;
67        }
68        ExtremePoints.Add(new ThreeDimensionalPacking(0, sourcePointX.X, currentYValue, sourcePointX.Z));
69
70        //Traversing down the z-axis
71        int currentZValue = sourcePointX.Z;
72        while (currentZValue > 0 && !IsPointOccupied(new ThreeDimensionalPacking (0, sourcePointX.X, sourcePointX.Y, currentZValue - 1))) {
73          currentZValue--;
74        }
75        ExtremePoints.Add(new ThreeDimensionalPacking(0, sourcePointX.X, sourcePointX.Y, currentZValue));
76      }
77
78
79
80
81      //Find ExtremePoints beginning from sourcepointY
82      var sourcePointY = new ThreeDimensionalPacking(0, position.X, position.Y + newItem.Height, position.Z);
83      if (sourcePointY.X < BinMeasures.Width && sourcePointY.Y < BinMeasures.Height && sourcePointY.Z < BinMeasures.Depth) {
84        //Traversing down the x-axis 
85        int currentXValue = sourcePointY.X;
86        while (currentXValue > 0 && !IsPointOccupied(new ThreeDimensionalPacking (0, currentXValue - 1, sourcePointY.Y, sourcePointY.Z))) {
87          currentXValue--;
88        }
89        ExtremePoints.Add(new ThreeDimensionalPacking(0, currentXValue, sourcePointY.Y, sourcePointY.Z));
90
91        //Traversing down the z-axis
92        int currentZValue = sourcePointY.Z;
93        while (currentZValue > 0 && !IsPointOccupied(new ThreeDimensionalPacking (0, sourcePointY.X, sourcePointY.Y, currentZValue - 1))) {
94          currentZValue--;
95        }
96        ExtremePoints.Add(new ThreeDimensionalPacking(0, sourcePointY.X, sourcePointY.Y, currentZValue));
97      }
98
99
100
101
102
103      //Find ExtremePoints beginning from sourcepointZ
104      var sourcePointZ = new ThreeDimensionalPacking(0, position.X, position.Y, position.Z + newDepth);
105      if (sourcePointZ.X < BinMeasures.Width && sourcePointZ.Y < BinMeasures.Height && sourcePointZ.Z < BinMeasures.Depth) {
106        //Traversing down the x-axis 
107        int currentXValue = sourcePointZ.X;
108        while (currentXValue > 0 && !IsPointOccupied(new ThreeDimensionalPacking (0, currentXValue - 1, sourcePointZ.Y, sourcePointZ.Z))) {
109          currentXValue--;
110        }
111        ExtremePoints.Add(new ThreeDimensionalPacking(0, currentXValue, sourcePointZ.Y, sourcePointZ.Z));
112
113        //Traversing down the y-axis                                                                           
114        int currentYValue = sourcePointZ.Y;
115        while (currentYValue > 0 && !IsPointOccupied(new ThreeDimensionalPacking (0, sourcePointZ.X, currentYValue, sourcePointZ.Z))) {
116          currentYValue--;
117        }
118        ExtremePoints.Add(new ThreeDimensionalPacking(0, sourcePointZ.X, currentYValue, sourcePointZ.Z));
119      }
120
121      ExtremePoints = new HashSet<ThreeDimensionalPacking>(ExtremePoints.
122        OrderBy(ep => ep.Z).
123        ThenBy(ep => ep.X).
124        ThenBy(ep => ep.Y).
125        ThenBy(ep => ShortestPossibleSideFromPoint(ep)));
126    }
127
128    public override ThreeDimensionalPacking FindExtremePointForItem(CuboidPackingItem measures, bool rotated, bool stackingConstraints) {
129
130      CuboidPackingItem item = new CuboidPackingItem(
131        rotated ? measures.Depth : measures.Width,
132        measures.Height,
133        rotated ? measures.Width : measures.Depth,
134        measures.TargetBin);
135
136      int epIndex = 0;
137      while (epIndex < ExtremePoints.Count && (
138        !IsPositionFeasible(item, ExtremePoints.ElementAt(epIndex)) || (stackingConstraints && !IsStaticStable(item, ExtremePoints.ElementAt(epIndex)))
139      )) { epIndex++; }
140
141      if (epIndex < ExtremePoints.Count) {
142        var result = ExtremePoints.ElementAt(epIndex);
143        result.Rotated = rotated;
144        return result;
145      }
146      return null;
147    }
148    public override ThreeDimensionalPacking FindPositionBySliding(CuboidPackingItem measures, bool rotated) {
149      //Starting-position at upper right corner (=left bottom point of item-rectangle is at position item.width,item.height)
150      ThreeDimensionalPacking currentPosition = new ThreeDimensionalPacking(0,
151        BinMeasures.Width - (rotated ? measures.Depth : measures.Width),
152        BinMeasures.Height - measures.Height,
153        BinMeasures.Depth - (rotated ? measures.Width : measures.Depth), rotated);
154      //Slide the item as far as possible to the bottom
155      while (IsPositionFeasible(measures, ThreeDimensionalPacking.MoveDown(currentPosition))
156        || IsPositionFeasible(measures, ThreeDimensionalPacking.MoveLeft(currentPosition))
157        || IsPositionFeasible(measures, ThreeDimensionalPacking.MoveBack(currentPosition))) {
158        //Slide the item as far as possible to the left
159          while (IsPositionFeasible(measures, ThreeDimensionalPacking.MoveLeft(currentPosition))
160        || IsPositionFeasible(measures, ThreeDimensionalPacking.MoveBack(currentPosition))) {
161          //Slide the item as far as possible to the back
162          while (IsPositionFeasible(measures, ThreeDimensionalPacking.MoveBack(currentPosition))) {
163            currentPosition = ThreeDimensionalPacking.MoveBack(currentPosition);
164          }
165          if (IsPositionFeasible(measures, ThreeDimensionalPacking.MoveLeft(currentPosition)))
166            currentPosition = ThreeDimensionalPacking.MoveLeft(currentPosition);
167        }
168          if (IsPositionFeasible(measures, ThreeDimensionalPacking.MoveDown(currentPosition)))
169            currentPosition = ThreeDimensionalPacking.MoveDown(currentPosition);
170      }
171
172      return IsPositionFeasible(measures, currentPosition) ? currentPosition : null;
173    }
174   
175    public override void SlidingBasedPacking(ref List<int> sequence, ItemList<CuboidPackingItem> itemMeasures) {
176      var temp = new List<int>(sequence);
177      for (int i = 0; i < temp.Count; i++) {
178        var item = itemMeasures[temp[i]];
179        var position = FindPositionBySliding(item, false);
180        if (position != null) {
181          PackItem(temp[i], item, position);
182          sequence.Remove(temp[i]);
183        }
184      }
185    }
186    public override void SlidingBasedPacking(ref List<int> sequence, ItemList<CuboidPackingItem> itemMeasures, Dictionary<int, bool> rotationArray) {
187      var temp = new List<int>(sequence);
188      for (int i = 0; i < temp.Count; i++) {
189        var item = itemMeasures[temp[i]];
190        var position = FindPositionBySliding(item, rotationArray[i]);
191        if (position != null) {
192          PackItem(temp[i], item, position);
193          sequence.Remove(temp[i]);
194        }
195      }
196    }
197    public override void ExtremePointBasedPacking(ref List<int> sequence, ItemList<CuboidPackingItem> itemMeasures, bool stackingConstraints) {
198      var temp = new List<int>(sequence);
199      foreach (int itemID in temp) {
200        var item = itemMeasures[itemID];
201        var positionFound = FindExtremePointForItem(item, false, stackingConstraints);
202        if (positionFound != null) {
203          PackItem(itemID, item, positionFound);
204          sequence.Remove(itemID);
205        }
206      }
207    }
208    public override void ExtremePointBasedPacking(ref List<int> sequence, ItemList<CuboidPackingItem> itemMeasures, bool stackingConstraints, Dictionary<int, bool> rotationArray) {
209      var temp = new List<int>(sequence);
210      foreach (int itemID in temp) {
211        var item = itemMeasures[itemID];
212        var positionFound = FindExtremePointForItem(item, rotationArray[itemID], stackingConstraints);
213        if (positionFound != null) {
214          PackItem(itemID, item, positionFound);
215          sequence.Remove(itemID);
216        }
217      }
218    }
219   
220
221    [Storable]
222    private bool depthWasDoubled = false;
223    public void DoubleDepth() {
224      if (!depthWasDoubled) {
225        var oldDepth = BinMeasures.Depth;
226        BinMeasures.Depth = BinMeasures.Depth * 2;
227        //OccupiedPoints.ChangeBinMeasures(BinMeasures);
228        depthWasDoubled = true;
229      }
230    }
231
232    public override int ShortestPossibleSideFromPoint(ThreeDimensionalPacking position) {
233
234      int shortestSide = int.MaxValue;
235      int width = BinMeasures.Width;
236      int height = BinMeasures.Height;
237      int depth = BinMeasures.Depth;
238
239      if (position.X >= width || position.Y >= height || position.Z >= depth)
240        return shortestSide;
241
242      ThreeDimensionalPacking current = new ThreeDimensionalPacking (0, position.X, position.Y, position.Z);
243      while (current.X < width && IsPointOccupied(current)) { current = ThreeDimensionalPacking.MoveRight(current); }
244      if (current.X - position.X < shortestSide)
245        shortestSide = current.X - position.X;
246
247
248      current = new ThreeDimensionalPacking(0, position.X, position.Y, position.Z);
249      while (current.Y < height && IsPointOccupied(current)) { current = ThreeDimensionalPacking.MoveUp (current); }
250      if (current.Y - position.Y < shortestSide)
251        shortestSide = current.Y - position.Y;
252
253
254      current = new ThreeDimensionalPacking(0, position.X, position.Y, position.Z);
255      while (current.Z < depth && IsPointOccupied(current)) { current = ThreeDimensionalPacking.MoveFront(current); }
256      if (current.Z - position.Z < shortestSide)
257        shortestSide = current.Z - position.Z;
258
259      return shortestSide;
260    }
261    public override bool IsStaticStable(CuboidPackingItem item, ThreeDimensionalPacking position) {
262      //Static stability is given, if item is placed on the ground
263      if (position.Y == 0)
264        return true;
265
266      if (IsPointOccupied (new ThreeDimensionalPacking (0, position.X, position.Y - 1, position.Z))
267        && IsPointOccupied (new ThreeDimensionalPacking (0, position.X + item.Width - 1, position.Y - 1, position.Z))
268        && IsPointOccupied (new ThreeDimensionalPacking (0, position.X, position.Y - 1, position.Z + item.Depth - 1))
269        && IsPointOccupied (new ThreeDimensionalPacking (0, position.X + item.Width - 1, position.Y - 1, position.Z + item.Depth - 1)))
270        return true;
271
272
273      //if (occupiedPoints[position.X, position.Y - 1, position.Z] != -1
274      //  && occupiedPoints[position.X + item.Width - 1, position.Y - 1, position.Z] != -1
275      //  && occupiedPoints[position.X, position.Y - 1, position.Z + item.Depth - 1] != -1
276      //  && occupiedPoints[position.X + item.Width - 1, position.Y - 1, position.Z + item.Depth - 1] != -1)
277      //  return true;
278
279      //int groundCount = 0;
280      //for (int x = ep.X; x < ep.X + item.Width - 1; x++) {
281      //  for (int z = ep.Z; z < ep.Z + item.Depth - 1; z++) {
282      //    if (occupiedPoints[x,ep.Y-1, z] != -1)                                                     
283      //      groundCount++;
284      //  }
285      //}
286      //double stableGround = (double)(groundCount) / (double)(item.Width * item.Depth);
287      //if (stableGround > 0.75)
288      //  return true;
289
290      return false;
291    }
292  }
293}
Note: See TracBrowser for help on using the repository browser.