Skip to content
Snippets Groups Projects
Crossover.java 2.91 KiB
Newer Older
  • Learn to ignore specific revisions
  • istkabra's avatar
    istkabra committed
    package Mutators;
    
    import Interfaces.Mutator;
    import MainClasses.Candidate;
    
    import java.util.Random;
    
    public class Crossover<T extends Enum<?>> implements Mutator {
    
        boolean isFRL;
        Class<T> possibleDirections;
        Random rand;
        int crossoverAttemptsPerCandidate;
        double crossoverChance;
    
        double crossoverMinimalChance;
    
    istkabra's avatar
    istkabra committed
        double crossoverMultiplier;
    
        public Crossover(Class<T> possibleDirections, Random rand, int crossoverAttemptsPerCandidate,
    
                         double crossoverChance, double crossoverMinimalChance, double crossoverMultiplier) {
    
    istkabra's avatar
    istkabra committed
            this.possibleDirections = possibleDirections;
            this.isFRL = Mutator.isFRLEncoding(possibleDirections);
            this.rand = rand;
            this.crossoverAttemptsPerCandidate = crossoverAttemptsPerCandidate;
            this.crossoverChance = crossoverChance;
    
            this.crossoverMinimalChance = crossoverMinimalChance;
    
    istkabra's avatar
    istkabra committed
            this.crossoverMultiplier = crossoverMultiplier;
        }
    
        @Override
        public Candidate[] mutatePopulation(Candidate[] population) {
    
    Lennart Eichhorn's avatar
    Lennart Eichhorn committed
            Candidate[] mutatedPopulation = new Candidate[population.length];
    
            if (this.crossoverChance > crossoverMinimalChance) {
    
    istkabra's avatar
    istkabra committed
                int populationSize = population.length;
    
    Lennart Eichhorn's avatar
    Lennart Eichhorn committed
                int proteinLength = population[0].getFolding().length;
    
    Lennart Eichhorn's avatar
    Lennart Eichhorn committed
                for (int candidateId = 0; candidateId<population.length ; candidateId++) {
                    //Mutates only the selected Candidate not the partner
                    int[] mutatedFolding = population[candidateId].getFolding();
    
    istkabra's avatar
    istkabra committed
                    for (int j = 0; j < this.crossoverAttemptsPerCandidate; j++) {
                        if (this.crossoverChance > this.rand.nextDouble()) {
                            int crossoverPartner = this.rand.nextInt(populationSize);
                            int crossoverPlace = this.rand.nextInt(proteinLength);
    
    Lennart Eichhorn's avatar
    Lennart Eichhorn committed
                            int[] partnerFolding = population[crossoverPartner].getFolding();
    
    Lennart Eichhorn's avatar
    Lennart Eichhorn committed
                            for (int i = crossoverPlace; i < mutatedFolding.length; i++) {
                                mutatedFolding[i] = partnerFolding[i];
    
    Lennart Eichhorn's avatar
    Lennart Eichhorn committed
                            // Removed partner crossover mutation, because this can lead to unexpected double mutations if the partner mutates again
    
    Lennart Eichhorn's avatar
    Lennart Eichhorn committed
                            //for (int i = crossoverPlace; i < candidate.outgoingDirection.length; i++) {
                            //    population[crossoverPartner].outgoingDirection[i] = originalDirections[i];
                            //}
    
    Lennart Eichhorn's avatar
    Lennart Eichhorn committed
                    mutatedPopulation[candidateId] = new Candidate(mutatedFolding);
    
    istkabra's avatar
    istkabra committed
                }
    
                System.out.printf("CrossoverChance: %.4f\n", this.crossoverChance);
    
                this.crossoverChance *= (1 - this.crossoverMultiplier); // Lower mutation rate with generation
            }
    
    Lennart Eichhorn's avatar
    Lennart Eichhorn committed
            return  mutatedPopulation;