118 lines
4.3 KiB
C#
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 }));
|
|
}
|
|
|
|
}
|
|
}
|