Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PackingShape.cs

Last change on this file was 16140, checked in by abeham, 6 years ago

#2817: updated to trunk r15680

File size: 7.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 Joseph Helm and 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 HeuristicLab.Core;
24using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
25using HeuristicLab.Common;
26using HeuristicLab.Data;
27using HeuristicLab.Parameters;
28using HeuristicLab.Problems.BinPacking;
29using HeuristicLab.Problems.BinPacking3D.Material;
30
31namespace HeuristicLab.Problems.BinPacking3D {
32  [Item("PackingShape (3d)", "Represents the cuboid measures (width, height, depth) of a three-dimensional cuboidic bin-packing object.")]
33  [StorableClass]
34  public class PackingShape : PackingShape<PackingPosition>, IComparable<PackingShape> {
35    public IFixedValueParameter<IntValue> HeightParameter {
36      get { return (IFixedValueParameter<IntValue>)Parameters["Height"]; }
37    }
38    public IFixedValueParameter<IntValue> WidthParameter {
39      get { return (IFixedValueParameter<IntValue>)Parameters["Width"]; }
40    }
41    public IFixedValueParameter<IntValue> DepthParameter {
42      get { return (IFixedValueParameter<IntValue>)Parameters["Depth"]; }
43    }
44
45    public int Height {
46      get { return HeightParameter.Value.Value; }
47      set { HeightParameter.Value.Value = value; }
48    }
49
50    public int Width {
51      get { return WidthParameter.Value.Value; }
52      set { WidthParameter.Value.Value = value; }
53    }
54
55    public int Depth {
56      get { return DepthParameter.Value.Value; }
57      set { DepthParameter.Value.Value = value; }
58    }
59
60    public IFixedValueParameter<EnumValue<MaterialType>> MaterialBottomParameter {
61      get { return (IFixedValueParameter<EnumValue<MaterialType>>)Parameters["MaterialBottom"]; }
62    }
63    public MaterialType MaterialBottom {
64      get { return MaterialBottomParameter.Value.Value; }
65      set { MaterialBottomParameter.Value.Value = value; }
66    }
67
68    [StorableConstructor]
69    protected PackingShape(bool deserializing) : base(deserializing) { }
70    protected PackingShape(PackingShape original, Cloner cloner)
71      : base(original, cloner) {
72      RegisterEvents();
73    }
74    public PackingShape()
75      : base() {
76      Parameters.Add(new FixedValueParameter<IntValue>("Width"));
77      Parameters.Add(new FixedValueParameter<IntValue>("Height"));
78      Parameters.Add(new FixedValueParameter<IntValue>("Depth"));
79      Parameters.Add(new FixedValueParameter<EnumValue<MaterialType>>("MaterialBottom"));
80
81      MaterialBottom = MaterialType.ScreenPrintingPlate;
82
83      RegisterEvents();
84    }
85
86    public PackingShape(int width, int height, int depth)
87      : this() {
88      this.Width = width;
89      this.Height = height;
90      this.Depth = depth;
91    }
92
93    public override IDeepCloneable Clone(Cloner cloner) {
94      return new PackingShape(this, cloner);
95    }
96
97    [StorableHook(HookType.AfterDeserialization)]
98    private void AfterDeserialization() {
99      RegisterEvents();
100    }
101
102    private void RegisterEvents() {
103      // only because of ToString override
104      HeightParameter.Value.ValueChanged += (sender, args) => OnToStringChanged();
105      WidthParameter.Value.ValueChanged += (sender, args) => OnToStringChanged();
106      DepthParameter.Value.ValueChanged += (sender, args) => OnToStringChanged();
107    }
108
109    public override string ToString() {
110      return String.Format("CuboidPackingShape ({0}, {1}, {2})", this.Width, this.Height, this.Depth);
111    }
112
113    #region IComparable Members
114
115    public int CompareTo(PackingShape other) {
116      //Using "Clustered-Area-Height"-comparison as descr
117
118      int result = (this.Width * this.Depth).CompareTo(other.Width * other.Depth);
119
120      if (result == 0)
121        result = this.Volume.CompareTo(other.Volume);
122      if (result == 0)
123        result = this.Height.CompareTo(other.Height);
124      return result;
125    }
126
127    public override int CompareTo(object obj) {
128      var other = (PackingShape)obj;
129      if (other != null) return CompareTo(other);
130      else throw new ArgumentException(string.Format("Cannot compare with object {0}", obj), "obj");
131    }
132
133    #endregion
134
135    private struct CuboidDiagonal {
136      public int x1;
137      public int y1;
138      public int z1;
139      public int x2;
140      public int y2;
141      public int z2;
142      public CuboidDiagonal(PackingShape myShape) : this(new PackingPosition(0, 0, 0, 0), myShape) { }
143      public CuboidDiagonal(PackingPosition myPosition, PackingShape myShape) {
144        x1 = myPosition.X;
145        y1 = myPosition.Y;
146        z1 = myPosition.Z;
147        x2 = myPosition.X + (myPosition.Rotated ? myShape.Depth : myShape.Width) - 1;
148        y2 = myPosition.Y + myShape.Height - 1;
149        z2 = myPosition.Z + (myPosition.Rotated ? myShape.Width : myShape.Depth) - 1;
150      }
151    }
152
153
154    #region Helpers
155    public override PackingPosition Origin { get { return new PackingPosition(0, 0, 0, 0); } }
156    public override int Volume { get { return Width * Height * Depth; } }
157
158    public override bool EnclosesPoint(PackingPosition myPosition, PackingPosition checkedPoint) {
159      return (myPosition.X <= checkedPoint.X &&
160                (myPosition.X + (myPosition.Rotated ? Depth : Width) - 1) >= checkedPoint.X &&
161                myPosition.Y <= checkedPoint.Y &&
162                (myPosition.Y + Height - 1) >= checkedPoint.Y &&
163                myPosition.Z <= checkedPoint.Z &&
164                (myPosition.Z + (myPosition.Rotated ? Width : Depth) - 1) >= checkedPoint.Z);
165    }
166    public override bool Encloses(PackingPosition checkedPosition, PackingShape<PackingPosition> checkedShape) {
167      return Encloses(checkedPosition, (PackingShape)checkedShape);
168    }
169    private bool Encloses(PackingPosition checkedPosition, PackingShape checkedShape) {
170      return Encloses(new CuboidDiagonal(this), new CuboidDiagonal(checkedPosition, checkedShape));
171    }
172    private bool Encloses(CuboidDiagonal c1, CuboidDiagonal c2) {
173      return (c1.x1 <= c2.x1 &&
174                c1.x2 >= c2.x2 &&
175                c1.y1 <= c2.y1 &&
176                c1.y2 >= c2.y2 &&
177                c1.z1 <= c2.z1 &&
178                c1.z2 >= c2.z2);
179    }
180
181    public override bool Overlaps(PackingPosition myPosition, PackingPosition checkedPosition, PackingShape<PackingPosition> checkedShape) {
182      return Overlaps(myPosition, checkedPosition, (PackingShape)checkedShape);
183    }
184    private bool Overlaps(PackingPosition myPosition, PackingPosition checkedPosition, PackingShape checkedShape) {
185      return Overlaps(new CuboidDiagonal(myPosition, this), new CuboidDiagonal(checkedPosition, checkedShape));
186    }
187    private bool Overlaps(CuboidDiagonal c1, CuboidDiagonal c2) {
188      return !(c1.x1 > c2.x2 ||
189               c1.y1 > c2.y2 ||
190               c1.z1 > c2.z2 ||
191               c1.x2 < c2.x1 ||
192               c1.y2 < c2.y1 ||
193               c1.z2 < c2.z1);
194    }
195
196    public override void ApplyHorizontalOrientation() {
197      if (Width > Depth) {
198        var aux = Width;
199        Width = Depth;
200        Depth = aux;
201      }
202    }
203    #endregion
204
205  }
206}
Note: See TracBrowser for help on using the repository browser.