public void GenerateGenomes()
        {
            var count = 1000000;

            var maxDepthRandomGenome = ModelHelper.GetBpmModel().GetMaxDepthRandomGenome();

            var genomes = new List <string>();

            for (var i = 0; i < count; i++)
            {
                var genome = new BpmGenome
                {
                    RootGene =
                        ProcessHelper.ProcessGenerator.GenerateRandomValidBpmGenome2(
                            maxDepthRandomGenome, null)
                };

                genomes.Add(genome.ToString());
            }

            var distinctCount = genomes.Distinct().Count();

            Assert.IsTrue(distinctCount >= count * 0.5);
        }
        private BpmSolution Evaluate(BpmGenome genome)
        {
            // start time measurement
            var startTime = DateTime.Now;

            Debug.WriteLine("Evaluating: " + genome);

            // load pain factor
            painFactor = ModelHelper.GetBpmModel().GetPainFactor();

            #region costevaluation

            // calculate all process paths
            // - splitted by XOR for dependent probabilities
            var splitterXor           = new ProcessHelper.PathSplitter(genome);
            var pathsForProbabilities = splitterXor.GetPaths();

            // remove paths with 0.0 percentage probability
            pathsForProbabilities.RemoveAll(x => x.Probability == 0);

            // calculate probabilities for each activity

            //

            // [2] Wahrscheinlichkeiten für jede Activity
            var activitieProbabilities = new HashSet <BpmnActivity>();

            var painFactorActivityAttributeCovering = false;
            var painFactorObjectDependencies        = 0;

            // Calculate probabilities for every activity
            CalculateActivityProbabilities(ref activitieProbabilities, pathsForProbabilities);

            // Check resulting probabilities with input data
            painFactorActivityAttributeCovering = !CheckActivityAttributeCovering(genome.RootGene);

            // Check input/ouput realtionships from activities to objects
            //painFactorObjectDependencies = !CheckObjectDependencies();
            var valide = ProcessHelper.Validator.ValidateGenome(genome, ref painFactorObjectDependencies);

            // Calculate µNPV
            var mueP   = CalculateMueP(valide, activitieProbabilities);
            var mueNpv = CalculateMueNpv(genome, mueP);

            // Calculate σ^2NPV
            var sigma2P   = CalculateSigma2P(mueP, activitieProbabilities, pathsForProbabilities);
            var sigma2Npv = CalculateSigma2Npv(sigma2P);

            // Calculate preference function
            var costFitness = mueNpv - ModelHelper.GetBpmModel().GetAlpha() / 2 * sigma2Npv;

            Debug.WriteLine("costFitness: " + costFitness + " = " + mueNpv + " - (" +
                            ModelHelper.GetBpmModel().GetAlpha() + "/2) * " + sigma2Npv);

            #endregion

            #region timeevaluation

            double timeFitness = 0;
            foreach (var bpa in DataHelper.ActivityAttributeHelper.Instance().GetAll())
            {
                timeFitness += bpa.DecisionProbability * CalculateTime(bpa, genome.RootGene);
            }

            if (DataHelper.ActivityAttributeHelper.Instance().GetAll().Count <= 0)
            {
                timeFitness = TreeHelper.CalculateLongestTime(genome.RootGene);
            }
            #endregion

            #region fitness merge

            var fitness = costFitness * ModelHelper.GetBpmModel().GetCostWeight();
            fitness += -1 * timeFitness * ModelHelper.GetBpmModel().GetTimeWeight();

            #endregion

            if (painFactorActivityAttributeCovering)
            {
                fitness -= ModelHelper.GetBpmModel().GetPainFactor();
            }
            if (painFactorObjectDependencies > 0)
            {
                fitness -= ModelHelper.GetBpmModel().GetPainFactor() * painFactorObjectDependencies;
            }

            // only when pretty process enabled
            if (pretty)
            {
                fitness -= ModelHelper.GetBpmModel().GetPainFactor() * ProcessHelper.PrettyPrint.Check(genome);
            }

            var endTime = DateTime.Now;

            var activities = activitieProbabilities.Select(x => x.Name).Distinct().ToList();

            var index = GeneticAlgorithm.Instance()?.Population?.CurrentGeneration?.GenerationIndex;

            if (!index.HasValue)
            {
                index = -1;
            }

            var solution = new BpmSolution(
                (endTime - startTime).TotalMilliseconds,
                index.Value,
                fitness,
                genome.ToString(),
                valide,
                "[" + string.Join(", ", activities.ToArray()) + "]",
                mueP,
                mueNpv,
                sigma2P,
                sigma2Npv,
                timeFitness,
                costFitness
                );

            return(solution);
        }