public reference Crossover(reference pParentA, reference pParentB, string pSecret_Phrase)
        {
            int crossover_point;

            lock (syncLock)
                crossover_point = random.Next(pParentA.phrase.Length);

            reference tempChild = new reference(pSecret_Phrase);

            for (int i = 0; i < crossover_point; i++)
            {
                tempChild.phrase[i] = pParentA.phrase[i];
            }

            for (int i = crossover_point; i < pParentA.phrase.Length; i++)
            {
                if (pParentA.phrase[i] != pSecret_Phrase[i])
                {
                    tempChild.phrase[i] = pParentB.phrase[i];
                }
                else
                {
                    tempChild.phrase[i] = pParentA.phrase[i];
                }
            }

            var fitness = Fitness(tempChild.phrase, pSecret_Phrase);

            tempChild.fitness = fitness;


            return(tempChild);
        }
        public reference Generate(string pSecret_Phrase)
        {
            //genes = new char[pSecret_Phrase.Length];
            //string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ";
            //string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ";

            // to generate elete solution
            CharDictionary = CountLetters(pSecret_Phrase);

            int position = 0;

            char[] new_phrase = new char[pSecret_Phrase.Length];
            for (int j = 0; j < CharDictionary.Count; j++)
            {
                char key   = CharDictionary.Keys.ElementAt(j);
                int  value = CharDictionary.Values.ElementAt(j);


                for (int k = 0; k < value; k++)
                {
                    lock (syncLock)
                        position = random.Next(pSecret_Phrase.Length);

                    if (new_phrase[position] == '\0')
                    {
                        new_phrase[position] = key;
                    }
                    else
                    {
                        int  count = 0;
                        bool flag  = true;
                        while (flag)
                        {
                            if (new_phrase[count] == '\0')
                            {
                                new_phrase[count] = key;
                                flag = false;
                            }
                            count++;
                        }
                    }
                }
            }
            reference tempRef = new reference(pSecret_Phrase);

            tempRef.phrase  = new_phrase;
            tempRef.fitness = Fitness(new_phrase, pSecret_Phrase);

            return(tempRef);
        }
        private void Start_Click(object sender, RoutedEventArgs e)
        {
            SSMethods myssMethods = new SSMethods();

            //1. generate inital solution & evaluate fitness of each solution
            for (int i = 0; i < initialSolutionSize; i++)
            {
                InitialSolutions.Add(myssMethods.Generate(secret_phrase));
            }
            //2. apply improvment mehtod to solutions
            myssMethods.ImprovementMethod(InitialSolutions, secret_phrase);
            // evaluate fitness again
            myssMethods.FitnessOfSet(InitialSolutions, secret_phrase);

            // select best solutions set and make a reference set;
            var InitialSolutionsOrdered = (from r in InitialSolutions
                                           orderby r.fitness descending
                                           select r).ToList();;

            //3. create a reference set by taking top 20 from Initial Solution
            for (int i = 0; i < referenceSetSize; i++)
            {
                // have to create a temp object othervise it is copied by ref not by value;
                reference temp = new reference();
                temp.fitness = InitialSolutionsOrdered[i].fitness;
                temp.phrase  = InitialSolutionsOrdered[i].phrase;
                RefSet.Add(temp);
            }

            initialFitness = myssMethods.PointDistance(RefSet);

            bool solution_not_found = true;
            int  iteration_count    = 0;

            int test_refupdate_count = 0;

            while (iteration_count < maxIteration && solution_not_found)
            {
                //4. Crossover reference set
                List <reference> Children = new List <reference>();

                for (int i = 0; i < RefSet.Count; i++)
                {
                    var ParentA = RefSet[i];
                    for (int j = i + 1; j < referenceSetSize; j++)
                    {
                        var tempChild = myssMethods.Crossover(ParentA, RefSet[j], secret_phrase);
                        Children.Add(tempChild);
                    }
                }

                myssMethods.ImprovementMethod(Children, secret_phrase);
                myssMethods.FitnessOfSet(Children, secret_phrase);

                var childrenInOrder = (from c in Children
                                       orderby c.fitness descending
                                       select c).ToList();


                //5. update reference set with better fitness
                for (int j = 0; j < referenceSetSize; j++)
                {
                    bool flag  = true;
                    int  count = 0;
                    while (flag)
                    {
                        if (RefSet[j].fitness < childrenInOrder[count].fitness)
                        {
                            reference tempRef = new reference(secret_phrase);
                            tempRef.fitness = childrenInOrder[count].fitness;
                            tempRef.phrase  = childrenInOrder[count].phrase;

                            RefSet[j].fitness = tempRef.fitness;
                            RefSet[j].phrase  = tempRef.phrase;

                            childrenInOrder.RemoveAt(count);

                            test_refupdate_count++;

                            if (RefSet[j].fitness == 1)
                            {
                                solution_not_found = false;
                            }

                            flag = false;
                        }

                        count++;
                        if (count == childrenInOrder.Count)
                        {
                            flag = false;
                        }
                    }
                }
                iteration_count++;
            }

            //things to improve
            //1. when the referense set stops updating, the we need to generate new Inital Solutions
            //2. add initial solutions to reference set for deversification
            //3. make sure that when crossing all letters are present in the phrase and not being excluded
            // right now when crossing i loose some of letters
            //4. improvement function is ok but can be so much better good , it just


            double finalFitness   = RefSet[0].fitness; //myssMethods.PointDistance(RefSet);
            var    refset_strings = myssMethods.getPhrase(RefSet);
            //RefSet[0].fitness = 1;

            double improvment = finalFitness - initialFitness;

            int b = 0;
        }