#region License Information
/* HeuristicLab
* Copyright (C) 2002-2018 Joseph Helm and Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using HeuristicLab.Core;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
using HeuristicLab.Common;
using HeuristicLab.Data;
using HeuristicLab.Parameters;
using HeuristicLab.Problems.BinPacking;
using HeuristicLab.Problems.BinPacking3D.Material;
namespace HeuristicLab.Problems.BinPacking3D {
[Item("PackingItem (3d)", "Represents a cuboidic packing-item for bin-packing problems.")]
[StorableClass]
public class PackingItem : PackingShape, IPackingItem {
#region Properties
public IValueParameter TargetBinParameter {
get { return (IValueParameter)Parameters["TargetBin"]; }
}
public IFixedValueParameter WeightParameter {
get { return (IFixedValueParameter)Parameters["Weight"]; }
}
public IFixedValueParameter LayerParameter {
get { return (IFixedValueParameter)Parameters["Layer"]; }
}
public IFixedValueParameter SequenceGroupParameter {
get { return (IFixedValueParameter)Parameters["SequenceGroup"]; }
}
public IFixedValueParameter IdParameter {
get { return (IFixedValueParameter)Parameters["Id"]; }
}
public PackingShape TargetBin {
get { return TargetBinParameter.Value; }
set { TargetBinParameter.Value = value; }
}
public double Weight {
get { return WeightParameter.Value.Value; }
set { WeightParameter.Value.Value = value; }
}
public int Layer {
get { return LayerParameter.Value.Value; }
set { LayerParameter.Value.Value = value; }
}
public int SequenceGroup {
get { return SequenceGroupParameter.Value.Value; }
set { SequenceGroupParameter.Value.Value = value; }
}
public int Id {
get { return IdParameter.Value.Value; }
set { IdParameter.Value.Value = value; }
}
#region Material
public IFixedValueParameter> MaterialTopParameter {
get { return (IFixedValueParameter>)Parameters["MaterialTop"]; }
}
public MaterialType MaterialTop {
get { return MaterialTopParameter.Value.Value; }
set { MaterialTopParameter.Value.Value = value; }
}
#endregion
public IFixedValueParameter SupportedWeightParameter {
get { return (IFixedValueParameter)Parameters["SupportedWeight"]; }
}
public double SupportedWeight {
get { return SupportedWeightParameter.Value.Value; }
set { SupportedWeightParameter.Value.Value = value; }
}
public double SupportedWeightPerSquareMeter {
get {
return SupportedWeight / (Width * Depth);
}
}
public IValueParameter IsStackableParameter {
get { return (IValueParameter)Parameters["IsStackable"]; }
}
///
/// Indicates that another item can be stacked on the current one.
///
public bool IsStackabel {
get { return IsStackableParameter.Value.Value; }
set { IsStackableParameter.Value.Value = value; }
}
public IValueParameter RotateEnabledParameter {
get { return (IValueParameter)Parameters["RotateEnabled"]; }
}
public IValueParameter RotatedParameter {
get { return (IValueParameter)Parameters["Rotated"]; }
}
public IValueParameter TiltEnabledParameter {
get { return (IValueParameter)Parameters["TiltEnabled"]; }
}
public IValueParameter TiltedParameter {
get { return (IValueParameter)Parameters["Tilted"]; }
}
///
/// Enables that the current item can be rotated.
///
public bool RotateEnabled {
get { return RotateEnabledParameter.Value.Value; }
set { RotateEnabledParameter.Value.Value = value; }
}
///
/// Indicates that the current item is rotated.
/// If the item is also tilted it will be tilted first.
///
public bool Rotated {
get { return RotatedParameter.Value.Value; }
set { RotatedParameter.Value.Value = value; }
}
///
/// Enables that the current item can be tilted.
///
public bool TiltEnabled {
get { return TiltEnabledParameter.Value.Value; }
set { TiltEnabledParameter.Value.Value = value; }
}
///
/// Indicates that the current item is tilted.
/// Tilted means that the item is tilted sidewards.
/// If the item is also rotated it will be tilted first.
///
public bool Tilted {
get { return TiltedParameter.Value.Value; }
set { TiltedParameter.Value.Value = value; }
}
public IFixedValueParameter LoadSecuringHeightParameter {
get { return (IFixedValueParameter)Parameters["LoadSecuringHeight"]; }
}
public IFixedValueParameter LoadSecuringWidthParameter {
get { return (IFixedValueParameter)Parameters["LoadSecuringWidth"]; }
}
public IFixedValueParameter LoadSecuringDepthParameter {
get { return (IFixedValueParameter)Parameters["LoadSecuringDepth"]; }
}
public int LoadSecuringHeight {
get { return LoadSecuringHeightParameter.Value.Value; }
set { LoadSecuringHeightParameter.Value.Value = value; }
}
public int LoadSecuringWidth {
get { return LoadSecuringWidthParameter.Value.Value; }
set { LoadSecuringWidthParameter.Value.Value = value; }
}
public int LoadSecuringDepth {
get { return LoadSecuringDepthParameter.Value.Value; }
set { LoadSecuringDepthParameter.Value.Value = value; }
}
///
/// This property represents the height as needed in the bin packing.
///
public new int Height {
get {
if (!Tilted) {
return HeightParameter.Value.Value + LoadSecuringHeightParameter.Value.Value;
} else {
return WidthParameter.Value.Value + LoadSecuringHeightParameter.Value.Value;
}
}
}
///
/// This property represents the width as needed in the bin packing.
///
public new int Width {
get {
if (Rotated) {
return DepthParameter.Value.Value + LoadSecuringWidthParameter.Value.Value;
} else {
if (!Tilted) {
return WidthParameter.Value.Value + LoadSecuringWidthParameter.Value.Value;
} else {
return HeightParameter.Value.Value + LoadSecuringWidthParameter.Value.Value;
}
}
}
}
///
/// This property represents the depth as needed in the bin packing.
///
public new int Depth {
get {
if (!Rotated) {
return DepthParameter.Value.Value + LoadSecuringDepthParameter.Value.Value;
} else {
if (!Tilted) {
return WidthParameter.Value.Value + LoadSecuringDepthParameter.Value.Value;
} else {
return HeightParameter.Value.Value + LoadSecuringDepthParameter.Value.Value;
}
}
}
}
///
/// This property represents the height as it is seen in the view of the bin packing.
///
public int HeightInView {
get {
if (!Tilted) {
return HeightParameter.Value.Value;
} else {
return WidthParameter.Value.Value;
}
}
}
///
/// This property represents the width as it is seen in the view of the bin packing.
///
public int WidthInView {
get {
if (Rotated) {
return DepthParameter.Value.Value;
} else {
if (!Tilted) {
return WidthParameter.Value.Value;
} else {
return HeightParameter.Value.Value;
}
}
}
}
///
/// This property represents the depth as it is seen in the view of the bin packing.
///
public int DepthInView {
get {
if (!Rotated) {
return DepthParameter.Value.Value;
} else {
if (!Tilted) {
return WidthParameter.Value.Value;
} else {
return HeightParameter.Value.Value;
}
}
}
}
///
/// This property represents the original height.
///
public int OriginalHeight {
get { return HeightParameter.Value.Value; }
set { HeightParameter.Value.Value = value; }
}
///
/// This property represents the original width.
///
public int OriginalWidth {
get { return WidthParameter.Value.Value; }
set { WidthParameter.Value.Value = value; }
}
///
/// This property represents the original depth.
///
public int OriginalDepth {
get { return DepthParameter.Value.Value; }
set { DepthParameter.Value.Value = value; }
}
public bool SupportsStacking(IPackingItem other) {
return other.Layer <= this.Layer && SupportedWeight > 0;
}
public bool SupportWeight(double weigth) {
return SupportedWeight >= weigth;
}
#endregion
[StorableConstructor]
protected PackingItem(bool deserializing) : base(deserializing) { }
protected PackingItem(PackingItem original, Cloner cloner)
: base(original, cloner) {
RegisterEvents();
}
public PackingItem()
: base() {
Parameters.Add(new ValueParameter("TargetBin"));
Parameters.Add(new FixedValueParameter("Weight"));
Parameters.Add(new FixedValueParameter("Layer"));
Parameters.Add(new FixedValueParameter("SequenceGroup"));
Parameters.Add(new FixedValueParameter("Id"));
Parameters.Add(new FixedValueParameter>("MaterialTop"));
Parameters.Add(new FixedValueParameter("SupportedWeight"));
Parameters.Add(new FixedValueParameter("RotateEnabled"));
Parameters.Add(new FixedValueParameter("Rotated"));
Parameters.Add(new FixedValueParameter("TiltEnabled"));
Parameters.Add(new FixedValueParameter("Tilted"));
Parameters.Add(new FixedValueParameter("IsStackable"));
Parameters.Add(new FixedValueParameter("LoadSecuringHeight"));
Parameters.Add(new FixedValueParameter("LoadSecuringWidth"));
Parameters.Add(new FixedValueParameter("LoadSecuringDepth"));
IsStackabel = true;
RegisterEvents();
}
public PackingItem(int width, int height, int depth, PackingShape targetBin)
: this() {
this.OriginalWidth = width;
this.OriginalHeight = height;
this.OriginalDepth = depth;
this.TargetBin = (PackingShape)targetBin.Clone();
}
public PackingItem(int width, int height, int depth, PackingShape targetBin, double weight, int sequenceNumber, int layer)
: this(width, height, depth, targetBin) {
this.Weight = weight;
this.Layer = layer;
this.SequenceGroup = sequenceNumber;
}
public PackingItem(PackingItem packingItem) : this() {
OriginalWidth = packingItem.OriginalWidth;
OriginalHeight = packingItem.OriginalHeight;
OriginalDepth = packingItem.OriginalDepth;
TargetBin = (PackingShape)packingItem.TargetBin.Clone();
Weight = packingItem.Weight;
Layer = packingItem.Layer;
SequenceGroup = packingItem.SequenceGroup;
Id = packingItem.Id;
Rotated = packingItem.Rotated;
Tilted = packingItem.Tilted;
IsStackabel = packingItem.IsStackabel;
MaterialTop = packingItem.MaterialTop;
MaterialBottom = packingItem.MaterialBottom;
LoadSecuringDepth = packingItem.LoadSecuringDepth;
LoadSecuringHeight = packingItem.LoadSecuringHeight;
LoadSecuringWidth = packingItem.LoadSecuringWidth;
}
[StorableHook(HookType.AfterDeserialization)]
private void AfterDeserialization() {
RegisterEvents();
}
public override IDeepCloneable Clone(Cloner cloner) {
return new PackingItem(this, cloner);
}
private void RegisterEvents() {
// NOTE: only because of ToString override
WeightParameter.Value.ValueChanged += (sender, args) => OnToStringChanged();
LayerParameter.Value.ValueChanged += (sender, args) => OnToStringChanged();
// target bin does not occur in ToString()
}
public override string ToString() {
return string.Format("CuboidPackingItem ({0}, {1}, {2}; weight={3}, layer={4})", this.Width, this.Height, this.Depth, this.Weight, this.Layer);
}
}
}