diff --git a/src/main/java/Enums/DirectionFRL.java b/src/main/java/Enums/DirectionFRL.java new file mode 100644 index 0000000000000000000000000000000000000000..f870ea5d001328699a0067a2f26d002eb6844bcb --- /dev/null +++ b/src/main/java/Enums/DirectionFRL.java @@ -0,0 +1,18 @@ +package Enums; + +// TODO: Maybe actually replace these with a boolean and hard code... + +public enum DirectionFRL { + Forward(0), + Right(1), + Left(2); + + private final int value; + private DirectionFRL(int value) { + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/Enums/DirectionNESW.java b/src/main/java/Enums/DirectionNESW.java new file mode 100644 index 0000000000000000000000000000000000000000..5daa97ef051cb9e5ae688167f1a33c904b1208fb --- /dev/null +++ b/src/main/java/Enums/DirectionNESW.java @@ -0,0 +1,19 @@ +package Enums; + +// TODO: Maybe actually replace these with a boolean and hard code... + +public enum DirectionNESW { + North(0), + East(1), + South(2), + West(3); + + private final int value; + private DirectionNESW(int value) { + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/InitialGenerationCreators/Curl.java b/src/main/java/InitialGenerationCreators/Curl.java new file mode 100644 index 0000000000000000000000000000000000000000..798da729bd724aa7f2c014c31872d598951be3e4 --- /dev/null +++ b/src/main/java/InitialGenerationCreators/Curl.java @@ -0,0 +1,108 @@ +package InitialGenerationCreators; + +import Enums.DirectionFRL; +import Enums.DirectionNESW; +import Interfaces.InitialGenerationCreator; +import MainClasses.Candidate; + +public class Curl<T extends Enum<?>> implements InitialGenerationCreator { + + Class<T> possibleDirections; + + public Curl(Class<T> possibleDirections) { + this.possibleDirections = possibleDirections; + } + + @Override + public Candidate[] initializeDirections(int populationSize, int[] isHydrophobic) { + Candidate[] population = new Candidate[populationSize]; + int proteinLength = isHydrophobic.length; + + int[] candidateDirections; + if (isFRLEncoding(possibleDirections) && populationSize > 0) { + candidateDirections = curlFRL(proteinLength); + } else { + candidateDirections = curlNESW(proteinLength); + } + + for (int i = 0; i < populationSize; i++) { + population[i] = new Candidate(isHydrophobic, candidateDirections); + } + + return population; + } + + private int[] curlNESW(int proteinLength) { + int[] candidateDirections = new int[proteinLength]; + int stepSize = 1; + int stepsLeft = 1; + boolean stepSizeChange = false; // To increase stepSize every second time + DirectionNESW dir = DirectionNESW.North; + + for (int j = 0; j < proteinLength; j++) { + candidateDirections[j] = dir.getValue(); + stepsLeft--; + + if (stepsLeft == 0) { + if (stepSizeChange) { + stepSize++; + stepsLeft = stepSize; + stepSizeChange = false; + } else { + stepsLeft = stepSize; + stepSizeChange = true; + } + + // Rotate direction + if (dir == DirectionNESW.North) { + dir = DirectionNESW.East; + } else if (dir == DirectionNESW.East) { + dir = DirectionNESW.South; + } else if (dir == DirectionNESW.South) { + dir = DirectionNESW.West; + } else { + dir = DirectionNESW.North; + } + } + } + return candidateDirections; + } + + private int[] curlFRL(int proteinLength) { + int[] candidateDirections = new int[proteinLength]; + candidateDirections[0] = DirectionFRL.Forward.getValue(); + + int stepSize = 0; + int stepsLeft = 0; + boolean stepSizeChange = false; // To increase stepSize every second time + + for (int j = 1; j < proteinLength; j++) { + if (stepsLeft == 0) { // Turn + candidateDirections[j] = DirectionFRL.Right.getValue(); + + if (stepSizeChange) { + stepSize++; + stepSizeChange = false; + } else { + stepSizeChange = true; + } + stepsLeft = stepSize; + + } else { // Straight + candidateDirections[j] = DirectionFRL.Forward.getValue(); + stepsLeft--; + } + } + return candidateDirections; + } + + private <T extends Enum<?>> boolean isFRLEncoding(Class<T> possibleDirections) { + T[] possibleDirectionsEnum = possibleDirections.getEnumConstants(); + for (int i = 0; i < possibleDirectionsEnum.length; i++) { + if (possibleDirectionsEnum[i].equals(DirectionFRL.Forward)) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/InitialGenerationCreators/RandomDirection.java b/src/main/java/InitialGenerationCreators/RandomDirection.java new file mode 100644 index 0000000000000000000000000000000000000000..20eafa287d56e30ffb6d4ebefb84c4bf305ebe60 --- /dev/null +++ b/src/main/java/InitialGenerationCreators/RandomDirection.java @@ -0,0 +1,38 @@ +package InitialGenerationCreators; + +import Enums.DirectionNESW; +import Interfaces.InitialGenerationCreator; +import MainClasses.Candidate; + +import java.util.Random; + +public class RandomDirection<T extends Enum<?>> implements InitialGenerationCreator { + + Random rand; + Class<T> possibleDirections; + + public RandomDirection(Random rand, Class<T> possibleDirections) { + this.rand = rand; + this.possibleDirections = possibleDirections; + } + + @Override + public Candidate[] initializeDirections(int populationSize, int[] isHydrophobic) { + Candidate[] population = new Candidate[populationSize]; + int proteinLength = isHydrophobic.length; + + for (int i = 0; i < populationSize; i++) { + int[] candidateDirections = new int[proteinLength]; + for (int j = 0; j < proteinLength; j++) { + candidateDirections[j] = this.randomDirection(this.possibleDirections); + } + population[i] = new Candidate(isHydrophobic, candidateDirections); + } + + return population; + } + + private int randomDirection(Class<T> dirEnum) { + return rand.nextInt(dirEnum.getEnumConstants().length); + } +} diff --git a/src/main/java/InitialGenerationCreators/StraightLine.java b/src/main/java/InitialGenerationCreators/StraightLine.java new file mode 100644 index 0000000000000000000000000000000000000000..abdde5c504779dabe7488e4e63d44cd05c1efb1d --- /dev/null +++ b/src/main/java/InitialGenerationCreators/StraightLine.java @@ -0,0 +1,30 @@ +package InitialGenerationCreators; + +import Enums.DirectionFRL; +import Interfaces.InitialGenerationCreator; +import MainClasses.Candidate; + +import java.util.Random; + +public class StraightLine implements InitialGenerationCreator { + + public StraightLine() { + } + + @Override + public Candidate[] initializeDirections(int populationSize, int[] isHydrophobic) { + Candidate[] population = new Candidate[populationSize]; + int proteinLength = isHydrophobic.length; + + int[] candidateDirections = new int[proteinLength]; + for (int j = 0; j < proteinLength; j++) { + candidateDirections[j] = 0; // Default starting direction is set by Enum + } + + for (int i = 0; i < populationSize; i++) { + population[i] = new Candidate(isHydrophobic, candidateDirections); + } + + return population; + } +} diff --git a/src/main/java/Interfaces/Evaluater.java b/src/main/java/Interfaces/Evaluater.java new file mode 100644 index 0000000000000000000000000000000000000000..3e0557427375fab813758c6323b6988d46f550b2 --- /dev/null +++ b/src/main/java/Interfaces/Evaluater.java @@ -0,0 +1,4 @@ +package Interfaces; + +public interface Evaluater { +} diff --git a/src/main/java/Interfaces/InitialGenerationCreator.java b/src/main/java/Interfaces/InitialGenerationCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..182069c21397b50fb7d237f38b6280f592c9a2f2 --- /dev/null +++ b/src/main/java/Interfaces/InitialGenerationCreator.java @@ -0,0 +1,8 @@ +package Interfaces; + +import MainClasses.Candidate; + +public interface InitialGenerationCreator { + + Candidate[] initializeDirections(int populationSize, int[] isHydrophobic); +} diff --git a/src/main/java/Interfaces/Mutator.java b/src/main/java/Interfaces/Mutator.java new file mode 100644 index 0000000000000000000000000000000000000000..90e45beedd70f17ea1c4584b09a05215429b3c4c --- /dev/null +++ b/src/main/java/Interfaces/Mutator.java @@ -0,0 +1,4 @@ +package Interfaces; + +public interface Mutator { +} diff --git a/src/main/java/Interfaces/Selector.java b/src/main/java/Interfaces/Selector.java new file mode 100644 index 0000000000000000000000000000000000000000..123c19943335ea6a6a256bb16dd2f8f71d25be0b --- /dev/null +++ b/src/main/java/Interfaces/Selector.java @@ -0,0 +1,4 @@ +package Interfaces; + +public interface Selector { +} diff --git a/src/main/java/Interfaces/Visualizer.java b/src/main/java/Interfaces/Visualizer.java new file mode 100644 index 0000000000000000000000000000000000000000..f93e288b9162a71a72e181d32872202f994d8e78 --- /dev/null +++ b/src/main/java/Interfaces/Visualizer.java @@ -0,0 +1,4 @@ +package Interfaces; + +public interface Visualizer { +} diff --git a/src/main/java/Candidate.java b/src/main/java/MainClasses/Candidate.java similarity index 99% rename from src/main/java/Candidate.java rename to src/main/java/MainClasses/Candidate.java index 42fa4f206111725f140bca6e5855931161467b73..50e25e957ac8b980a50fb9c30041bfd502637397 100644 --- a/src/main/java/Candidate.java +++ b/src/main/java/MainClasses/Candidate.java @@ -1,3 +1,5 @@ +package MainClasses; + import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/Examples.java b/src/main/java/MainClasses/Examples.java similarity index 97% rename from src/main/java/Examples.java rename to src/main/java/MainClasses/Examples.java index ee4593759b1cbb4ac88548a4aa357c527d11ae9d..dc829b3303b8fa9277ed668ea607f949df644bbb 100644 --- a/src/main/java/Examples.java +++ b/src/main/java/MainClasses/Examples.java @@ -1,4 +1,4 @@ - +package MainClasses; // benchmark sequences for the 2d HP model // 0 = hydrophil, "white" // 1 = hydrophob, "black" diff --git a/src/main/java/GeneticAlgorithm.java b/src/main/java/MainClasses/GeneticAlgorithm.java similarity index 92% rename from src/main/java/GeneticAlgorithm.java rename to src/main/java/MainClasses/GeneticAlgorithm.java index 727d69fa8cfafc1048f478b667a60b4538111731..8b6354fb3e357987a2ac058fd620b65d38c4727f 100644 --- a/src/main/java/GeneticAlgorithm.java +++ b/src/main/java/MainClasses/GeneticAlgorithm.java @@ -1,3 +1,11 @@ +package MainClasses; + +import Enums.DirectionNESW; +import InitialGenerationCreators.Curl; +import InitialGenerationCreators.RandomDirection; +import InitialGenerationCreators.StraightLine; +import Interfaces.InitialGenerationCreator; + import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; @@ -35,11 +43,17 @@ public class GeneticAlgorithm { tournament } + InitialGenerationCreator initialGenCreator; + Selection selectionVariant; int k; // Number of selected Candidates to face off in a tournament selection // Initialize with protein public GeneticAlgorithm (Properties properties, int[] protein) { +// this.initialGenCreator = new RandomDirection(this.rand, DirectionNESW.class); +// this.initialGenCreator = new StraightLine(); + this.initialGenCreator = new Curl(DirectionNESW.class); + this.properties = properties; this.isHydrophobic = protein; initializeProperties(); @@ -53,7 +67,7 @@ public class GeneticAlgorithm { e.printStackTrace(); } - this.population = generateInitalPopulation(); + this.population = this.initialGenCreator.initializeDirections(this.populationSize, this.isHydrophobic); this.totalFitness = 0; this.fitness = new double[populationSize]; this.overallBestFitness = 0; @@ -87,21 +101,6 @@ public class GeneticAlgorithm { this.pdraw = new ProteinDrawer(properties.getProperty("imageSequencePath")); } - // Generate initial population - private Candidate[] generateInitalPopulation() { - Candidate[] population = new Candidate[populationSize]; - - for (int i = 0; i < populationSize; i++) { - int[] canidateDirections = new int[isHydrophobic.length]; - for (int j = 0; j < isHydrophobic.length; j++) { - canidateDirections[j] = rand.nextInt(4); - } - population[i] = new Candidate(isHydrophobic, canidateDirections); - } - - return population; - } - public void simulateGenerations() { for (int gen = 0; gen < totalGenerations-1; gen++) { evaluateGeneration(gen); @@ -140,7 +139,7 @@ public class GeneticAlgorithm { pdraw.drawProteinToFile(population[bestIndex].getVertexList(), population[bestIndex].calculateFitness(true), gen); // Save the overall best - if (bestFitness > overallBestFitness) { + if (bestFitness >= overallBestFitness) { overallBestFitness = bestFitness; overallBest = new Candidate(this.isHydrophobic, population[bestIndex].getOutgoing()); } diff --git a/src/main/java/JpegImagesToMovie.java b/src/main/java/MainClasses/JpegImagesToMovie.java similarity index 97% rename from src/main/java/JpegImagesToMovie.java rename to src/main/java/MainClasses/JpegImagesToMovie.java index 992ef43732f4d6bc3f03c6c4f3b8bfb8464e1717..12ea63cbfc1553b6f6e91bf260c6533e6702c16c 100644 --- a/src/main/java/JpegImagesToMovie.java +++ b/src/main/java/MainClasses/JpegImagesToMovie.java @@ -1,5 +1,5 @@ -/* - * @(#)JpegImagesToMovie.java 1.3 01/03/13 +package MainClasses;/* + * @(#)MainClasses.JpegImagesToMovie.java 1.3 01/03/13 * Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved. * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, @@ -324,7 +324,7 @@ public class JpegImagesToMovie implements ControllerListener, DataSinkListener { System.exit(0); } - JpegImagesToMovie imageToMovie = new JpegImagesToMovie(); + MainClasses.JpegImagesToMovie imageToMovie = new MainClasses.JpegImagesToMovie(); imageToMovie.doIt(width, height, frameRate, inputFiles, oml); System.exit(0); @@ -332,7 +332,7 @@ public class JpegImagesToMovie implements ControllerListener, DataSinkListener { static void prUsage() { System.err - .println("Usage: java JpegImagesToMovie -w <width> -h <height> -f <frame rate> -o <output URL> <input JPEG file 1> <input JPEG file 2> ..."); + .println("Usage: java MainClasses.JpegImagesToMovie -w <width> -h <height> -f <frame rate> -o <output URL> <input JPEG file 1> <input JPEG file 2> ..."); System.exit(-1); } diff --git a/src/main/java/Main.java b/src/main/java/MainClasses/Main.java similarity index 92% rename from src/main/java/Main.java rename to src/main/java/MainClasses/Main.java index 8f8cc426e9830b06d488b036ba671b6883b9fce6..ae3c48cd74f46946dd1c7d634c9b7715bd431c0d 100644 --- a/src/main/java/Main.java +++ b/src/main/java/MainClasses/Main.java @@ -1,11 +1,9 @@ +package MainClasses; + import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.List; import java.util.Properties; -import java.util.Random; public class Main { @@ -30,7 +28,7 @@ public class Main { e.printStackTrace(); } -// ProteinDrawer pdraw = new ProteinDrawer("./visualization/individual/", "image.jpg"); +// MainClasses.ProteinDrawer pdraw = new MainClasses.ProteinDrawer("./visualization/individual/", "image.jpg"); // // // int[] isHydrophobic = {0, 0, 0, 1, 0, 1, 1, 0, 0}; // 0 = no | 1 = yes diff --git a/src/main/java/ProteinDrawer.java b/src/main/java/MainClasses/ProteinDrawer.java similarity index 99% rename from src/main/java/ProteinDrawer.java rename to src/main/java/MainClasses/ProteinDrawer.java index 0dd4b71b30fda3b2a21418e699f786de168b40b7..5efc888e08dbc368481ac9c35be5ccb636d5ac73 100644 --- a/src/main/java/ProteinDrawer.java +++ b/src/main/java/MainClasses/ProteinDrawer.java @@ -1,3 +1,5 @@ +package MainClasses; + import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; diff --git a/src/main/java/Vertex.java b/src/main/java/MainClasses/Vertex.java similarity index 97% rename from src/main/java/Vertex.java rename to src/main/java/MainClasses/Vertex.java index be0ef1cd967d6c5e18c6398ea41a0bb21c8f5eeb..5c62cd3688e3ae915ed7c73f39c8e6237b3c9d8a 100644 --- a/src/main/java/Vertex.java +++ b/src/main/java/MainClasses/Vertex.java @@ -1,3 +1,5 @@ +package MainClasses; + // Helper class representing a single amino acid class Vertex { int x; diff --git a/src/main/java/VideoCreator.java b/src/main/java/MainClasses/VideoCreator.java similarity index 88% rename from src/main/java/VideoCreator.java rename to src/main/java/MainClasses/VideoCreator.java index 2df6611150b8318a2b18a622ea94248821610d2f..4c7c81fc21ca298704e6d728e72fee2a20ad7970 100644 --- a/src/main/java/VideoCreator.java +++ b/src/main/java/MainClasses/VideoCreator.java @@ -1,5 +1,6 @@ +package MainClasses; + import java.awt.Graphics2D; -import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.File; import java.io.FilenameFilter; @@ -12,6 +13,7 @@ import javax.media.MediaLocator; public class VideoCreator{ + private static final int MAXIMUM_SIZE = 3000; public static File dir = new File("./visualization/series"); // Default public static final String[] extensions = new String[]{"jpg", "png"}; public static final FilenameFilter imageFilter = new FilenameFilter() { @@ -32,8 +34,8 @@ public class VideoCreator{ if (dir.isDirectory()) { // reads input images and determines maximum required size - int maxHeight = ProteinDrawer.maxWidth; - int maxWidth = ProteinDrawer.maxHeight; + int maxHeight = ProteinDrawer.maxHeight; + int maxWidth = ProteinDrawer.maxWidth; if (maxHeight <= 0 || maxWidth <= 0) { int counter = 1; @@ -48,6 +50,14 @@ public class VideoCreator{ } } + // Needed because video is not playable with bigger sizes, mostly a concern for straight line initialization + if (maxWidth > MAXIMUM_SIZE) { + maxWidth = MAXIMUM_SIZE; + } + if (maxHeight > MAXIMUM_SIZE) { + maxHeight = MAXIMUM_SIZE; + } + widthHeight[0] = maxWidth; widthHeight[1] = maxHeight; @@ -74,7 +84,7 @@ public class VideoCreator{ return widthHeight; } - // Main function + // MainClasses.Main function public static void createVideo(Properties properties) throws IOException { String imagesPath = properties.getProperty("imageSequencePath"); String videoPathAndFile = properties.getProperty("videoPathAndFile"); diff --git a/src/main/resources/genetic.properties b/src/main/resources/genetic.properties index 52e499bf9fd8712d841fb7b3e03e7680f89f3e75..bc334681e2a76dd86cbedd74e63e4dbb5b6d3e38 100644 --- a/src/main/resources/genetic.properties +++ b/src/main/resources/genetic.properties @@ -1,7 +1,7 @@ logfilePath = log.txt -populationSize = 300 +populationSize = 10 # Do NOT go OVER 1_000_000 generations, as the filenames don't play nice then -noGenerations = 1000 +noGenerations = 10 # proportional OR tournament selection = proportional # Number of tournament participants @@ -12,11 +12,16 @@ mutationChance = 1.0 # Decline in mutation probability with generations -> ex with 0.05: 2nd 0.95, 3rd 0.9025, 4th 0.857 mutationDecline = 0.001 mutationAttemptsPerCanidate = 1 -crossoverChance = 0.2 -crossoverDecline = 0.01 +crossoverChance = 0.6 +crossoverDecline = 0.005 # For video imageSequencePath = ./visualization/series videoPathAndFile = ./visualization/video.mp4 # ms between images -imgInterval = 100 \ No newline at end of file +imgInterval = 100 + + +# TODO: +createVideo = true +initializationMethod = curl, straight, random \ No newline at end of file