public Tuple<char[][], char[][]> CrossoverPMX(Tuple<char[][], char[][]> parents)
        {
            if (rnd.NextDouble() > Values.CROSSOVER_RATE)
                return parents;

            char[] mom = Utilities.FlattenArray(parents.Item1);
            char[] dad = Utilities.FlattenArray(parents.Item2);

            char[] baby1 = new char[mom.Length];
            Array.Copy(mom, baby1, mom.Length);

            char[] baby2 = new char[dad.Length];
            Array.Copy(dad, baby2, dad.Length);

            int beg = rnd.Next(0, mom.Length - 1);

            int end = beg;

            while (end <= beg)
            {
                end = rnd.Next(0, mom.Length);
            }

            //iterate through matched pairs of genes from begininng to end
            for (int pos = beg; pos < end +1; ++pos)
            {

                //get char from position of each chromosome
                char gene1 = mom[pos];
                char gene2 = dad[pos];

                //[5,4,7,9]     //mom
                //[7,9,4,5]     //dad

                //gene1 is 5, gene2 is 7

                if (gene1 != gene2)
                {
                    //Find the element of the chars in baby1
                    int posGene1 = Array.FindIndex(baby1, element => element.Equals(gene1));
                    int posGene2 = Array.FindIndex(baby1, element => element.Equals(gene2));

                    //posgene1 is index 0   (5 in baby1)
                    //posgene2 is index 2   (7 in baby1)

                    Utilities.swap(ref baby1[posGene1], ref baby1[posGene2]);

                    //[7,4,5,9]     //baby1 after swap
                    //[7,9,4,5]     //baby2

                    //Find the element of the char in baby2
                    posGene1 = Array.FindIndex(baby2, element => element.Equals(gene1));
                    posGene2 = Array.FindIndex(baby2, element => element.Equals(gene2));

                    //posgene1 is index 3   (5 in baby2)
                    //posgene2 is index 0   (7 in baby2)

                    Utilities.swap(ref baby2[posGene1], ref baby2[posGene2]);

                    //[7,4,5,9]     //baby1 after swap
                    //[5,9,4,7]     //baby2 after swap

                }


            }

            return new Tuple<char[][], char[][]>(Utilities.FlatToKeyboard(baby1), Utilities.FlatToKeyboard(baby2));

        }