//public static Reserve[] Calc2(IEnumerable<Batch> productBatches, IEnumerable<Batch> materialBatches) //{ // List<Reserve> reserves = new List<Reserve>(); // var materials = materialBatches.ToLookup(x => x.product.id); // foreach (var productBatch in productBatches.OrderBy(b => b.deadline).ThenByDescending(b => b.RequiredLen)) // { // var material = materials[productBatch.product.material]; // var availabilities = material.ToLookup(m => m.availability); // List<Batch> availBatches = new List<Batch>(); // foreach (var availability in availabilities.OrderBy(x => x.Key)) // { // availBatches.AddRange(availability); // ReserveCreate(reserves, productBatch, availBatches.ToArray()); // if (productBatch.NotProvided <= 0) break; // } // } // return reserves.ToArray(); //} public static Reserve[] CalcWithAlt(IEnumerable <Batch> productBatches, IEnumerable <Batch> materialBatches, Alt[] alts, Reserve[] reserveList = null) { string[] altMaterialIds = alts.Select(x => x.alterMatarialId).Distinct().ToArray(); var materialMinLen = productBatches.GroupBy(b => b.product.material).ToDictionary(m => m.Key, m => m.Min(b => b.product.len)); if (reserveList == null) { reserveList = new Reserve[] { } } ; ConcurrentBag <Reserve> reservesBag = new ConcurrentBag <Reserve>(reserveList); var materials = materialBatches.ToLookup(x => x.product.id); var productMaterialIds = productBatches.ToLookup(pb => pb.product.material); Parallel.ForEach(materials.Select(x => x.Key).Except(altMaterialIds), (materialId) => { var prodBatches = productMaterialIds[materialId]; foreach (var productBatch in prodBatches.OrderBy(b => b.deadline).ThenByDescending(b => b.RequiredLen)) { { var material = materials[productBatch.product.material].Where(b => b.NotReserved > productBatch.product.len).ToArray(); ReserveMaterial(reservesBag, productBatch, material, materialMinLen); } } }); var altByOriginalAndProduct = alts.ToLookup(a => a.originalMatarialId + a.productId, a => a.alterMatarialId); { var prodBatches = productBatches.Where(pb => pb.NotProvided > 0).ToArray(); foreach (var productBatch in prodBatches.OrderBy(b => b.deadline).ThenByDescending(b => b.RequiredLen)) { { var material = materials[productBatch.product.material].Where(b => b.NotReserved > productBatch.product.len).ToArray(); ReserveMaterial(reservesBag, productBatch, material, materialMinLen); } if (productBatch.NotProvided > 0) { List <string> altIds = altByOriginalAndProduct[productBatch.product.material + productBatch.product.id].ToList(); altIds.AddRange(altByOriginalAndProduct[productBatch.product.material]); var material = altIds.SelectMany(altId => materials[altId].Where(b => b.NotReserved > productBatch.product.len)) .ToArray(); ReserveMaterial(reservesBag, productBatch, material, materialMinLen); } } } return(reservesBag.ToArray()); }
private static void ReserveCreate(ConcurrentBag <Reserve> reserves, Batch productBatch, Batch[] matBatches, Dictionary <string, int> materialMinLen) { var melts = matBatches.ToLookup(x => x.melt).ToArray(); foreach (var meltBatches in melts .OrderByDescending(m => CountMelt(m, productBatch.quantity, productBatch.product.len, MinLen(materialMinLen, m.First().product.id))) .ThenBy(m => m.Sum(x => x.NotReserved)) .ToArray()) { if (CheckMelt(meltBatches, productBatch.quantity, productBatch.product.len)) { int minLen = MinLen(materialMinLen, meltBatches.First().product.id); foreach (var materialBatch in meltBatches .Where(b => b.NotReserved <= (productBatch.NotProvided + minLen) && b.NotReserved % productBatch.product.len < minLen) .OrderByDescending(b => b.NotReserved).ToArray()) { if (materialBatch.NotReserved >= productBatch.product.len && productBatch.NotProvided > 0) { var reserve = new Reserve(productBatch, materialBatch); reserves.Add(reserve); if (productBatch.NotProvided <= 0) { break; } } } if (productBatch.NotProvided <= 0) { break; } foreach (var materialBatch in meltBatches.OrderBy(b => b.NotReserved).ToArray()) { if (materialBatch.NotReserved >= productBatch.product.len) { var reserve = new Reserve(productBatch, materialBatch); reserves.Add(reserve); if (productBatch.NotProvided <= 0) { break; } } } break; } } }