#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.Common; using HeuristicLab.Core; using HeuristicLab.Encodings.PermutationEncoding; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.BinPacking3D; using HeuristicLab.Problems.BinPacking3D.ExtremePointCreation; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HeuristicLab.Problems.BinPacking3D.Packer { internal abstract class BinPacker : Item, IBinPacker { #region Constructors for HEAL [StorableConstructor] protected BinPacker(bool deserializing) : base(deserializing) { } protected BinPacker(BinPacker original, Cloner cloner) : base(original, cloner) { } #endregion public BinPacker() { } /// /// Packs all items of the bin packer and returns a collection of BinPacking3D objects /// /// Permutation of items sorted by a sorting method. The value of each permutation index references to the index of the items list /// Bin for storing the items /// A list of packing items which should be assigned to a bin /// Flag for using stacking constraints /// Returns a collection of bin packing 3d objects. Each object represents a bin and the packed items public abstract IList PackItems(Permutation sortedItems, PackingShape binShape, IList items, ExtremePointCreationMethod epCreationMethod, ExtremePointPruningMethod epPruningMethod, bool useStackingConstraints); public abstract void PackItemsToPackingList(IList packingList, Permutation sortedItems, PackingShape binShape, IList items, ExtremePointCreationMethod epCreationMethod, ExtremePointPruningMethod epPruningMethod, bool useStackingConstraints); /// /// Pack a given item into a given bin and updates the residual space and the extreme points /// /// /// /// /// protected virtual void PackItem(BinPacking3D packingBin, int itemId, PackingItem packingItem, PackingPosition position, IExtremePointCreator extremePointCreator, bool useStackingConstraints) { packingBin.PackItem(itemId, packingItem, position); extremePointCreator.UpdateBinPacking(packingBin, packingItem, position); } /// /// This method tries to find a valid packing position for an given item in a given packing bin /// /// /// /// /// Returns the packing position for an given item. If there could not be found a valid position it returns null protected virtual PackingPosition FindPackingPositionForItem(BinPacking3D packingBin, PackingItem packingItem, bool useStackingConstraints) { if (!CheckItemDimensions(packingBin, packingItem)) { throw new BinPacking3DException($"The dimensions of the given item exceeds the bin dimensions. " + $"Bin: ({packingBin.BinShape.Width} {packingBin.BinShape.Depth} {packingBin.BinShape.Height})" + $"Item: ({packingItem.Width} {packingItem.Depth} {packingItem.Height})"); } PackingItem newItem = new PackingItem( packingItem.Width, packingItem.Height, packingItem.Depth, packingItem.TargetBin, packingItem.Weight, packingItem.SequenceGroup, packingItem.Layer); // The extremepoints are sortet by Y / Z / X var newPosition = packingBin.ExtremePoints.Where(x => packingBin.IsPositionFeasible(newItem, x.Key, useStackingConstraints)).FirstOrDefault(); return newPosition.Key; } /// /// Compares the dimensions of a given item and the current bin. /// /// /// Returns true if the dimensions of an given item are less or equal to the bin. protected virtual bool CheckItemDimensions(BinPacking3D packingBin, PackingItem item) { var width = item.Width; var depth = item.Depth; return packingBin.BinShape.Width >= width && packingBin.BinShape.Height >= item.Height && packingBin.BinShape.Depth >= depth; } /// /// Clones a given list of packing items. /// /// /// protected static IList CloneItems(IList items) { var clonedItems = new List(); foreach (var item in items) { clonedItems.Add(item.Clone() as PackingItem); } return clonedItems; } } }