diff --git a/src/main/java/Enums/MutatorMethods.java b/src/main/java/Enums/MutatorMethods.java index 3ec0bb1c2283987189ca1034ee304336bfbd4bda..fe3a5ef1b4d556a15fb9e08bfccaec6f78ed68b3 100644 --- a/src/main/java/Enums/MutatorMethods.java +++ b/src/main/java/Enums/MutatorMethods.java @@ -2,5 +2,6 @@ package Enums; public enum MutatorMethods { SinglePoint, + SinglePointGlobal, Crossover } diff --git a/src/main/java/MainClasses/Config.java b/src/main/java/MainClasses/Config.java index 58f1b75995832fe48f82c7b19b07be2bbb5eab1a..96f17dcfd9b8cb84480528d7c0ed6c403ae6e5cc 100644 --- a/src/main/java/MainClasses/Config.java +++ b/src/main/java/MainClasses/Config.java @@ -134,6 +134,8 @@ public class Config { mutatorMethods[i] = MutatorMethods.SinglePoint; } else if (mutatorsToUse[i].equals("crossover")) { mutatorMethods[i] = MutatorMethods.Crossover; + } else if (mutatorsToUse[i].equals("singlePointGlobal")) { + mutatorMethods[i] = MutatorMethods.SinglePointGlobal; } } diff --git a/src/main/java/MainClasses/GeneticAlgorithm.java b/src/main/java/MainClasses/GeneticAlgorithm.java index 5951276871cc8ed823b6fea42c9a0048701e7729..45ec810daf0c9ccfdd2fb2475e56e3a8bf725d72 100644 --- a/src/main/java/MainClasses/GeneticAlgorithm.java +++ b/src/main/java/MainClasses/GeneticAlgorithm.java @@ -8,15 +8,12 @@ import InitialGenerationCreators.StraightLine; import Interfaces.*; import Mutators.Crossover; import Mutators.SinglePoint; +import Mutators.SinglePointGlobalBend; import Selectors.FitnessProportional; import Selectors.OnlyBest; import Selectors.Tournament; -import Visualizers.BestFoldingToConsole; -import Visualizers.BestFoldingToImage; +import Visualizers.*; -import Visualizers.BestFoldingsToVideo; -import Visualizers.GenerationOverviewToConsole; -import Visualizers.GenerationProgressToLog; import java.util.Random; public class GeneticAlgorithm { @@ -105,6 +102,10 @@ public class GeneticAlgorithm { } else if (config.getMutatorMethods()[i].equals(MutatorMethods.Crossover)) { this.mutators[i] = new Crossover<>(DirectionNESW.class, this.rand, config.getCrossoverAttemptsPerCandidate(), config.getCrossoverChance(), config.getCrossoverMinimalChance(), config.getCrossoverMultiplier()); + + } else if (config.getMutatorMethods()[i].equals(MutatorMethods.SinglePointGlobal)) { + this.mutators[i] = new SinglePointGlobalBend<>(DirectionNESW.class, this.rand, + config.getMutationAttemptsPerCandidate(), config.getMutationChance(), config.getMutationMinimalChance(), config.getMutationMultiplier()); } } diff --git a/src/main/java/Mutators/SinglePointBend.java b/src/main/java/Mutators/SinglePointGlobalBend.java similarity index 57% rename from src/main/java/Mutators/SinglePointBend.java rename to src/main/java/Mutators/SinglePointGlobalBend.java index 1fc4146cf5885ebd631668be19b17d2c6e564b81..ab035239b682a076a7678d983f7991c8a4c49dd5 100644 --- a/src/main/java/Mutators/SinglePointBend.java +++ b/src/main/java/Mutators/SinglePointGlobalBend.java @@ -2,9 +2,10 @@ package Mutators; import Interfaces.Mutator; import MainClasses.Candidate; + import java.util.Random; -public class SinglePointBend<T extends Enum<?>> implements Mutator { +public class SinglePointGlobalBend<T extends Enum<?>> implements Mutator { // TODO: Maybe this should just extend SinglePoint boolean isFRL; Class<T> possibleDirections; @@ -14,8 +15,8 @@ public class SinglePointBend<T extends Enum<?>> implements Mutator { double mutationMinimalChance; double mutationMultiplier; - public SinglePointBend(Class<T> possibleDirections, Random rand, int mutationAttemptsPerCandidate, - double mutationChance, double mutationMinimalChance, double mutationMultiplier) { + public SinglePointGlobalBend(Class<T> possibleDirections, Random rand, int mutationAttemptsPerCandidate, + double mutationChance, double mutationMinimalChance, double mutationMultiplier) { this.possibleDirections = possibleDirections; this.isFRL = Mutator.isFRLEncoding(possibleDirections); this.rand = rand; @@ -38,11 +39,23 @@ public class SinglePointBend<T extends Enum<?>> implements Mutator { for (int j = 0; j < this.mutationAttemptsPerCandidate; j++) { if (this.mutationChance > this.rand.nextDouble()) { int mutationPlace = this.rand.nextInt(proteinLength); - // TODO Do complete bend instead of local bend if (this.isFRL) { mutatedFolding[mutationPlace] = this.rand.nextInt(3); } else { - mutatedFolding[mutationPlace] = this.rand.nextInt(4); + int oldDirection = mutatedFolding[mutationPlace]; + if (mutationPlace == 0) { + // Allow any direction in the first position + mutatedFolding[mutationPlace] = this.rand.nextInt(4); + } else { + // Make sure there can never be a backtracking overlap while mutating + mutatedFolding[mutationPlace] = + ((mutatedFolding[mutationPlace-1] - 1 + this.rand.nextInt(3)) + 4 ) % 4; + } + // Also bend the following amino acids in the right way to achieve a "global" bend + int offset = (mutatedFolding[mutationPlace] - oldDirection + 4) % 4; + for (int r = mutationPlace + 1; r < mutatedFolding.length; r++) { + mutatedFolding[r] = (mutatedFolding[r] + offset) % 4; + } } } }