/** * Intuitive logic: Organize the powerplants by cost (Ascending low -> high) and use the right amount to have the load. * **/ public static IEnumerable <ProductionVm> Calculate(PayloadVm payloads) { ICollection <ProductionVm> productionplans = new List <ProductionVm>(); foreach (var powerplant in payloads.Powerplants) { //Get the variable cost & update the P values powerplant.GetUnitCostAndUpdateP(payloads.Fuels); } //Rank Up the power plants according to cost metric payloads.Powerplants = payloads.Powerplants.OrderBy(x => x.UnitCost).ToList(); bool isPossible = payloads.Powerplants.Sum(x => x.Pmax) > payloads.Load; if (!isPossible) { return(null); } //Use the minimum of powerplants to produce the needed load double currentPowerPlantProduction = 0; double load = payloads.Load; for (int i = 0; i < payloads.Powerplants.Count; i++) { Powerplant currentPowerplant = payloads.Powerplants[i]; Powerplant nextPowerplant = null; if (i + 1 < payloads.Powerplants.Count) { nextPowerplant = payloads.Powerplants[i + 1]; } currentPowerPlantProduction = 0; if (load > 0) { if (load - currentPowerplant.Pmax >= 0) { //Check if the combinaison of the current powerplant and the next powerplant can produce all the current load amount. if (nextPowerplant != null && load < currentPowerplant.Pmax + nextPowerplant.Pmax && load - currentPowerplant.Pmax < nextPowerplant.Pmin) { currentPowerPlantProduction = currentPowerplant.Pmax - nextPowerplant.Pmin; } else { currentPowerPlantProduction = currentPowerplant.Pmax; } load -= currentPowerPlantProduction; } else if (load - currentPowerplant.Pmin >= 0) { currentPowerPlantProduction = load; load -= currentPowerPlantProduction; } } currentPowerPlantProduction = Math.Round(currentPowerPlantProduction, 1); productionplans.Add(new ProductionVm { PowerplantName = currentPowerplant.Name, Production = currentPowerPlantProduction }); } return(productionplans); }
public ActionResult <IEnumerable <ProductionVm> > GetProduction([FromBody] PayloadVm payloads) { var production = ProductionPlanCalculatorExtensions.Calculate(payloads); if (production == null) { return(BadRequest()); } return(Ok(production)); }