#region License Information
/* HeuristicLab
* Copyright (C) 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 HEAL.Attic;
using HeuristicLab.Common;
using System.Collections.Generic;
using System.Linq;
using HeuristicLab.Encodings.IntegerVectorEncoding;
namespace HeuristicLab.Problems.BinPacking2D {
[StorableType("63588140-31BB-402A-BEEE-B11C8809A585")]
public abstract class IntegerVectorDecoderBase : Item, IDecoder {
[StorableConstructor]
protected IntegerVectorDecoderBase(StorableConstructorFlag _) : base(_) { }
protected IntegerVectorDecoderBase(IntegerVectorDecoderBase original, Cloner cloner)
: base(original, cloner) {
}
protected IntegerVectorDecoderBase() : base() { }
public virtual Solution Decode(IntegerVector intVec, PackingShape binShape, IList items) {
var sequenceMatrix = IntegerVectorProblem.GenerateSequenceMatrix(intVec);
Solution result = CreateSolution(binShape);
//Fill bins according to grouping vector
IList remainingIDs = new List();
foreach (var sequence in sequenceMatrix) {
remainingIDs = remainingIDs.Concat(sequence).ToList();
result.Bins.Add(CreatePacking(result, ref remainingIDs, items));
}
result.UpdateBinPackings();
//Try to put remaining items in existing bins
var temp = new List(remainingIDs);
foreach (int id in temp) {
foreach (BinPacking2D bp in result.Bins) {
var position = FindPositionForItem(bp, items[id]);
if (position != null) {
bp.PackItem(id, items[id], position);
remainingIDs.Remove(id);
break;
}
}
}
//Put still remaining items in new bins
while (remainingIDs.Count > 0) {
result.Bins.Add(CreatePacking(result, ref remainingIDs, items));
}
result.UpdateBinPackings();
// gkronber: original implementation by Helm also updates the encoded solution (TODO)
// var newSolution = new int[intVec.Length];
// int binIndex = 0;
// foreach (var bp in result.BinPackings) {
// foreach (var entry in bp.ItemPositions)
// newSolution[entry.Key] = binIndex;
// binIndex++;
// }
// solution.GroupingVector = new IntegerVector(newSolution);
return result;
}
protected abstract Solution CreateSolution(PackingShape binShape);
protected abstract PackingPosition FindPositionForItem(BinPacking2D bp, PackingItem item);
protected abstract BinPacking2D CreatePacking(Solution partialSolution, ref IList remainingIDs, IList items);
}
}