Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.BinPacking/HeuristicLab.Problems.BinPacking/3.3/Encodings/PackingPlans/BinPacking2D.cs @ 9674

Last change on this file since 9674 was 9599, checked in by jhelm, 12 years ago

#1966: Bugfixing; Refactoring; Performancetuning;

File size: 10.1 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("BinPacking2D", "Represents a single-bin packing for a 2D bin-packing problem.")]
40  [StorableClass]
41  public class BinPacking2D : BinPacking<TwoDimensionalPacking, RectangularPackingBin, RectangularPackingItem> {
42
43    public BinPacking2D(RectangularPackingBin binMeasures)
44      : base(binMeasures) {
45      //ExtremePoints = new HashSet<TwoDimensionalPacking>();
46      ExtremePoints = new SortedSet<TwoDimensionalPacking>(new EPComparer2D());
47      ExtremePoints.Add(binMeasures.Origin);
48    }
49    [StorableConstructor]
50    protected BinPacking2D(bool deserializing) : base(deserializing) { }
51    protected BinPacking2D(BinPacking2D original, Cloner cloner)
52      : base(original, cloner) {
53      this.ExtremePoints = new SortedSet<TwoDimensionalPacking>(original.ExtremePoints, new EPComparer2D());
54    }
55    public override IDeepCloneable Clone(Cloner cloner) {
56      return new BinPacking2D(this, cloner);
57    }
58                     
59    protected override void GenerateNewExtremePointsForNewItem(RectangularPackingItem newItem, TwoDimensionalPacking position) {
60
61      int newWidth = position.Rotated ? newItem.Height : newItem.Width;
62      int newHeight = position.Rotated ? newItem.Width : newItem.Height;
63
64      //Find ExtremePoints beginning from sourcepointX
65      var sourcePointX = new TwoDimensionalPacking(0, position.X + newWidth, position.Y);
66      if (sourcePointX.X < BinMeasures.Width && sourcePointX.Y < BinMeasures.Height) {
67        //Traversing down the y-axis       
68        while (sourcePointX.Y > 0 && !IsPointOccupied(new TwoDimensionalPacking(0, sourcePointX.X, sourcePointX.Y - 1))) {
69          sourcePointX.Y--;
70        }
71        ExtremePoints.Add(new TwoDimensionalPacking(0, sourcePointX.X, sourcePointX.Y));
72      }
73
74
75
76
77      //Find ExtremePoints beginning from sourcepointY
78      var sourcePointY = new TwoDimensionalPacking(0, position.X, position.Y + newItem.Height);
79      if (sourcePointY.X < BinMeasures.Width && sourcePointY.Y < BinMeasures.Height) {
80        //Traversing down the x-axis 
81        while (sourcePointY.X > 0 && !IsPointOccupied(new TwoDimensionalPacking (0,sourcePointY.X - 1, sourcePointY.Y))) {
82          sourcePointY.X--;
83        }
84        ExtremePoints.Add(new TwoDimensionalPacking(0, sourcePointY.X, sourcePointY.Y));
85      }
86
87      //ExtremePoints.RemoveWhere(ep => IsPointOccupied(ep));
88
89      //ExtremePoints = new HashSet<TwoDimensionalPacking>(ExtremePoints.
90      //  OrderBy(ep => ep.X).
91      //  ThenBy(ep => ep.Y).
92      //  ThenBy(ep => ShortestPossibleSideFromPoint(ep)));
93    }
94
95    public override TwoDimensionalPacking FindExtremePointForItem(RectangularPackingItem measures, bool rotated, bool stackingConstraints) {
96      RectangularPackingItem item = new RectangularPackingItem(
97        rotated ? measures.Height : measures.Width,
98        rotated ? measures.Width : measures.Height,
99        measures.TargetBin);
100
101      int epIndex = 0;
102      while (epIndex < ExtremePoints.Count && (!IsPositionFeasible(item, ExtremePoints.ElementAt(epIndex)))) { epIndex++; }
103
104      if (epIndex < ExtremePoints.Count) {
105        var result = ExtremePoints.ElementAt(epIndex);
106        result.Rotated = rotated;
107        return result;
108      }
109      return null;
110    }
111    public override TwoDimensionalPacking FindPositionBySliding(RectangularPackingItem measures, bool rotated) {
112      TwoDimensionalPacking currentPosition = new TwoDimensionalPacking(0,
113        BinMeasures.Width - (rotated ? measures.Height : measures.Width),
114        BinMeasures.Height - (rotated ? measures.Width : measures.Height), rotated);
115      //Slide the item as far as possible to the left
116      while (IsPositionFeasible(measures, TwoDimensionalPacking.MoveLeft(currentPosition))
117        || IsPositionFeasible(measures, TwoDimensionalPacking.MoveDown(currentPosition))) {
118        //Slide the item as far as possible to the bottom
119          while (IsPositionFeasible(measures, TwoDimensionalPacking.MoveDown(currentPosition))) {
120            currentPosition = TwoDimensionalPacking.MoveDown(currentPosition);
121        }
122          if (IsPositionFeasible(measures, TwoDimensionalPacking.MoveLeft(currentPosition)))
123          currentPosition = TwoDimensionalPacking.MoveLeft(currentPosition);
124      }
125
126      return IsPositionFeasible(measures, currentPosition) ? currentPosition : null;
127    }
128   
129    public override void SlidingBasedPacking(ref List<int> sequence, ItemList<RectangularPackingItem> itemMeasures) {
130      var temp = new List<int>(sequence);
131      for (int i = 0; i < temp.Count; i++) {
132        var item = itemMeasures[temp[i]];
133        var position = FindPositionBySliding(item, false);
134        if (position != null) {
135          PackItem(temp[i], item, position);
136          sequence.Remove(temp[i]);
137        }
138      }
139    }
140    public override void SlidingBasedPacking(ref List<int> sequence, ItemList<RectangularPackingItem> itemMeasures, Dictionary<int, bool> rotationArray) {
141      var temp = new List<int>(sequence);
142      for (int i = 0; i < temp.Count; i++) {
143        var item = itemMeasures[temp[i]];
144        var position = FindPositionBySliding(item, rotationArray[temp[i]]);
145        if (position != null) {
146          PackItem(temp[i], item, position);
147          sequence.Remove(temp[i]);
148        }
149      }
150    }
151    public override void ExtremePointBasedPacking(ref List<int> sequence, ItemList<RectangularPackingItem> itemMeasures, bool stackingConstraints) {
152      var temp = new List<int>(sequence);
153      foreach (int itemID in temp) {
154        var item = itemMeasures[itemID];
155        var positionFound = FindExtremePointForItem(item, false, false);
156        if (positionFound != null) {
157          PackItem(itemID, item, positionFound);
158          sequence.Remove(itemID);
159        }
160      }
161    }
162    public override void ExtremePointBasedPacking(ref List<int> sequence, ItemList<RectangularPackingItem> itemMeasures, bool stackingConstraints, Dictionary<int, bool> rotationArray) {
163      var temp = new List<int>(sequence);
164      foreach (int itemID in temp) {
165        var item = itemMeasures[itemID];
166        var positionFound = FindExtremePointForItem(item, rotationArray[itemID], false);
167        if (positionFound != null) {
168          PackItem(itemID, item, positionFound);
169          sequence.Remove(itemID);
170        }
171      }
172    }
173
174    public override int ShortestPossibleSideFromPoint(TwoDimensionalPacking position) {
175      int shortestSide = int.MaxValue;
176      int width = BinMeasures.Width;
177      int height = BinMeasures.Height;
178
179      if (position.X >= width || position.Y >= height)
180        return shortestSide;
181
182      TwoDimensionalPacking current = new TwoDimensionalPacking(0, position.X, position.Y);
183      while (current.X < width && IsPointOccupied(current)) { current = TwoDimensionalPacking.MoveRight(current); }
184      if (current.X - position.X < shortestSide)
185        shortestSide = current.X - position.X;
186
187
188      current = new TwoDimensionalPacking(0, position.X, position.Y);
189      while (current.Y < height && IsPointOccupied(current)) { current = TwoDimensionalPacking.MoveUp(current); }
190      if (current.Y - position.Y < shortestSide)
191        shortestSide = current.Y - position.Y;
192
193      return shortestSide;
194    }
195    public override bool IsStaticStable(RectangularPackingItem item, TwoDimensionalPacking position) {
196      throw new NotImplementedException();
197    }
198
199
200    protected override void InitializeOccupationLayers() {
201      for (int i = 0; i*10 <= BinMeasures.Width; i += 1 ) {
202        OccupationLayers[i] = new List<int>();
203      }
204    }
205    protected override void AddNewItemToOccupationLayers(int itemID, RectangularPackingItem measures, TwoDimensionalPacking position) {
206      int x1 = position.X / 10;
207      int x2 = (position.X + (position.Rotated ? measures.Height : measures.Width)) / 10;
208
209      for (int i = x1; i <= x2; i++)
210        OccupationLayers[i].Add(itemID);
211    }
212    protected override List<int> GetLayerItemIDs(TwoDimensionalPacking position) {
213      return OccupationLayers[position.X / 10];
214    }
215    protected override List<int> GetLayerItemIDs(RectangularPackingItem measures, TwoDimensionalPacking position) {
216      List<int> result = new List<int> ();
217      int x1 = position.X / 10;
218      int x2 = (position.X + (position.Rotated ? measures.Height : measures.Width)) / 10;
219
220      for (int i = x1; i <= x2; i++)
221        result.AddRange(OccupationLayers[i]);
222
223      return result;
224    }
225  }
226  public class EPComparer2D : IComparer<TwoDimensionalPacking> {
227    public int Compare(TwoDimensionalPacking a, TwoDimensionalPacking b) {
228      int result = a.X.CompareTo(b.X);
229      if (result == 0)
230        result = a.Y.CompareTo(b.Y);
231
232      return result;
233    }
234  }
235}
Note: See TracBrowser for help on using the repository browser.