using HeuristicLab.Encodings.PermutationEncoding; using HeuristicLab.Problems.BinPacking2D; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HeuristicLab.Problems.BinPacking3D.Sorting { /// /// This is a extension class for sorting a permutation. /// They are extension methods for the class Permutation. /// public static class PermutationPackingItemSorter { /// /// Sorts a given permutation first by the volume and secoundly by the height. /// /// Permuation which should be sorted /// A new sorted permutation public static Permutation SortByVolumeHeight(this IList items) { return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v }) .OrderByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height) .ThenByDescending(x => x.Item.Height) .Select(x => x.Index).ToArray()); } /// /// Sorts a given permutation first by the heigth and secoundly by the volume. /// /// Permuation which should be sorted /// A new sorted permutation public static Permutation SortByHeightVolume(this IList items) { return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v }) .OrderByDescending(x => x.Item.Height) .ThenByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height) .Select(x => x.Index).ToArray()); } /// /// Sorts a given permutation first by the area and secondly by the height. /// /// Permuation which should be sorted /// A new sorted permutation public static Permutation SortByAreaHeight(this IList items) { return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v }) .OrderByDescending(x => x.Item.Depth * x.Item.Width) .ThenByDescending(x => x.Item.Height) .Select(x => x.Index).ToArray()); } /// /// Sorts a given permuation first by the height and secoundly by the area. /// /// Permuation which should be sorted /// A new sorted permutation public static Permutation SortByHeightArea(this IList items) { return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v }) .OrderByDescending(x => x.Item.Height) .ThenByDescending(x => x.Item.Depth * x.Item.Width) .Select(x => x.Index).ToArray()); } /// /// Sorts a given permutation. The items are being grouped by the cluster id. /// The cluster id is calulated as followed: clusterId = Ceiling( (width * depth) / (width * depth * delta)) /// The permutation is first being sorted by the area and secoundly by the height. /// /// Permuation which should be sorted /// The bin is needed for building the cluster /// The delta is needed for building the cluster /// A new sorted permutation public static Permutation SortByClusteredAreaHeight(this IList items, PackingShape bin, double delta) { double clusterRange = bin.Width * bin.Depth * delta; return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v, ClusterId = (int)(Math.Ceiling(v.Width * v.Depth / clusterRange)) }) .GroupBy(x => x.ClusterId) .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(y => y.Item.Height).ToList() }) .OrderByDescending(x => x.Cluster) .SelectMany(x => x.Items) .Select(x => x.Index).ToArray()); } /// /// Sorts a given permutation. The items are being grouped by the cluster id. /// The cluster id is calulated as followed: clusterId = Ceiling( (height) / (height * delta)) /// The permutation is first being sorted by the height and secoundly by the area. /// /// Permuation which should be sorted /// The bin is needed for building the cluster /// The delta is needed for building the cluster /// A new sorted permutation public static Permutation SortByClusteredHeightArea(this IList items, PackingShape bin, double delta) { double clusterRange2 = bin.Height * delta; return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v, ClusterId = (int)(Math.Ceiling(v.Height / clusterRange2)) }) .GroupBy(x => x.ClusterId) .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(y => y.Item.Depth * y.Item.Width).ToList() }) .OrderByDescending(x => x.Cluster) .SelectMany(x => x.Items) .Select(x => x.Index).ToArray()); } /// /// Sorts a given permutation first by the material, secoundly by the volume and finally by the height. /// /// Permuation which should be sorted /// A new sorted permutation public static Permutation SortByMaterialVolumeHeight(this IList items) { return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v }) .OrderByDescending(x => x.Item.Material) .ThenByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height) .ThenByDescending(x => x.Item.Height) .Select(x => x.Index).ToArray()); } /// /// Sorts a given permutation first by the material, secoundly by the heigth and finally by the volume. /// /// Permuation which should be sorted /// A new sorted permutation public static Permutation SortByMaterialHeightVolume(this IList items) { return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v }) .OrderByDescending(x => x.Item.Material) .ThenByDescending(x => x.Item.Height) .ThenByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height) .Select(x => x.Index).ToArray()); } /// /// Sorts a given permutation first by the material, secoundly by the area and finally by the height. /// /// Permuation which should be sorted /// A new sorted permutation public static Permutation SortByMaterialAreaHeight(this IList items) { return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v }) .OrderByDescending(x => x.Item.Material) .ThenByDescending(x => x.Item.Depth * x.Item.Width) .ThenByDescending(x => x.Item.Height) .Select(x => x.Index).ToArray()); } /// /// Sorts a given permuation first by the material, secoundly by the height and finally by the area. /// /// Permuation which should be sorted /// A new sorted permutation public static Permutation SortByMaterialHeightArea(this IList items) { return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v }) .OrderByDescending(x => x.Item.Material) .ThenByDescending(x => x.Item.Height) .ThenByDescending(x => x.Item.Depth * x.Item.Width) .Select(x => x.Index).ToArray()); } /// /// Sorts a given permutation. The items are being grouped by the cluster id. /// The cluster id is calulated as followed: clusterId = Ceiling( (width * depth) / (width * depth * delta)) /// The permutation is being clusterd by the area, first sorted by the material, secoundly by the height. /// /// Permuation which should be sorted /// The bin is needed for building the cluster /// The delta is needed for building the cluster /// A new sorted permutation public static Permutation SortByMaterialClusteredAreaHeight(this IList items, PackingShape bin, double delta) { double clusterRange = bin.Width * bin.Depth * delta; return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v, ClusterId = (int)(Math.Ceiling(v.Width * v.Depth / clusterRange)) }) .GroupBy(x => x.ClusterId) .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(z => z.Item.Material).ThenByDescending(y => y.Item.Height).ToList() }) .OrderByDescending(x => x.Cluster) .SelectMany(x => x.Items) .Select(x => x.Index).ToArray()); } /// /// Sorts a given permutation. The items are being grouped by the cluster id. /// The cluster id is calulated as followed: clusterId = Ceiling( (height) / (height * delta)) /// The permutation is being clusterd by the height, first sorted by the material, secoundly by the area. /// /// Permuation which should be sorted /// The bin is needed for building the cluster /// The delta is needed for building the cluster /// A new sorted permutation public static Permutation SortByMaterialClusteredHeightArea(this IList items, PackingShape bin, double delta) { double clusterRange2 = bin.Height * delta; return new Permutation(PermutationTypes.Absolute, items.Select((v, i) => new { Index = i, Item = v, ClusterId = (int)(Math.Ceiling(v.Height / clusterRange2)) }) .GroupBy(x => x.ClusterId) .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(z => z.Item.Material).ThenByDescending(y => y.Item.Depth * y.Item.Width).ToList() }) .OrderByDescending(x => x.Cluster) .SelectMany(x => x.Items) .Select(x => x.Index).ToArray()); } } }