private void UpdateFitnesses(Parameters key, double fitness)
    {
        Load();//update the fitness table from possible other executions
        ParameterFitness pf = new ParameterFitness();

        if (fitnesses.ContainsKey(key))
        {
            pf = fitnesses[key];
        }
        pf.AddValue(fitness);

        fitnesses[key] = pf;
    }
    public IEnumerator RunGeneration()
    {
        for (int i = 0; i < population.Length; i++)
        {
            ParameterFitness pf = new ParameterFitness();
            if (fitnesses.ContainsKey(population[i]))
            {
                pf = fitnesses[population[i]];

                if (i > 1 || (2 * pf.GetVariance() / Math.Sqrt(pf.n) < 0.1 * pf.average && r.Next(pf.n + 1) != 0))
                {
                    continue;
                }
            }

            SimulationInitializer.SetSimulation(population[i], RUNNING_SPEED);
            simulationTimer.Restart();
            while (simulationTimer.Elapsed.TotalSeconds < singleSimulationTime)
            {
                yield return(new WaitForSeconds(1));

                _current_simulation_timer = (int)simulationTimer.Elapsed.TotalSeconds;
            }
            double fitness = GetFitness();
            UpdateFitnesses(population[i], fitness);

            if (_current_best_fitness < fitness)
            {
                _current_best_fitness          = fitness;
                _current_best_fitness_variance = fitnesses[population[i]].GetVariance();
            }
            text.text = "i=" + i + " gen: " + _generation + " timer:" + _current_simulation_timer + "  fitness = " + fitness + "avg:" + pf.average + " var=" + pf.GetVariance() + " n:" + pf.n + " Z:" + (2 * pf.GetVariance() / Math.Sqrt(pf.n)) + "<" + (0.1 * pf.average) + " best:" + _current_best_fitness + " bestVar:" + _current_best_fitness_variance;


            Save();
        }

        CreateNewGeneration();

        completed = true;
    }