Files
lux/EgwCoreLib.Lux.Core/MachineCalc/Utils.cs
T

118 lines
4.3 KiB
C#

using EgwCoreLib.Lux.Core.RestPayload;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EgwCoreLib.Lux.Core.MachineCalc
{
public class Utils
{
/// <summary>
/// Helper calcolo Intersezione lista macchine
/// </summary>
/// <param name="machines"></param>
/// <param name="predicate"></param>
/// <returns></returns>
public static IEnumerable<string> IntersectTags(List<MachineCalcResultDTO> machines, Func<PartCalcDTO, bool> predicate)
{
return machines
.Select(m => m.PartList.Where(predicate).Select(p => p.Tag).ToHashSet())
.Aggregate((set1, set2) => { set1.IntersectWith(set2); return set1; });
}
/// <summary>
/// Calcolo delle intersezioni Macchine/Tags(Parts)
/// </summary>
/// <param name="machineResult"></param>
/// <returns></returns>
public static List<MachineTagDTO> CalculateIntersections(List<MachineCalcResultDTO> machineResult)
{
// Step 1: extract workable tags per machine
var machineTags = machineResult
.ToDictionary(
m => m.Name,
m => m.PartList
.Where(p => p.CalcResult == Enums.PartVerificationResult.MACHINABLE)
.ToList()
);
var machineNames = machineTags.Keys.ToList();
var results = new List<MachineTagDTO>();
// Step 2: generate all combinations of machines
for (int size = 1; size <= machineNames.Count; size++)
{
foreach (var combo in GetCombinations(machineNames, size))
{
var comboList = combo.ToList();
// Intersection of tags across all machines in this combo
var intersectionTags = comboList
.Select(name => machineTags[name].Select(p => p.Tag).ToHashSet())
.Aggregate((set1, set2) => { set1.IntersectWith(set2); return set1; });
// Compute per-machine sums of Time for these tags
var sums = comboList.Select(name =>
machineTags[name]
.Where(p => intersectionTags.Contains(p.Tag))
.Sum(p => p.Time)
).ToList();
results.Add(new MachineTagDTO
{
Machines = comboList,
Tags = intersectionTags.ToList(),
MinTime = sums.Any() ? sums.Min() : 0,
MaxTime = sums.Any() ? sums.Max() : 0
});
}
}
// Step 3: add unique (non-intersecting) tags per machine
foreach (var name in machineNames)
{
var uniqueTags = machineTags[name]
.Select(p => p.Tag)
.Except(machineNames.Where(n => n != name)
.SelectMany(n => machineTags[n].Select(p => p.Tag)))
.ToList();
var sum = machineTags[name]
.Where(p => uniqueTags.Contains(p.Tag))
.Sum(p => p.Time);
results.Add(new MachineTagDTO
{
Machines = new List<string> { name },
Tags = uniqueTags,
MinTime = sum,
MaxTime = sum
});
}
return results;
}
/// <summary>
/// Helper generazione combinazioni di items per una data length
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="items"></param>
/// <param name="length"></param>
/// <returns></returns>
public static IEnumerable<IEnumerable<T>> GetCombinations<T>(IEnumerable<T> items, int length)
{
if (length == 1)
return items.Select(i => new T[] { i });
return GetCombinations(items, length - 1)
.SelectMany(c => items.Where(i => !c.Contains(i)),
(c, i) => c.Concat(new T[] { i }));
}
}
}