1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)


4  *


5  * This file is part of HeuristicLab.


6  *


7  * HeuristicLab is free software: you can redistribute it and/or modify


8  * it under the terms of the GNU General Public License as published by


9  * the Free Software Foundation, either version 3 of the License, or


10  * (at your option) any later version.


11  *


12  * HeuristicLab is distributed in the hope that it will be useful,


13  * but WITHOUT ANY WARRANTY; without even the implied warranty of


14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


15  * GNU General Public License for more details.


16  *


17  * You should have received a copy of the GNU General Public License


18  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.


19  */


20  #endregion


21 


22  using HeuristicLab.Encodings.PermutationEncoding;


23  using HeuristicLab.Problems.BinPacking2D;


24  using System;


25  using System.Collections.Generic;


26  using System.Linq;


27  using System.Text;


28  using System.Threading.Tasks;


29 


30  namespace HeuristicLab.Problems.BinPacking3D.Sorting {


31 


32  /// <summary>


33  /// This is a extension class for sorting a permutation.


34  /// They are extension methods for the class Permutation.


35  /// </summary>


36  public static class PermutationPackingItemSorter {


37 


38  /// <summary>


39  /// Sorts a given permutation first by the volume and secoundly by the height.


40  /// </summary>


41  /// <param name="items">Permuation which should be sorted</param>


42  /// <returns>A new sorted permutation</returns>


43  public static Permutation SortByVolumeHeight(this IList<PackingItem> items) {


44  return new Permutation(PermutationTypes.Absolute,


45  items.Select((v, i) => new { Index = i, Item = v })


46  .OrderByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height)


47  .ThenByDescending(x => x.Item.Height)


48  .Select(x => x.Index).ToArray());


49  }


50 


51  /// <summary>


52  /// Sorts a given permutation first by the heigth and secoundly by the volume.


53  /// </summary>


54  /// <param name="items">Permuation which should be sorted</param>


55  /// <returns>A new sorted permutation</returns>


56  public static Permutation SortByHeightVolume(this IList<PackingItem> items) {


57  return new Permutation(PermutationTypes.Absolute,


58  items.Select((v, i) => new { Index = i, Item = v })


59  .OrderByDescending(x => x.Item.Height)


60  .ThenByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height)


61  .Select(x => x.Index).ToArray());


62  }


63 


64  /// <summary>


65  /// Sorts a given permutation first by the area and secondly by the height.


66  /// </summary>


67  /// <param name="items">Permuation which should be sorted</param>


68  /// <returns>A new sorted permutation</returns>


69  public static Permutation SortByAreaHeight(this IList<PackingItem> items) {


70  return new Permutation(PermutationTypes.Absolute,


71  items.Select((v, i) => new { Index = i, Item = v })


72  .OrderByDescending(x => x.Item.Depth * x.Item.Width)


73  .ThenByDescending(x => x.Item.Height)


74  .Select(x => x.Index).ToArray());


75  }


76 


77  /// <summary>


78  /// Sorts a given permuation first by the height and secoundly by the area.


79  /// </summary>


80  /// <param name="items">Permuation which should be sorted</param>


81  /// <returns>A new sorted permutation</returns>


82  public static Permutation SortByHeightArea(this IList<PackingItem> items) {


83  return new Permutation(PermutationTypes.Absolute,


84  items.Select((v, i) => new { Index = i, Item = v })


85  .OrderByDescending(x => x.Item.Height)


86  .ThenByDescending(x => x.Item.Depth * x.Item.Width)


87  .Select(x => x.Index).ToArray());


88  }


89 


90  /// <summary>


91  /// Sorts a given permutation. The items are being grouped by the cluster id.


92  /// The cluster id is calulated as followed: clusterId = Ceiling( (width * depth) / (width * depth * delta))


93  /// The permutation is first being sorted by the area and secoundly by the height.


94  /// </summary>


95  /// <param name="items">Permuation which should be sorted</param>


96  /// <param name="bin">The bin is needed for building the cluster</param>


97  /// <param name="delta">The delta is needed for building the cluster</param>


98  /// <returns>A new sorted permutation</returns>


99  public static Permutation SortByClusteredAreaHeight(this IList<PackingItem> items, PackingShape bin, double delta) {


100  double clusterRange = bin.Width * bin.Depth * delta;


101  return new Permutation(PermutationTypes.Absolute,


102  items.Select((v, i) => new { Index = i, Item = v, ClusterId = (int)(Math.Ceiling(v.Width * v.Depth / clusterRange)) })


103  .GroupBy(x => x.ClusterId)


104  .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(y => y.Item.Height).ToList() })


105  .OrderByDescending(x => x.Cluster)


106  .SelectMany(x => x.Items)


107  .Select(x => x.Index).ToArray());


108  }


109 


110  /// <summary>


111  /// Sorts a given permutation. The items are being grouped by the cluster id.


112  /// The cluster id is calulated as followed: clusterId = Ceiling( (height) / (height * delta))


113  /// The permutation is first being sorted by the height and secoundly by the area.


114  /// </summary>


115  /// <param name="items">Permuation which should be sorted</param>


116  /// <param name="bin">The bin is needed for building the cluster</param>


117  /// <param name="delta">The delta is needed for building the cluster</param>


118  /// <returns>A new sorted permutation</returns>


119  public static Permutation SortByClusteredHeightArea(this IList<PackingItem> items, PackingShape bin, double delta) {


120  double clusterRange2 = bin.Height * delta;


121  return new Permutation(PermutationTypes.Absolute,


122  items.Select((v, i) => new { Index = i, Item = v, ClusterId = (int)(Math.Ceiling(v.Height / clusterRange2)) })


123  .GroupBy(x => x.ClusterId)


124  .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(y => y.Item.Depth * y.Item.Width).ToList() })


125  .OrderByDescending(x => x.Cluster)


126  .SelectMany(x => x.Items)


127  .Select(x => x.Index).ToArray());


128  }


129 


130  /// <summary>


131  /// Sorts a given permutation first by the material, secoundly by the volume and finally by the height.


132  /// </summary>


133  /// <param name="items">Permuation which should be sorted</param>


134  /// <returns>A new sorted permutation</returns>


135  public static Permutation SortByMaterialVolumeHeight(this IList<PackingItem> items) {


136  return new Permutation(PermutationTypes.Absolute,


137  items.Select((v, i) => new { Index = i, Item = v })


138  ./*OrderByDescending(x => x.Item.IsStackabel ? 1 : 0)


139  .*/OrderByDescending(x => x.Item.Material)


140  .ThenByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height)


141  .ThenByDescending(x => x.Item.Height)


142  .Select(x => x.Index).ToArray());


143  }


144 


145  /// <summary>


146  /// Sorts a given permutation first by the material, secoundly by the heigth and finally by the volume.


147  /// </summary>


148  /// <param name="items">Permuation which should be sorted</param>


149  /// <returns>A new sorted permutation</returns>


150  public static Permutation SortByMaterialHeightVolume(this IList<PackingItem> items) {


151  return new Permutation(PermutationTypes.Absolute,


152  items.Select((v, i) => new { Index = i, Item = v })


153  ./*OrderByDescending(x => x.Item.IsStackabel ? 1 : 0)


154  .*/OrderByDescending(x => x.Item.Material)


155  .ThenByDescending(x => x.Item.Height)


156  .ThenByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height)


157  .Select(x => x.Index).ToArray());


158  }


159 


160  /// <summary>


161  /// Sorts a given permutation first by the material, secoundly by the area and finally by the height.


162  /// </summary>


163  /// <param name="items">Permuation which should be sorted</param>


164  /// <returns>A new sorted permutation</returns>


165  public static Permutation SortByMaterialAreaHeight(this IList<PackingItem> items) {


166  return new Permutation(PermutationTypes.Absolute,


167  items.Select((v, i) => new { Index = i, Item = v })


168  ./*OrderByDescending(x => x.Item.IsStackabel ? 1 : 0)


169  .*/OrderByDescending(x => x.Item.Material)


170  .ThenByDescending(x => x.Item.Depth * x.Item.Width)


171  .ThenByDescending(x => x.Item.Height)


172  .Select(x => x.Index).ToArray());


173  }


174 


175  /// <summary>


176  /// Sorts a given permuation first by the material, secoundly by the height and finally by the area.


177  /// </summary>


178  /// <param name="items">Permuation which should be sorted</param>


179  /// <returns>A new sorted permutation</returns>


180  public static Permutation SortByMaterialHeightArea(this IList<PackingItem> items) {


181  return new Permutation(PermutationTypes.Absolute,


182  items.Select((v, i) => new { Index = i, Item = v })


183  ./*OrderByDescending(x => x.Item.IsStackabel ? 1 : 0)


184  .*/OrderByDescending(x => x.Item.Material)


185  .ThenByDescending(x => x.Item.Height)


186  .ThenByDescending(x => x.Item.Depth * x.Item.Width)


187  .Select(x => x.Index).ToArray());


188  }


189 


190  /// <summary>


191  /// Sorts a given permutation. The items are being grouped by the cluster id.


192  /// The cluster id is calulated as followed: clusterId = Ceiling( (width * depth) / (width * depth * delta))


193  /// The permutation is being clusterd by the area, first sorted by the material, secoundly by the height.


194  /// </summary>


195  /// <param name="items">Permuation which should be sorted</param>


196  /// <param name="bin">The bin is needed for building the cluster</param>


197  /// <param name="delta">The delta is needed for building the cluster</param>


198  /// <returns>A new sorted permutation</returns>


199  public static Permutation SortByMaterialClusteredAreaHeight(this IList<PackingItem> items, PackingShape bin, double delta) {


200  double clusterRange = bin.Width * bin.Depth * delta;


201  return new Permutation(PermutationTypes.Absolute,


202  items.Select((v, i) => new { Index = i, Item = v, ClusterId = (int)(Math.Ceiling(v.Width * v.Depth / clusterRange)) })


203  .GroupBy(x => x.ClusterId)


204  .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(z => z.Item.Material).ThenByDescending(y => y.Item.Height).ToList() })


205  .OrderByDescending(x => x.Cluster)


206  .SelectMany(x => x.Items)


207  .Select(x => x.Index).ToArray());


208  }


209 


210  /// <summary>


211  /// Sorts a given permutation. The items are being grouped by the cluster id.


212  /// The cluster id is calulated as followed: clusterId = Ceiling( (height) / (height * delta))


213  /// The permutation is being clusterd by the height, first sorted by the material, secoundly by the area.


214  /// </summary>


215  /// <param name="items">Permuation which should be sorted</param>


216  /// <param name="bin">The bin is needed for building the cluster</param>


217  /// <param name="delta">The delta is needed for building the cluster</param>


218  /// <returns>A new sorted permutation</returns>


219  public static Permutation SortByMaterialClusteredHeightArea(this IList<PackingItem> items, PackingShape bin, double delta) {


220  double clusterRange2 = bin.Height * delta;


221  return new Permutation(PermutationTypes.Absolute,


222  items.Select((v, i) => new { Index = i, Item = v, ClusterId = (int)(Math.Ceiling(v.Height / clusterRange2)) })


223  .GroupBy(x => x.ClusterId)


224  .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(z => z.Item.Material).ThenByDescending(y => y.Item.Depth * y.Item.Width).ToList() })


225  .OrderByDescending(x => x.Cluster)


226  .SelectMany(x => x.Items)


227  .Select(x => x.Index).ToArray());


228  }


229  }


230  }

