diff --git a/src/main/java/Interfaces/Visualizer.java b/src/main/java/Interfaces/Visualizer.java index f1440a5b2f56545599f8749308e593b746914d3f..1b6c6469d26ab638e7da50c435a5c72dc67587c4 100644 --- a/src/main/java/Interfaces/Visualizer.java +++ b/src/main/java/Interfaces/Visualizer.java @@ -1,6 +1,8 @@ package Interfaces; import Enums.State; +import MainClasses.Candidate; +import MainClasses.GeneticAlgorithm; import MainClasses.Vertex; import Visualization.Cell; @@ -9,7 +11,8 @@ import java.util.List; public interface Visualizer { - void drawProtein(ArrayList<Vertex> vertexListOriginal, double fit, int bond, int over, int gen); + //TODO There should probably be a seperate datastructure for generation information/ga information + void drawProtein(Candidate[] generation, GeneticAlgorithm geneticAlgorithm); static ArrayList<Vertex> deepCopyVertexList (List<Vertex> vertexListOriginal) { ArrayList<Vertex> vertexList = new ArrayList<>(); @@ -84,8 +87,4 @@ public interface Visualizer { return cellArray; } - - void setFilename(String filename); - int getMaxH(); - int getMaxW(); } diff --git a/src/main/java/MainClasses/GeneticAlgorithm.java b/src/main/java/MainClasses/GeneticAlgorithm.java index 4a3a987d9700e7d20ac76f7dc4b0cc5c776b34b5..13be23837ba320743ff1163238862d57ef5ec387 100644 --- a/src/main/java/MainClasses/GeneticAlgorithm.java +++ b/src/main/java/MainClasses/GeneticAlgorithm.java @@ -11,8 +11,8 @@ import Mutators.SinglePoint; import Selectors.FitnessProportional; import Selectors.OnlyBest; import Selectors.Tournament; -import Visualization.Visualizers.PrintFoldingToConsole; -import Visualization.Visualizers.PrintFoldingToFile; +import Visualization.Visualizers.BestFoldingToConsole; +import Visualization.Visualizers.BestFoldingToImage; import java.io.IOException; import java.nio.file.Files; @@ -25,20 +25,24 @@ public class GeneticAlgorithm { Config config; - int[] isHydrophobic; - Candidate[] population; + //TODO Make private again when the Generation class is created + public int[] isHydrophobic; + public Candidate[] population; - double totalFitness; - double[] fitness; + public double totalFitness; + public double[] fitness; - double overallBestFitness; - Candidate overallBest; + public double overallBestFitness; + public Candidate overallBest; - InitialGenerationCreator initialGenCreator; - Mutator[] mutators; - Selector selector; - Evaluator evaluator; - Visualizer[] visualizers; + public InitialGenerationCreator initialGenCreator; + public Mutator[] mutators; + public Selector selector; + public Evaluator evaluator; + public Visualizer[] visualizers; + + //TODO Remove again with the new Generation class + public int generation; // Initialize with protein public GeneticAlgorithm (int[] protein, Config config) { @@ -52,6 +56,7 @@ public class GeneticAlgorithm { this.totalFitness = 0; this.fitness = new double[config.getPopulationSize()]; this.overallBestFitness = 0; + this.generation = 0; } @@ -75,10 +80,10 @@ public class GeneticAlgorithm { int j = 0; for (VisualizerMethods vm : config.getVisualizers()) { if (vm.equals(VisualizerMethods.Console)) { - this.visualizers[j] = new PrintFoldingToConsole(isHydrophobic, config); + this.visualizers[j] = new BestFoldingToConsole(isHydrophobic, config); j++; } else if (vm.equals(VisualizerMethods.Image)) { - this.visualizers[j] = new PrintFoldingToFile(isHydrophobic, config); + this.visualizers[j] = new BestFoldingToImage(isHydrophobic, config); j++; } } @@ -133,6 +138,8 @@ public class GeneticAlgorithm { public void simulateGenerations() { for (int gen = 0; gen < config.getTotalGenerations()-1; gen++) { + //TODO Remove with the new Generation class + generation = gen; this.evaluateGeneration(gen); this.population = this.selector.selectNewPopulation(this.population, this.fitness, this.totalFitness); @@ -164,10 +171,8 @@ public class GeneticAlgorithm { } for (Visualizer v : this.visualizers) { - String imagePath = config.getImageSequenceDirectory() + "/" + config.getJobName() + "_" + gen + ".png"; - v.setFilename(imagePath); //TODO Print real bond and overlap amount - v.drawProtein(this.population[bestIndex].getVertices(), bestFitness, -1, -1, gen); + v.drawProtein(this.population, this); } //TODO Print real bond and overlap amount @@ -199,22 +204,20 @@ public class GeneticAlgorithm { } public int getMaxH() { - int maxHAcrossVisualiszators = 0; for (Visualizer v : visualizers) { - if (maxHAcrossVisualiszators < v.getMaxH()) { - maxHAcrossVisualiszators = v.getMaxH(); + if(v instanceof BestFoldingToImage){ + return ((BestFoldingToImage)v).getMaxH(); } } - return maxHAcrossVisualiszators; + return 0; } public int getMaxW() { - int maxWAcrossVisualiszators = 0; for (Visualizer v : visualizers) { - if (maxWAcrossVisualiszators < v.getMaxW()) { - maxWAcrossVisualiszators = v.getMaxW(); + if(v instanceof BestFoldingToImage){ + return ((BestFoldingToImage)v).getMaxW(); } } - return maxWAcrossVisualiszators; + return 0; } } diff --git a/src/main/java/MainClasses/Main.java b/src/main/java/MainClasses/Main.java index e9f8f7e751016716d39c302683414f912aea4f73..d063f4800f8a5fc83cf476c2ceef0329dfe593f8 100644 --- a/src/main/java/MainClasses/Main.java +++ b/src/main/java/MainClasses/Main.java @@ -12,7 +12,7 @@ public class Main { String propertyPath = "./src/main/resources/genetic.properties"; Config config = new Config(propertyPath); - int[] protein = Examples.convertStringToIntArray(Examples.SEQ36); + int[] protein = Examples.convertStringToIntArray(Examples.SEQ50); GeneticAlgorithm ga = new GeneticAlgorithm(protein, config); ga.simulateGenerations(); diff --git a/src/main/java/Visualization/Visualizers/PrintFoldingToConsole.java b/src/main/java/Visualization/Visualizers/BestFoldingToConsole.java similarity index 70% rename from src/main/java/Visualization/Visualizers/PrintFoldingToConsole.java rename to src/main/java/Visualization/Visualizers/BestFoldingToConsole.java index 3a9b4da3d17ce694c279703e7b4ce2144b7ad48d..d5eb289c7f405d65e4fc5d0eedd982418ab32509 100644 --- a/src/main/java/Visualization/Visualizers/PrintFoldingToConsole.java +++ b/src/main/java/Visualization/Visualizers/BestFoldingToConsole.java @@ -2,7 +2,9 @@ package Visualization.Visualizers; import Enums.State; import Interfaces.Visualizer; +import MainClasses.Candidate; import MainClasses.Config; +import MainClasses.GeneticAlgorithm; import MainClasses.Vertex; import Visualization.Cell; @@ -13,23 +15,25 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; -public class PrintFoldingToConsole implements Visualizer { +public class BestFoldingToConsole implements Visualizer { - int maxHeight; - int maxWidth; final int[] isHydrophobic; Config config; - public PrintFoldingToConsole(int[] isHydrophobic, Config config) { - this.maxHeight = 0; - this.maxWidth = 0; + public BestFoldingToConsole(int[] isHydrophobic, Config config) { this.isHydrophobic = isHydrophobic; this.config = config; } - public void drawProtein(ArrayList<Vertex> vertexListOriginal, double fit, int bond, int over, int gen) { - // Copy VertexList to be able to manipulate it - ArrayList<Vertex> vertexList = Visualizer.deepCopyVertexList(vertexListOriginal); + public void drawProtein(Candidate[] generation, GeneticAlgorithm geneticAlgorithm) { + Candidate bestCandidateOfGeneration = generation[0]; + for (Candidate evaluatedCandidate : generation) { + if(bestCandidateOfGeneration.getFitness() < evaluatedCandidate.getFitness()){ + bestCandidateOfGeneration=evaluatedCandidate; + } + } + + ArrayList<Vertex> vertexList = bestCandidateOfGeneration.getVertices(); Cell[][] cellArray = Visualizer.convertProteinTo2DArray(vertexList, isHydrophobic); @@ -75,20 +79,4 @@ public class PrintFoldingToConsole implements Visualizer { // Fallback return config.getConsoleEmpty(); } - - - @Override - public void setFilename(String format) { - // Only here so file based visualizers work - } - - @Override - public int getMaxH() { - return this.maxHeight; - } - - @Override - public int getMaxW() { - return this.maxWidth; - } } diff --git a/src/main/java/Visualization/Visualizers/PrintFoldingToFile.java b/src/main/java/Visualization/Visualizers/BestFoldingToImage.java similarity index 74% rename from src/main/java/Visualization/Visualizers/PrintFoldingToFile.java rename to src/main/java/Visualization/Visualizers/BestFoldingToImage.java index 787339be0ce04ed023824fc0911f4257ba840e23..32d4c55a9306a1087af48182dbdda589b5790c98 100644 --- a/src/main/java/Visualization/Visualizers/PrintFoldingToFile.java +++ b/src/main/java/Visualization/Visualizers/BestFoldingToImage.java @@ -1,11 +1,17 @@ package Visualization.Visualizers; import Enums.State; +import Evaluators.EvaluatorNESW; +import Interfaces.Evaluator; import Interfaces.Visualizer; +import MainClasses.Candidate; import MainClasses.Config; +import MainClasses.GeneticAlgorithm; import MainClasses.Vertex; import Visualization.Cell; +import java.nio.file.Files; +import java.nio.file.Paths; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; @@ -13,10 +19,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; -public class PrintFoldingToFile implements Visualizer { - - String folder; - String filename; +public class BestFoldingToImage implements Visualizer { int maxHeight; int maxWidth; @@ -28,21 +31,31 @@ public class PrintFoldingToFile implements Visualizer { final int[] isHydrophobic; Config config; - public PrintFoldingToFile(int[] isHydrophobic, Config config) { - //TODO This is not really needed - //this.folder = config.getImageSequenceDirectory(); - this.folder = ""; - this.filename = "image.png"; // Default - + public BestFoldingToImage(int[] isHydrophobic, Config config) { this.maxHeight = 0; this.maxWidth = 0; this.isHydrophobic = isHydrophobic; this.config = config; + try { + Files.createDirectories(Paths.get(config.getImageSequenceDirectory())); + } catch (IOException e) { + e.printStackTrace(); + } + } - public void drawProtein(ArrayList<Vertex> vertexListOriginal, double fit, int bond, int over, int gen) { - // Copy VertexList to be able to manipulate it - ArrayList<Vertex> vertexList = Visualizer.deepCopyVertexList(vertexListOriginal); + public void drawProtein(Candidate[] generation, GeneticAlgorithm geneticAlgorithm) { + String filename = config.getImageSequenceDirectory() + "/" + config.getJobName() + "_" + geneticAlgorithm.generation + ".png"; + + //TODO This should probably be in the new Generation Class + Candidate bestCandidateOfGeneration = generation[0]; + for (Candidate evaluatedCandidate : generation) { + if(bestCandidateOfGeneration.getFitness() < evaluatedCandidate.getFitness()){ + bestCandidateOfGeneration=evaluatedCandidate; + } + } + + ArrayList<Vertex> vertexList = bestCandidateOfGeneration.getVertices(); Cell[][] cellArray = Visualizer.convertProteinTo2DArray(vertexList, this.isHydrophobic); @@ -130,17 +143,19 @@ public class PrintFoldingToFile implements Visualizer { } g2.setColor(config.getImageText()); - String label = "Gen: " + gen - + " Fitness: " + String.format("%.4f", fit) - + " H/H Bonds: " + bond - + " Overlaps: " + over; + //TODO Get the labels from the new Generation class? + EvaluatorNESW evaluator = new EvaluatorNESW(1,isHydrophobic); + int bonds = evaluator.evaluateBonds(bestCandidateOfGeneration); + int overlaps = evaluator.evaluateBonds(bestCandidateOfGeneration); + String label = "Gen: " + geneticAlgorithm.generation + + " Fitness: " + String.format("%.4f", bestCandidateOfGeneration.getFitness()) + + " H/H Bonds: " + bonds + + " Overlaps: " + overlaps; int labelWidth = metrics.stringWidth(label); int x = margin / 4; int y = margin / 4; g2.drawString(label, x, y); - if (!new File(folder).exists()) new File(folder).mkdirs(); - try { //ImageIO.write(image, "png", new File(folder + File.separator + filename)); ImageIO.write(image, "png", new File(filename)); @@ -150,17 +165,10 @@ public class PrintFoldingToFile implements Visualizer { } } - @Override - public void setFilename(String filename) { - this.filename = filename; - } - - @Override public int getMaxH() { return this.maxHeight; } - @Override public int getMaxW() { return this.maxWidth; }