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());
}
}
}