public Tuple<IOrganism, IOrganism> CrossLink(IOrganism parent1, IOrganism parent2)
        {
            if (parent1.Chromosomes.Count != parent2.Chromosomes.Count) {
                throw new InvalidOperationException("Parents must have the same number of chromosomes");
            }

            IOrganism child1 = parent1.Clone();
            IOrganism child2 = parent2.Clone();
            for (int chromosomeIndex = 0; chromosomeIndex <= parent1.Chromosomes.Count - 1; chromosomeIndex++) {
                if (rand.NextDouble() > this.CrossLinkProbability) {
                    continue;
                }

                var child1Genes = child1.Chromosomes[chromosomeIndex].GetGenes();
                var child2Genes = child2.Chromosomes[chromosomeIndex].GetGenes();

                int matchIndex = rand.Next(Math.Min(child1Genes.Count(), child2Genes.Count()));
                Chromosome match1 = child1Genes.ElementAt(matchIndex);
                Chromosome match2 = child2Genes.ElementAt(matchIndex);

                this.SwapGenes(child1.Chromosomes[chromosomeIndex], match1, match2);
                this.SwapGenes(child2.Chromosomes[chromosomeIndex], match1, match2);
            }

            return new Tuple<IOrganism, IOrganism>(child1, child2);
        }
        public Tuple <IOrganism, IOrganism> CrossLink(IOrganism parent1, IOrganism parent2)
        {
            if (parent1.Chromosomes.Count != parent2.Chromosomes.Count)
            {
                throw new InvalidOperationException("Parents must have the same number of chromosomes");
            }

            IOrganism child1 = parent1.Clone();
            IOrganism child2 = parent2.Clone();

            for (int chromosomeIndex = 0; chromosomeIndex <= parent1.Chromosomes.Count - 1; chromosomeIndex++)
            {
                if (rand.NextDouble() > this.CrossLinkProbability)
                {
                    continue;
                }

                var child1Genes = child1.Chromosomes[chromosomeIndex].GetGenes();
                var child2Genes = child2.Chromosomes[chromosomeIndex].GetGenes();

                int        matchIndex = rand.Next(Math.Min(child1Genes.Count(), child2Genes.Count()));
                Chromosome match1     = child1Genes.ElementAt(matchIndex);
                Chromosome match2     = child2Genes.ElementAt(matchIndex);

                this.SwapGenes(child1.Chromosomes[chromosomeIndex], match1, match2);
                this.SwapGenes(child2.Chromosomes[chromosomeIndex], match1, match2);
            }

            return(new Tuple <IOrganism, IOrganism>(child1, child2));
        }
        public Tuple <IOrganism, IOrganism> CrossLink(IOrganism parent1, IOrganism parent2)
        {
            if (parent1.Chromosomes.Count != parent2.Chromosomes.Count)
            {
                throw new InvalidOperationException("Parents must have the same number of chromosomes");
            }

            IOrganism child1 = parent1.Clone();
            IOrganism child2 = parent2.Clone();

            for (int i = 0; i <= parent1.Chromosomes.Count - 1; i++)
            {
                if (rand.NextDouble() > this.CrossLinkProbability)
                {
                    continue;
                }

                int crossLinkIndex1 = rand.Next(Math.Min(parent1.Chromosomes[i].Length, parent2.Chromosomes[i].Length) - 1);
                int crossLinkIndex2 = rand.Next(crossLinkIndex1 + 1, Math.Min(parent1.Chromosomes[i].Length, parent2.Chromosomes[i].Length));

                child1.Chromosomes[i].OverWrite(crossLinkIndex1, parent2.Chromosomes[i].Bits.Skip(crossLinkIndex1).Take(crossLinkIndex2 - crossLinkIndex1).ToArray());
                child2.Chromosomes[i].OverWrite(crossLinkIndex1, parent1.Chromosomes[i].Bits.Take(crossLinkIndex2 - crossLinkIndex1).ToArray());
            }

            return(new Tuple <IOrganism, IOrganism>(child1, child2));
        }
        public Tuple<IOrganism, IOrganism> CrossLink(IOrganism parent1, IOrganism parent2)
        {
            if (parent1.Chromosomes.Count != parent2.Chromosomes.Count) {
                throw new InvalidOperationException("Parents must have the same number of chromosomes");
            }

            IOrganism child1 = parent1.Clone();
            IOrganism child2 = parent2.Clone();
            for (int i = 0; i <= parent1.Chromosomes.Count - 1; i++) {
                if (rand.NextDouble() > this.CrossLinkProbability) {
                    continue;
                }

                int crossLinkIndex = rand.Next(Math.Min(parent1.Chromosomes[i].Length, parent2.Chromosomes[i].Length));
                child1.Chromosomes[i].OverWrite(crossLinkIndex, parent2.Chromosomes[i].Bits.Skip(crossLinkIndex).ToArray());
                child2.Chromosomes[i].OverWrite(crossLinkIndex, parent1.Chromosomes[i].Bits.Take(child2.Chromosomes[i].Length - crossLinkIndex).ToArray());
            }

            return new Tuple<IOrganism, IOrganism>(child1, child2);
        }