protected override void AllocateAll(IRequirementBatch batch) { foreach (var req in batch.Unallocated) { var stocks = batch.GetAvailableStock(req.Product); var allocated = 0; foreach (var stock in stocks) { var quantity = Math.Min(req.Quantity - allocated, stock.Quantity); if (ShouldAllocate(stock, quantity)) { allocated += quantity; batch.AddPurchaseOrderLine(stock.Supplier, stock.Product, stock.Cost, quantity); if (req.Quantity == allocated) { break; } } else { break; } } } }
public string Allocate(IRequirementBatch batch) { var stopWatch = new Stopwatch(); var unallocated = batch.UnallocatedCount; OnAllocating(batch); stopWatch.Start(); AllocateAll(batch); stopWatch.Stop(); OnProgress(true); return($"{GetType().Name} allocated {unallocated - batch.UnallocatedCount} units in {stopWatch.ElapsedMilliseconds:n0} ms.\r\n" + $"** Currnt state - Allocated: {batch.AllocatedCount} Unallocated: {batch.UnallocatedCount} Unfulfilled: {batch.UnfulfilledCount}\r\n"); }
private void ProcessPo(IRequirementBatch batch, PurchaseOrderLine[][] lines, long current, long total) { var supplierLines = lines.SelectMany(x => x); var cost = batch.CalculateEffectiveCost(supplierLines); if (cost > _highestTotal) { _highestTotal = cost; _mostExpensive = supplierLines; } if (cost < _lowestTotal) { _cheapest = supplierLines; _lowestTotal = cost; } OnProgress(false, current, total, $"trying {current:n0}/{total:n0} combinations to save you money"); }
protected override void AllocateAll(IRequirementBatch batch) { Reset(); var requirements = batch.Unallocated .Select(x => GetAllPremutations(x, batch.GetAvailableStock(x.Product).ToList())) .ToArray(); var premuter = new Premuting <PurchaseOrderLine[]>(requirements); premuter.Premute((combination, current, total) => ProcessPo(batch, combination, current, total)); foreach (var item in _cheapest) { batch.AddPurchaseOrderLine(item); } ; OnProgress(true); Console.WriteLine(); Console.WriteLine($"{nameof(BestCombinationAllocator)} - Cheapest {_lowestTotal} Most expensive: {_highestTotal}"); }
protected override void OnAllocating(IRequirementBatch batch) { //ensure no stock items are removed to avoid processing unnecessary combinations. batch.ProcessNoStock(); base.OnAllocating(batch); }
protected override void OnAllocating(IRequirementBatch batch) { _existingSuppliers = batch.AllocatedSuppliers; base.OnAllocating(batch); }
protected override void AllocateAll(IRequirementBatch batch) { batch.ProcessNoStock(); }
/// <summary> /// Only override this if Allocate gets called from derived code /// </summary> /// <param name="stock"></param> /// <param name="quantity"></param> /// <returns></returns> protected virtual void OnAllocating(IRequirementBatch batch) { }
protected abstract void AllocateAll(IRequirementBatch batch);