#region License Information /* HeuristicLab * Copyright (C) 2002-2018 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; 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 MaterialParameter { get { return (IFixedValueParameter)Parameters["Material"]; } } 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 Material { get { return MaterialParameter.Value.Value; } set { MaterialParameter.Value.Value = value; } } public IFixedValueParameter SupportedWeightParameter { get { return (IFixedValueParameter)Parameters["SupportedWeight"]; } } public double SupportedWeight { get { return SupportedWeightParameter.Value.Value; } set { SupportedWeightParameter.Value.Value = value; } } 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.Material < this.Material) || (other.Material.Equals(this.Material) && other.Weight <= this.Weight)); } #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("Material")); 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 material) : this(width, height, depth, targetBin) { this.Weight = weight; this.Material = material; } public PackingItem(PackingItem packingItem) : this() { OriginalWidth = packingItem.OriginalWidth; OriginalHeight = packingItem.OriginalHeight; OriginalDepth = packingItem.OriginalDepth; TargetBin = (PackingShape)packingItem.TargetBin.Clone(); Weight = packingItem.Weight; Material = packingItem.Material; Rotated = packingItem.Rotated; Tilted = packingItem.Tilted; IsStackabel = packingItem.IsStackabel; 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(); MaterialParameter.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}, mat={4})", this.Width, this.Height, this.Depth, this.Weight, this.Material); } } }