From d2c949ddec5dac7c25a49f00abdb288a384bda14 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Thu, 30 Jan 2020 14:32:19 +0100 Subject: [PATCH 01/30] Add ant colony skeleton --- app/build.gradle | 8 ++++---- .../java/org/mate/ExecuteMATEAntColony.java | 20 +++++++++++++++++++ .../eyesfree/utils/ScreenshotUtils.java | 5 +++-- app/src/main/java/org/mate/MATE.java | 18 +++++++++++++++++ app/src/main/java/org/mate/Properties.java | 4 ++++ .../org/mate/exploration/ant/AntColony.java | 13 ++++++++++++ build.gradle | 2 +- gradle.properties | 2 +- 8 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 app/src/androidTest/java/org/mate/ExecuteMATEAntColony.java create mode 100644 app/src/main/java/org/mate/exploration/ant/AntColony.java diff --git a/app/build.gradle b/app/build.gradle index eab27779..72e2764c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,12 +64,12 @@ task checkstyle(type: Checkstyle) { } android { - compileSdkVersion 28 - buildToolsVersion '28.0.3' + compileSdkVersion 29 + buildToolsVersion '29.0.3' defaultConfig { applicationId "org.mate" minSdkVersion 21 - targetSdkVersion 28 + targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -97,7 +97,7 @@ android { dependencies { implementation 'com.android.support:appcompat-v7:28.0.0' - testImplementation 'junit:junit:4.12' + testImplementation 'junit:junit:4.13' implementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3' implementation 'com.android.support.test:runner:1.0.2' } diff --git a/app/src/androidTest/java/org/mate/ExecuteMATEAntColony.java b/app/src/androidTest/java/org/mate/ExecuteMATEAntColony.java new file mode 100644 index 00000000..1d527a27 --- /dev/null +++ b/app/src/androidTest/java/org/mate/ExecuteMATEAntColony.java @@ -0,0 +1,20 @@ +package org.mate; + +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class ExecuteMATEAntColony { + + + @Test + public void useAppContext() throws Exception { + + MATE.log_acc("Starting Ant Colony Exploration..."); + + MATE mate = new MATE(); + mate.testApp("AntColonyExploration"); + } +} diff --git a/app/src/main/java/com/google/eyesfree/utils/ScreenshotUtils.java b/app/src/main/java/com/google/eyesfree/utils/ScreenshotUtils.java index 253ac8a3..d8b400ae 100644 --- a/app/src/main/java/com/google/eyesfree/utils/ScreenshotUtils.java +++ b/app/src/main/java/com/google/eyesfree/utils/ScreenshotUtils.java @@ -46,8 +46,9 @@ private ScreenshotUtils() { } public static boolean hasScreenshotPermission(Context context) { - return (context.checkCallingOrSelfPermission(Manifest.permission.READ_FRAME_BUFFER) == - PackageManager.PERMISSION_GRANTED); + throw new UnsupportedOperationException(); + //return (context.checkCallingOrSelfPermission(Manifest.permission.READ_FRAME_BUFFER) == + // PackageManager.PERMISSION_GRANTED); } /** diff --git a/app/src/main/java/org/mate/MATE.java b/app/src/main/java/org/mate/MATE.java index 5e9313d7..903595f9 100644 --- a/app/src/main/java/org/mate/MATE.java +++ b/app/src/main/java/org/mate/MATE.java @@ -15,6 +15,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityWindowInfo; +import org.mate.exploration.ant.AntColony; import org.mate.exploration.genetic.algorithm.RandomSearch; import org.mate.exploration.genetic.fitness.BranchDistanceFitnessFunction; import org.mate.exploration.genetic.fitness.BranchDistanceFitnessFunctionMultiObjective; @@ -251,6 +252,23 @@ public Void call() throws Exception { .withTerminationCondition(IterTerminationCondition.TERMINATION_CONDITION_ID) .build(); nsga.run(); + } else if (explorationStrategy.equals("AntColonyExploration")) { + uiAbstractionLayer = new UIAbstractionLayer(deviceMgr, packageName); + + final AntColony antColony = new AntColony(); + + TimeoutRun.timeoutRun(new Callable() { + @Override + public Void call() throws Exception { + antColony.run(); + return null; + } + }, MATE.TIME_OUT); + + if (Properties.STORE_COVERAGE()) { + Registry.getEnvironmentManager().storeCoverageData(antColony, null); + MATE.log_acc("Total coverage: " + Registry.getEnvironmentManager().getCombinedCoverage()); + } } else if (explorationStrategy.equals("PrimitiveStandardGeneticAlgorithm")) { uiAbstractionLayer = new UIAbstractionLayer(deviceMgr, packageName); MATE.log_acc("Activities"); diff --git a/app/src/main/java/org/mate/Properties.java b/app/src/main/java/org/mate/Properties.java index d8c40ea1..08db1308 100644 --- a/app/src/main/java/org/mate/Properties.java +++ b/app/src/main/java/org/mate/Properties.java @@ -125,6 +125,10 @@ public static Coverage COVERAGE() { return propertyOr(Coverage.LINE_COVERAGE); } + public static String TARGET_LINE() { + return propertyOr(null); + } + // Primitive actions or widget based actions? diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java new file mode 100644 index 00000000..85b37b4b --- /dev/null +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -0,0 +1,13 @@ +package org.mate.exploration.ant; + +import org.mate.Properties; +import org.mate.exploration.genetic.fitness.LineCoveredPercentageFitnessFunction; + +public class AntColony { + public void run() { + //TODO start algorithm + String targetLine = Properties.TARGET_LINE(); + LineCoveredPercentageFitnessFunction lineCoveredPercentageFitnessFunction + = new LineCoveredPercentageFitnessFunction(targetLine); + } +} diff --git a/build.gradle b/build.gradle index 2dafc921..7bc93d63 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { maven { url 'https://plugins.gradle.org/m2/' } } dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' + classpath 'com.android.tools.build:gradle:3.5.3' classpath 'gradle.plugin.com.github.spotbugs:spotbugs-gradle-plugin:1.7.1' // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle.properties b/gradle.properties index aac7c9b4..27b14e86 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m +org.gradle.jvmargs=-Xmx768m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit From d37dc7d8dee51ac31886a92a6629049efbffd53d Mon Sep 17 00:00:00 2001 From: reissi01 Date: Thu, 30 Jan 2020 15:11:18 +0100 Subject: [PATCH 02/30] Add ant logger --- .gitignore | 1 + .../org/mate/exploration/ant/AntColony.java | 39 +++++++++++++++++ .../mate/exploration/ant/AntStatsLogger.java | 43 +++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 app/src/main/java/org/mate/exploration/ant/AntStatsLogger.java diff --git a/.gitignore b/.gitignore index 5281f985..6cfd1225 100644 --- a/.gitignore +++ b/.gitignore @@ -112,3 +112,4 @@ gradle-app.setting ## Local properties local.properties +ant.log diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 85b37b4b..586d5748 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -1,13 +1,52 @@ package org.mate.exploration.ant; +import android.content.Context; +import android.support.test.InstrumentationRegistry; + +import org.mate.MATE; import org.mate.Properties; import org.mate.exploration.genetic.fitness.LineCoveredPercentageFitnessFunction; +import org.mate.interaction.UIAbstractionLayer; +import org.mate.model.TestCase; +import org.mate.ui.WidgetAction; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.List; public class AntColony { + private final UIAbstractionLayer uiAbstractionLayer; + private final AntStatsLogger antStatsLogger; + + public AntColony() { + uiAbstractionLayer = MATE.uiAbstractionLayer; + antStatsLogger = new AntStatsLogger(); + } + public void run() { + //TODO start algorithm String targetLine = Properties.TARGET_LINE(); LineCoveredPercentageFitnessFunction lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(targetLine); + + //Liste an momentan möglichen Aktionen + List executableActions = uiAbstractionLayer.getExecutableActions(); + + //Aktion ausführen + TestCase testCase = TestCase.newInitializedTestCase(); + testCase.updateTestCase(executableActions.get(0), "0"); + + //Daten in Datei schreiben + antStatsLogger.write("asdf\n"); + //... am Schluss zu machen + antStatsLogger.close(); + } } diff --git a/app/src/main/java/org/mate/exploration/ant/AntStatsLogger.java b/app/src/main/java/org/mate/exploration/ant/AntStatsLogger.java new file mode 100644 index 00000000..266523f4 --- /dev/null +++ b/app/src/main/java/org/mate/exploration/ant/AntStatsLogger.java @@ -0,0 +1,43 @@ +package org.mate.exploration.ant; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; + +import java.io.BufferedWriter; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; + +public class AntStatsLogger { + private FileOutputStream fos; + private BufferedWriter writer; + + public AntStatsLogger() { + try { + fos = InstrumentationRegistry.getTargetContext().openFileOutput("port", Context.MODE_PRIVATE); + } catch (FileNotFoundException e) { + //Fehlerbehandlung + } + writer = new BufferedWriter(new OutputStreamWriter(fos)); + } + + public void write(String log) { + try { + writer.write(log); + writer.flush(); + } catch (IOException e) { + //Fehlerbehandlung + } + } + + public void close() { + try { + writer.close(); + fos.close(); + } catch (IOException e) { + //Fehlerbehandlung + throw new IllegalStateException("Error while closing ant stats logger", e); + } + } +} From f5c7e9c752d74384b24c283360c0f4264a3acd0c Mon Sep 17 00:00:00 2001 From: pjottr Date: Thu, 20 Feb 2020 17:34:54 +0100 Subject: [PATCH 03/30] First steps to implement ant colony algorithm --- .../org/mate/exploration/ant/AntColony.java | 100 +++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 586d5748..8eb85ced 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -18,12 +18,24 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; +import java.util.HashMap; import java.util.List; public class AntColony { private final UIAbstractionLayer uiAbstractionLayer; private final AntStatsLogger antStatsLogger; + private static final int generationAmount = 5; + private static final int generationSize = 1; + private static final int antPathLength = 20; + private static final double evaporationRate = 0.1; + //TODO change depending of the datatype for interactionelements + private static HashMap pheromones = new HashMap<>(); + private double currentPheromoneStandardValue; + private Boolean targetReached; + + //TODO Set start and end for the algorithm + public AntColony() { uiAbstractionLayer = MATE.uiAbstractionLayer; antStatsLogger = new AntStatsLogger(); @@ -31,11 +43,43 @@ public AntColony() { public void run() { - //TODO start algorithm + //TODO start algorithm (Vorgegeben) String targetLine = Properties.TARGET_LINE(); LineCoveredPercentageFitnessFunction lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(targetLine); + + // Value to add the correct pheromone amount to unknown widget actions + currentPheromoneStandardValue = 0.5; + + // Loop to create multiple generations of ants + outerLoop: for (int i = 0; i < generationAmount; i++) { + // Create ants and update pheromone values accordingly + for (int z = 0; z < generationSize; z++){ + // Create a ant to traverse the graph + runAnt(); + + // Stop algorithm if target was reached + if (targetReached) { + //TODO add necessary action for successful run (print message, etc) + break outerLoop; + } + + // Pheromone evaporation + /* + pheromones.entrySet().forEach(entry->{ + entry.setValue((1-evaporationRate)*entry.getValue()); + }); + */ + + // Deposit pheromones + //TODO add loop for each element used in ant runs to deposit pheromones + } + } + + + + //TODO delete examples after using them (Vorgegeben) //Liste an momentan möglichen Aktionen List executableActions = uiAbstractionLayer.getExecutableActions(); @@ -49,4 +93,58 @@ public void run() { antStatsLogger.close(); } + + //TODO finish ant method + private void runAnt() { + //TODO set current and previous WA and other variables + HashMap probabilities = new HashMap<>(); + + // Start the loop to traverse the app with antPathLength-many steps + for (int i = 0; i < antPathLength; i++) { + // Get possible options to move through the app + List executableActions = uiAbstractionLayer.getExecutableActions(); + + // If there is only one possible widget action execute that one + if (executableActions.size() == 1) { + // TODO set pheromone value for the viable option (if not already existing) + + // TODO use the only option and update relevant variables + } else { + // Set pheromone values for the available widget actions without one + //TODO set pheromone values if not yet existing) + + // Calculate attractiveness for all available actions and store their probabilities + //TODO add iteration over all executableActions + while(targetReached) { + // Get pheromone value for the current action + double currentPheromoneValue = pheromones.get(currentWidgetAction); + + // Calculate attractiveness for the current action + double probability = (Math.pow(pheromone)); + + // Reduce probability if the current action is the previous action (step back) + if () { + probability /= 2; + } + + // Store the calculated value in combination with the target action for the current option + probabilities.put(, probability); + } + + // Sum up all the probabilites + double sumProbabilities = probabilities.values().stream().mapToDouble(v -> v).sum(); + + // Calculate relative probability for each option + //TODO iterate over probabilities (und teile jede durch die gesamtwahrscheinlichkeit) + + // Determine the next action with roulette and make the step + } + + // Check if target was reached in this step and stop the ant if that is the case + + + // Reset used variables if the ant continues to traverse the app + probabilities.clear(); + } + } } From b2de1409dadd806e5e8ae496d96024adc063d4b9 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Thu, 20 Feb 2020 21:28:07 +0100 Subject: [PATCH 04/30] Improved ACO --- .../org/mate/exploration/ant/AntColony.java | 146 ++++++++++++------ 1 file changed, 95 insertions(+), 51 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 8eb85ced..289349a0 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -29,12 +30,9 @@ public class AntColony { private static final int generationSize = 1; private static final int antPathLength = 20; private static final double evaporationRate = 0.1; - //TODO change depending of the datatype for interactionelements - private static HashMap pheromones = new HashMap<>(); private double currentPheromoneStandardValue; - private Boolean targetReached; - - //TODO Set start and end for the algorithm + private HashMap pheromones = new HashMap<>(); + private ArrayList testCasesList = new ArrayList<>(); public AntColony() { uiAbstractionLayer = MATE.uiAbstractionLayer; @@ -48,103 +46,149 @@ public void run() { LineCoveredPercentageFitnessFunction lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(targetLine); - // Value to add the correct pheromone amount to unknown widget actions currentPheromoneStandardValue = 0.5; // Loop to create multiple generations of ants outerLoop: for (int i = 0; i < generationAmount; i++) { - // Create ants and update pheromone values accordingly + MATE.log_acc("Generation #" + (i + 1)); + antStatsLogger.write("Start of Generation #" + (i + 1)); + + // Create ants and check if they reach the target line for (int z = 0; z < generationSize; z++){ + MATE.log_acc("Ant #" + (z + 1)); + antStatsLogger.write("Start of Ant #" + (z + 1)); + // Create a ant to traverse the graph - runAnt(); + TestCase testCase = runAnt(); - // Stop algorithm if target was reached - if (targetReached) { - //TODO add necessary action for successful run (print message, etc) + // Stop algorithm if target line was reached (Fitness of testCase == 1) Wie und wo wird diese berechnet? + // Wie kann ich den Wert verwenden? + if (false) { + //TODO add necessary action for successful algorithm run (print message, etc) break outerLoop; + } else { + // Add testcase of current ant to list for later deposition of pheromones + //TODO add testCase to list of testCases for later use + testCasesList.add(testCase); } - // Pheromone evaporation - /* - pheromones.entrySet().forEach(entry->{ - entry.setValue((1-evaporationRate)*entry.getValue()); - }); - */ - - // Deposit pheromones - //TODO add loop for each element used in ant runs to deposit pheromones + antStatsLogger.write("End of Ant #" + (z + 1)); } - } - - - - //TODO delete examples after using them (Vorgegeben) - //Liste an momentan möglichen Aktionen - List executableActions = uiAbstractionLayer.getExecutableActions(); + // Pheromone evaporation + for (HashMap.Entry entry : pheromones.entrySet()) { + entry.setValue((1-evaporationRate)*entry.getValue()); + } + currentPheromoneStandardValue *= (1-evaporationRate); - //Aktion ausführen - TestCase testCase = TestCase.newInitializedTestCase(); - testCase.updateTestCase(executableActions.get(0), "0"); + // Deposit pheromones + //TODO add loop for each element used in ant runs to deposit pheromones depending on fitness + //(Noch nicht ganz sicher ob deposit einmal pro generation oder nach jeder ameise) - //Daten in Datei schreiben - antStatsLogger.write("asdf\n"); - //... am Schluss zu machen + antStatsLogger.write("End of Generation #" + (i + 1)); + } + // Close the logger antStatsLogger.close(); - } //TODO finish ant method - private void runAnt() { - //TODO set current and previous WA and other variables + private TestCase runAnt() { + //TODO set variables (start widget action, previous action, current action), start test case, etc... + WidgetAction previousAction = null; + //WidgetAction currentAction; ?? Wo fängt der Algortihmus an, wie bestimme ich den aktuellen Standort bzw setze ihn weiter HashMap probabilities = new HashMap<>(); + TestCase testCase = TestCase.newInitializedTestCase(); // Start the loop to traverse the app with antPathLength-many steps for (int i = 0; i < antPathLength; i++) { - // Get possible options to move through the app + // Get list possible actions to execute List executableActions = uiAbstractionLayer.getExecutableActions(); // If there is only one possible widget action execute that one if (executableActions.size() == 1) { - // TODO set pheromone value for the viable option (if not already existing) + if (!pheromones.containsKey(executableActions.get(0))) { + pheromones.put(executableActions.get(0), currentPheromoneStandardValue); + } // TODO use the only option and update relevant variables + testCase.updateTestCase(executableActions.get(0), "" + i); } else { // Set pheromone values for the available widget actions without one - //TODO set pheromone values if not yet existing) + for (WidgetAction action : executableActions) { + if (!pheromones.containsKey(action)) { + pheromones.put(action, currentPheromoneStandardValue); + } + } // Calculate attractiveness for all available actions and store their probabilities - //TODO add iteration over all executableActions - while(targetReached) { + for (WidgetAction action : executableActions) { // Get pheromone value for the current action - double currentPheromoneValue = pheromones.get(currentWidgetAction); + double currentPheromoneValue = pheromones.get(action); - // Calculate attractiveness for the current action - double probability = (Math.pow(pheromone)); + // Calculate attractiveness for the current action (pheromone * fitness) möglich?? falls nicht prob = pheromone + // Eventuell action type (??) einbeziehen in die bewertung + double probability = (Math.pow(currentPheromoneValue, 2)); // Reduce probability if the current action is the previous action (step back) - if () { + if (action.equals(previousAction)) { probability /= 2; } // Store the calculated value in combination with the target action for the current option - probabilities.put(, probability); + probabilities.put(action, probability); } // Sum up all the probabilites - double sumProbabilities = probabilities.values().stream().mapToDouble(v -> v).sum(); + double sumProbabilities = 0.0; + for (HashMap.Entry entry : probabilities.entrySet()) { + sumProbabilities += entry.getValue(); + } // Calculate relative probability for each option - //TODO iterate over probabilities (und teile jede durch die gesamtwahrscheinlichkeit) + for (HashMap.Entry entry : probabilities.entrySet()) { + entry.setValue(entry.getValue() / sumProbabilities); + } // Determine the next action with roulette and make the step + double randomValue = Math.random(); + double sum = 0.0; + for (HashMap.Entry entry : probabilities.entrySet()) { + sum += entry.getValue(); + if (sum > randomValue) { + // TODO use the chosen option and update relevant variables + testCase.updateTestCase(entry.getKey(), "" + i); + break; + } + } } - // Check if target was reached in this step and stop the ant if that is the case - + // TODO remove if it is not possible to test this during the testcase (test afterwards with fitness = 1) + // Kann man die fitness von den unvollständigen testcases berechnen und in jedem schritt überprüfen ob die Zeile erreich wurde? + /* Check if target was reached in this step and stop the ant if that is the case + If () { + return testCase; + } + */ - // Reset used variables if the ant continues to traverse the app + // Reset used variables (if the ant continues to traverse the app) probabilities.clear(); + MATE.uiAbstractionLayer.restartApp(); } + return testCase; } + + /* + //TODO delete examples after using them (Vorgegeben) + //Liste an momentan möglichen Aktionen + List executableActions = uiAbstractionLayer.getExecutableActions(); + + //Aktion ausführen + TestCase testCase = TestCase.newInitializedTestCase(); + testCase.updateTestCase(executableActions.get(0), "0"); + + //Daten in Datei schreiben + antStatsLogger.write("asdf\n"); + //... am Schluss zu machen + antStatsLogger.close(); + */ } From d27c5f2e528197672d19ec9e8db153036fe9150b Mon Sep 17 00:00:00 2001 From: reissi01 Date: Fri, 21 Feb 2020 13:48:00 +0100 Subject: [PATCH 05/30] Improved ACO during meeting with leon --- .../org/mate/exploration/ant/AntColony.java | 61 ++++++++++--------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 289349a0..b44ada3c 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -5,10 +5,15 @@ import org.mate.MATE; import org.mate.Properties; +import org.mate.Registry; +import org.mate.exploration.genetic.chromosome.Chromosome; +import org.mate.exploration.genetic.chromosome.IChromosome; +import org.mate.exploration.genetic.fitness.IFitnessFunction; import org.mate.exploration.genetic.fitness.LineCoveredPercentageFitnessFunction; import org.mate.interaction.UIAbstractionLayer; import org.mate.model.TestCase; import org.mate.ui.WidgetAction; +import org.mate.utils.Coverage; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -20,7 +25,9 @@ import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; +import java.util.Map; public class AntColony { private final UIAbstractionLayer uiAbstractionLayer; @@ -31,8 +38,8 @@ public class AntColony { private static final int antPathLength = 20; private static final double evaporationRate = 0.1; private double currentPheromoneStandardValue; - private HashMap pheromones = new HashMap<>(); - private ArrayList testCasesList = new ArrayList<>(); + private Map pheromones = new HashMap<>(); + private List> testCasesList = new ArrayList<>(); public AntColony() { uiAbstractionLayer = MATE.uiAbstractionLayer; @@ -43,7 +50,7 @@ public void run() { //TODO start algorithm (Vorgegeben) String targetLine = Properties.TARGET_LINE(); - LineCoveredPercentageFitnessFunction lineCoveredPercentageFitnessFunction + IFitnessFunction lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(targetLine); // Value to add the correct pheromone amount to unknown widget actions @@ -60,23 +67,25 @@ public void run() { antStatsLogger.write("Start of Ant #" + (z + 1)); // Create a ant to traverse the graph - TestCase testCase = runAnt(); + IChromosome chromosome = new Chromosome<>(runAnt()); - // Stop algorithm if target line was reached (Fitness of testCase == 1) Wie und wo wird diese berechnet? - // Wie kann ich den Wert verwenden? - if (false) { + Registry.getEnvironmentManager().storeCoverageData(chromosome, null); + LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); + + + // Stop algorithm if target line was reached (Fitness of testCase == 1) + if (lineCoveredPercentageFitnessFunction.getFitness(chromosome) == 1) { //TODO add necessary action for successful algorithm run (print message, etc) break outerLoop; } else { // Add testcase of current ant to list for later deposition of pheromones - //TODO add testCase to list of testCases for later use - testCasesList.add(testCase); + testCasesList.add(chromosome); } antStatsLogger.write("End of Ant #" + (z + 1)); } // Pheromone evaporation - for (HashMap.Entry entry : pheromones.entrySet()) { + for (Map.Entry entry : pheromones.entrySet()) { entry.setValue((1-evaporationRate)*entry.getValue()); } currentPheromoneStandardValue *= (1-evaporationRate); @@ -93,10 +102,10 @@ public void run() { //TODO finish ant method private TestCase runAnt() { + MATE.uiAbstractionLayer.restartApp(); + //TODO set variables (start widget action, previous action, current action), start test case, etc... - WidgetAction previousAction = null; - //WidgetAction currentAction; ?? Wo fängt der Algortihmus an, wie bestimme ich den aktuellen Standort bzw setze ihn weiter - HashMap probabilities = new HashMap<>(); + Map probabilities = new HashMap<>(); TestCase testCase = TestCase.newInitializedTestCase(); // Start the loop to traverse the app with antPathLength-many steps @@ -130,49 +139,45 @@ private TestCase runAnt() { double probability = (Math.pow(currentPheromoneValue, 2)); // Reduce probability if the current action is the previous action (step back) + //TODO Check if necessary + /* if (action.equals(previousAction)) { probability /= 2; } + */ + // Store the calculated value in combination with the target action for the current option probabilities.put(action, probability); } // Sum up all the probabilites double sumProbabilities = 0.0; - for (HashMap.Entry entry : probabilities.entrySet()) { + for (Map.Entry entry : probabilities.entrySet()) { sumProbabilities += entry.getValue(); } // Calculate relative probability for each option - for (HashMap.Entry entry : probabilities.entrySet()) { + for (Map.Entry entry : probabilities.entrySet()) { entry.setValue(entry.getValue() / sumProbabilities); } // Determine the next action with roulette and make the step double randomValue = Math.random(); double sum = 0.0; - for (HashMap.Entry entry : probabilities.entrySet()) { + WidgetAction currentAction = null; + for (Map.Entry entry : probabilities.entrySet()) { sum += entry.getValue(); + currentAction = entry.getKey(); if (sum > randomValue) { - // TODO use the chosen option and update relevant variables - testCase.updateTestCase(entry.getKey(), "" + i); break; } } + testCase.updateTestCase(currentAction, "" + i); } - // TODO remove if it is not possible to test this during the testcase (test afterwards with fitness = 1) - // Kann man die fitness von den unvollständigen testcases berechnen und in jedem schritt überprüfen ob die Zeile erreich wurde? - /* Check if target was reached in this step and stop the ant if that is the case - If () { - return testCase; - } - */ - - // Reset used variables (if the ant continues to traverse the app) + // Reset used variables probabilities.clear(); - MATE.uiAbstractionLayer.restartApp(); } return testCase; } From f84a32cc28a6f0f561ca0c8ff9a6852ebe021c52 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Mon, 24 Feb 2020 22:43:30 +0100 Subject: [PATCH 06/30] First implementation of changes after coordinating with gordon --- .../org/mate/exploration/ant/AntColony.java | 184 +++++++++++++----- 1 file changed, 133 insertions(+), 51 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index b44ada3c..a2864ff6 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -12,6 +12,8 @@ import org.mate.exploration.genetic.fitness.LineCoveredPercentageFitnessFunction; import org.mate.interaction.UIAbstractionLayer; import org.mate.model.TestCase; +import org.mate.ui.Action; +import org.mate.ui.Widget; import org.mate.ui.WidgetAction; import org.mate.utils.Coverage; @@ -25,30 +27,48 @@ import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.TreeMap; public class AntColony { private final UIAbstractionLayer uiAbstractionLayer; private final AntStatsLogger antStatsLogger; - private static final int generationAmount = 5; - private static final int generationSize = 1; - private static final int antPathLength = 20; - private static final double evaporationRate = 0.1; private double currentPheromoneStandardValue; private Map pheromones = new HashMap<>(); private List> testCasesList = new ArrayList<>(); + // Parameters to customize the ACO algorithm + private static final int generationAmount = 10; + private static final int generationSize = 5; + private static final int antPathLength = 30; + private static final double evaporationRate = 0.1; + + /* Parameter to change the process of calculating the action probability + * True: Calculate the probability for a action by taking the pheromone value and + * multiplying it with the weight of the action (depending on the action type) + * False: Only use the pheromone value of the action as the probability + */ + private static final boolean includeActionTypeInTransition = false; + + /* Parameter to change the process of depositing pheromones. + * True: Rank all ants in a generation according to the fitness value of their testcase. + * Best ants get to deposit most pheromones, decreasing downwards and worst ants don´t + * deposit any pheromones + * False: Only the ant with the best fitness value in a generation gets to deposit pheromones + */ + private static final boolean depositPheromonesWithRanking = true; + public AntColony() { uiAbstractionLayer = MATE.uiAbstractionLayer; antStatsLogger = new AntStatsLogger(); } public void run() { - - //TODO start algorithm (Vorgegeben) + // Get the target line for ACO to generate a test for and initialise the fitness function String targetLine = Properties.TARGET_LINE(); IFitnessFunction lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(targetLine); @@ -66,19 +86,20 @@ public void run() { MATE.log_acc("Ant #" + (z + 1)); antStatsLogger.write("Start of Ant #" + (z + 1)); - // Create a ant to traverse the graph + // Create an ant to traverse the app and wrap the generated testcase in a chromosome IChromosome chromosome = new Chromosome<>(runAnt()); + // Necessary lines to calculate the fitness value for the stored chromosome Registry.getEnvironmentManager().storeCoverageData(chromosome, null); LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); - - // Stop algorithm if target line was reached (Fitness of testCase == 1) + // Stop algorithm if target line was reached if (lineCoveredPercentageFitnessFunction.getFitness(chromosome) == 1) { - //TODO add necessary action for successful algorithm run (print message, etc) + //TODO add necessary action for successful algorithm run (write log) + MATE.log_acc("ACO finished successfully"); break outerLoop; } else { - // Add testcase of current ant to list for later deposition of pheromones + // Add testcase of current ant to list for later depositing of pheromones testCasesList.add(chromosome); } @@ -91,8 +112,48 @@ public void run() { currentPheromoneStandardValue *= (1-evaporationRate); // Deposit pheromones - //TODO add loop for each element used in ant runs to deposit pheromones depending on fitness - //(Noch nicht ganz sicher ob deposit einmal pro generation oder nach jeder ameise) + // TODO finish the deposit + if (depositPheromonesWithRanking) { + // Map test cases to their fitness values + Map fitnessValues = new TreeMap<>(); + for (int y = 0; y < testCasesList.size(); y++) { + fitnessValues.put( + lineCoveredPercentageFitnessFunction.getFitness(testCasesList.get(y)), + testCasesList.get(y).getValue()); + } + + // Sort map according to the fitness values + + + // Deposit pheromones for the better half of test cases. Amount steadily decreases + + } else { + // Set the cache to the test case of the first ant in the generation + IChromosome bestTestCase = testCasesList.get(0); + + // Compare each of the test cases of all ants in the generation with the current + // best one and store the best of both in the cache + for (int y = 1; y < testCasesList.size(); y++) { + if (lineCoveredPercentageFitnessFunction.getFitness(testCasesList.get(y)) > + lineCoveredPercentageFitnessFunction.getFitness(bestTestCase)) { + bestTestCase = testCasesList.get(y); + } + } + + // Store the used actions of the best test case without duplicates + List actionList = new ArrayList<>(); + List eventSequence = bestTestCase.getValue().getEventSequence(); + for (int y = 0; y < eventSequence.size(); y++) { + if (!actionList.contains(eventSequence.get(y))) { + actionList.add(eventSequence.get(y)); + } + } + + // Deposit pheromones for all actions used in the best test case + for (int y = 0; y < actionList.size(); y++) { + pheromones.replace(actionList.get(y), 0.5); + } + } antStatsLogger.write("End of Generation #" + (i + 1)); } @@ -100,11 +161,15 @@ public void run() { antStatsLogger.close(); } - //TODO finish ant method + /** + * Method to create ants that run through the app to create a testcase + * @return the generated testcase + */ private TestCase runAnt() { + // Reset the current App to guarantee standardized testing starting at the same state MATE.uiAbstractionLayer.restartApp(); - //TODO set variables (start widget action, previous action, current action), start test case, etc... + // Initialise probabilities and create a new testcase for the current ant Map probabilities = new HashMap<>(); TestCase testCase = TestCase.newInitializedTestCase(); @@ -113,14 +178,20 @@ private TestCase runAnt() { // Get list possible actions to execute List executableActions = uiAbstractionLayer.getExecutableActions(); + // If there is no executable action stop MATE and throw exception + if (executableActions.size() == 0) { + // TODO throw exception + // If there is only one possible widget action execute that one - if (executableActions.size() == 1) { + } else if (executableActions.size() == 1) { + // Set pheromone value for the action if it does not already have one if (!pheromones.containsKey(executableActions.get(0))) { pheromones.put(executableActions.get(0), currentPheromoneStandardValue); } - // TODO use the only option and update relevant variables + // Execute the widget action and update the testcase testCase.updateTestCase(executableActions.get(0), "" + i); + } else { // Set pheromone values for the available widget actions without one for (WidgetAction action : executableActions) { @@ -129,29 +200,30 @@ private TestCase runAnt() { } } - // Calculate attractiveness for all available actions and store their probabilities - for (WidgetAction action : executableActions) { - // Get pheromone value for the current action - double currentPheromoneValue = pheromones.get(action); - - // Calculate attractiveness for the current action (pheromone * fitness) möglich?? falls nicht prob = pheromone - // Eventuell action type (??) einbeziehen in die bewertung - double probability = (Math.pow(currentPheromoneValue, 2)); - - // Reduce probability if the current action is the previous action (step back) - //TODO Check if necessary - /* - if (action.equals(previousAction)) { - probability /= 2; - } + // Store probabilities for each action with or without factoring in the action type + if(includeActionTypeInTransition) { + // Calculate attractiveness for all available actions and store the results + for (WidgetAction action : executableActions) { + // Get pheromone value for the current action + double pheromoneValue = pheromones.get(action); + + // Get the weight for the current action type + double actionTypeWeight = getActionTypeWeight(action); - */ + // Calculate attractiveness for the current action (pheromone * action type) + double probability = (pheromoneValue*actionTypeWeight); - // Store the calculated value in combination with the target action for the current option - probabilities.put(action, probability); + // Store the calculated value for the current action + probabilities.put(action, probability); + } + } else { + // Store pheromone value of all actions as their probability + for (WidgetAction action : executableActions) { + probabilities.put(action, pheromones.get(action)); + } } - // Sum up all the probabilites + // Sum up all the probabilities double sumProbabilities = 0.0; for (Map.Entry entry : probabilities.entrySet()) { sumProbabilities += entry.getValue(); @@ -173,27 +245,37 @@ private TestCase runAnt() { break; } } + // Execute the widget action and update the testcase testCase.updateTestCase(currentAction, "" + i); } - // Reset used variables probabilities.clear(); } return testCase; } - /* - //TODO delete examples after using them (Vorgegeben) - //Liste an momentan möglichen Aktionen - List executableActions = uiAbstractionLayer.getExecutableActions(); - - //Aktion ausführen - TestCase testCase = TestCase.newInitializedTestCase(); - testCase.updateTestCase(executableActions.get(0), "0"); - - //Daten in Datei schreiben - antStatsLogger.write("asdf\n"); - //... am Schluss zu machen - antStatsLogger.close(); - */ + /** + * Determine the weight for an action depending on the type of the action + * @param action the action to get a weight value for + * @return the determined value + */ + private Double getActionTypeWeight (WidgetAction action) { + double eventTypeWeight; + switch (action.getActionType()) { + case SWIPE_UP: + case SWIPE_DOWN: + case SWIPE_LEFT: + case SWIPE_RIGHT: + case BACK: + eventTypeWeight = 0.5; + break; + case MENU: + eventTypeWeight = 2; + break; + default: + eventTypeWeight = 1; + break; + } + return eventTypeWeight; + } } From 91befafb9b7900f9ba9b1e52cff588ecb993560f Mon Sep 17 00:00:00 2001 From: reissi01 Date: Fri, 28 Feb 2020 19:38:17 +0100 Subject: [PATCH 07/30] Finished implementing ACO and changes after agreeing with Prof. Fraser, fixed errors (Not tested yet) --- .../org/mate/exploration/ant/AntColony.java | 77 +++++++++++++++---- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index a2864ff6..f6faf4c3 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -74,7 +74,7 @@ public void run() { = new LineCoveredPercentageFitnessFunction(targetLine); // Value to add the correct pheromone amount to unknown widget actions - currentPheromoneStandardValue = 0.5; + currentPheromoneStandardValue = 1.0; // Loop to create multiple generations of ants outerLoop: for (int i = 0; i < generationAmount; i++) { @@ -112,23 +112,62 @@ public void run() { currentPheromoneStandardValue *= (1-evaporationRate); // Deposit pheromones - // TODO finish the deposit if (depositPheromonesWithRanking) { - // Map test cases to their fitness values - Map fitnessValues = new TreeMap<>(); + // Map test cases to their fitness values in a sorted treemap + Map> sortedFitnessValues = new TreeMap<>(); for (int y = 0; y < testCasesList.size(); y++) { - fitnessValues.put( - lineCoveredPercentageFitnessFunction.getFitness(testCasesList.get(y)), - testCasesList.get(y).getValue()); + // Retrieve fitness value for current ant + double fitnessValue = + lineCoveredPercentageFitnessFunction.getFitness(testCasesList.get(y)); + + // Check if previous ant had same fitness value + if (sortedFitnessValues.containsKey(fitnessValue)) { + // Add current testcase to the list of testcases with that fitness value + sortedFitnessValues.get(fitnessValue).add(testCasesList.get(y).getValue()); + } else { + // Create a new map entry and add the current testcase + List tempList = new ArrayList<>(); + sortedFitnessValues.put(fitnessValue, tempList); + sortedFitnessValues.get(fitnessValue).add(testCasesList.get(y).getValue()); + } } - // Sort map according to the fitness values - - - // Deposit pheromones for the better half of test cases. Amount steadily decreases + // Deposit pheromones for the better half of testcases. Amount steadily decreases + // TODO Set deposit amount + double depositAmount = 1.0; + double reductionAmount = 1 / (testCasesList.size() / 2.0); + int antsAllowedToDeposit = (int) Math.ceil(testCasesList.size() / 2.0); + for (Map.Entry> entry : sortedFitnessValues.entrySet()) { + // Check if all relevant ants have already deposited their pheromones + if(antsAllowedToDeposit > 0) { + for (TestCase currentTestCase : entry.getValue()) { + // Store the used actions of the current testcase without duplicates + List actionList = new ArrayList<>(); + List eventSequence = (List)(List) + currentTestCase.getEventSequence(); + for (int y = 0; y < eventSequence.size(); y++) { + if (!actionList.contains(eventSequence.get(y))) { + actionList.add(eventSequence.get(y)); + } + } + + // Deposit pheromones for all actions used in the current testcase + for (int y = 0; y < actionList.size(); y++) { + double newValue = pheromones.get(actionList.get(y)) + depositAmount; + pheromones.put(actionList.get(y), newValue); + } + + // Updating of iteration variables + depositAmount -= reductionAmount; + antsAllowedToDeposit--; + } + } else { + break; + } + } } else { - // Set the cache to the test case of the first ant in the generation + // Set the cache to the testcase of the first ant in the generation IChromosome bestTestCase = testCasesList.get(0); // Compare each of the test cases of all ants in the generation with the current @@ -140,18 +179,21 @@ public void run() { } } - // Store the used actions of the best test case without duplicates + // Store the used actions of the best testcase without duplicates List actionList = new ArrayList<>(); - List eventSequence = bestTestCase.getValue().getEventSequence(); + List eventSequence = + (List)(List) bestTestCase.getValue().getEventSequence(); for (int y = 0; y < eventSequence.size(); y++) { if (!actionList.contains(eventSequence.get(y))) { actionList.add(eventSequence.get(y)); } } - // Deposit pheromones for all actions used in the best test case + // Deposit pheromones for all actions used in the best testcase for (int y = 0; y < actionList.size(); y++) { - pheromones.replace(actionList.get(y), 0.5); + // TODO add pheromone amount to deposit for best ant + double newValue = pheromones.get(actionList.get(y)) + 1.0; + pheromones.put(actionList.get(y), newValue); } } @@ -180,7 +222,8 @@ private TestCase runAnt() { // If there is no executable action stop MATE and throw exception if (executableActions.size() == 0) { - // TODO throw exception + throw new IllegalStateException("No possible Transitions available! App contains" + + "a dead end."); // If there is only one possible widget action execute that one } else if (executableActions.size() == 1) { From 2480eed600e09198245a7bdf47536ae28464c489 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Fri, 28 Feb 2020 19:45:09 +0100 Subject: [PATCH 08/30] Minor Change, Changed deposit amount to global parameter for the entire algorithm --- app/src/main/java/org/mate/exploration/ant/AntColony.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index f6faf4c3..0022d00a 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -46,6 +46,8 @@ public class AntColony { private static final int generationSize = 5; private static final int antPathLength = 30; private static final double evaporationRate = 0.1; + // TODO Choose appropriate deposit amount + private static final double standardDepositAmount = 1.0; /* Parameter to change the process of calculating the action probability * True: Calculate the probability for a action by taking the pheromone value and @@ -133,8 +135,7 @@ public void run() { } // Deposit pheromones for the better half of testcases. Amount steadily decreases - // TODO Set deposit amount - double depositAmount = 1.0; + double depositAmount = standardDepositAmount; double reductionAmount = 1 / (testCasesList.size() / 2.0); int antsAllowedToDeposit = (int) Math.ceil(testCasesList.size() / 2.0); for (Map.Entry> entry : sortedFitnessValues.entrySet()) { @@ -191,8 +192,7 @@ public void run() { // Deposit pheromones for all actions used in the best testcase for (int y = 0; y < actionList.size(); y++) { - // TODO add pheromone amount to deposit for best ant - double newValue = pheromones.get(actionList.get(y)) + 1.0; + double newValue = pheromones.get(actionList.get(y)) + standardDepositAmount; pheromones.put(actionList.get(y), newValue); } } From 30eea737fcf587dff81b716079484dc36fe99a5c Mon Sep 17 00:00:00 2001 From: reissi01 Date: Tue, 3 Mar 2020 17:30:21 +0100 Subject: [PATCH 09/30] Fixed AntStatsLogger --- app/src/main/java/org/mate/exploration/ant/AntStatsLogger.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntStatsLogger.java b/app/src/main/java/org/mate/exploration/ant/AntStatsLogger.java index 266523f4..cb6d6d0a 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntStatsLogger.java +++ b/app/src/main/java/org/mate/exploration/ant/AntStatsLogger.java @@ -15,7 +15,7 @@ public class AntStatsLogger { public AntStatsLogger() { try { - fos = InstrumentationRegistry.getTargetContext().openFileOutput("port", Context.MODE_PRIVATE); + fos = InstrumentationRegistry.getTargetContext().openFileOutput("antstats.log", Context.MODE_PRIVATE); } catch (FileNotFoundException e) { //Fehlerbehandlung } From 9d7929b84652713cd0bf4acb4e1d7d5fcaef0530 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Tue, 10 Mar 2020 15:20:29 +0100 Subject: [PATCH 10/30] Fixed running MATE on windows by Leon --- app/src/main/java/org/mate/MATE.java | 13 +++--------- .../org/mate/exploration/ant/AntColony.java | 21 ++++++++++++++----- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/mate/MATE.java b/app/src/main/java/org/mate/MATE.java index 903595f9..7fc3ddf8 100644 --- a/app/src/main/java/org/mate/MATE.java +++ b/app/src/main/java/org/mate/MATE.java @@ -255,15 +255,8 @@ public Void call() throws Exception { } else if (explorationStrategy.equals("AntColonyExploration")) { uiAbstractionLayer = new UIAbstractionLayer(deviceMgr, packageName); - final AntColony antColony = new AntColony(); - - TimeoutRun.timeoutRun(new Callable() { - @Override - public Void call() throws Exception { - antColony.run(); - return null; - } - }, MATE.TIME_OUT); + AntColony antColony = new AntColony(); + antColony.run(); if (Properties.STORE_COVERAGE()) { Registry.getEnvironmentManager().storeCoverageData(antColony, null); @@ -416,7 +409,7 @@ public Void call() throws Exception { MATE.log_acc("\t" + s); } - final RandomExploration randomExploration = new RandomExploration(50); + final RandomExploration randomExploration = new RandomExploration(Properties.STORE_COVERAGE(), true, 50); TimeoutRun.timeoutRun(new Callable() { @Override diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 0022d00a..125e5455 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -43,8 +43,8 @@ public class AntColony { // Parameters to customize the ACO algorithm private static final int generationAmount = 10; - private static final int generationSize = 5; - private static final int antPathLength = 30; + private static final int generationSize = 2; + private static final int antPathLength = 4; private static final double evaporationRate = 0.1; // TODO Choose appropriate deposit amount private static final double standardDepositAmount = 1.0; @@ -95,6 +95,9 @@ public void run() { Registry.getEnvironmentManager().storeCoverageData(chromosome, null); LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); + // DEBUG + System.out.println(lineCoveredPercentageFitnessFunction.getFitness(chromosome)); + // Stop algorithm if target line was reached if (lineCoveredPercentageFitnessFunction.getFitness(chromosome) == 1) { //TODO add necessary action for successful algorithm run (write log) @@ -209,7 +212,7 @@ public void run() { */ private TestCase runAnt() { // Reset the current App to guarantee standardized testing starting at the same state - MATE.uiAbstractionLayer.restartApp(); + MATE.uiAbstractionLayer.resetApp(); // Initialise probabilities and create a new testcase for the current ant Map probabilities = new HashMap<>(); @@ -219,6 +222,7 @@ private TestCase runAnt() { for (int i = 0; i < antPathLength; i++) { // Get list possible actions to execute List executableActions = uiAbstractionLayer.getExecutableActions(); + boolean prematureShutdown; // If there is no executable action stop MATE and throw exception if (executableActions.size() == 0) { @@ -233,7 +237,7 @@ private TestCase runAnt() { } // Execute the widget action and update the testcase - testCase.updateTestCase(executableActions.get(0), "" + i); + prematureShutdown = !testCase.updateTestCase(executableActions.get(0), "" + i); } else { // Set pheromone values for the available widget actions without one @@ -289,8 +293,15 @@ private TestCase runAnt() { } } // Execute the widget action and update the testcase - testCase.updateTestCase(currentAction, "" + i); + prematureShutdown = !testCase.updateTestCase(currentAction, "" + i); + } + + // TODO Comment + if (prematureShutdown) { + break; } + + // Reset used variables probabilities.clear(); } From fe1ce833cc3a782f3c383a867ccf71823631ac2f Mon Sep 17 00:00:00 2001 From: pjottr Date: Mon, 16 Mar 2020 16:42:26 +0100 Subject: [PATCH 11/30] Fixed exiting loop and added temporary debugging comments --- .../org/mate/exploration/ant/AntColony.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 125e5455..41e1171c 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -222,7 +222,13 @@ private TestCase runAnt() { for (int i = 0; i < antPathLength; i++) { // Get list possible actions to execute List executableActions = uiAbstractionLayer.getExecutableActions(); + + //TODO REMOVE + MATE.log_acc("---------- Anzahl an Möglichkeiten "+ executableActions.size() +" ----------"); + + // Variable to flag a premature shutdown due to ant executing closing action boolean prematureShutdown; + WidgetAction currentAction = null; // If there is no executable action stop MATE and throw exception if (executableActions.size() == 0) { @@ -238,7 +244,7 @@ private TestCase runAnt() { // Execute the widget action and update the testcase prematureShutdown = !testCase.updateTestCase(executableActions.get(0), "" + i); - + currentAction = executableActions.get(0); } else { // Set pheromone values for the available widget actions without one for (WidgetAction action : executableActions) { @@ -277,14 +283,19 @@ private TestCase runAnt() { } // Calculate relative probability for each option + //TODO Remove + int temp = 1; + MATE.log_acc("---------- Wahrscheinlichkeiten : ----------"); for (Map.Entry entry : probabilities.entrySet()) { entry.setValue(entry.getValue() / sumProbabilities); + //TODO REMOVE + MATE.log_acc("---------- Für Action Nr. "+ temp +": "+ entry.getValue() +" ----------"); + temp++; } // Determine the next action with roulette and make the step double randomValue = Math.random(); double sum = 0.0; - WidgetAction currentAction = null; for (Map.Entry entry : probabilities.entrySet()) { sum += entry.getValue(); currentAction = entry.getKey(); @@ -296,18 +307,22 @@ private TestCase runAnt() { prematureShutdown = !testCase.updateTestCase(currentAction, "" + i); } - // TODO Comment + // If the application gets shutdown the ant run is terminated and the action resulting + // in the shutdown gets set to 0 to not be used in future runs if (prematureShutdown) { + pheromones.put(currentAction, 0.0); + //TODO REMOVE + MATE.log_acc("---------- Pheromone von exit action auf 0 gesetzt ----------"); break; } - // Reset used variables probabilities.clear(); } return testCase; } + /** * Determine the weight for an action depending on the type of the action * @param action the action to get a weight value for From a4d3526cd1448b8842b86a23d5f51ee4ea018014 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Tue, 7 Apr 2020 20:30:30 +0200 Subject: [PATCH 12/30] Latest Changes, updated Genetic fitting to Ant --- app/src/main/java/org/mate/MATE.java | 31 ++++------------ .../org/mate/exploration/ant/AntColony.java | 37 +++++++++++++++---- .../builder/GeneticAlgorithmProvider.java | 4 ++ ...TargetLineCoveredTerminationCondition.java | 34 +++++++++++++++++ .../heuristical/RandomExploration.java | 32 +++++++++++++++- 5 files changed, 107 insertions(+), 31 deletions(-) create mode 100644 app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java diff --git a/app/src/main/java/org/mate/MATE.java b/app/src/main/java/org/mate/MATE.java index 7fc3ddf8..9f80f2db 100644 --- a/app/src/main/java/org/mate/MATE.java +++ b/app/src/main/java/org/mate/MATE.java @@ -50,6 +50,8 @@ import org.mate.exploration.genetic.fitness.TestLengthFitnessFunction; import org.mate.exploration.genetic.crossover.UniformSuiteCrossoverFunction; import org.mate.exploration.genetic.termination.NeverTerminationCondition; +import org.mate.exploration.genetic.termination.TargetLineCoveredTerminationCondition; +import org.mate.exploration.genetic.fitness.LineCoveredPercentageFitnessFunction; import org.mate.exploration.heuristical.HeuristicExploration; import org.mate.exploration.heuristical.RandomExploration; import org.mate.interaction.DeviceMgr; @@ -297,20 +299,6 @@ public Void call() throws Exception { } } else if (explorationStrategy.equals("StandardGeneticAlgorithm")) { uiAbstractionLayer = new UIAbstractionLayer(deviceMgr, packageName); - MATE.log_acc("Activities"); - for (String s : Registry.getEnvironmentManager().getActivityNames()) { - MATE.log_acc("\t" + s); - } - - if (Properties.COVERAGE() == Coverage.BRANCH_COVERAGE) { - // init the CFG - boolean isInit = Registry.getEnvironmentManager().initCFG(); - - if (!isInit) { - MATE.log("Couldn't initialise CFG! Aborting."); - throw new IllegalStateException("Graph initialisation failed!"); - } - } final IGeneticAlgorithm genericGA = new GeneticAlgorithmBuilder() .withAlgorithm(StandardGeneticAlgorithm.ALGORITHM_NAME) @@ -318,21 +306,18 @@ public Void call() throws Exception { .withSelectionFunction(FitnessProportionateSelectionFunction.SELECTION_FUNCTION_ID) .withCrossoverFunction(TestCaseMergeCrossOverFunction.CROSSOVER_FUNCTION_ID) .withMutationFunction(CutPointMutationFunction.MUTATION_FUNCTION_ID) - .withFitnessFunction(BranchDistanceFitnessFunction.FITNESS_FUNCTION_ID) - .withTerminationCondition(NeverTerminationCondition.TERMINATION_CONDITION_ID) + .withFitnessFunction(LineCoveredPercentageFitnessFunction.FITNESS_FUNCTION_ID, + Properties.TARGET_LINE()) + .withTerminationCondition(TargetLineCoveredTerminationCondition.TERMINATION_CONDITION_ID) .withPopulationSize(50) .withBigPopulationSize(100) .withMaxNumEvents(50) .withPMutate(0.3) .withPCrossover(0.7) .build(); - TimeoutRun.timeoutRun(new Callable() { - @Override - public Void call() throws Exception { - genericGA.run(); - return null; - } - }, MATE.TIME_OUT); + + TargetLineCoveredTerminationCondition.INSTANCE.setGeneticAlgorithm(genericGA); + genericGA.run(); if (Properties.STORE_COVERAGE()) { if (Properties.COVERAGE() == Coverage.BRANCH_COVERAGE) { diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 41e1171c..6c3032f7 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -43,8 +43,8 @@ public class AntColony { // Parameters to customize the ACO algorithm private static final int generationAmount = 10; - private static final int generationSize = 2; - private static final int antPathLength = 4; + private static final int generationSize = 5; + private static final int antPathLength = 30; private static final double evaporationRate = 0.1; // TODO Choose appropriate deposit amount private static final double standardDepositAmount = 1.0; @@ -95,7 +95,7 @@ public void run() { Registry.getEnvironmentManager().storeCoverageData(chromosome, null); LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); - // DEBUG + // TODO REMOVE - DEBUG System.out.println(lineCoveredPercentageFitnessFunction.getFitness(chromosome)); // Stop algorithm if target line was reached @@ -224,7 +224,15 @@ private TestCase runAnt() { List executableActions = uiAbstractionLayer.getExecutableActions(); //TODO REMOVE - MATE.log_acc("---------- Anzahl an Möglichkeiten "+ executableActions.size() +" ----------"); + MATE.log_acc("========== Schritt #"+ (i + 1)); + MATE.log_acc("---------- Anzahl an Möglichkeiten "+ executableActions.size()); + int tempNum = 0; + for (WidgetAction action : executableActions) { + MATE.log_acc("Aktionnummer: #" + tempNum + ", Actiontype: " + action.getActionType()); + tempNum++; + } + MATE.log_acc("---------- Anzahl Iterationen über executableActions: " + tempNum); + // Variable to flag a premature shutdown due to ant executing closing action boolean prematureShutdown; @@ -247,11 +255,19 @@ private TestCase runAnt() { currentAction = executableActions.get(0); } else { // Set pheromone values for the available widget actions without one + //TODO REMOVE + tempNum = 0; for (WidgetAction action : executableActions) { if (!pheromones.containsKey(action)) { pheromones.put(action, currentPheromoneStandardValue); } + //TODO REMOVE + MATE.log_acc("AKtion hinzugefügt: Actionnummer: #" + tempNum + ", Actiontype: " + action.getActionType() + ", Aktionsname: " + action + " --- Größe: "+ pheromones.size()); + tempNum++; } + //TODO REMOVE + MATE.log_acc("---------- Anzahl Iterationen für Vergabe von Pheromonwerten über executableActions: " + tempNum); + MATE.log_acc("---------- Anzahl an Einträgen in Pheromonmap: " + pheromones.size()); // Store probabilities for each action with or without factoring in the action type if(includeActionTypeInTransition) { @@ -271,9 +287,16 @@ private TestCase runAnt() { } } else { // Store pheromone value of all actions as their probability + //TODO REMOVE + tempNum = 0; for (WidgetAction action : executableActions) { probabilities.put(action, pheromones.get(action)); + //TODO REMOVE + tempNum++; } + //TODO REMOVE + MATE.log_acc("---------- Anzahl Iterationen für Vergabe von Attraktivitätswerten über executableActions: " + tempNum); + MATE.log_acc("---------- Anzahl an Einträgen in Probabilities: "+ probabilities.size()); } // Sum up all the probabilities @@ -285,11 +308,11 @@ private TestCase runAnt() { // Calculate relative probability for each option //TODO Remove int temp = 1; - MATE.log_acc("---------- Wahrscheinlichkeiten : ----------"); + MATE.log_acc("---------- Wahrscheinlichkeiten :"); for (Map.Entry entry : probabilities.entrySet()) { entry.setValue(entry.getValue() / sumProbabilities); //TODO REMOVE - MATE.log_acc("---------- Für Action Nr. "+ temp +": "+ entry.getValue() +" ----------"); + MATE.log_acc("Für Action Nr. "+ temp +": "+ entry.getValue() +", Typ: " + entry.getKey().getActionType()); temp++; } @@ -312,7 +335,7 @@ private TestCase runAnt() { if (prematureShutdown) { pheromones.put(currentAction, 0.0); //TODO REMOVE - MATE.log_acc("---------- Pheromone von exit action auf 0 gesetzt ----------"); + MATE.log_acc("---------- Pheromone von exit action auf 0 gesetzt"); break; } diff --git a/app/src/main/java/org/mate/exploration/genetic/builder/GeneticAlgorithmProvider.java b/app/src/main/java/org/mate/exploration/genetic/builder/GeneticAlgorithmProvider.java index 24af1747..3985e19a 100644 --- a/app/src/main/java/org/mate/exploration/genetic/builder/GeneticAlgorithmProvider.java +++ b/app/src/main/java/org/mate/exploration/genetic/builder/GeneticAlgorithmProvider.java @@ -42,6 +42,7 @@ import org.mate.exploration.genetic.termination.ITerminationCondition; import org.mate.exploration.genetic.termination.IterTerminationCondition; import org.mate.exploration.genetic.termination.NeverTerminationCondition; +import org.mate.exploration.genetic.termination.TargetLineCoveredTerminationCondition; import org.mate.model.TestCase; import java.util.ArrayList; @@ -362,6 +363,9 @@ private ITerminationCondition initializeTerminationCondition() { return new NeverTerminationCondition(); case ConditionalTerminationCondition.TERMINATION_CONDITION_ID: return new ConditionalTerminationCondition(); + case TargetLineCoveredTerminationCondition.TERMINATION_CONDITION_ID: + return new TargetLineCoveredTerminationCondition(); + default: throw new UnsupportedOperationException("Unknown termination condition: " + terminationConditionId); diff --git a/app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java b/app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java new file mode 100644 index 00000000..42d7c7b9 --- /dev/null +++ b/app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java @@ -0,0 +1,34 @@ +package org.mate.exploration.genetic.termination; + +import org.mate.Properties; +import org.mate.exploration.genetic.chromosome.IChromosome; +import org.mate.exploration.genetic.core.IGeneticAlgorithm; +import org.mate.exploration.genetic.fitness.LineCoveredPercentageFitnessFunction; +import org.mate.model.TestCase; + +public class TargetLineCoveredTerminationCondition implements ITerminationCondition { + public static final String TERMINATION_CONDITION_ID = "target_line_covered_termination_condition"; + + public static TargetLineCoveredTerminationCondition INSTANCE = null; + private LineCoveredPercentageFitnessFunction lineCoveredPercentageFitnessFunction; + private IGeneticAlgorithm geneticAlgorithm; + + public TargetLineCoveredTerminationCondition() { + INSTANCE = this; + lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(Properties.TARGET_LINE()); + } + + public void setGeneticAlgorithm(IGeneticAlgorithm geneticAlgorithm) { + this.geneticAlgorithm = geneticAlgorithm; + } + + @Override + public boolean isMet() { + for (IChromosome chromosome : geneticAlgorithm.getCurrentPopulation()) { + if (lineCoveredPercentageFitnessFunction.getFitness(chromosome) == 1.0) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java index 094f699f..54fde11f 100644 --- a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java +++ b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java @@ -2,7 +2,13 @@ import org.mate.MATE; import org.mate.Properties; +import org.mate.Registry; +import org.mate.exploration.genetic.chromosome.Chromosome; +import org.mate.exploration.genetic.chromosome.IChromosome; import org.mate.exploration.genetic.chromosome_factory.AndroidRandomChromosomeFactory; +import org.mate.exploration.genetic.fitness.IFitnessFunction; +import org.mate.exploration.genetic.fitness.LineCoveredPercentageFitnessFunction; +import org.mate.model.TestCase; public class RandomExploration { private final AndroidRandomChromosomeFactory randomChromosomeFactory; @@ -18,12 +24,36 @@ public RandomExploration(boolean storeCoverage, boolean alwaysReset, int maxNumE } public void run() { + // Get the target line to generate a test for and initialise the fitness function + String targetLine = Properties.TARGET_LINE(); + IFitnessFunction lineCoveredPercentageFitnessFunction + = new LineCoveredPercentageFitnessFunction(targetLine); + if (!alwaysReset) { MATE.uiAbstractionLayer.resetApp(); } for (int i = 0; true; i++) { MATE.log_acc("Exploration #" + (i + 1)); - randomChromosomeFactory.createChromosome(); + + //TODO REMOVE after successful implementation of aborting runs with fitness = 1 + //randomChromosomeFactory.createChromosome(); + + // Store the chromosome created in each step to calculate fitness value + IChromosome chromosome = randomChromosomeFactory.createChromosome(); + + if (!alwaysReset) { + MATE.uiAbstractionLayer.restartApp(); + } + + // TODO REMOVE - DEBUG + System.out.println(lineCoveredPercentageFitnessFunction.getFitness(chromosome)); + + // Stop algorithm if target line was reached + if (lineCoveredPercentageFitnessFunction.getFitness(chromosome) == 1) { + MATE.log_acc("Random Exploration finished successfully"); + break; + } + if (!alwaysReset) { MATE.uiAbstractionLayer.restartApp(); } From 5789989ae77ea2cc1a16d9de16d8497818a8ab8a Mon Sep 17 00:00:00 2001 From: reissi01 Date: Thu, 16 Jul 2020 11:04:22 +0200 Subject: [PATCH 13/30] Latest Changes, finalizing functionality AntColony, RandomWalk added Logs --- app/src/main/java/org/mate/MATE.java | 9 +- .../org/mate/exploration/ant/AntColony.java | 84 +++++++++---------- .../heuristical/RandomExploration.java | 35 +++++++- 3 files changed, 75 insertions(+), 53 deletions(-) diff --git a/app/src/main/java/org/mate/MATE.java b/app/src/main/java/org/mate/MATE.java index 9f80f2db..9976d985 100644 --- a/app/src/main/java/org/mate/MATE.java +++ b/app/src/main/java/org/mate/MATE.java @@ -395,14 +395,7 @@ public Void call() throws Exception { } final RandomExploration randomExploration = new RandomExploration(Properties.STORE_COVERAGE(), true, 50); - - TimeoutRun.timeoutRun(new Callable() { - @Override - public Void call() throws Exception { - randomExploration.run(); - return null; - } - }, MATE.TIME_OUT); + randomExploration.run(); if (Properties.STORE_COVERAGE()) { Registry.getEnvironmentManager().storeCoverageData(randomExploration, null); diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 6c3032f7..4366541d 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; +import java.util.concurrent.TimeUnit; public class AntColony { private final UIAbstractionLayer uiAbstractionLayer; @@ -42,8 +43,8 @@ public class AntColony { private List> testCasesList = new ArrayList<>(); // Parameters to customize the ACO algorithm - private static final int generationAmount = 10; - private static final int generationSize = 5; + private static final int generationAmount = 20; + private static final int generationSize = 8; private static final int antPathLength = 30; private static final double evaporationRate = 0.1; // TODO Choose appropriate deposit amount @@ -70,6 +71,12 @@ public AntColony() { } public void run() { + long algorithmStartTime = System.currentTimeMillis(); + // TODO Remove + //antStatsLogger.write("Start of Algorithm at " + startTime + ", "); + antStatsLogger.write("Algorithm Type; Generation #; Ant #; Fitness Value; Runtime\n"); + + // Get the target line for ACO to generate a test for and initialise the fitness function String targetLine = Properties.TARGET_LINE(); IFitnessFunction lineCoveredPercentageFitnessFunction @@ -79,14 +86,16 @@ public void run() { currentPheromoneStandardValue = 1.0; // Loop to create multiple generations of ants + long generationStartTime, antStartTime; outerLoop: for (int i = 0; i < generationAmount; i++) { + generationStartTime = System.currentTimeMillis(); MATE.log_acc("Generation #" + (i + 1)); - antStatsLogger.write("Start of Generation #" + (i + 1)); // Create ants and check if they reach the target line for (int z = 0; z < generationSize; z++){ + antStartTime = System.currentTimeMillis(); MATE.log_acc("Ant #" + (z + 1)); - antStatsLogger.write("Start of Ant #" + (z + 1)); + antStatsLogger.write("ant; " + (i + 1) + "; " + (z + 1) + "; "); // Create an ant to traverse the app and wrap the generated testcase in a chromosome IChromosome chromosome = new Chromosome<>(runAnt()); @@ -96,20 +105,27 @@ public void run() { LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); // TODO REMOVE - DEBUG - System.out.println(lineCoveredPercentageFitnessFunction.getFitness(chromosome)); + double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); + System.out.println(fitnessValue); + antStatsLogger.write(fitnessValue + "; "); + logCurrentRuntime(antStartTime); // Stop algorithm if target line was reached - if (lineCoveredPercentageFitnessFunction.getFitness(chromosome) == 1) { - //TODO add necessary action for successful algorithm run (write log) + if (fitnessValue == 1) { + //TODO finish necessary action for successful algorithm run (write log) + antStatsLogger.write("ant; " + (i + 1) + "; -; -; "); + logCurrentRuntime(generationStartTime); + MATE.log_acc("ACO finished successfully"); + antStatsLogger.write("ant; -; -; -; "); + logCurrentRuntime(algorithmStartTime); break outerLoop; } else { // Add testcase of current ant to list for later depositing of pheromones testCasesList.add(chromosome); } - - antStatsLogger.write("End of Ant #" + (z + 1)); } + // Pheromone evaporation for (Map.Entry entry : pheromones.entrySet()) { entry.setValue((1-evaporationRate)*entry.getValue()); @@ -200,7 +216,14 @@ public void run() { } } - antStatsLogger.write("End of Generation #" + (i + 1)); + antStatsLogger.write("ant; " + (i + 1) + "; -; -; "); + logCurrentRuntime(generationStartTime); + + // TODO Comment + if ((i + 1) == generationAmount) { + antStatsLogger.write("ant; -; -; -; "); + logCurrentRuntime(algorithmStartTime); + } } // Close the logger antStatsLogger.close(); @@ -223,17 +246,6 @@ private TestCase runAnt() { // Get list possible actions to execute List executableActions = uiAbstractionLayer.getExecutableActions(); - //TODO REMOVE - MATE.log_acc("========== Schritt #"+ (i + 1)); - MATE.log_acc("---------- Anzahl an Möglichkeiten "+ executableActions.size()); - int tempNum = 0; - for (WidgetAction action : executableActions) { - MATE.log_acc("Aktionnummer: #" + tempNum + ", Actiontype: " + action.getActionType()); - tempNum++; - } - MATE.log_acc("---------- Anzahl Iterationen über executableActions: " + tempNum); - - // Variable to flag a premature shutdown due to ant executing closing action boolean prematureShutdown; WidgetAction currentAction = null; @@ -255,19 +267,11 @@ private TestCase runAnt() { currentAction = executableActions.get(0); } else { // Set pheromone values for the available widget actions without one - //TODO REMOVE - tempNum = 0; for (WidgetAction action : executableActions) { if (!pheromones.containsKey(action)) { pheromones.put(action, currentPheromoneStandardValue); } - //TODO REMOVE - MATE.log_acc("AKtion hinzugefügt: Actionnummer: #" + tempNum + ", Actiontype: " + action.getActionType() + ", Aktionsname: " + action + " --- Größe: "+ pheromones.size()); - tempNum++; } - //TODO REMOVE - MATE.log_acc("---------- Anzahl Iterationen für Vergabe von Pheromonwerten über executableActions: " + tempNum); - MATE.log_acc("---------- Anzahl an Einträgen in Pheromonmap: " + pheromones.size()); // Store probabilities for each action with or without factoring in the action type if(includeActionTypeInTransition) { @@ -287,16 +291,9 @@ private TestCase runAnt() { } } else { // Store pheromone value of all actions as their probability - //TODO REMOVE - tempNum = 0; for (WidgetAction action : executableActions) { probabilities.put(action, pheromones.get(action)); - //TODO REMOVE - tempNum++; } - //TODO REMOVE - MATE.log_acc("---------- Anzahl Iterationen für Vergabe von Attraktivitätswerten über executableActions: " + tempNum); - MATE.log_acc("---------- Anzahl an Einträgen in Probabilities: "+ probabilities.size()); } // Sum up all the probabilities @@ -306,14 +303,8 @@ private TestCase runAnt() { } // Calculate relative probability for each option - //TODO Remove - int temp = 1; - MATE.log_acc("---------- Wahrscheinlichkeiten :"); for (Map.Entry entry : probabilities.entrySet()) { entry.setValue(entry.getValue() / sumProbabilities); - //TODO REMOVE - MATE.log_acc("Für Action Nr. "+ temp +": "+ entry.getValue() +", Typ: " + entry.getKey().getActionType()); - temp++; } // Determine the next action with roulette and make the step @@ -334,8 +325,6 @@ private TestCase runAnt() { // in the shutdown gets set to 0 to not be used in future runs if (prematureShutdown) { pheromones.put(currentAction, 0.0); - //TODO REMOVE - MATE.log_acc("---------- Pheromone von exit action auf 0 gesetzt"); break; } @@ -370,4 +359,11 @@ private Double getActionTypeWeight (WidgetAction action) { } return eventTypeWeight; } + + private void logCurrentRuntime (long startTime) { + long currentTime = System.currentTimeMillis(); + currentTime = currentTime - startTime; + long seconds = (currentTime/(1000)); + antStatsLogger.write(seconds + "\n"); + } } diff --git a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java index 54fde11f..aeb9378c 100644 --- a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java +++ b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java @@ -3,6 +3,7 @@ import org.mate.MATE; import org.mate.Properties; import org.mate.Registry; +import org.mate.exploration.ant.AntStatsLogger; import org.mate.exploration.genetic.chromosome.Chromosome; import org.mate.exploration.genetic.chromosome.IChromosome; import org.mate.exploration.genetic.chromosome_factory.AndroidRandomChromosomeFactory; @@ -12,6 +13,7 @@ public class RandomExploration { private final AndroidRandomChromosomeFactory randomChromosomeFactory; + private final AntStatsLogger antStatsLogger; private final boolean alwaysReset; public RandomExploration(int maxNumEvents) { @@ -21,9 +23,15 @@ public RandomExploration(int maxNumEvents) { public RandomExploration(boolean storeCoverage, boolean alwaysReset, int maxNumEvents) { this.alwaysReset = alwaysReset; randomChromosomeFactory = new AndroidRandomChromosomeFactory(storeCoverage, alwaysReset, maxNumEvents); + + antStatsLogger = new AntStatsLogger(); } public void run() { + long algorithmStartTime = System.currentTimeMillis(); + + antStatsLogger.write("Algorithm Type; Test Case #; Fitness Value; Runtime\n"); + // Get the target line to generate a test for and initialise the fitness function String targetLine = Properties.TARGET_LINE(); IFitnessFunction lineCoveredPercentageFitnessFunction @@ -32,12 +40,17 @@ public void run() { if (!alwaysReset) { MATE.uiAbstractionLayer.resetApp(); } + + long testCaseStartTime; + for (int i = 0; true; i++) { MATE.log_acc("Exploration #" + (i + 1)); //TODO REMOVE after successful implementation of aborting runs with fitness = 1 //randomChromosomeFactory.createChromosome(); + testCaseStartTime = System.currentTimeMillis(); + // Store the chromosome created in each step to calculate fitness value IChromosome chromosome = randomChromosomeFactory.createChromosome(); @@ -48,9 +61,22 @@ public void run() { // TODO REMOVE - DEBUG System.out.println(lineCoveredPercentageFitnessFunction.getFitness(chromosome)); + + antStatsLogger.write("random; " + (i + 1) + "; "); + + double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); + + antStatsLogger.write(fitnessValue + "; "); + + logCurrentRuntime(testCaseStartTime); + // Stop algorithm if target line was reached - if (lineCoveredPercentageFitnessFunction.getFitness(chromosome) == 1) { + if (fitnessValue == 1) { MATE.log_acc("Random Exploration finished successfully"); + + antStatsLogger.write("random; -; -; "); + logCurrentRuntime(algorithmStartTime); + break; } @@ -59,4 +85,11 @@ public void run() { } } } + + private void logCurrentRuntime (long startTime) { + long currentTime = System.currentTimeMillis(); + currentTime = currentTime - startTime; + long seconds = (currentTime/(1000)); + antStatsLogger.write(seconds + "\n"); + } } From 3188649aa2ab6f7cd82ba241f94aa7f8bf98602e Mon Sep 17 00:00:00 2001 From: reissi01 Date: Sun, 26 Jul 2020 11:50:23 +0200 Subject: [PATCH 14/30] Updated logging in RandomExploration and AntColony, Added logging for GeneticAlgorithm --- .../org/mate/exploration/ant/AntColony.java | 29 ++++++---- .../genetic/core/GeneticAlgorithm.java | 55 +++++++++++++++++++ .../heuristical/RandomExploration.java | 23 +++++++- 3 files changed, 93 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 4366541d..7b9f2b1b 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -44,7 +44,7 @@ public class AntColony { // Parameters to customize the ACO algorithm private static final int generationAmount = 20; - private static final int generationSize = 8; + private static final int generationSize = 10; private static final int antPathLength = 30; private static final double evaporationRate = 0.1; // TODO Choose appropriate deposit amount @@ -72,10 +72,10 @@ public AntColony() { public void run() { long algorithmStartTime = System.currentTimeMillis(); - // TODO Remove + // TODO Print target line & coverage //antStatsLogger.write("Start of Algorithm at " + startTime + ", "); - antStatsLogger.write("Algorithm Type; Generation #; Ant #; Fitness Value; Runtime\n"); - + antStatsLogger.write("Algorithm Type; Generation #; Ant #; Fitness Value;" + + " Current Coverage; Combined Coverage; Runtime in s\n"); // Get the target line for ACO to generate a test for and initialise the fitness function String targetLine = Properties.TARGET_LINE(); @@ -104,21 +104,26 @@ public void run() { Registry.getEnvironmentManager().storeCoverageData(chromosome, null); LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); - // TODO REMOVE - DEBUG double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); + double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); + double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); System.out.println(fitnessValue); - antStatsLogger.write(fitnessValue + "; "); + antStatsLogger.write(fitnessValue + "; " + + coverage + "; " + combinedCoverage + "; "); logCurrentRuntime(antStartTime); // Stop algorithm if target line was reached if (fitnessValue == 1) { //TODO finish necessary action for successful algorithm run (write log) - antStatsLogger.write("ant; " + (i + 1) + "; -; -; "); + antStatsLogger.write("ant; " + (i + 1) + "; -; -; -; -; "); logCurrentRuntime(generationStartTime); MATE.log_acc("ACO finished successfully"); - antStatsLogger.write("ant; -; -; -; "); + antStatsLogger.write("ant; -; -; -; -; -; "); logCurrentRuntime(algorithmStartTime); + + antStatsLogger.write("random; -; -; -; -; successful\n"); + break outerLoop; } else { // Add testcase of current ant to list for later depositing of pheromones @@ -216,13 +221,15 @@ public void run() { } } - antStatsLogger.write("ant; " + (i + 1) + "; -; -; "); + antStatsLogger.write("ant; " + (i + 1) + "; -; -; -; -; "); logCurrentRuntime(generationStartTime); - // TODO Comment + // TODO Comment max generations reached if ((i + 1) == generationAmount) { - antStatsLogger.write("ant; -; -; -; "); + antStatsLogger.write("ant; -; -; -; -; -; "); logCurrentRuntime(algorithmStartTime); + + antStatsLogger.write("random; -; -; -; -; unsuccessful\n"); } } // Close the logger diff --git a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java index 37b89067..e0de983a 100644 --- a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java +++ b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java @@ -3,13 +3,16 @@ import org.mate.MATE; import org.mate.Properties; import org.mate.Registry; +import org.mate.exploration.ant.AntStatsLogger; import org.mate.exploration.genetic.chromosome.IChromosome; import org.mate.exploration.genetic.chromosome_factory.IChromosomeFactory; import org.mate.exploration.genetic.crossover.ICrossOverFunction; import org.mate.exploration.genetic.fitness.IFitnessFunction; +import org.mate.exploration.genetic.fitness.LineCoveredPercentageFitnessFunction; import org.mate.exploration.genetic.mutation.IMutationFunction; import org.mate.exploration.genetic.selection.ISelectionFunction; import org.mate.exploration.genetic.termination.ITerminationCondition; +import org.mate.model.TestCase; import org.mate.ui.EnvironmentManager; import org.mate.utils.Coverage; import org.mate.utils.Randomness; @@ -36,6 +39,8 @@ public abstract class GeneticAlgorithm implements IGeneticAlgorithm { protected double pCrossover; protected double pMutate; + private final AntStatsLogger antStatsLogger; + /** * Initializing the genetic algorithm with all necessary attributes @@ -65,14 +70,35 @@ public GeneticAlgorithm(IChromosomeFactory chromosomeFactory, ISelectionFunct this.pCrossover = pCrossover; this.pMutate = pMutate; + antStatsLogger = new AntStatsLogger(); + currentGenerationNumber = 0; } @Override public void run() { + long algorithmStartTime = System.currentTimeMillis(); + long generationStartTime = System.currentTimeMillis(); + antStatsLogger.write("Algorithm Type; Generation Number; Population Number; " + + "Fitness Value; Current Coverage; Combined Coverage; Runtime in s\n"); + + String targetLine = Properties.TARGET_LINE(); + IFitnessFunction lineCoveredPercentageFitnessFunction + = new LineCoveredPercentageFitnessFunction(targetLine); + createInitialPopulation(); + + antStatsLogger.write("genetic; " + currentGenerationNumber + "; -; -; -; -; "); + logCurrentRuntime(generationStartTime); + while (!terminationCondition.isMet()) { evolve(); + + if(terminationCondition.isMet()) { + antStatsLogger.write("genetic; -; -; -; -; -; "); + logCurrentRuntime(algorithmStartTime); + antStatsLogger.write("genetic; -; -; -; -; -; successful"); + } } } @@ -85,7 +111,13 @@ public List> getCurrentPopulation() { public void createInitialPopulation() { MATE.log_acc("Creating initial population (1st generation)"); for (int i = 0; i < populationSize; i++) { + long populationStartTime = System.currentTimeMillis(); + population.add(chromosomeFactory.createChromosome()); + + antStatsLogger.write("genetic; " + currentGenerationNumber + "; " + (i + 1) + + "; ?; ?; ?; "); + logCurrentRuntime(populationStartTime); } logCurrentFitness(); @@ -94,6 +126,8 @@ public void createInitialPopulation() { @Override public void evolve() { + long generationStartTime = System.currentTimeMillis(); + MATE.log_acc("Creating population #" + (currentGenerationNumber + 1)); List> newGeneration = new ArrayList<>(population); @@ -131,6 +165,20 @@ public void evolve() { List> tmp = getGenerationSurvivors(); population.clear(); population.addAll(tmp); + // TODO log new generation infos + for (int i = 0; i < population.size(); i++) { + IChromosome chromosome = population.get(i); + + //LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); + + //double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); + + antStatsLogger.write("genetic; " + currentGenerationNumber + "; " + (i + 1) + + "; ?; ?; ?; -;"); + } + antStatsLogger.write("genetic; " + currentGenerationNumber + "; -; -; -; -; "); + logCurrentRuntime(generationStartTime); + logCurrentFitness(); currentGenerationNumber++; } @@ -167,4 +215,11 @@ protected void logCurrentFitness() { } } + private void logCurrentRuntime (long startTime) { + long currentTime = System.currentTimeMillis(); + currentTime = currentTime - startTime; + long seconds = (currentTime/(1000)); + antStatsLogger.write(seconds + "\n"); + } + } diff --git a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java index aeb9378c..955904ce 100644 --- a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java +++ b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java @@ -29,8 +29,11 @@ public RandomExploration(boolean storeCoverage, boolean alwaysReset, int maxNumE public void run() { long algorithmStartTime = System.currentTimeMillis(); + // number of ants created in a full ACO run, generationAmount * generationSize + int antAmount = 20 * 10; - antStatsLogger.write("Algorithm Type; Test Case #; Fitness Value; Runtime\n"); + antStatsLogger.write("Algorithm Type; Test Case #; Fitness Value;" + + " Current Coverage; Combined Coverage; Runtime in s\n"); // Get the target line to generate a test for and initialise the fitness function String targetLine = Properties.TARGET_LINE(); @@ -65,8 +68,11 @@ public void run() { antStatsLogger.write("random; " + (i + 1) + "; "); double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); + double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); + double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); - antStatsLogger.write(fitnessValue + "; "); + antStatsLogger.write(fitnessValue + "; " + + coverage + "; " + combinedCoverage + "; "); logCurrentRuntime(testCaseStartTime); @@ -74,9 +80,20 @@ public void run() { if (fitnessValue == 1) { MATE.log_acc("Random Exploration finished successfully"); - antStatsLogger.write("random; -; -; "); + antStatsLogger.write("random; -; -; -; -; "); logCurrentRuntime(algorithmStartTime); + antStatsLogger.write("random; -; -; -; -; successful\n"); + + break; + } else if (i == (antAmount - 1)) { + MATE.log_acc("Random Exploration finished unsuccessfully"); + + antStatsLogger.write("random; -; -; -; -; "); + logCurrentRuntime(algorithmStartTime); + + antStatsLogger.write("random; -; -; -; -; unsuccessful\n"); + break; } From bc2dba9ca5e10cae6687e2188bc5fe18b7f7b946 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Thu, 30 Jul 2020 20:48:53 +0200 Subject: [PATCH 15/30] Fixed logging for Genetic Algorithm --- .../genetic/core/GeneticAlgorithm.java | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java index e0de983a..c7926a0d 100644 --- a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java +++ b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java @@ -82,10 +82,6 @@ public void run() { antStatsLogger.write("Algorithm Type; Generation Number; Population Number; " + "Fitness Value; Current Coverage; Combined Coverage; Runtime in s\n"); - String targetLine = Properties.TARGET_LINE(); - IFitnessFunction lineCoveredPercentageFitnessFunction - = new LineCoveredPercentageFitnessFunction(targetLine); - createInitialPopulation(); antStatsLogger.write("genetic; " + currentGenerationNumber + "; -; -; -; -; "); @@ -110,13 +106,28 @@ public List> getCurrentPopulation() { @Override public void createInitialPopulation() { MATE.log_acc("Creating initial population (1st generation)"); + + String targetLine = Properties.TARGET_LINE(); + IFitnessFunction lineCoveredPercentageFitnessFunction + = new LineCoveredPercentageFitnessFunction(targetLine); + for (int i = 0; i < populationSize; i++) { long populationStartTime = System.currentTimeMillis(); - population.add(chromosomeFactory.createChromosome()); + IChromosome chromosomeT = chromosomeFactory.createChromosome(); + IChromosome chromosome = (IChromosome) chromosomeT; + + LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); + + double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); + double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); + double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); + + population.add(chromosomeT); + + antStatsLogger.write("genetic; " + (currentGenerationNumber - 1) + "; " + (i + 1) + + "; " + fitnessValue + "; " + coverage + "; " + combinedCoverage + "; "); - antStatsLogger.write("genetic; " + currentGenerationNumber + "; " + (i + 1) + - "; ?; ?; ?; "); logCurrentRuntime(populationStartTime); } @@ -128,6 +139,10 @@ public void createInitialPopulation() { public void evolve() { long generationStartTime = System.currentTimeMillis(); + String targetLine = Properties.TARGET_LINE(); + IFitnessFunction lineCoveredPercentageFitnessFunction + = new LineCoveredPercentageFitnessFunction(targetLine); + MATE.log_acc("Creating population #" + (currentGenerationNumber + 1)); List> newGeneration = new ArrayList<>(population); @@ -167,14 +182,16 @@ public void evolve() { population.addAll(tmp); // TODO log new generation infos for (int i = 0; i < population.size(); i++) { - IChromosome chromosome = population.get(i); + IChromosome chromosome = (IChromosome) population.get(i); - //LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); + LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); - //double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); + double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); + double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); + double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); antStatsLogger.write("genetic; " + currentGenerationNumber + "; " + (i + 1) + - "; ?; ?; ?; -;"); + "; " + fitnessValue + "; " + coverage + "; " + combinedCoverage + "; -\n"); } antStatsLogger.write("genetic; " + currentGenerationNumber + "; -; -; -; -; "); logCurrentRuntime(generationStartTime); From b57cbca1ddf539692c2325dbb7d7864bc4c4fe9f Mon Sep 17 00:00:00 2001 From: reissi01 Date: Thu, 6 Aug 2020 19:38:02 +0200 Subject: [PATCH 16/30] Added logging of target line and fixed an error in Logging for GA --- .../main/java/org/mate/exploration/ant/AntColony.java | 3 +++ .../exploration/genetic/core/GeneticAlgorithm.java | 10 +++++++--- .../exploration/heuristical/RandomExploration.java | 3 +++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 7b9f2b1b..be2e0934 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -82,6 +82,9 @@ public void run() { IFitnessFunction lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(targetLine); + // Log the current target line for later identification of the test + antStatsLogger.write("ant; -; -; -; -; -; " + targetLine + "\n"); + // Value to add the correct pheromone amount to unknown widget actions currentPheromoneStandardValue = 1.0; diff --git a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java index c7926a0d..f38b2353 100644 --- a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java +++ b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java @@ -82,6 +82,7 @@ public void run() { antStatsLogger.write("Algorithm Type; Generation Number; Population Number; " + "Fitness Value; Current Coverage; Combined Coverage; Runtime in s\n"); + createInitialPopulation(); antStatsLogger.write("genetic; " + currentGenerationNumber + "; -; -; -; -; "); @@ -111,6 +112,9 @@ public void createInitialPopulation() { IFitnessFunction lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(targetLine); + // Log the current target line for later identification of the test + antStatsLogger.write("genetic; -; -; -; -; -; " + targetLine + "\n"); + for (int i = 0; i < populationSize; i++) { long populationStartTime = System.currentTimeMillis(); @@ -125,7 +129,7 @@ public void createInitialPopulation() { population.add(chromosomeT); - antStatsLogger.write("genetic; " + (currentGenerationNumber - 1) + "; " + (i + 1) + + antStatsLogger.write("genetic; " + (currentGenerationNumber + 1) + "; " + (i + 1) + "; " + fitnessValue + "; " + coverage + "; " + combinedCoverage + "; "); logCurrentRuntime(populationStartTime); @@ -190,10 +194,10 @@ public void evolve() { double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); - antStatsLogger.write("genetic; " + currentGenerationNumber + "; " + (i + 1) + + antStatsLogger.write("genetic; " + (currentGenerationNumber + 1) + "; " + (i + 1) + "; " + fitnessValue + "; " + coverage + "; " + combinedCoverage + "; -\n"); } - antStatsLogger.write("genetic; " + currentGenerationNumber + "; -; -; -; -; "); + antStatsLogger.write("genetic; " + (currentGenerationNumber + 1) + "; -; -; -; -; "); logCurrentRuntime(generationStartTime); logCurrentFitness(); diff --git a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java index 955904ce..30eac9fe 100644 --- a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java +++ b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java @@ -40,6 +40,9 @@ public void run() { IFitnessFunction lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(targetLine); + // Log the current target line for later identification of the test + antStatsLogger.write("random; -; -; -; -; " + targetLine + "\n"); + if (!alwaysReset) { MATE.uiAbstractionLayer.resetApp(); } From 750c8cc34fb6232a491319432823cfdeee590efc Mon Sep 17 00:00:00 2001 From: reissi01 Date: Sat, 22 Aug 2020 08:50:32 +0200 Subject: [PATCH 17/30] Fixed logging to be processable by RStudio, added "", removed spaces --- .../org/mate/exploration/ant/AntColony.java | 31 ++++++++++--------- .../genetic/core/GeneticAlgorithm.java | 28 ++++++++++------- .../heuristical/RandomExploration.java | 22 ++++++------- 3 files changed, 44 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index be2e0934..ef5a0d29 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -74,16 +74,19 @@ public void run() { long algorithmStartTime = System.currentTimeMillis(); // TODO Print target line & coverage //antStatsLogger.write("Start of Algorithm at " + startTime + ", "); - antStatsLogger.write("Algorithm Type; Generation #; Ant #; Fitness Value;" + - " Current Coverage; Combined Coverage; Runtime in s\n"); + antStatsLogger.write("\"Algorithm_Type\";\"Generation\";\"Ant\";\"Fitness_Value\";" + + "\"Current_Coverage\";\"Combined_Coverage\";\"Runtime\"\n"); // Get the target line for ACO to generate a test for and initialise the fitness function String targetLine = Properties.TARGET_LINE(); IFitnessFunction lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(targetLine); - // Log the current target line for later identification of the test - antStatsLogger.write("ant; -; -; -; -; -; " + targetLine + "\n"); + // Log the current target line for later identification of the test and the settings for this run + antStatsLogger.write("\"ant\";\"" + + "includeActionTypeInTransition:\";\"" + includeActionTypeInTransition + "\";\"" + + "depositPheromonesWithRanking:\";\"" + depositPheromonesWithRanking + + "\";\"-\";\"" + targetLine + "\"\n"); // Value to add the correct pheromone amount to unknown widget actions currentPheromoneStandardValue = 1.0; @@ -98,7 +101,7 @@ public void run() { for (int z = 0; z < generationSize; z++){ antStartTime = System.currentTimeMillis(); MATE.log_acc("Ant #" + (z + 1)); - antStatsLogger.write("ant; " + (i + 1) + "; " + (z + 1) + "; "); + antStatsLogger.write("\"ant\";\"" + (i + 1) + "\";\"" + (z + 1) + "\";"); // Create an ant to traverse the app and wrap the generated testcase in a chromosome IChromosome chromosome = new Chromosome<>(runAnt()); @@ -111,21 +114,21 @@ public void run() { double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); System.out.println(fitnessValue); - antStatsLogger.write(fitnessValue + "; " + - coverage + "; " + combinedCoverage + "; "); + antStatsLogger.write("\"" + fitnessValue + "\";\"" + coverage + "\";\"" + + combinedCoverage + "\";\""); logCurrentRuntime(antStartTime); // Stop algorithm if target line was reached if (fitnessValue == 1) { //TODO finish necessary action for successful algorithm run (write log) - antStatsLogger.write("ant; " + (i + 1) + "; -; -; -; -; "); + antStatsLogger.write("\"ant\";\"" + (i + 1) + "\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); MATE.log_acc("ACO finished successfully"); - antStatsLogger.write("ant; -; -; -; -; -; "); + antStatsLogger.write("\"ant\";\"-\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(algorithmStartTime); - antStatsLogger.write("random; -; -; -; -; successful\n"); + antStatsLogger.write("\"ant\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\"\n"); break outerLoop; } else { @@ -224,15 +227,15 @@ public void run() { } } - antStatsLogger.write("ant; " + (i + 1) + "; -; -; -; -; "); + antStatsLogger.write("\"ant\";\"" + (i + 1) + "\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); // TODO Comment max generations reached if ((i + 1) == generationAmount) { - antStatsLogger.write("ant; -; -; -; -; -; "); + antStatsLogger.write("\"ant\";\"-\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(algorithmStartTime); - antStatsLogger.write("random; -; -; -; -; unsuccessful\n"); + antStatsLogger.write("\"ant\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\"\n"); } } // Close the logger @@ -374,6 +377,6 @@ private void logCurrentRuntime (long startTime) { long currentTime = System.currentTimeMillis(); currentTime = currentTime - startTime; long seconds = (currentTime/(1000)); - antStatsLogger.write(seconds + "\n"); + antStatsLogger.write(seconds + "\"\n"); } } diff --git a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java index f38b2353..2cd3d7b8 100644 --- a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java +++ b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java @@ -79,22 +79,23 @@ public GeneticAlgorithm(IChromosomeFactory chromosomeFactory, ISelectionFunct public void run() { long algorithmStartTime = System.currentTimeMillis(); long generationStartTime = System.currentTimeMillis(); - antStatsLogger.write("Algorithm Type; Generation Number; Population Number; " + - "Fitness Value; Current Coverage; Combined Coverage; Runtime in s\n"); + antStatsLogger.write("\"Algorithm_Type\";\"Generation_Number\";\"Population_Number\"" + + ";\"Fitness_Value\";\"Current_Coverage\";\"Combined_Coverage\";\"Runtime\"\n"); createInitialPopulation(); - antStatsLogger.write("genetic; " + currentGenerationNumber + "; -; -; -; -; "); + antStatsLogger.write("\"genetic\";\"" + currentGenerationNumber + "\";\"-\";\"-\";" + + "\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); while (!terminationCondition.isMet()) { evolve(); if(terminationCondition.isMet()) { - antStatsLogger.write("genetic; -; -; -; -; -; "); + antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(algorithmStartTime); - antStatsLogger.write("genetic; -; -; -; -; -; successful"); + antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\""); } } } @@ -113,7 +114,7 @@ public void createInitialPopulation() { = new LineCoveredPercentageFitnessFunction(targetLine); // Log the current target line for later identification of the test - antStatsLogger.write("genetic; -; -; -; -; -; " + targetLine + "\n"); + antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"" + targetLine + "\"\n"); for (int i = 0; i < populationSize; i++) { long populationStartTime = System.currentTimeMillis(); @@ -129,8 +130,9 @@ public void createInitialPopulation() { population.add(chromosomeT); - antStatsLogger.write("genetic; " + (currentGenerationNumber + 1) + "; " + (i + 1) + - "; " + fitnessValue + "; " + coverage + "; " + combinedCoverage + "; "); + antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" + + (i + 1) + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" + + combinedCoverage + "\";\""); logCurrentRuntime(populationStartTime); } @@ -194,10 +196,12 @@ public void evolve() { double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); - antStatsLogger.write("genetic; " + (currentGenerationNumber + 1) + "; " + (i + 1) + - "; " + fitnessValue + "; " + coverage + "; " + combinedCoverage + "; -\n"); + antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" + + (i + 1) + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" + + combinedCoverage + "\";\"-\"\n"); } - antStatsLogger.write("genetic; " + (currentGenerationNumber + 1) + "; -; -; -; -; "); + antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"-\";" + + "\"-\";\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); logCurrentFitness(); @@ -240,7 +244,7 @@ private void logCurrentRuntime (long startTime) { long currentTime = System.currentTimeMillis(); currentTime = currentTime - startTime; long seconds = (currentTime/(1000)); - antStatsLogger.write(seconds + "\n"); + antStatsLogger.write(seconds + "\"\n"); } } diff --git a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java index 30eac9fe..e31a0bbd 100644 --- a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java +++ b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java @@ -32,8 +32,8 @@ public void run() { // number of ants created in a full ACO run, generationAmount * generationSize int antAmount = 20 * 10; - antStatsLogger.write("Algorithm Type; Test Case #; Fitness Value;" + - " Current Coverage; Combined Coverage; Runtime in s\n"); + antStatsLogger.write("\"Algorithm_Type\";\"Test_Case\";\"Fitness_Value\";" + + "\"Current_Coverage\";\"Combined_Coverage\";\"Runtime\"\n"); // Get the target line to generate a test for and initialise the fitness function String targetLine = Properties.TARGET_LINE(); @@ -41,7 +41,7 @@ public void run() { = new LineCoveredPercentageFitnessFunction(targetLine); // Log the current target line for later identification of the test - antStatsLogger.write("random; -; -; -; -; " + targetLine + "\n"); + antStatsLogger.write("\"random\";\"-\";\"-\";\"-\";\"-\";\"" + targetLine + "\"\n"); if (!alwaysReset) { MATE.uiAbstractionLayer.resetApp(); @@ -68,14 +68,14 @@ public void run() { System.out.println(lineCoveredPercentageFitnessFunction.getFitness(chromosome)); - antStatsLogger.write("random; " + (i + 1) + "; "); + antStatsLogger.write("\"random\";\"" + (i + 1) + "\";"); double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); - antStatsLogger.write(fitnessValue + "; " + - coverage + "; " + combinedCoverage + "; "); + antStatsLogger.write("\"" + fitnessValue + "\";\"" + + coverage + "\";\"" + combinedCoverage + "\";\""); logCurrentRuntime(testCaseStartTime); @@ -83,19 +83,19 @@ public void run() { if (fitnessValue == 1) { MATE.log_acc("Random Exploration finished successfully"); - antStatsLogger.write("random; -; -; -; -; "); + antStatsLogger.write("\"random\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(algorithmStartTime); - antStatsLogger.write("random; -; -; -; -; successful\n"); + antStatsLogger.write("\"random\";\"-\";\"-\";\"-\";\"-\";\"successful\"\n"); break; } else if (i == (antAmount - 1)) { MATE.log_acc("Random Exploration finished unsuccessfully"); - antStatsLogger.write("random; -; -; -; -; "); + antStatsLogger.write("\"random\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(algorithmStartTime); - antStatsLogger.write("random; -; -; -; -; unsuccessful\n"); + antStatsLogger.write("\"random\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\"\n"); break; } @@ -110,6 +110,6 @@ private void logCurrentRuntime (long startTime) { long currentTime = System.currentTimeMillis(); currentTime = currentTime - startTime; long seconds = (currentTime/(1000)); - antStatsLogger.write(seconds + "\n"); + antStatsLogger.write(seconds + "\"\n"); } } From 92a987c94b779a9dfe3f32e207d15050e6cb6c36 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Mon, 24 Aug 2020 20:51:53 +0200 Subject: [PATCH 18/30] Fixed logging in ACO, missing column value if run unsuccessful; Added successful/unsuccessful log after population evolve in GA --- .../org/mate/exploration/ant/AntColony.java | 2 +- .../genetic/core/GeneticAlgorithm.java | 37 +++++++++++++++++-- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index ef5a0d29..894895f5 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -235,7 +235,7 @@ public void run() { antStatsLogger.write("\"ant\";\"-\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(algorithmStartTime); - antStatsLogger.write("\"ant\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\"\n"); + antStatsLogger.write("\"ant\";\"-\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\"\n"); } } // Close the logger diff --git a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java index 2cd3d7b8..a7625eb9 100644 --- a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java +++ b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java @@ -20,6 +20,9 @@ import java.util.ArrayList; import java.util.List; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; + /** * Abstract class that serves as a basis for genetic algorithms * @param Type wrapped by the chromosome implementation @@ -78,16 +81,12 @@ public GeneticAlgorithm(IChromosomeFactory chromosomeFactory, ISelectionFunct @Override public void run() { long algorithmStartTime = System.currentTimeMillis(); - long generationStartTime = System.currentTimeMillis(); antStatsLogger.write("\"Algorithm_Type\";\"Generation_Number\";\"Population_Number\"" + ";\"Fitness_Value\";\"Current_Coverage\";\"Combined_Coverage\";\"Runtime\"\n"); createInitialPopulation(); - antStatsLogger.write("\"genetic\";\"" + currentGenerationNumber + "\";\"-\";\"-\";" + - "\"-\";\"-\";\""); - logCurrentRuntime(generationStartTime); while (!terminationCondition.isMet()) { evolve(); @@ -107,6 +106,7 @@ public List> getCurrentPopulation() { @Override public void createInitialPopulation() { + long generationStartTime = System.currentTimeMillis(); MATE.log_acc("Creating initial population (1st generation)"); String targetLine = Properties.TARGET_LINE(); @@ -116,6 +116,9 @@ public void createInitialPopulation() { // Log the current target line for later identification of the test antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"" + targetLine + "\"\n"); + //TODO comment + boolean successful = FALSE; + for (int i = 0; i < populationSize; i++) { long populationStartTime = System.currentTimeMillis(); @@ -130,6 +133,10 @@ public void createInitialPopulation() { population.add(chromosomeT); + if(fitnessValue == 1.0) { + successful = TRUE; + } + antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" + (i + 1) + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" + combinedCoverage + "\";\""); @@ -137,6 +144,14 @@ public void createInitialPopulation() { logCurrentRuntime(populationStartTime); } + antStatsLogger.write("\"genetic\";\"" + currentGenerationNumber + "\";\"-\";\"-\";" + + "\"-\";\"-\";\""); + logCurrentRuntime(generationStartTime); + + if(successful) { + antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\"\n"); + } + logCurrentFitness(); currentGenerationNumber++; } @@ -187,6 +202,10 @@ public void evolve() { population.clear(); population.addAll(tmp); // TODO log new generation infos + + //TODO comment + boolean successful = FALSE; + for (int i = 0; i < population.size(); i++) { IChromosome chromosome = (IChromosome) population.get(i); @@ -196,6 +215,10 @@ public void evolve() { double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); + if(fitnessValue == 1.0) { + successful = TRUE; + } + antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" + (i + 1) + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" + combinedCoverage + "\";\"-\"\n"); @@ -204,6 +227,12 @@ public void evolve() { "\"-\";\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); + if(successful) { + antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\"\n"); + } else { + antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\"\n"); + } + logCurrentFitness(); currentGenerationNumber++; } From 786c9dde19a447205ad53f11a96de25dec8ebe1a Mon Sep 17 00:00:00 2001 From: reissi01 Date: Wed, 2 Sep 2020 22:33:56 +0200 Subject: [PATCH 19/30] Added timeout after 200 Test Cases for genetic algorithm --- .../TargetLineCoveredTerminationCondition.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java b/app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java index 42d7c7b9..ba78e289 100644 --- a/app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java +++ b/app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java @@ -12,10 +12,14 @@ public class TargetLineCoveredTerminationCondition implements ITerminationCondit public static TargetLineCoveredTerminationCondition INSTANCE = null; private LineCoveredPercentageFitnessFunction lineCoveredPercentageFitnessFunction; private IGeneticAlgorithm geneticAlgorithm; + private int iterations; + private int maxIterations; public TargetLineCoveredTerminationCondition() { INSTANCE = this; lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(Properties.TARGET_LINE()); + iterations = 0; + maxIterations = 4; } public void setGeneticAlgorithm(IGeneticAlgorithm geneticAlgorithm) { @@ -29,6 +33,13 @@ public boolean isMet() { return true; } } + + iterations++; + + if(iterations==maxIterations) { + return true; + } + return false; } } \ No newline at end of file From 2c1181feb4f6632ecc9a8c32cfbfdf6cf3963a51 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Wed, 9 Sep 2020 17:08:41 +0200 Subject: [PATCH 20/30] Fixed genetic algorithm timeout and adapted logging accordingly --- .../genetic/core/GeneticAlgorithm.java | 33 ++++++++++++------- ...TargetLineCoveredTerminationCondition.java | 11 ------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java index a7625eb9..59839232 100644 --- a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java +++ b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java @@ -87,16 +87,27 @@ public void run() { createInitialPopulation(); + int iterations = 1; + boolean success = TRUE; while (!terminationCondition.isMet()) { - evolve(); - - if(terminationCondition.isMet()) { - antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\""); - logCurrentRuntime(algorithmStartTime); - antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\""); + if (iterations < 4) { + evolve(); + iterations++; + } else { + success = FALSE; + break; } } + + antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\""); + logCurrentRuntime(algorithmStartTime); + + if(success) { + antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\""); + } else { + antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\""); + } } @Override @@ -204,20 +215,19 @@ public void evolve() { // TODO log new generation infos //TODO comment - boolean successful = FALSE; + //boolean successful = FALSE; for (int i = 0; i < population.size(); i++) { IChromosome chromosome = (IChromosome) population.get(i); - LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); - double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); + /* if(fitnessValue == 1.0) { successful = TRUE; - } + }*/ antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" + (i + 1) + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" @@ -227,11 +237,12 @@ public void evolve() { "\"-\";\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); + /* if(successful) { antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\"\n"); } else { antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\"\n"); - } + }*/ logCurrentFitness(); currentGenerationNumber++; diff --git a/app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java b/app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java index ba78e289..42d7c7b9 100644 --- a/app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java +++ b/app/src/main/java/org/mate/exploration/genetic/termination/TargetLineCoveredTerminationCondition.java @@ -12,14 +12,10 @@ public class TargetLineCoveredTerminationCondition implements ITerminationCondit public static TargetLineCoveredTerminationCondition INSTANCE = null; private LineCoveredPercentageFitnessFunction lineCoveredPercentageFitnessFunction; private IGeneticAlgorithm geneticAlgorithm; - private int iterations; - private int maxIterations; public TargetLineCoveredTerminationCondition() { INSTANCE = this; lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(Properties.TARGET_LINE()); - iterations = 0; - maxIterations = 4; } public void setGeneticAlgorithm(IGeneticAlgorithm geneticAlgorithm) { @@ -33,13 +29,6 @@ public boolean isMet() { return true; } } - - iterations++; - - if(iterations==maxIterations) { - return true; - } - return false; } } \ No newline at end of file From 50de166d717244b9b5334fc3c0293322fc8c4bfe Mon Sep 17 00:00:00 2001 From: reissi01 Date: Wed, 9 Sep 2020 21:28:05 +0200 Subject: [PATCH 21/30] Fixed problem with genetic algorithm logging where double successful row would be logged if initialPopulation reached target line --- .../exploration/genetic/core/GeneticAlgorithm.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java index 59839232..3bc0575f 100644 --- a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java +++ b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java @@ -88,14 +88,14 @@ public void run() { createInitialPopulation(); int iterations = 1; - boolean success = TRUE; + boolean successful = TRUE; while (!terminationCondition.isMet()) { if (iterations < 4) { evolve(); iterations++; } else { - success = FALSE; + successful = FALSE; break; } } @@ -103,7 +103,7 @@ public void run() { antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(algorithmStartTime); - if(success) { + if(successful) { antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\""); } else { antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\""); @@ -144,10 +144,6 @@ public void createInitialPopulation() { population.add(chromosomeT); - if(fitnessValue == 1.0) { - successful = TRUE; - } - antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" + (i + 1) + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" + combinedCoverage + "\";\""); @@ -159,10 +155,6 @@ public void createInitialPopulation() { "\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); - if(successful) { - antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\"\n"); - } - logCurrentFitness(); currentGenerationNumber++; } From 442a9153ed3ce2f7bdb33d53d58350efe4316219 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Tue, 15 Sep 2020 09:26:35 +0200 Subject: [PATCH 22/30] Fixed a copy paste error resulting in a wrong log write --- .../org/mate/exploration/genetic/core/GeneticAlgorithm.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java index 3bc0575f..43d42261 100644 --- a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java +++ b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java @@ -127,9 +127,6 @@ public void createInitialPopulation() { // Log the current target line for later identification of the test antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"" + targetLine + "\"\n"); - //TODO comment - boolean successful = FALSE; - for (int i = 0; i < populationSize; i++) { long populationStartTime = System.currentTimeMillis(); @@ -151,7 +148,7 @@ public void createInitialPopulation() { logCurrentRuntime(populationStartTime); } - antStatsLogger.write("\"genetic\";\"" + currentGenerationNumber + "\";\"-\";\"-\";" + + antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"-\";\"-\";" + "\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); From 27658583e87375e052e77a3cfa2a3cfd0d71d933 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Sat, 19 Sep 2020 01:19:10 +0200 Subject: [PATCH 23/30] Modified Genetic Algorithm to stop after finding a successful TestCase, Changed the max Amount of TestCases for my used Algorithms from 200 to 400, Changed ACO PathLength to 50 to be the same as the other Algorithms, Changed GA Population size to 20 instead of 50 --- app/src/main/java/org/mate/MATE.java | 4 +- .../org/mate/exploration/ant/AntColony.java | 4 +- .../genetic/core/GeneticAlgorithm.java | 77 ++++++++++++++----- .../heuristical/RandomExploration.java | 2 +- 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/org/mate/MATE.java b/app/src/main/java/org/mate/MATE.java index 9976d985..0ecb7755 100644 --- a/app/src/main/java/org/mate/MATE.java +++ b/app/src/main/java/org/mate/MATE.java @@ -309,8 +309,8 @@ public Void call() throws Exception { .withFitnessFunction(LineCoveredPercentageFitnessFunction.FITNESS_FUNCTION_ID, Properties.TARGET_LINE()) .withTerminationCondition(TargetLineCoveredTerminationCondition.TERMINATION_CONDITION_ID) - .withPopulationSize(50) - .withBigPopulationSize(100) + .withPopulationSize(20) + .withBigPopulationSize(40) .withMaxNumEvents(50) .withPMutate(0.3) .withPCrossover(0.7) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 894895f5..367ae672 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -43,9 +43,9 @@ public class AntColony { private List> testCasesList = new ArrayList<>(); // Parameters to customize the ACO algorithm - private static final int generationAmount = 20; + private static final int generationAmount = 40; private static final int generationSize = 10; - private static final int antPathLength = 30; + private static final int antPathLength = 50; private static final double evaporationRate = 0.1; // TODO Choose appropriate deposit amount private static final double standardDepositAmount = 1.0; diff --git a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java index 43d42261..513142e8 100644 --- a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java +++ b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java @@ -43,7 +43,7 @@ public abstract class GeneticAlgorithm implements IGeneticAlgorithm { protected double pMutate; private final AntStatsLogger antStatsLogger; - + private Boolean algorithmFinished = FALSE; /** * Initializing the genetic algorithm with all necessary attributes @@ -84,19 +84,26 @@ public void run() { antStatsLogger.write("\"Algorithm_Type\";\"Generation_Number\";\"Population_Number\"" + ";\"Fitness_Value\";\"Current_Coverage\";\"Combined_Coverage\";\"Runtime\"\n"); + boolean successful = TRUE; createInitialPopulation(); int iterations = 1; - boolean successful = TRUE; - while (!terminationCondition.isMet()) { - if (iterations < 4) { - evolve(); - iterations++; - } else { - successful = FALSE; - break; + if(!algorithmFinished) { + while (!terminationCondition.isMet()) { + if (iterations < 20) { + evolve(); + + if(algorithmFinished) { + break; + } + + iterations++; + } else { + successful = FALSE; + break; + } } } @@ -141,11 +148,20 @@ public void createInitialPopulation() { population.add(chromosomeT); + MATE.log_acc("Fitness Value: " + fitnessValue); + antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" + (i + 1) + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" + combinedCoverage + "\";\""); logCurrentRuntime(populationStartTime); + + if(fitnessValue == 1.0) { + algorithmFinished = TRUE; + break; + } + + MATE.log_acc("Algorithm Finished: " + algorithmFinished); } antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"-\";\"-\";" + @@ -159,6 +175,7 @@ public void createInitialPopulation() { @Override public void evolve() { long generationStartTime = System.currentTimeMillis(); + int testCaseCount = 0; String targetLine = Properties.TARGET_LINE(); IFitnessFunction lineCoveredPercentageFitnessFunction @@ -167,7 +184,9 @@ public void evolve() { MATE.log_acc("Creating population #" + (currentGenerationNumber + 1)); List> newGeneration = new ArrayList<>(population); - while (newGeneration.size() < bigPopulationSize) { + outerLoop: while (newGeneration.size() < bigPopulationSize) { + long algorithmStartTime = System.currentTimeMillis(); + List> parents = selectionFunction.select(population, fitnessFunctions); IChromosome parent; @@ -192,7 +211,29 @@ public void evolve() { newGeneration.add(chromosome); + testCaseCount++; + + IChromosome iChromosome = (IChromosome) chromosome; + + double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(iChromosome); + double coverage = Registry.getEnvironmentManager().getCoverage(iChromosome); + double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); + + antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" + + testCaseCount + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" + + combinedCoverage + "\";\""); + logCurrentRuntime(algorithmStartTime); + + if(fitnessValue == 1.0) { + algorithmFinished = TRUE; + break outerLoop; + } } + /* + antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"-\";" + + "\"-\";\"-\";\"-\";\""); + logCurrentRuntime(algorithmStartTime); + */ } //todo: beautify later when more time @@ -203,6 +244,7 @@ public void evolve() { population.addAll(tmp); // TODO log new generation infos + /* //TODO comment //boolean successful = FALSE; @@ -213,26 +255,23 @@ public void evolve() { double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); - /* - if(fitnessValue == 1.0) { - successful = TRUE; - }*/ - antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" + (i + 1) + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" + combinedCoverage + "\";\"-\"\n"); } - antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"-\";" + - "\"-\";\"-\";\"-\";\""); - logCurrentRuntime(generationStartTime); - /* + + if(successful) { antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\"\n"); } else { antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\"\n"); }*/ + antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"-\";" + + "\"-\";\"-\";\"-\";\""); + logCurrentRuntime(generationStartTime); + logCurrentFitness(); currentGenerationNumber++; } diff --git a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java index e31a0bbd..39934b77 100644 --- a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java +++ b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java @@ -30,7 +30,7 @@ public RandomExploration(boolean storeCoverage, boolean alwaysReset, int maxNumE public void run() { long algorithmStartTime = System.currentTimeMillis(); // number of ants created in a full ACO run, generationAmount * generationSize - int antAmount = 20 * 10; + int antAmount = 40 * 10; antStatsLogger.write("\"Algorithm_Type\";\"Test_Case\";\"Fitness_Value\";" + "\"Current_Coverage\";\"Combined_Coverage\";\"Runtime\"\n"); From cc28bf8d46d586096348004acc9186b73b5c406d Mon Sep 17 00:00:00 2001 From: reissi01 Date: Tue, 22 Sep 2020 22:22:26 +0200 Subject: [PATCH 24/30] Removed unnecessary code, Added Comments in all Algorithms --- .../org/mate/exploration/ant/AntColony.java | 39 ++++++--- .../genetic/core/GeneticAlgorithm.java | 83 ++++++++++--------- .../heuristical/RandomExploration.java | 46 ++++++---- 3 files changed, 99 insertions(+), 69 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 367ae672..9df9bdd4 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -47,7 +47,6 @@ public class AntColony { private static final int generationSize = 10; private static final int antPathLength = 50; private static final double evaporationRate = 0.1; - // TODO Choose appropriate deposit amount private static final double standardDepositAmount = 1.0; /* Parameter to change the process of calculating the action probability @@ -67,12 +66,15 @@ public class AntColony { public AntColony() { uiAbstractionLayer = MATE.uiAbstractionLayer; + + // Create a logger to store collected data during the run antStatsLogger = new AntStatsLogger(); } public void run() { + // Store the start time of the algorithm for later runtime calculation long algorithmStartTime = System.currentTimeMillis(); - // TODO Print target line & coverage + //antStatsLogger.write("Start of Algorithm at " + startTime + ", "); antStatsLogger.write("\"Algorithm_Type\";\"Generation\";\"Ant\";\"Fitness_Value\";" + "\"Current_Coverage\";\"Combined_Coverage\";\"Runtime\"\n"); @@ -94,13 +96,19 @@ public void run() { // Loop to create multiple generations of ants long generationStartTime, antStartTime; outerLoop: for (int i = 0; i < generationAmount; i++) { + // Store the start time of the generation for later runtime calculation generationStartTime = System.currentTimeMillis(); + MATE.log_acc("Generation #" + (i + 1)); // Create ants and check if they reach the target line for (int z = 0; z < generationSize; z++){ + // Store the start time of the current ant for later runtime calculation antStartTime = System.currentTimeMillis(); + MATE.log_acc("Ant #" + (z + 1)); + + // Log the start of the log file line for the relevant data antStatsLogger.write("\"ant\";\"" + (i + 1) + "\";\"" + (z + 1) + "\";"); // Create an ant to traverse the app and wrap the generated testcase in a chromosome @@ -110,17 +118,18 @@ public void run() { Registry.getEnvironmentManager().storeCoverageData(chromosome, null); LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); + // Retrieve the relevant test case data double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); - System.out.println(fitnessValue); + + // Log the relevant test case data antStatsLogger.write("\"" + fitnessValue + "\";\"" + coverage + "\";\"" + combinedCoverage + "\";\""); logCurrentRuntime(antStartTime); - // Stop algorithm if target line was reached + // Stop algorithm if target line was reached and log the runtime + result if (fitnessValue == 1) { - //TODO finish necessary action for successful algorithm run (write log) antStatsLogger.write("\"ant\";\"" + (i + 1) + "\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); @@ -164,7 +173,7 @@ public void run() { } } - // Deposit pheromones for the better half of testcases. Amount steadily decreases + // Deposit pheromones for the better half of test cases. Amount steadily decreases double depositAmount = standardDepositAmount; double reductionAmount = 1 / (testCasesList.size() / 2.0); int antsAllowedToDeposit = (int) Math.ceil(testCasesList.size() / 2.0); @@ -227,10 +236,11 @@ public void run() { } } + // Log the runtime of the current generation antStatsLogger.write("\"ant\";\"" + (i + 1) + "\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); - // TODO Comment max generations reached + // Check if the max amount of generations has been reached and log the result if so if ((i + 1) == generationAmount) { antStatsLogger.write("\"ant\";\"-\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(algorithmStartTime); @@ -238,6 +248,7 @@ public void run() { antStatsLogger.write("\"ant\";\"-\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\"\n"); } } + // Close the logger antStatsLogger.close(); } @@ -373,10 +384,18 @@ private Double getActionTypeWeight (WidgetAction action) { return eventTypeWeight; } + /** + * Log the time past from a certain point in time until now + * @param startTime the start point to calculate the time difference from + */ private void logCurrentRuntime (long startTime) { + // Get the current time long currentTime = System.currentTimeMillis(); - currentTime = currentTime - startTime; - long seconds = (currentTime/(1000)); - antStatsLogger.write(seconds + "\"\n"); + + // Calculate the time difference in seconds + long secondsPast = (currentTime - startTime)/(1000); + + // Log the calculated time in the file + antStatsLogger.write(secondsPast + "\"\n"); } } diff --git a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java index 513142e8..d0cbdea6 100644 --- a/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java +++ b/app/src/main/java/org/mate/exploration/genetic/core/GeneticAlgorithm.java @@ -73,6 +73,7 @@ public GeneticAlgorithm(IChromosomeFactory chromosomeFactory, ISelectionFunct this.pCrossover = pCrossover; this.pMutate = pMutate; + // Create a logger to store collected data during the run antStatsLogger = new AntStatsLogger(); currentGenerationNumber = 0; @@ -80,25 +81,28 @@ public GeneticAlgorithm(IChromosomeFactory chromosomeFactory, ISelectionFunct @Override public void run() { + // Store the start time of the algorithm for later runtime calculation long algorithmStartTime = System.currentTimeMillis(); + + // Add the column headlines to the log file antStatsLogger.write("\"Algorithm_Type\";\"Generation_Number\";\"Population_Number\"" + ";\"Fitness_Value\";\"Current_Coverage\";\"Combined_Coverage\";\"Runtime\"\n"); - boolean successful = TRUE; - createInitialPopulation(); + boolean successful = TRUE; int iterations = 1; + // Run the algorithm unit the max amount of test cases was executed if(!algorithmFinished) { while (!terminationCondition.isMet()) { if (iterations < 20) { evolve(); + // Exit the loop if a successful test case was found if(algorithmFinished) { break; } - iterations++; } else { successful = FALSE; @@ -107,14 +111,19 @@ public void run() { } } + // Log the runtime of the algorithm antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(algorithmStartTime); + // Log the final result if(successful) { antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\""); } else { antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\""); } + + // Close the logger + antStatsLogger.close(); } @Override @@ -124,9 +133,11 @@ public List> getCurrentPopulation() { @Override public void createInitialPopulation() { + // Store the start time of the generation for later runtime calculation long generationStartTime = System.currentTimeMillis(); MATE.log_acc("Creating initial population (1st generation)"); + // Get the target line to generate a test for and initialise the fitness function String targetLine = Properties.TARGET_LINE(); IFitnessFunction lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(targetLine); @@ -135,6 +146,7 @@ public void createInitialPopulation() { antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"" + targetLine + "\"\n"); for (int i = 0; i < populationSize; i++) { + // Store the start time of the population for later runtime calculation long populationStartTime = System.currentTimeMillis(); IChromosome chromosomeT = chromosomeFactory.createChromosome(); @@ -142,6 +154,7 @@ public void createInitialPopulation() { LineCoveredPercentageFitnessFunction.retrieveFitnessValues(chromosome); + // Retrieve the relevant test case data double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); @@ -150,12 +163,13 @@ public void createInitialPopulation() { MATE.log_acc("Fitness Value: " + fitnessValue); + // Log the relevant test case data antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" + (i + 1) + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" + combinedCoverage + "\";\""); - logCurrentRuntime(populationStartTime); + // Check if the current generated test case was successful if(fitnessValue == 1.0) { algorithmFinished = TRUE; break; @@ -164,6 +178,7 @@ public void createInitialPopulation() { MATE.log_acc("Algorithm Finished: " + algorithmFinished); } + // Log the runtime for the current generation antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"-\";\"-\";" + "\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); @@ -174,9 +189,13 @@ public void createInitialPopulation() { @Override public void evolve() { + // Store the start time of the generation for later runtime calculation long generationStartTime = System.currentTimeMillis(); + + // Initialise a variable to keep track of the current test case number int testCaseCount = 0; + // Get the target line to generate a test for and initialise the fitness function String targetLine = Properties.TARGET_LINE(); IFitnessFunction lineCoveredPercentageFitnessFunction = new LineCoveredPercentageFitnessFunction(targetLine); @@ -185,7 +204,8 @@ public void evolve() { List> newGeneration = new ArrayList<>(population); outerLoop: while (newGeneration.size() < bigPopulationSize) { - long algorithmStartTime = System.currentTimeMillis(); + // Store the start time for the current test case + long testCaseStartTime = System.currentTimeMillis(); List> parents = selectionFunction.select(population, fitnessFunctions); @@ -203,7 +223,6 @@ public void evolve() { offspring = mutationFunction.mutate(parent); } - for (IChromosome chromosome : offspring) { if (newGeneration.size() == bigPopulationSize) { break; @@ -215,25 +234,23 @@ public void evolve() { IChromosome iChromosome = (IChromosome) chromosome; + // Retrieve the relevant test case data double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(iChromosome); double coverage = Registry.getEnvironmentManager().getCoverage(iChromosome); double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); + // Log the relevant test case data antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" + testCaseCount + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" + combinedCoverage + "\";\""); - logCurrentRuntime(algorithmStartTime); + logCurrentRuntime(testCaseStartTime); + // Check if the current generated test case was successful if(fitnessValue == 1.0) { algorithmFinished = TRUE; break outerLoop; } } - /* - antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"-\";" + - "\"-\";\"-\";\"-\";\""); - logCurrentRuntime(algorithmStartTime); - */ } //todo: beautify later when more time @@ -244,30 +261,7 @@ public void evolve() { population.addAll(tmp); // TODO log new generation infos - /* - //TODO comment - //boolean successful = FALSE; - - for (int i = 0; i < population.size(); i++) { - IChromosome chromosome = (IChromosome) population.get(i); - - double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); - double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); - double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); - - antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"" - + (i + 1) + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" - + combinedCoverage + "\";\"-\"\n"); - } - - - - if(successful) { - antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"successful\"\n"); - } else { - antStatsLogger.write("\"genetic\";\"-\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\"\n"); - }*/ - + // Log the runtime for the current generation antStatsLogger.write("\"genetic\";\"" + (currentGenerationNumber + 1) + "\";\"-\";" + "\"-\";\"-\";\"-\";\""); logCurrentRuntime(generationStartTime); @@ -308,11 +302,18 @@ protected void logCurrentFitness() { } } + /** + * Log the time past from a certain point in time until now + * @param startTime the start point to calculate the time difference from + */ private void logCurrentRuntime (long startTime) { + // Get the current time long currentTime = System.currentTimeMillis(); - currentTime = currentTime - startTime; - long seconds = (currentTime/(1000)); - antStatsLogger.write(seconds + "\"\n"); - } -} + // Calculate the time difference in seconds + long secondsPast = (currentTime - startTime)/(1000); + + // Log the calculated time in the file + antStatsLogger.write(secondsPast + "\"\n"); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java index 39934b77..0648c572 100644 --- a/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java +++ b/app/src/main/java/org/mate/exploration/heuristical/RandomExploration.java @@ -24,14 +24,18 @@ public RandomExploration(boolean storeCoverage, boolean alwaysReset, int maxNumE this.alwaysReset = alwaysReset; randomChromosomeFactory = new AndroidRandomChromosomeFactory(storeCoverage, alwaysReset, maxNumEvents); + // Create a logger to store collected data during the run antStatsLogger = new AntStatsLogger(); } public void run() { + // Store the start time of the algorithm for later runtime calculation long algorithmStartTime = System.currentTimeMillis(); - // number of ants created in a full ACO run, generationAmount * generationSize + + // Maximum amount of test cases equal to ants in aco, generationAmount * generationSize int antAmount = 40 * 10; + // Add the column headlines to the log file antStatsLogger.write("\"Algorithm_Type\";\"Test_Case\";\"Fitness_Value\";" + "\"Current_Coverage\";\"Combined_Coverage\";\"Runtime\"\n"); @@ -47,14 +51,14 @@ public void run() { MATE.uiAbstractionLayer.resetApp(); } + // Declare a variable for the storing of the start time for each test case long testCaseStartTime; + // Loop to create the individual test cases and log collected information during them for (int i = 0; true; i++) { MATE.log_acc("Exploration #" + (i + 1)); - //TODO REMOVE after successful implementation of aborting runs with fitness = 1 - //randomChromosomeFactory.createChromosome(); - + // Store the start time for the current test case testCaseStartTime = System.currentTimeMillis(); // Store the chromosome created in each step to calculate fitness value @@ -64,37 +68,32 @@ public void run() { MATE.uiAbstractionLayer.restartApp(); } - // TODO REMOVE - DEBUG - System.out.println(lineCoveredPercentageFitnessFunction.getFitness(chromosome)); - - - antStatsLogger.write("\"random\";\"" + (i + 1) + "\";"); - + // Retrieve the relevant test case data double fitnessValue = lineCoveredPercentageFitnessFunction.getFitness(chromosome); double coverage = Registry.getEnvironmentManager().getCoverage(chromosome); double combinedCoverage = Registry.getEnvironmentManager().getCombinedCoverage(); - antStatsLogger.write("\"" + fitnessValue + "\";\"" + + // Log the relevant test case data + antStatsLogger.write("\"random\";\"" + (i + 1) + "\";\"" + fitnessValue + "\";\"" + coverage + "\";\"" + combinedCoverage + "\";\""); - logCurrentRuntime(testCaseStartTime); - // Stop algorithm if target line was reached + // Stop algorithm if the target line or if the max amount of test cases is reached if (fitnessValue == 1) { MATE.log_acc("Random Exploration finished successfully"); + // Log algorithm runtime and results into the file antStatsLogger.write("\"random\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(algorithmStartTime); - antStatsLogger.write("\"random\";\"-\";\"-\";\"-\";\"-\";\"successful\"\n"); break; } else if (i == (antAmount - 1)) { MATE.log_acc("Random Exploration finished unsuccessfully"); + // Log algorithm runtime and results into the file antStatsLogger.write("\"random\";\"-\";\"-\";\"-\";\"-\";\""); logCurrentRuntime(algorithmStartTime); - antStatsLogger.write("\"random\";\"-\";\"-\";\"-\";\"-\";\"unsuccessful\"\n"); break; @@ -104,12 +103,23 @@ public void run() { MATE.uiAbstractionLayer.restartApp(); } } + + // Close the logger + antStatsLogger.close(); } + /** + * Log the time past from a certain point in time until now + * @param startTime the start point to calculate the time difference from + */ private void logCurrentRuntime (long startTime) { + // Get the current time long currentTime = System.currentTimeMillis(); - currentTime = currentTime - startTime; - long seconds = (currentTime/(1000)); - antStatsLogger.write(seconds + "\"\n"); + + // Calculate the time difference in seconds + long secondsPast = (currentTime - startTime)/(1000); + + // Log the calculated time in the file + antStatsLogger.write(secondsPast + "\"\n"); } } From dac0f4dc5a563ceae0b3b436fd99cd22c5b9e5fc Mon Sep 17 00:00:00 2001 From: reissi01 Date: Fri, 9 Oct 2020 09:53:58 +0200 Subject: [PATCH 25/30] Set ACO parameters to Condition 2 (ActionTypeInTransition = false, RankingDeposit = false) --- app/src/main/java/org/mate/exploration/ant/AntColony.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 9df9bdd4..4a51a946 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -62,7 +62,7 @@ public class AntColony { * deposit any pheromones * False: Only the ant with the best fitness value in a generation gets to deposit pheromones */ - private static final boolean depositPheromonesWithRanking = true; + private static final boolean depositPheromonesWithRanking = false; public AntColony() { uiAbstractionLayer = MATE.uiAbstractionLayer; From bc05672909a74fae0a594046d0886cb5cc42af9b Mon Sep 17 00:00:00 2001 From: reissi01 Date: Wed, 14 Oct 2020 11:23:45 +0200 Subject: [PATCH 26/30] Set ACO parameters to Condition 3 (ActionTypeInTransition = true, RankingDeposit = false) --- app/src/main/java/org/mate/exploration/ant/AntColony.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 4a51a946..54d53c90 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -54,7 +54,7 @@ public class AntColony { * multiplying it with the weight of the action (depending on the action type) * False: Only use the pheromone value of the action as the probability */ - private static final boolean includeActionTypeInTransition = false; + private static final boolean includeActionTypeInTransition = true; /* Parameter to change the process of depositing pheromones. * True: Rank all ants in a generation according to the fitness value of their testcase. From 35f5a2fc5dcd3dedfa239f74ad54a909769363e1 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Wed, 21 Oct 2020 17:54:47 +0200 Subject: [PATCH 27/30] Set ACO parameters to Condition 4 (ActionTypeInTransition = true, RankingDeposit = true) --- app/src/main/java/org/mate/exploration/ant/AntColony.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 54d53c90..da957754 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -62,7 +62,7 @@ public class AntColony { * deposit any pheromones * False: Only the ant with the best fitness value in a generation gets to deposit pheromones */ - private static final boolean depositPheromonesWithRanking = false; + private static final boolean depositPheromonesWithRanking = true; public AntColony() { uiAbstractionLayer = MATE.uiAbstractionLayer; From f3e12b1b4dbb5fff5431e829f3725356d7150c7c Mon Sep 17 00:00:00 2001 From: reissi01 Date: Sun, 8 Nov 2020 11:08:51 +0100 Subject: [PATCH 28/30] Set ACO parameters to new Condition 2 (ActionTypeInTransition = true, RankingDeposit = false) --- app/src/main/java/org/mate/exploration/ant/AntColony.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index da957754..54d53c90 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -62,7 +62,7 @@ public class AntColony { * deposit any pheromones * False: Only the ant with the best fitness value in a generation gets to deposit pheromones */ - private static final boolean depositPheromonesWithRanking = true; + private static final boolean depositPheromonesWithRanking = false; public AntColony() { uiAbstractionLayer = MATE.uiAbstractionLayer; From 93acd9b83ecd31174ae03f2817afa36dd6ba170f Mon Sep 17 00:00:00 2001 From: reissi01 Date: Mon, 16 Nov 2020 08:01:02 +0100 Subject: [PATCH 29/30] Set ACO parameters to new Condition 3 (ActionTypeInTransition = false, RankingDeposit = true) --- app/src/main/java/org/mate/exploration/ant/AntColony.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 54d53c90..9df9bdd4 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -54,7 +54,7 @@ public class AntColony { * multiplying it with the weight of the action (depending on the action type) * False: Only use the pheromone value of the action as the probability */ - private static final boolean includeActionTypeInTransition = true; + private static final boolean includeActionTypeInTransition = false; /* Parameter to change the process of depositing pheromones. * True: Rank all ants in a generation according to the fitness value of their testcase. @@ -62,7 +62,7 @@ public class AntColony { * deposit any pheromones * False: Only the ant with the best fitness value in a generation gets to deposit pheromones */ - private static final boolean depositPheromonesWithRanking = false; + private static final boolean depositPheromonesWithRanking = true; public AntColony() { uiAbstractionLayer = MATE.uiAbstractionLayer; From d62aab2fd9c7e2a4d1af82fa85db8736d2e4f123 Mon Sep 17 00:00:00 2001 From: reissi01 Date: Sat, 21 Nov 2020 11:13:30 +0100 Subject: [PATCH 30/30] Set ACO parameters to new Condition 4 (ActionTypeInTransition = false, RankingDeposit = false) --- app/src/main/java/org/mate/exploration/ant/AntColony.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/mate/exploration/ant/AntColony.java b/app/src/main/java/org/mate/exploration/ant/AntColony.java index 9df9bdd4..4a51a946 100644 --- a/app/src/main/java/org/mate/exploration/ant/AntColony.java +++ b/app/src/main/java/org/mate/exploration/ant/AntColony.java @@ -62,7 +62,7 @@ public class AntColony { * deposit any pheromones * False: Only the ant with the best fitness value in a generation gets to deposit pheromones */ - private static final boolean depositPheromonesWithRanking = true; + private static final boolean depositPheromonesWithRanking = false; public AntColony() { uiAbstractionLayer = MATE.uiAbstractionLayer;