/// <summary> /// We keep the population bound to a probablity of fitness /// </summary> /// <param name="pop"> /// </param> /// <example> /// <![CDATA[ /// The population is represented as a coupled-pair of weighted fitness probablity /// to the the State /// /// Weighted Prob State /// 1 s_1 /// 0.7961956521 s_2 /// 0.5448369565 s_3 /// ... ... /// 0.1698369565 s_i-1 /// 0.0543478260 s_i /// /// ]]> /// </example> private void CalcWtFitness2State(IList<IState> pop) { pop.Shuffle(); var calc = new List<Tuple<double, IState>>(); var total = pop.Select(x => FitnessFunction.Eval(x)).Sum(); var runningTotal = 0.0D; foreach (var s in pop) { runningTotal += FitnessFunction.Eval(s) / total; calc.Add(new Tuple<double, IState>(runningTotal, s)); } _wtFitness2State = calc.OrderByDescending(x => x.Item1).ToList(); }
/// <summary> /// Does NOT use <see cref="IProblem.IsGoalTest"/> to return an <see cref="IState"/> but simply gets /// the <see cref="IState"/> which max'ed the <see cref="FitnessFunction"/> after <see cref="NumberOfGenerations"/> /// generations. /// </summary> /// <returns></returns> public IState Search() { var popLen = _wtFitness2State.Count; //go through the number of supplied generations for (var i = 0; i < _numberOfGenerations; i++) { //for each generation the population is replaced by children of more fit offspring var nextGeneration = new List<IState>(); for (var j = 0; j < popLen; j++) { var ps = PickFolks(); var child = _mutationFx(_reproductionFx(ps.Item1, ps.Item2)); nextGeneration.Add(child); } CalcWtFitness2State(nextGeneration); } //there can be only one. return _wtFitness2State.Select(x => x.Item2).OrderBy(x => FitnessFunction.Eval(x)).First(); }