#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
}
}