private static Tuple <Solution, double> Optimize(PackingShape bin, IList <PackingItem> items, SortingMethod sorting, FittingMethod fitting, double delta, bool stackingConstraints, IEvaluator evaluator, CancellationToken token) { Permutation sorted = null; switch (sorting) { case SortingMethod.Given: sorted = new Permutation(PermutationTypes.Absolute, Enumerable.Range(0, items.Count).ToArray()); break; case SortingMethod.VolumeHeight: sorted = 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()); break; case SortingMethod.HeightVolume: sorted = 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()); break; case SortingMethod.AreaHeight: sorted = 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()); break; case SortingMethod.HeightArea: sorted = 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()); break; case SortingMethod.ClusteredAreaHeight: double clusterRange = bin.Width * bin.Depth * delta; sorted = 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()); break; case SortingMethod.ClusteredHeightArea: double clusterRange2 = bin.Height * delta; sorted = 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()); break; default: throw new ArgumentException("Unknown sorting method: " + sorting); } ExtremePointPermutationDecoderBase decoder = null; switch (fitting) { case FittingMethod.FirstFit: decoder = new ExtremePointPermutationDecoder(); break; case FittingMethod.FreeVolumeBestFit: decoder = new FreeVolumeBestFitExtremePointPermutationDecoder(); break; case FittingMethod.ResidualSpaceBestFit: decoder = new ResidualSpaceBestFitExtremePointPermutationDecoder(); break; default: throw new ArgumentException("Unknown fitting method: " + fitting); } var sol = decoder.Decode(sorted, bin, items, stackingConstraints); var fit = evaluator.Evaluate(sol); return(Tuple.Create(sol, fit)); }
protected FreeVolumeBestFitExtremePointPermutationDecoder(FreeVolumeBestFitExtremePointPermutationDecoder original, Cloner cloner) : base(original, cloner) { }