private async Task <IndividualSet> CalcFitness(IndividualSet individualSet) { var substitution = new Substitution(Alphabet, individualSet.Select(i => i.Key).ToList()); string decryptedMessage = substitution.Decrypt(EncryptedText); IEnumerable <double> results = await Task.WhenAll( CalcFittingQuotient(decryptedMessage, _twoLettersFrequencies), CalcFittingQuotient(decryptedMessage, _threeLettersFrequencies)); individualSet.Fitness = TwoLettersFittingQuotientCoef * results.ElementAt(0) + ThreeLettersFittingQuotientCoef * results.ElementAt(1); return(individualSet); }
private IEnumerable <IndividualSet> GeneratePoputation(int size) { var random = new Random(); var population = new HashSet <IndividualSet>(size, new IndividualSetsComparer()); IndividualSet individualSet; Individual individual; while (population.Count != size) { individualSet = new IndividualSet(IndividualSetMembersCount); while (individualSet.Count != IndividualSetMembersCount) { individual = new Individual(new string(Alphabet.ToCharArray().OrderBy(s => (random.Next(2) % 2) == 0).ToArray()), Alphabet.Length); individualSet.Add(individual); } population.Add(individualSet); } return(population); }
private List <IndividualSet> Crossover(IndividualSet firstSet, IndividualSet secondSet, bool needsMutation = false) { IndividualSet firstChildSet = new IndividualSet(IndividualSetMembersCount); IndividualSet secondChildSet = new IndividualSet(IndividualSetMembersCount); var random = new Random(); char[] firstChildKey, secondChildKey; LinkedList <char> firstKeyCopy, secondKeyCopy; List <(int index, int indicator)> positions; for (int keyIndex = 0; keyIndex < firstSet.Count; keyIndex++) { firstChildKey = new char[Alphabet.Length]; secondChildKey = new char[Alphabet.Length]; firstKeyCopy = new LinkedList <char>(firstSet[keyIndex].Key); secondKeyCopy = new LinkedList <char>(secondSet[keyIndex].Key); positions = Enumerable.Range(0, Alphabet.Length) .Select(i => (i, random.Next(0, 2))).ToList(); foreach ((int letterIndex, int indicator) in positions) { if (indicator == 0) { firstChildKey[letterIndex] = firstSet[keyIndex].Key[letterIndex]; secondKeyCopy.Remove(firstSet[keyIndex].Key[letterIndex]); } else { secondChildKey[letterIndex] = secondSet[keyIndex].Key[letterIndex]; firstKeyCopy.Remove(secondSet[keyIndex].Key[letterIndex]); } } foreach ((int index, int indicator) in positions) { if (indicator == 1) { firstChildKey[index] = secondKeyCopy.First.Value; secondKeyCopy.RemoveFirst(); } else { secondChildKey[index] = firstKeyCopy.First.Value; firstKeyCopy.RemoveFirst(); } } if (needsMutation) { int randomPos = random.Next(0, Alphabet.Length); int firstLetterIndex = random.Next(0, randomPos); int secondLetterIndex = random.Next(randomPos, Alphabet.Length); Swap(firstChildKey, firstLetterIndex, secondLetterIndex); Swap(secondChildKey, firstLetterIndex, secondLetterIndex); } firstChildSet.Add(new Individual(new string(firstChildKey), Alphabet.Length)); secondChildSet.Add(new Individual(new string(secondChildKey), Alphabet.Length)); } return(new List <IndividualSet> { firstChildSet, secondChildSet }); void Swap(char[] childKey, int firstLetterIndex, int secondLetterIndex) { char temp = childKey[firstLetterIndex]; childKey[firstLetterIndex] = childKey[secondLetterIndex]; childKey[secondLetterIndex] = temp; } }