private static void Evaluate ( int remainingCombinations, bool enableMultithreading, IEnumerable <AminoAcidProfile> currentProfiles, IEnumerable <AminoAcidProfile> profiles, OptimalSource optimalSource, OptimalSource optimalSource2 ) { if (remainingCombinations <= 0) { decimal muscleGain = GetMuscleGain(currentProfiles); UpdateOptimalSource(muscleGain, currentProfiles, optimalSource); var sourceNames = new HashSet <string>(); foreach (var profile in currentProfiles) { sourceNames.Add(profile.Source); } if (sourceNames.Count <= 2) { UpdateOptimalSource(muscleGain, currentProfiles, optimalSource2); } return; } int newRemainingCombinations = remainingCombinations - 1; var tasks = new List <Task>(); foreach (var profile in profiles) { var newProfileList = new AminoAcidProfile[] { profile }; var newCurrentProfiles = currentProfiles.Concat(newProfileList); Action evaluate = () => Evaluate(newRemainingCombinations, false, newCurrentProfiles, profiles, optimalSource, optimalSource2); if (enableMultithreading) { var task = new Task(evaluate); task.Start(); tasks.Add(task); } else { evaluate(); } } if (enableMultithreading) { foreach (var task in tasks) { task.Wait(); } } }
static void Main(string[] arguments) { var currentProfiles = new AminoAcidProfile[] { }; var optimalSource = new OptimalSource(); var optimalSource2 = new OptimalSource(); int granularity = 10; Evaluate(granularity, true, currentProfiles, Profiles.Sources, optimalSource, optimalSource2); PrintOptimalSource("Optimal combination of plant-based protein sources for muscle gain", optimalSource, granularity); PrintOptimalSource("When limiting blend to just two ingredients", optimalSource2, granularity); foreach (var profile in Profiles.Sources) { var simpleProfile = new AminoAcidProfile[] { profile }; decimal muscleGain = GetMuscleGain(simpleProfile); Console.WriteLine($"In comparison to 100% \"{profile.Source}\" protein: {muscleGain * 100:0.0} g"); } }