#region License Information /* HeuristicLab * Copyright (C) 2002-2015 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 System; using System.Linq; using HeuristicLab.Problems.BinPacking.Interfaces; using HeuristicLab.Problems.BinPacking.Shapes; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Common; using HeuristicLab.Parameters; using HeuristicLab.Problems.BinPacking.Decoders; using HeuristicLab.PluginInfrastructure; using HeuristicLab.Data; using HeuristicLab.Problems.BinPacking.Analyzers; using HeuristicLab.Encodings.PackingEncoding.PackingSequence; using HeuristicLab.Encodings.PackingEncoding.GroupingVector; using HeuristicLab.Problems.Instances; using HeuristicLab.Encodings.PackingEncoding.MultiComponentVector; namespace HeuristicLab.Problems.BinPacking.Problem { [Item("RegularIdenticalBinPackingProblem", "Represents a bin-packing problem-instance using only bins with identical measures and bins/items with regular shapes (e.g. rectangle, cuboid).")] [StorableClass] public abstract class RegularIdenticalBinPackingProblem : BinPackingProblem, IProblemInstanceConsumer, IProblemInstanceExporter where D : class, IPackingDimensions where B : PackingShape, IPackingBin, IRegularPackingShape, new() where I : PackingShape, IPackingItem, IRegularPackingShape, new() { #region Parameter Properties #endregion #region Properties #endregion [StorableConstructor] protected RegularIdenticalBinPackingProblem(bool deserializing) : base(deserializing) { } protected RegularIdenticalBinPackingProblem(RegularIdenticalBinPackingProblem original, Cloner cloner) : base(original, cloner) { InitializeEventHandlers(); } protected RegularIdenticalBinPackingProblem(IPackingPlanEvaluationAlgorithm e) : this(e, new MultiComponentVectorRandomCreator()) { } protected RegularIdenticalBinPackingProblem(IPackingPlanEvaluationAlgorithm e, IPackingSolutionCreator c) : base(e, c) { Parameters.Add(new ValueParameter("PackingBinMeasures", "Packing-bin data defining the measures of the used bins.", new B())); Parameters.Add(new ValueParameter("PackingPlanEvaluator", "The evaluator is used to determine the quality of a solution.", CreateDefaultEvaluator())); Parameters.Add(new ConstrainedValueParameter("PackingSolutionDecoder", "The operator that decodes the representation and creates a packing plan.")); this.Maximization.Value = true; InitializeProblemInstance(); InitializeOperators(); InitializeEventHandlers(); } #region Helpers protected override void InitializeProblemInstance() { InitializeProblemData(); ApplyHorizontalOrientation(); SortItems(); RemoveTooBigItems(); PackingItemsParameter.Value.Value = PackingItemMeasures.Count; LowerBoundParameter.Value.Value = CalculateLowerBound(); } protected abstract void RemoveTooBigItems(); protected abstract void InitializeProblemData(); protected abstract IPackingPlanEvaluator CreateDefaultEvaluator(); protected void ApplyHorizontalOrientation() { PackingBinMeasures.ApplyHorizontalOrientation(); foreach (IRegularPackingShape shape in PackingItemMeasures) { shape.ApplyHorizontalOrientation(); } } protected void SortItems() { PackingItemMeasures.Sort((x, y) => y.CompareTo(x)); } protected int CalculateLowerBound() { //This is the obvious continuous lower bound calculation; Martello and Vigo proposed a better way but it has not been implemented yet; int items = PackingItemMeasures.Select(x => x.Volume).Sum(); int bin = PackingBinMeasures.Volume; return (items + bin - 1) / (bin); } protected override void InitializeOperators() { Operators.Clear(); Operators.Add(new BestBinPackingSolutionAnalyzer()); ApplyEncoding(); ParameterizeOperators(); } private void ApplyEncoding() { if (SolutionCreator.GetType() == typeof(PackingSequenceRandomCreator)) { Operators.AddRange(ApplicationManager.Manager.GetInstances()); InitializeDecoder(); } else if (SolutionCreator.GetType() == typeof(GroupingVectorRandomCreator)) { Operators.AddRange(ApplicationManager.Manager.GetInstances()); InitializeDecoder(); } else if (SolutionCreator.GetType() == typeof(MultiComponentVectorRandomCreator)) { Operators.AddRange(ApplicationManager.Manager.GetInstances()); InitializeDecoder(); } } private void ParameterizeOperators() { foreach (var op in Operators.OfType>()) { op.QualityParameter.ActualName = PackingPlanEvaluator.QualityParameter.ActualName; } Evaluator.PackingSolutionDecoderParameter.ActualName = PackingSolutionDecoderParameter.Name; Evaluator.PackingSolutionDecoderParameter.Hidden = true; Evaluator.PackingPlanEvaluatorParameter.ActualName = PackingPlanEvaluatorParameter.Name; Evaluator.PackingPlanEvaluatorParameter.Hidden = true; Evaluator.QualityParameter.ActualName = PackingPlanEvaluator.QualityParameter.ActualName; Evaluator.QualityParameter.Hidden = true; if (PackingSolutionDecoder != null) PackingSolutionDecoder.EncodedSolutionParameter.ActualName = SolutionCreator.EncodedSolutionParameter.ActualName; if (PackingSolutionDecoder != null) { PackingPlanEvaluator.PackingPlanParameter.ActualName = PackingSolutionDecoder.PackingPlanParameter.ActualName; PackingPlanEvaluator.PackingPlanParameter.Hidden = true; } else { PackingPlanEvaluator.PackingPlanParameter.ActualName = PackingPlanEvaluator.PackingPlanParameter.Name; PackingPlanEvaluator.PackingPlanParameter.Hidden = false; } foreach (var op in Operators.OfType()) { op.EncodedSolutionParameter.ActualName = SolutionCreator.EncodedSolutionParameter.ActualName; op.EncodedSolutionParameter.Hidden = true; } foreach (var op in Operators.OfType()) { op.ChildParameter.ActualName = SolutionCreator.EncodedSolutionParameter.ActualName; op.ChildParameter.Hidden = true; op.ParentsParameter.ActualName = SolutionCreator.EncodedSolutionParameter.ActualName; op.ParentsParameter.Hidden = true; } foreach (var op in Operators.OfType>()) { op.QualityParameter.ActualName = PackingPlanEvaluator.QualityParameter.ActualName; if (PackingSolutionDecoder != null) { op.PackingPlanParameter.ActualName = PackingSolutionDecoder.PackingPlanParameter.ActualName; op.PackingPlanParameter.Hidden = true; } else { op.PackingPlanParameter.ActualName = op.PackingPlanParameter.Name; op.PackingPlanParameter.Hidden = false; } } } protected override void InitializeEventHandlers() { PackingPlanEvaluatorParameter.ValueChanged += PackingPlanEvaluatorParameter_ValueChanged; PackingPlanEvaluator.QualityParameter.ActualNameChanged += PackingPlanEvaluator_QualityParameter_ActualNameChanged; SolutionCreatorParameter.ValueChanged += SolutionCreatorParameter_ValueChanged; SolutionCreator.EncodedSolutionParameter.ActualNameChanged += SolutionCreator_EncodedSolutionParameter_ActualNameChanged; PackingSolutionDecoderParameter.ValueChanged += PackingSolutionDecoderParameter_ValueChanged; if (PackingSolutionDecoder != null) PackingSolutionDecoder.PackingPlanParameter.ActualNameChanged += PackingSolutionDecoder_PackingPlanParameter_ActualNameChanged; } #endregion #region Events protected override void OnSolutionCreatorChanged() { InitializeOperators(); } protected override void OnEvaluatorChanged() { base.OnEvaluatorChanged(); ParameterizeOperators(); } private void PackingPlanEvaluatorParameter_ValueChanged(object sender, EventArgs eventArgs) { PackingPlanEvaluator.QualityParameter.ActualNameChanged += PackingPlanEvaluator_QualityParameter_ActualNameChanged; ParameterizeOperators(); } private void PackingPlanEvaluator_QualityParameter_ActualNameChanged(object sender, EventArgs eventArgs) { ParameterizeOperators(); } private void SolutionCreatorParameter_ValueChanged(object sender, EventArgs eventArgs) { SolutionCreator.EncodedSolutionParameter.ActualNameChanged += SolutionCreator_EncodedSolutionParameter_ActualNameChanged; ParameterizeOperators(); } private void SolutionCreator_EncodedSolutionParameter_ActualNameChanged(object sender, EventArgs eventArgs) { ParameterizeOperators(); } private void PackingSolutionDecoderParameter_ValueChanged(object sender, EventArgs eventArgs) { if (PackingSolutionDecoder != null) PackingSolutionDecoder.PackingPlanParameter.ActualNameChanged += PackingSolutionDecoder_PackingPlanParameter_ActualNameChanged; ParameterizeOperators(); } private void PackingSolutionDecoder_PackingPlanParameter_ActualNameChanged(object sender, EventArgs eventArgs) { ParameterizeOperators(); } public abstract void Load(BPPData data); public abstract BPPData Export(); #endregion } }