diff --git a/.travis.yml b/.travis.yml index dd479ff414..243bee2509 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: include: - stage: compile script: - - "./gradlew build -x test" + - "./gradlew build -x test -x signArchives" - stage: analysis addons: sonarcloud: @@ -33,9 +33,9 @@ jobs: - ./gradlew compileJava - ./gradlew testClasses - ./gradlew sonarqube -x test - - stage: deploy - script: - - "./gradlew publish -PnexusBaseUrl=$nexusBaseUrl -PnexusUpRepo=$nexusUpRepo -PnexusUser=$nexusUser -PnexusPassword=$nexusPassword" + #- stage: deploy + #script: + #- "./gradlew publish -PnexusBaseUrl=$nexusBaseUrl -PnexusUpRepo=$nexusUpRepo -PnexusUser=$nexusUser -PnexusPassword=$nexusPassword" env: global: - secure: FkCxTnMbWP3Whd61puUXI6VJhhhXTeFby0k2Rmq01dYZN8asZ1FCoQFw1dEOlcx7dWLYFvb1feSmi7YOW+u6WznrbORu41NWFpA5VvGJyPkrsrhNN6xaNy7PNfFCMjmhZqcOAUoCCDwGzyUe17qoip1NfjNiIIFa+G6HNATUaODeGBtDBYpKVw3tvzM/rz14cIx2U4wF1WphxaIME3X5pzBNm0JK0NsYOZOHpb96O5t0lVkQXFgsm2A7Q0yWV+fGENoqfHZlnKmuiXjd7VJDNl9VMPjCLbcgVeN7O7OSzOQ9Omb9YwesV2nMUPEX6g2/v9yzFOoDpghtKEU9jZaLpIfmHsRafCNx0jBdy482cjznfEYaowT4CG/lGi4tT8gMYxzJGsT8TAdHoyzX7ZZUJsY+LWqb0K45YTup51Ynbuz2xeGzWo6Ydm9kYeuBcmcMwEjXFcSubalobT3JGlKUIgW9abEUfTWZwuhAzsRJ6uzB2N7pVqC/MyGXvnDJcQNDObHlmeKA0pWqZ9yIWYxHqByuwWfs+Ac63XJOk1qboWBfRXQhTWI9qQPV1W1j0kHU4S+MA2vPS1P7evzcU+Ci/YdCDwONiZ8Df1mevV3U8uZPmMcb5rgJ2YQT7xlSahTE1n7St8SroP6vFdiCgKuj8RRAIn9IZM6uTBAN1dKyDxQ= diff --git a/.travis_push_javadoc.sh b/.travis_push_javadoc.sh deleted file mode 100644 index 22b1ffc9e1..0000000000 --- a/.travis_push_javadoc.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh - -generate_javadoc() { - - echo "Generating JavaDoc" - ./gradlew generateJavadoc - - echo "Removing lines that indicate the timestamp of creation to avoid unncessary change sets" - sed -i '/Generated by javadoc/d' `find -type f -follow | grep -v .travis` - sed -i '/meta name="date" content/d' `find -type f -follow | grep -v .travis` - -} - -setup_git() { - git config --global user.email "travis@travis-ci.org" - git config --global user.name "Travis CI" -} - -commit_website_files() { - git remote add origin-pages https://${GH_TOKEN}@github.com/fmohr/AILibs.git > /dev/null 2>&1 - if [ -z "${TRAVIS_PULL_REQUEST_BRANCH}" ]; then - echo "This is not a pull request check, so not pushing back the built JavaDoc" - exit - fi - echo "Last commit message was ${TRAVIS_COMMIT_MESSAGE}" - echo "Travis branch is \"${TRAVIS_BRANCH}\"" - echo "Travis pull request branch is \"${TRAVIS_PULL_REQUEST_BRANCH}\"" - echo "Checking out ${TRAVIS_PULL_REQUEST_BRANCH}, which is the source here" - git checkout -B ${TRAVIS_PULL_REQUEST_BRANCH} - echo "Staging changes on .html, .css, and .js-files" - git add ./\*.html - git add ./\*.css - git add ./\*.js - git add ./\*package-list - - echo "Change set is as follows:" - git status - - echo "Sending commit" - git commit --message "Travis built JavaDoc. ]ci skip[" > commit.out - - echo "Output of commit log file:" - cat commit.out - echo "Now deciding how to proceed ..." - - # if nothing has been commited, avoid a push - if grep -q "nothing to commit" "commit.out"; then - echo "Nothing comitted, canceling script here to avoid unnecessary push". - exit 0; - fi - if grep -q "nothing added to commit" "commit.out"; then - echo "Nothing comitted, canceling script here to avoid unnecessary push". - exit 0; - fi - echo "Apparently there are changes, so pushing to upstream" -} - -upload_files() { - echo "Pushing commit to upstream ..." - git push --set-upstream origin-pages -} - -setup_git -generate_javadoc -commit_website_files -upload_files diff --git a/JAICore/jaicore-basic/build.gradle b/JAICore/jaicore-basic/build.gradle index 13671e6fd1..8ca2f5bb8c 100644 --- a/JAICore/jaicore-basic/build.gradle +++ b/JAICore/jaicore-basic/build.gradle @@ -8,12 +8,15 @@ dependencies { uploadArchives { repositories { mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } pom.project { @@ -49,8 +52,8 @@ uploadArchives { } developer { id 'ahetzer' - name 'Alexander Hetzer' - email 'alexander.hetzer@upb.de' + name 'Alexander Tornede' + email 'alexander.tornede@upb.de' } } } diff --git a/JAICore/jaicore-basic/conf/log4j.xml b/JAICore/jaicore-basic/conf/log4j.xml index 39ea0f0c5e..6493fcb4cb 100644 --- a/JAICore/jaicore-basic/conf/log4j.xml +++ b/JAICore/jaicore-basic/conf/log4j.xml @@ -46,7 +46,7 @@ - + @@ -55,19 +55,19 @@ - + - + - + - + diff --git a/JAICore/jaicore-basic/resources/testrsc/dummy.resource b/JAICore/jaicore-basic/resources/ai/libs/jaicore/basic/testrsc/dummy.resource similarity index 100% rename from JAICore/jaicore-basic/resources/testrsc/dummy.resource rename to JAICore/jaicore-basic/resources/ai/libs/jaicore/basic/testrsc/dummy.resource diff --git a/JAICore/jaicore-basic/resources/ai/libs/jaicore/basic/testrsc/dummy2.resource b/JAICore/jaicore-basic/resources/ai/libs/jaicore/basic/testrsc/dummy2.resource new file mode 100644 index 0000000000..3ffe139819 --- /dev/null +++ b/JAICore/jaicore-basic/resources/ai/libs/jaicore/basic/testrsc/dummy2.resource @@ -0,0 +1 @@ +Lorem ipsum dolor sit amet. \ No newline at end of file diff --git a/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/FileUtil.java b/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/FileUtil.java index f7c825aedd..8d90e4964c 100644 --- a/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/FileUtil.java +++ b/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/FileUtil.java @@ -43,7 +43,11 @@ private FileUtil() { } public static List readFileAsList(final File file) throws IOException { - return readFileAsList(file.getAbsolutePath()); + if (file instanceof ResourceFile) { + return ResourceUtil.readResourceFileToStringList((ResourceFile) file); + } else { + return readFileAsList(file.getAbsolutePath()); + } } public static List readFileAsList(final String filename) throws IOException { @@ -180,6 +184,10 @@ public static Properties readPropertiesFile(final File propertiesFile) throws IO */ public static void requireFileExists(final File file) throws FileIsDirectoryException, FileNotFoundException { Objects.requireNonNull(file); + if (file instanceof ResourceFile) { + return; + } + if (!file.exists()) { throw new FileNotFoundException("File " + file.getAbsolutePath() + " does not exist"); } @@ -207,6 +215,7 @@ public static File getExistingFileWithHighestPriority(final String resourcePath, } } } + return ResourceUtil.getResourceAsFile(resourcePath); } } diff --git a/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/LoadResourceAsFileFailedException.java b/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/LoadResourceAsFileFailedException.java new file mode 100644 index 0000000000..674b952c48 --- /dev/null +++ b/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/LoadResourceAsFileFailedException.java @@ -0,0 +1,13 @@ +package ai.libs.jaicore.basic; + +public class LoadResourceAsFileFailedException extends RuntimeException { + + public LoadResourceAsFileFailedException(final String msg) { + super(msg); + } + + public LoadResourceAsFileFailedException(final String msg, final Throwable cause) { + super(msg, cause); + } + +} diff --git a/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/ResourceFile.java b/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/ResourceFile.java new file mode 100644 index 0000000000..dc8ff5866e --- /dev/null +++ b/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/ResourceFile.java @@ -0,0 +1,76 @@ +package ai.libs.jaicore.basic; + +import java.io.File; +import java.io.InputStream; +import java.util.LinkedList; +import java.util.List; + +import ai.libs.jaicore.basic.sets.SetUtil; + +public class ResourceFile extends File { + + /** + * + */ + private static final long serialVersionUID = -404232145050366072L; + private final String pathName; + + public ResourceFile(final String pathname) { + super(pathname); + this.pathName = pathname; + } + + public ResourceFile(final ResourceFile baseFile, final String pathname) { + super(getPathName(baseFile, pathname)); + this.pathName = getPathName(baseFile, pathname); + } + + private static String getPathName(final ResourceFile baseFile, final String pathName) { + List pathConstruct = new LinkedList<>(); + List concatPaths = new LinkedList<>(); + + concatPaths.addAll(SetUtil.explode(baseFile.getPathName(), "/")); + concatPaths.addAll(SetUtil.explode(pathName, "/")); + + for (String pathElement : concatPaths) { + if (pathElement.equals(".")) { + continue; + } else if (pathElement.equals("..")) { + if (pathConstruct.isEmpty()) { + throw new IllegalArgumentException("Cannot construct path from " + baseFile.getPathName() + " and " + pathName); + } else { + pathConstruct.remove(pathConstruct.size() - 1); + } + } else { + pathConstruct.add(pathElement); + } + } + + return SetUtil.implode(pathConstruct, "/"); + } + + public InputStream getInputStream() { + return this.getClass().getClassLoader().getResourceAsStream(this.pathName); + } + + public final String getPathName() { + return this.pathName; + } + + @Override + public final ResourceFile getParentFile() { + List stringList = SetUtil.explode(this.pathName, "/"); + if (stringList.size() >= 1) { + stringList.remove(stringList.size() - 1); + return new ResourceFile(SetUtil.implode(stringList, "/")); + } else { + return null; + } + } + + @Override + public boolean exists() { + return true; + } + +} diff --git a/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/ResourceUtil.java b/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/ResourceUtil.java index 4f765bbb5e..284cf23710 100644 --- a/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/ResourceUtil.java +++ b/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/ResourceUtil.java @@ -1,13 +1,17 @@ package ai.libs.jaicore.basic; import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; import java.util.LinkedList; import java.util.List; +import ai.libs.jaicore.basic.sets.SetUtil; + /** * Utils for handling resource access in a more convenient way. * @@ -27,14 +31,7 @@ private ResourceUtil() { * @throws IOException Throws an IOException if the file could not be read. */ public static String readResourceFileToString(final String path) throws IOException { - StringBuilder sb = new StringBuilder(); - try (BufferedReader br = new BufferedReader(new FileReader(getResourceAsFile(path)))) { - String line; - while ((line = br.readLine()) != null) { - sb.append(line + "\n"); - } - } - return sb.toString(); + return SetUtil.implode(readResourceFileToStringList(path), "\n"); } /** @@ -43,11 +40,10 @@ public static String readResourceFileToString(final String path) throws IOExcept * @param path The path of the resource that shall be read. * @return The contents of the resource parsed to a string. * @throws IOException Throws an IOException if the file could not be read. - * @throws FileNotFoundException Thrown if the file could not be found. */ public static List readResourceFileToStringList(final String path) throws IOException { List list = new LinkedList<>(); - try (BufferedReader br = new BufferedReader(new FileReader(getResourceAsFile(path)))) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(ResourceUtil.class.getClassLoader().getResourceAsStream(path)))) { String line; while ((line = br.readLine()) != null) { list.add(line); @@ -56,14 +52,55 @@ public static List readResourceFileToStringList(final String path) throw return list; } + /** + * Reads the contents of a resource to a list of strings. + * + * @param resourceFile The resource file to read. + * @return The contents of the resource parsed to a string. + * @throws IOException Throws an IOException if the file could not be read. + */ + public static List readResourceFileToStringList(final ResourceFile resourceFile) throws IOException { + return readResourceFileToStringList(resourceFile.getPathName()); + } + /** * Returns the file corresponding to the given path. * * @param path The path for which a resource shall be retrieved. * @return The resource file corresponding to the given path. + * @throws IOException */ - public static File getResourceAsFile(final String path) { - return new File(ResourceUtil.class.getClassLoader().getResource(path).getFile()); + public static ResourceFile getResourceAsFile(final String path) { + return new ResourceFile(path); + } + + /** + * Returns the file corresponding to the given path. + * + * @param path The path for which a resource shall be retrieved. + * @return The resource file corresponding to the given path. + * @throws IOException + */ + public static URL getResourceAsURL(final String path) { + return ResourceUtil.class.getClassLoader().getResource(path); + } + + /** + * Creates a temporary file from the resource to load. + * @param resourcePath The path to the resource. + * @return The canonical path to the temporary file reflecting the contents of the resource. + */ + public static String getResourceAsTempFile(final String resourcePath) { + try { + File tempFile = File.createTempFile("ai.libs-", ".res"); + tempFile.deleteOnExit(); + try (BufferedWriter bw = new BufferedWriter(new FileWriter(tempFile))) { + bw.write(ResourceUtil.readResourceFileToString(resourcePath)); + } + return tempFile.getCanonicalPath(); + } catch (IOException e) { + throw new LoadResourceAsFileFailedException("Could not load resource as a temporary file", e); + } } } diff --git a/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/algorithm/IAlgorithmConfig.java b/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/algorithm/IAlgorithmConfig.java index 3a73a92968..bba89079ff 100644 --- a/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/algorithm/IAlgorithmConfig.java +++ b/JAICore/jaicore-basic/src/main/java/ai/libs/jaicore/basic/algorithm/IAlgorithmConfig.java @@ -12,6 +12,8 @@ import ai.libs.jaicore.basic.FileUtil; import ai.libs.jaicore.basic.PropertiesLoadFailedException; +import ai.libs.jaicore.basic.ResourceFile; +import ai.libs.jaicore.basic.ResourceUtil; public interface IAlgorithmConfig extends Mutable { @@ -54,11 +56,28 @@ public interface IAlgorithmConfig extends Mutable { * @throws IOException Throws an IOException if an issue occurs while reading in the properties from the given file. */ default IAlgorithmConfig loadPropertiesFromFile(final File file) { - if (!file.exists() || !file.isFile()) { - throw new IllegalArgumentException("File (" + file.getAbsolutePath() + ") to load properties from does not exist or is not a file."); + if (!(file instanceof ResourceFile) && !file.exists()) { + throw new IllegalArgumentException("File (" + file + ") to load properties from does not exist."); } try { - return loadPropertiesFromList(FileUtil.readFileAsList(file)); + if (file instanceof ResourceFile) { + return loadPropertiesFromList(ResourceUtil.readResourceFileToStringList((ResourceFile) file)); + } else { + return loadPropertiesFromList(FileUtil.readFileAsList(file)); + } + } catch (IOException e) { + throw new PropertiesLoadFailedException("Could not load properties from the given file.", e); + } + } + + /** + * Reads properties of a config from a config file. + * @param file The file to read in as properties. + * @throws IOException Throws an IOException if an issue occurs while reading in the properties from the given file. + */ + default IAlgorithmConfig loadPropertiesFromPath(final String path) { + try { + return loadPropertiesFromList(FileUtil.readFileAsList(path)); } catch (IOException e) { throw new PropertiesLoadFailedException("Could not load properties from the given file.", e); } diff --git a/JAICore/jaicore-basic/src/test/java/ai/libs/jaicore/basic/ResourceUtilTest.java b/JAICore/jaicore-basic/src/test/java/ai/libs/jaicore/basic/ResourceUtilTest.java index fe58a3bb68..bd05a2db37 100644 --- a/JAICore/jaicore-basic/src/test/java/ai/libs/jaicore/basic/ResourceUtilTest.java +++ b/JAICore/jaicore-basic/src/test/java/ai/libs/jaicore/basic/ResourceUtilTest.java @@ -3,14 +3,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStreamReader; import org.junit.Test; -import ai.libs.jaicore.basic.ResourceUtil; - /** * This test checks the basic functionalities provided by the ResourceUtil class which provides a convenient API for handling resource files. * @@ -18,7 +18,7 @@ */ public class ResourceUtilTest { - private static final String RESOURCE_FILE_PATH = "testrsc/dummy.resource"; + private static final String RESOURCE_FILE_PATH = "ai/libs/jaicore/basic/testrsc/dummy.resource"; private static final String EXPECTED_CONTENT = "Lorem ipsum dolor sit amet."; /** @@ -42,4 +42,29 @@ public void testGetResourceAsFile() { assertTrue("The file returned is not a file but a directory.", !resourceFile.isDirectory()); } + @Test + public void test() { + ResourceFile resFile = ResourceUtil.getResourceAsFile(RESOURCE_FILE_PATH); + this.readRes(resFile.getPathName()); + + ResourceFile res2File = new ResourceFile(resFile.getParentFile(), "dummy2.resource"); + + this.readRes(resFile.getPathName()); + this.readRes(res2File.getPathName()); + } + + private void readRes(final String path) { + System.out.println("READ " + path); + System.out.println(this.getClass().getClassLoader().getResourceAsStream(path)); + + try (BufferedReader br = new BufferedReader(new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream(path)))) { + String line; + while ((line = br.readLine()) != null) { + System.out.println(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } diff --git a/JAICore/jaicore-ea/build.gradle b/JAICore/jaicore-ea/build.gradle index 0e282e7918..929044b6c4 100644 --- a/JAICore/jaicore-ea/build.gradle +++ b/JAICore/jaicore-ea/build.gradle @@ -6,12 +6,15 @@ dependencies { uploadArchives { repositories { mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } pom.project { @@ -47,8 +50,8 @@ uploadArchives { } developer { id 'ahetzer' - name 'Alexander Hetzer' - email 'alexander.hetzer@upb.de' + name 'Alexander Tornede' + email 'alexander.tornede@upb.de' } } } diff --git a/JAICore/jaicore-experiments/build.gradle b/JAICore/jaicore-experiments/build.gradle index 7d8eb71213..74c3b33847 100644 --- a/JAICore/jaicore-experiments/build.gradle +++ b/JAICore/jaicore-experiments/build.gradle @@ -17,12 +17,15 @@ dependencies { uploadArchives { repositories { mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } pom.project { @@ -58,8 +61,8 @@ uploadArchives { } developer { id 'ahetzer' - name 'Alexander Hetzer' - email 'alexander.hetzer@upb.de' + name 'Alexander Tornede' + email 'alexander.tornede@upb.de' } } } diff --git a/JAICore/jaicore-experiments/conf/log4j.xml b/JAICore/jaicore-experiments/conf/log4j.xml index 3310cac0db..d7e4aa59e7 100644 --- a/JAICore/jaicore-experiments/conf/log4j.xml +++ b/JAICore/jaicore-experiments/conf/log4j.xml @@ -46,7 +46,7 @@ - + @@ -55,7 +55,7 @@ - + \ No newline at end of file diff --git a/JAICore/jaicore-graphvisualizer/build.gradle b/JAICore/jaicore-graphvisualizer/build.gradle index a5b9aaddf1..605c74da71 100644 --- a/JAICore/jaicore-graphvisualizer/build.gradle +++ b/JAICore/jaicore-graphvisualizer/build.gradle @@ -1,77 +1,80 @@ -plugins { - id 'java' - id 'eclipse' - //id 'application' - //id 'org.openjfx.javafxplugin' version '0.0.5' -} -eclipse { - classpath { - downloadJavadoc = true - downloadSources = true - } -} -dependencies { - compile project(":JAICore:jaicore-basic") - - compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.7' - - implementation 'com.github.mwever:gs-core:2.0.2-synchrofix' - implementation 'com.github.graphstream:gs-ui-javafx:2.0-alpha' - implementation 'com.github.graphstream:gs-algo:2.0-alpha' - -} -//javafx { -// modules = [ 'javafx.controls', 'javafx.swing', 'javafx.web' ] -//} -uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") - } - snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") - } - - pom.project { - name 'JAICore-Graphvisualizer' - packaging 'jar' - // optionally artifactId can be defined here - description 'Thist project provides a graphical interface for visualizing algorithms (especially search and AutoML algorithms) contained in AILibs.' - url 'https://libs.ai' - - scm { - connection 'scm:git:https://github.com/fmohr/AILibs.git' - developerConnection 'scm:git:https://github.com/fmohr/AILibs.git' - url 'https://github.com/fmohr/AILibs' - } - - licenses { - license { - name 'GPLv3' - url 'https://www.gnu.org/licenses/gpl-3.0.en.html' - } - } - - developers { - developer { - id 'fmohr' - name 'Felix Mohr' - email 'felix.mohr@upb.de' - } - developer { - id 'mwever' - name 'Marcel Wever' - email 'marcel.wever@upb.de' - } - developer { - id 'ahetzer' - name 'Alexander Hetzer' - email 'alexander.hetzer@upb.de' - } - } - } - } - } +plugins { + id 'java' + id 'eclipse' + //id 'application' + //id 'org.openjfx.javafxplugin' version '0.0.5' +} +eclipse { + classpath { + downloadJavadoc = true + downloadSources = true + } +} +dependencies { + compile project(":JAICore:jaicore-basic") + + compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.7' + + implementation 'com.github.mwever:gs-core:2.0.2-synchrofix' + implementation 'com.github.graphstream:gs-ui-javafx:2.0-alpha' + implementation 'com.github.graphstream:gs-algo:2.0-alpha' + +} +//javafx { +// modules = [ 'javafx.controls', 'javafx.swing', 'javafx.web' ] +//} +uploadArchives { + repositories { + mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + + pom.project { + name 'JAICore-Graphvisualizer' + packaging 'jar' + // optionally artifactId can be defined here + description 'Thist project provides a graphical interface for visualizing algorithms (especially search and AutoML algorithms) contained in AILibs.' + url 'https://libs.ai' + + scm { + connection 'scm:git:https://github.com/fmohr/AILibs.git' + developerConnection 'scm:git:https://github.com/fmohr/AILibs.git' + url 'https://github.com/fmohr/AILibs' + } + + licenses { + license { + name 'GPLv3' + url 'https://www.gnu.org/licenses/gpl-3.0.en.html' + } + } + + developers { + developer { + id 'fmohr' + name 'Felix Mohr' + email 'felix.mohr@upb.de' + } + developer { + id 'mwever' + name 'Marcel Wever' + email 'marcel.wever@upb.de' + } + developer { + id 'ahetzer' + name 'Alexander Tornede' + email 'alexander.tornede@upb.de' + } + } + } + } + } } \ No newline at end of file diff --git a/JAICore/jaicore-graphvisualizer/conf/heatmap.css b/JAICore/jaicore-graphvisualizer/conf/heatmap.css new file mode 100644 index 0000000000..3d4641fbf1 --- /dev/null +++ b/JAICore/jaicore-graphvisualizer/conf/heatmap.css @@ -0,0 +1,2060 @@ +edge { + padding: 100px; + } + +node { + size-mode: fit; + fill-mode: plain; + fill-color: grey; + padding: 5px; +} + +node.root { + padding: 10px; + fill-color:black; +} + +node.n0 { + fill-color: rgb(0,00,255); +} + +node.n1 { + fill-color: rgb(1,00,255); +} + +node.n2 { + fill-color: rgb(2,00,255); +} + +node.n3 { + fill-color: rgb(3,00,255); +} + +node.n4 { + fill-color: rgb(4,00,255); +} + +node.n5 { + fill-color: rgb(5,00,255); +} + +node.n6 { + fill-color: rgb(6,00,255); +} + +node.n7 { + fill-color: rgb(7,00,255); +} + +node.n8 { + fill-color: rgb(8,00,255); +} + +node.n9 { + fill-color: rgb(9,00,255); +} + +node.n10 { + fill-color: rgb(10,00,255); +} + +node.n11 { + fill-color: rgb(11,00,255); +} + +node.n12 { + fill-color: rgb(12,00,255); +} + +node.n13 { + fill-color: rgb(13,00,255); +} + +node.n14 { + fill-color: rgb(14,00,255); +} + +node.n15 { + fill-color: rgb(15,00,255); +} + +node.n16 { + fill-color: rgb(16,00,255); +} + +node.n17 { + fill-color: rgb(17,00,255); +} + +node.n18 { + fill-color: rgb(18,00,255); +} + +node.n19 { + fill-color: rgb(19,00,255); +} + +node.n20 { + fill-color: rgb(20,00,255); +} + +node.n21 { + fill-color: rgb(21,00,255); +} + +node.n22 { + fill-color: rgb(22,00,255); +} + +node.n23 { + fill-color: rgb(23,00,255); +} + +node.n24 { + fill-color: rgb(24,00,255); +} + +node.n25 { + fill-color: rgb(25,00,255); +} + +node.n26 { + fill-color: rgb(26,00,255); +} + +node.n27 { + fill-color: rgb(27,00,255); +} + +node.n28 { + fill-color: rgb(28,00,255); +} + +node.n29 { + fill-color: rgb(29,00,255); +} + +node.n30 { + fill-color: rgb(30,00,255); +} + +node.n31 { + fill-color: rgb(31,00,255); +} + +node.n32 { + fill-color: rgb(32,00,255); +} + +node.n33 { + fill-color: rgb(33,00,255); +} + +node.n34 { + fill-color: rgb(34,00,255); +} + +node.n35 { + fill-color: rgb(35,00,255); +} + +node.n36 { + fill-color: rgb(36,00,255); +} + +node.n37 { + fill-color: rgb(37,00,255); +} + +node.n38 { + fill-color: rgb(38,00,255); +} + +node.n39 { + fill-color: rgb(39,00,255); +} + +node.n40 { + fill-color: rgb(40,00,255); +} + +node.n41 { + fill-color: rgb(41,00,255); +} + +node.n42 { + fill-color: rgb(42,00,255); +} + +node.n43 { + fill-color: rgb(43,00,255); +} + +node.n44 { + fill-color: rgb(44,00,255); +} + +node.n45 { + fill-color: rgb(45,00,255); +} + +node.n46 { + fill-color: rgb(46,00,255); +} + +node.n47 { + fill-color: rgb(47,00,255); +} + +node.n48 { + fill-color: rgb(48,00,255); +} + +node.n49 { + fill-color: rgb(49,00,255); +} + +node.n50 { + fill-color: rgb(50,00,255); +} + +node.n51 { + fill-color: rgb(51,00,255); +} + +node.n52 { + fill-color: rgb(52,00,255); +} + +node.n53 { + fill-color: rgb(53,00,255); +} + +node.n54 { + fill-color: rgb(54,00,255); +} + +node.n55 { + fill-color: rgb(55,00,255); +} + +node.n56 { + fill-color: rgb(56,00,255); +} + +node.n57 { + fill-color: rgb(57,00,255); +} + +node.n58 { + fill-color: rgb(58,00,255); +} + +node.n59 { + fill-color: rgb(59,00,255); +} + +node.n60 { + fill-color: rgb(60,00,255); +} + +node.n61 { + fill-color: rgb(61,00,255); +} + +node.n62 { + fill-color: rgb(62,00,255); +} + +node.n63 { + fill-color: rgb(63,00,255); +} + +node.n64 { + fill-color: rgb(64,00,255); +} + +node.n65 { + fill-color: rgb(65,00,255); +} + +node.n66 { + fill-color: rgb(66,00,255); +} + +node.n67 { + fill-color: rgb(67,00,255); +} + +node.n68 { + fill-color: rgb(68,00,255); +} + +node.n69 { + fill-color: rgb(69,00,255); +} + +node.n70 { + fill-color: rgb(70,00,255); +} + +node.n71 { + fill-color: rgb(71,00,255); +} + +node.n72 { + fill-color: rgb(72,00,255); +} + +node.n73 { + fill-color: rgb(73,00,255); +} + +node.n74 { + fill-color: rgb(74,00,255); +} + +node.n75 { + fill-color: rgb(75,00,255); +} + +node.n76 { + fill-color: rgb(76,00,255); +} + +node.n77 { + fill-color: rgb(77,00,255); +} + +node.n78 { + fill-color: rgb(78,00,255); +} + +node.n79 { + fill-color: rgb(79,00,255); +} + +node.n80 { + fill-color: rgb(80,00,255); +} + +node.n81 { + fill-color: rgb(81,00,255); +} + +node.n82 { + fill-color: rgb(82,00,255); +} + +node.n83 { + fill-color: rgb(83,00,255); +} + +node.n84 { + fill-color: rgb(84,00,255); +} + +node.n85 { + fill-color: rgb(85,00,255); +} + +node.n86 { + fill-color: rgb(86,00,255); +} + +node.n87 { + fill-color: rgb(87,00,255); +} + +node.n88 { + fill-color: rgb(88,00,255); +} + +node.n89 { + fill-color: rgb(89,00,255); +} + +node.n90 { + fill-color: rgb(90,00,255); +} + +node.n91 { + fill-color: rgb(91,00,255); +} + +node.n92 { + fill-color: rgb(92,00,255); +} + +node.n93 { + fill-color: rgb(93,00,255); +} + +node.n94 { + fill-color: rgb(94,00,255); +} + +node.n95 { + fill-color: rgb(95,00,255); +} + +node.n96 { + fill-color: rgb(96,00,255); +} + +node.n97 { + fill-color: rgb(97,00,255); +} + +node.n98 { + fill-color: rgb(98,00,255); +} + +node.n99 { + fill-color: rgb(99,00,255); +} + +node.n100 { + fill-color: rgb(100,00,255); +} + +node.n101 { + fill-color: rgb(101,00,255); +} + +node.n102 { + fill-color: rgb(102,00,255); +} + +node.n103 { + fill-color: rgb(103,00,255); +} + +node.n104 { + fill-color: rgb(104,00,255); +} + +node.n105 { + fill-color: rgb(105,00,255); +} + +node.n106 { + fill-color: rgb(106,00,255); +} + +node.n107 { + fill-color: rgb(107,00,255); +} + +node.n108 { + fill-color: rgb(108,00,255); +} + +node.n109 { + fill-color: rgb(109,00,255); +} + +node.n110 { + fill-color: rgb(110,00,255); +} + +node.n111 { + fill-color: rgb(111,00,255); +} + +node.n112 { + fill-color: rgb(112,00,255); +} + +node.n113 { + fill-color: rgb(113,00,255); +} + +node.n114 { + fill-color: rgb(114,00,255); +} + +node.n115 { + fill-color: rgb(115,00,255); +} + +node.n116 { + fill-color: rgb(116,00,255); +} + +node.n117 { + fill-color: rgb(117,00,255); +} + +node.n118 { + fill-color: rgb(118,00,255); +} + +node.n119 { + fill-color: rgb(119,00,255); +} + +node.n120 { + fill-color: rgb(120,00,255); +} + +node.n121 { + fill-color: rgb(121,00,255); +} + +node.n122 { + fill-color: rgb(122,00,255); +} + +node.n123 { + fill-color: rgb(123,00,255); +} + +node.n124 { + fill-color: rgb(124,00,255); +} + +node.n125 { + fill-color: rgb(125,00,255); +} + +node.n126 { + fill-color: rgb(126,00,255); +} + +node.n127 { + fill-color: rgb(127,00,255); +} + +node.n128 { + fill-color: rgb(128,00,255); +} + +node.n129 { + fill-color: rgb(129,00,255); +} + +node.n130 { + fill-color: rgb(130,00,255); +} + +node.n131 { + fill-color: rgb(131,00,255); +} + +node.n132 { + fill-color: rgb(132,00,255); +} + +node.n133 { + fill-color: rgb(133,00,255); +} + +node.n134 { + fill-color: rgb(134,00,255); +} + +node.n135 { + fill-color: rgb(135,00,255); +} + +node.n136 { + fill-color: rgb(136,00,255); +} + +node.n137 { + fill-color: rgb(137,00,255); +} + +node.n138 { + fill-color: rgb(138,00,255); +} + +node.n139 { + fill-color: rgb(139,00,255); +} + +node.n140 { + fill-color: rgb(140,00,255); +} + +node.n141 { + fill-color: rgb(141,00,255); +} + +node.n142 { + fill-color: rgb(142,00,255); +} + +node.n143 { + fill-color: rgb(143,00,255); +} + +node.n144 { + fill-color: rgb(144,00,255); +} + +node.n145 { + fill-color: rgb(145,00,255); +} + +node.n146 { + fill-color: rgb(146,00,255); +} + +node.n147 { + fill-color: rgb(147,00,255); +} + +node.n148 { + fill-color: rgb(148,00,255); +} + +node.n149 { + fill-color: rgb(149,00,255); +} + +node.n150 { + fill-color: rgb(150,00,255); +} + +node.n151 { + fill-color: rgb(151,00,255); +} + +node.n152 { + fill-color: rgb(152,00,255); +} + +node.n153 { + fill-color: rgb(153,00,255); +} + +node.n154 { + fill-color: rgb(154,00,255); +} + +node.n155 { + fill-color: rgb(155,00,255); +} + +node.n156 { + fill-color: rgb(156,00,255); +} + +node.n157 { + fill-color: rgb(157,00,255); +} + +node.n158 { + fill-color: rgb(158,00,255); +} + +node.n159 { + fill-color: rgb(159,00,255); +} + +node.n160 { + fill-color: rgb(160,00,255); +} + +node.n161 { + fill-color: rgb(161,00,255); +} + +node.n162 { + fill-color: rgb(162,00,255); +} + +node.n163 { + fill-color: rgb(163,00,255); +} + +node.n164 { + fill-color: rgb(164,00,255); +} + +node.n165 { + fill-color: rgb(165,00,255); +} + +node.n166 { + fill-color: rgb(166,00,255); +} + +node.n167 { + fill-color: rgb(167,00,255); +} + +node.n168 { + fill-color: rgb(168,00,255); +} + +node.n169 { + fill-color: rgb(169,00,255); +} + +node.n170 { + fill-color: rgb(170,00,255); +} + +node.n171 { + fill-color: rgb(171,00,255); +} + +node.n172 { + fill-color: rgb(172,00,255); +} + +node.n173 { + fill-color: rgb(173,00,255); +} + +node.n174 { + fill-color: rgb(174,00,255); +} + +node.n175 { + fill-color: rgb(175,00,255); +} + +node.n176 { + fill-color: rgb(176,00,255); +} + +node.n177 { + fill-color: rgb(177,00,255); +} + +node.n178 { + fill-color: rgb(178,00,255); +} + +node.n179 { + fill-color: rgb(179,00,255); +} + +node.n180 { + fill-color: rgb(180,00,255); +} + +node.n181 { + fill-color: rgb(181,00,255); +} + +node.n182 { + fill-color: rgb(182,00,255); +} + +node.n183 { + fill-color: rgb(183,00,255); +} + +node.n184 { + fill-color: rgb(184,00,255); +} + +node.n185 { + fill-color: rgb(185,00,255); +} + +node.n186 { + fill-color: rgb(186,00,255); +} + +node.n187 { + fill-color: rgb(187,00,255); +} + +node.n188 { + fill-color: rgb(188,00,255); +} + +node.n189 { + fill-color: rgb(189,00,255); +} + +node.n190 { + fill-color: rgb(190,00,255); +} + +node.n191 { + fill-color: rgb(191,00,255); +} + +node.n192 { + fill-color: rgb(192,00,255); +} + +node.n193 { + fill-color: rgb(193,00,255); +} + +node.n194 { + fill-color: rgb(194,00,255); +} + +node.n195 { + fill-color: rgb(195,00,255); +} + +node.n196 { + fill-color: rgb(196,00,255); +} + +node.n197 { + fill-color: rgb(197,00,255); +} + +node.n198 { + fill-color: rgb(198,00,255); +} + +node.n199 { + fill-color: rgb(199,00,255); +} + +node.n200 { + fill-color: rgb(200,00,255); +} + +node.n201 { + fill-color: rgb(201,00,255); +} + +node.n202 { + fill-color: rgb(202,00,255); +} + +node.n203 { + fill-color: rgb(203,00,255); +} + +node.n204 { + fill-color: rgb(204,00,255); +} + +node.n205 { + fill-color: rgb(205,00,255); +} + +node.n206 { + fill-color: rgb(206,00,255); +} + +node.n207 { + fill-color: rgb(207,00,255); +} + +node.n208 { + fill-color: rgb(208,00,255); +} + +node.n209 { + fill-color: rgb(209,00,255); +} + +node.n210 { + fill-color: rgb(210,00,255); +} + +node.n211 { + fill-color: rgb(211,00,255); +} + +node.n212 { + fill-color: rgb(212,00,255); +} + +node.n213 { + fill-color: rgb(213,00,255); +} + +node.n214 { + fill-color: rgb(214,00,255); +} + +node.n215 { + fill-color: rgb(215,00,255); +} + +node.n216 { + fill-color: rgb(216,00,255); +} + +node.n217 { + fill-color: rgb(217,00,255); +} + +node.n218 { + fill-color: rgb(218,00,255); +} + +node.n219 { + fill-color: rgb(219,00,255); +} + +node.n220 { + fill-color: rgb(220,00,255); +} + +node.n221 { + fill-color: rgb(221,00,255); +} + +node.n222 { + fill-color: rgb(222,00,255); +} + +node.n223 { + fill-color: rgb(223,00,255); +} + +node.n224 { + fill-color: rgb(224,00,255); +} + +node.n225 { + fill-color: rgb(225,00,255); +} + +node.n226 { + fill-color: rgb(226,00,255); +} + +node.n227 { + fill-color: rgb(227,00,255); +} + +node.n228 { + fill-color: rgb(228,00,255); +} + +node.n229 { + fill-color: rgb(229,00,255); +} + +node.n230 { + fill-color: rgb(230,00,255); +} + +node.n231 { + fill-color: rgb(231,00,255); +} + +node.n232 { + fill-color: rgb(232,00,255); +} + +node.n233 { + fill-color: rgb(233,00,255); +} + +node.n234 { + fill-color: rgb(234,00,255); +} + +node.n235 { + fill-color: rgb(235,00,255); +} + +node.n236 { + fill-color: rgb(236,00,255); +} + +node.n237 { + fill-color: rgb(237,00,255); +} + +node.n238 { + fill-color: rgb(238,00,255); +} + +node.n239 { + fill-color: rgb(239,00,255); +} + +node.n240 { + fill-color: rgb(240,00,255); +} + +node.n241 { + fill-color: rgb(241,00,255); +} + +node.n242 { + fill-color: rgb(242,00,255); +} + +node.n243 { + fill-color: rgb(243,00,255); +} + +node.n244 { + fill-color: rgb(244,00,255); +} + +node.n245 { + fill-color: rgb(245,00,255); +} + +node.n246 { + fill-color: rgb(246,00,255); +} + +node.n247 { + fill-color: rgb(247,00,255); +} + +node.n248 { + fill-color: rgb(248,00,255); +} + +node.n249 { + fill-color: rgb(249,00,255); +} + +node.n250 { + fill-color: rgb(250,00,255); +} + +node.n251 { + fill-color: rgb(251,00,255); +} + +node.n252 { + fill-color: rgb(252,00,255); +} + +node.n253 { + fill-color: rgb(253,00,255); +} + +node.n254 { + fill-color: rgb(254,00,255); +} + +node.n255 { + fill-color: rgb(255,00,255); +} + +node.n256 { + fill-color: rgb(255,00,254); +} + +node.n257 { + fill-color: rgb(255,00,253); +} + +node.n258 { + fill-color: rgb(255,00,252); +} + +node.n259 { + fill-color: rgb(255,00,251); +} + +node.n260 { + fill-color: rgb(255,00,250); +} + +node.n261 { + fill-color: rgb(255,00,249); +} + +node.n262 { + fill-color: rgb(255,00,248); +} + +node.n263 { + fill-color: rgb(255,00,247); +} + +node.n264 { + fill-color: rgb(255,00,246); +} + +node.n265 { + fill-color: rgb(255,00,245); +} + +node.n266 { + fill-color: rgb(255,00,244); +} + +node.n267 { + fill-color: rgb(255,00,243); +} + +node.n268 { + fill-color: rgb(255,00,242); +} + +node.n269 { + fill-color: rgb(255,00,241); +} + +node.n270 { + fill-color: rgb(255,00,240); +} + +node.n271 { + fill-color: rgb(255,00,239); +} + +node.n272 { + fill-color: rgb(255,00,238); +} + +node.n273 { + fill-color: rgb(255,00,237); +} + +node.n274 { + fill-color: rgb(255,00,236); +} + +node.n275 { + fill-color: rgb(255,00,235); +} + +node.n276 { + fill-color: rgb(255,00,234); +} + +node.n277 { + fill-color: rgb(255,00,233); +} + +node.n278 { + fill-color: rgb(255,00,232); +} + +node.n279 { + fill-color: rgb(255,00,231); +} + +node.n280 { + fill-color: rgb(255,00,230); +} + +node.n281 { + fill-color: rgb(255,00,229); +} + +node.n282 { + fill-color: rgb(255,00,228); +} + +node.n283 { + fill-color: rgb(255,00,227); +} + +node.n284 { + fill-color: rgb(255,00,226); +} + +node.n285 { + fill-color: rgb(255,00,225); +} + +node.n286 { + fill-color: rgb(255,00,224); +} + +node.n287 { + fill-color: rgb(255,00,223); +} + +node.n288 { + fill-color: rgb(255,00,222); +} + +node.n289 { + fill-color: rgb(255,00,221); +} + +node.n290 { + fill-color: rgb(255,00,220); +} + +node.n291 { + fill-color: rgb(255,00,219); +} + +node.n292 { + fill-color: rgb(255,00,218); +} + +node.n293 { + fill-color: rgb(255,00,217); +} + +node.n294 { + fill-color: rgb(255,00,216); +} + +node.n295 { + fill-color: rgb(255,00,215); +} + +node.n296 { + fill-color: rgb(255,00,214); +} + +node.n297 { + fill-color: rgb(255,00,213); +} + +node.n298 { + fill-color: rgb(255,00,212); +} + +node.n299 { + fill-color: rgb(255,00,211); +} + +node.n300 { + fill-color: rgb(255,00,210); +} + +node.n301 { + fill-color: rgb(255,00,209); +} + +node.n302 { + fill-color: rgb(255,00,208); +} + +node.n303 { + fill-color: rgb(255,00,207); +} + +node.n304 { + fill-color: rgb(255,00,206); +} + +node.n305 { + fill-color: rgb(255,00,205); +} + +node.n306 { + fill-color: rgb(255,00,204); +} + +node.n307 { + fill-color: rgb(255,00,203); +} + +node.n308 { + fill-color: rgb(255,00,202); +} + +node.n309 { + fill-color: rgb(255,00,201); +} + +node.n310 { + fill-color: rgb(255,00,200); +} + +node.n311 { + fill-color: rgb(255,00,199); +} + +node.n312 { + fill-color: rgb(255,00,198); +} + +node.n313 { + fill-color: rgb(255,00,197); +} + +node.n314 { + fill-color: rgb(255,00,196); +} + +node.n315 { + fill-color: rgb(255,00,195); +} + +node.n316 { + fill-color: rgb(255,00,194); +} + +node.n317 { + fill-color: rgb(255,00,193); +} + +node.n318 { + fill-color: rgb(255,00,192); +} + +node.n319 { + fill-color: rgb(255,00,191); +} + +node.n320 { + fill-color: rgb(255,00,190); +} + +node.n321 { + fill-color: rgb(255,00,189); +} + +node.n322 { + fill-color: rgb(255,00,188); +} + +node.n323 { + fill-color: rgb(255,00,187); +} + +node.n324 { + fill-color: rgb(255,00,186); +} + +node.n325 { + fill-color: rgb(255,00,185); +} + +node.n326 { + fill-color: rgb(255,00,184); +} + +node.n327 { + fill-color: rgb(255,00,183); +} + +node.n328 { + fill-color: rgb(255,00,182); +} + +node.n329 { + fill-color: rgb(255,00,181); +} + +node.n330 { + fill-color: rgb(255,00,180); +} + +node.n331 { + fill-color: rgb(255,00,179); +} + +node.n332 { + fill-color: rgb(255,00,178); +} + +node.n333 { + fill-color: rgb(255,00,177); +} + +node.n334 { + fill-color: rgb(255,00,176); +} + +node.n335 { + fill-color: rgb(255,00,175); +} + +node.n336 { + fill-color: rgb(255,00,174); +} + +node.n337 { + fill-color: rgb(255,00,173); +} + +node.n338 { + fill-color: rgb(255,00,172); +} + +node.n339 { + fill-color: rgb(255,00,171); +} + +node.n340 { + fill-color: rgb(255,00,170); +} + +node.n341 { + fill-color: rgb(255,00,169); +} + +node.n342 { + fill-color: rgb(255,00,168); +} + +node.n343 { + fill-color: rgb(255,00,167); +} + +node.n344 { + fill-color: rgb(255,00,166); +} + +node.n345 { + fill-color: rgb(255,00,165); +} + +node.n346 { + fill-color: rgb(255,00,164); +} + +node.n347 { + fill-color: rgb(255,00,163); +} + +node.n348 { + fill-color: rgb(255,00,162); +} + +node.n349 { + fill-color: rgb(255,00,161); +} + +node.n350 { + fill-color: rgb(255,00,160); +} + +node.n351 { + fill-color: rgb(255,00,159); +} + +node.n352 { + fill-color: rgb(255,00,158); +} + +node.n353 { + fill-color: rgb(255,00,157); +} + +node.n354 { + fill-color: rgb(255,00,156); +} + +node.n355 { + fill-color: rgb(255,00,155); +} + +node.n356 { + fill-color: rgb(255,00,154); +} + +node.n357 { + fill-color: rgb(255,00,153); +} + +node.n358 { + fill-color: rgb(255,00,152); +} + +node.n359 { + fill-color: rgb(255,00,151); +} + +node.n360 { + fill-color: rgb(255,00,150); +} + +node.n361 { + fill-color: rgb(255,00,149); +} + +node.n362 { + fill-color: rgb(255,00,148); +} + +node.n363 { + fill-color: rgb(255,00,147); +} + +node.n364 { + fill-color: rgb(255,00,146); +} + +node.n365 { + fill-color: rgb(255,00,145); +} + +node.n366 { + fill-color: rgb(255,00,144); +} + +node.n367 { + fill-color: rgb(255,00,143); +} + +node.n368 { + fill-color: rgb(255,00,142); +} + +node.n369 { + fill-color: rgb(255,00,141); +} + +node.n370 { + fill-color: rgb(255,00,140); +} + +node.n371 { + fill-color: rgb(255,00,139); +} + +node.n372 { + fill-color: rgb(255,00,138); +} + +node.n373 { + fill-color: rgb(255,00,137); +} + +node.n374 { + fill-color: rgb(255,00,136); +} + +node.n375 { + fill-color: rgb(255,00,135); +} + +node.n376 { + fill-color: rgb(255,00,134); +} + +node.n377 { + fill-color: rgb(255,00,133); +} + +node.n378 { + fill-color: rgb(255,00,132); +} + +node.n379 { + fill-color: rgb(255,00,131); +} + +node.n380 { + fill-color: rgb(255,00,130); +} + +node.n381 { + fill-color: rgb(255,00,129); +} + +node.n382 { + fill-color: rgb(255,00,128); +} + +node.n383 { + fill-color: rgb(255,00,127); +} + +node.n384 { + fill-color: rgb(255,00,126); +} + +node.n385 { + fill-color: rgb(255,00,125); +} + +node.n386 { + fill-color: rgb(255,00,124); +} + +node.n387 { + fill-color: rgb(255,00,123); +} + +node.n388 { + fill-color: rgb(255,00,122); +} + +node.n389 { + fill-color: rgb(255,00,121); +} + +node.n390 { + fill-color: rgb(255,00,120); +} + +node.n391 { + fill-color: rgb(255,00,119); +} + +node.n392 { + fill-color: rgb(255,00,118); +} + +node.n393 { + fill-color: rgb(255,00,117); +} + +node.n394 { + fill-color: rgb(255,00,116); +} + +node.n395 { + fill-color: rgb(255,00,115); +} + +node.n396 { + fill-color: rgb(255,00,114); +} + +node.n397 { + fill-color: rgb(255,00,113); +} + +node.n398 { + fill-color: rgb(255,00,112); +} + +node.n399 { + fill-color: rgb(255,00,111); +} + +node.n400 { + fill-color: rgb(255,00,110); +} + +node.n401 { + fill-color: rgb(255,00,109); +} + +node.n402 { + fill-color: rgb(255,00,108); +} + +node.n403 { + fill-color: rgb(255,00,107); +} + +node.n404 { + fill-color: rgb(255,00,106); +} + +node.n405 { + fill-color: rgb(255,00,105); +} + +node.n406 { + fill-color: rgb(255,00,104); +} + +node.n407 { + fill-color: rgb(255,00,103); +} + +node.n408 { + fill-color: rgb(255,00,102); +} + +node.n409 { + fill-color: rgb(255,00,101); +} + +node.n410 { + fill-color: rgb(255,00,100); +} + +node.n411 { + fill-color: rgb(255,00,99); +} + +node.n412 { + fill-color: rgb(255,00,98); +} + +node.n413 { + fill-color: rgb(255,00,97); +} + +node.n414 { + fill-color: rgb(255,00,96); +} + +node.n415 { + fill-color: rgb(255,00,95); +} + +node.n416 { + fill-color: rgb(255,00,94); +} + +node.n417 { + fill-color: rgb(255,00,93); +} + +node.n418 { + fill-color: rgb(255,00,92); +} + +node.n419 { + fill-color: rgb(255,00,91); +} + +node.n420 { + fill-color: rgb(255,00,90); +} + +node.n421 { + fill-color: rgb(255,00,89); +} + +node.n422 { + fill-color: rgb(255,00,88); +} + +node.n423 { + fill-color: rgb(255,00,87); +} + +node.n424 { + fill-color: rgb(255,00,86); +} + +node.n425 { + fill-color: rgb(255,00,85); +} + +node.n426 { + fill-color: rgb(255,00,84); +} + +node.n427 { + fill-color: rgb(255,00,83); +} + +node.n428 { + fill-color: rgb(255,00,82); +} + +node.n429 { + fill-color: rgb(255,00,81); +} + +node.n430 { + fill-color: rgb(255,00,80); +} + +node.n431 { + fill-color: rgb(255,00,79); +} + +node.n432 { + fill-color: rgb(255,00,78); +} + +node.n433 { + fill-color: rgb(255,00,77); +} + +node.n434 { + fill-color: rgb(255,00,76); +} + +node.n435 { + fill-color: rgb(255,00,75); +} + +node.n436 { + fill-color: rgb(255,00,74); +} + +node.n437 { + fill-color: rgb(255,00,73); +} + +node.n438 { + fill-color: rgb(255,00,72); +} + +node.n439 { + fill-color: rgb(255,00,71); +} + +node.n440 { + fill-color: rgb(255,00,70); +} + +node.n441 { + fill-color: rgb(255,00,69); +} + +node.n442 { + fill-color: rgb(255,00,68); +} + +node.n443 { + fill-color: rgb(255,00,67); +} + +node.n444 { + fill-color: rgb(255,00,66); +} + +node.n445 { + fill-color: rgb(255,00,65); +} + +node.n446 { + fill-color: rgb(255,00,64); +} + +node.n447 { + fill-color: rgb(255,00,63); +} + +node.n448 { + fill-color: rgb(255,00,62); +} + +node.n449 { + fill-color: rgb(255,00,61); +} + +node.n450 { + fill-color: rgb(255,00,60); +} + +node.n451 { + fill-color: rgb(255,00,59); +} + +node.n452 { + fill-color: rgb(255,00,58); +} + +node.n453 { + fill-color: rgb(255,00,57); +} + +node.n454 { + fill-color: rgb(255,00,56); +} + +node.n455 { + fill-color: rgb(255,00,55); +} + +node.n456 { + fill-color: rgb(255,00,54); +} + +node.n457 { + fill-color: rgb(255,00,53); +} + +node.n458 { + fill-color: rgb(255,00,52); +} + +node.n459 { + fill-color: rgb(255,00,51); +} + +node.n460 { + fill-color: rgb(255,00,50); +} + +node.n461 { + fill-color: rgb(255,00,49); +} + +node.n462 { + fill-color: rgb(255,00,48); +} + +node.n463 { + fill-color: rgb(255,00,47); +} + +node.n464 { + fill-color: rgb(255,00,46); +} + +node.n465 { + fill-color: rgb(255,00,45); +} + +node.n466 { + fill-color: rgb(255,00,44); +} + +node.n467 { + fill-color: rgb(255,00,43); +} + +node.n468 { + fill-color: rgb(255,00,42); +} + +node.n469 { + fill-color: rgb(255,00,41); +} + +node.n470 { + fill-color: rgb(255,00,40); +} + +node.n471 { + fill-color: rgb(255,00,39); +} + +node.n472 { + fill-color: rgb(255,00,38); +} + +node.n473 { + fill-color: rgb(255,00,37); +} + +node.n474 { + fill-color: rgb(255,00,36); +} + +node.n475 { + fill-color: rgb(255,00,35); +} + +node.n476 { + fill-color: rgb(255,00,34); +} + +node.n477 { + fill-color: rgb(255,00,33); +} + +node.n478 { + fill-color: rgb(255,00,32); +} + +node.n479 { + fill-color: rgb(255,00,31); +} + +node.n480 { + fill-color: rgb(255,00,30); +} + +node.n481 { + fill-color: rgb(255,00,29); +} + +node.n482 { + fill-color: rgb(255,00,28); +} + +node.n483 { + fill-color: rgb(255,00,27); +} + +node.n484 { + fill-color: rgb(255,00,26); +} + +node.n485 { + fill-color: rgb(255,00,25); +} + +node.n486 { + fill-color: rgb(255,00,24); +} + +node.n487 { + fill-color: rgb(255,00,23); +} + +node.n488 { + fill-color: rgb(255,00,22); +} + +node.n489 { + fill-color: rgb(255,00,21); +} + +node.n490 { + fill-color: rgb(255,00,20); +} + +node.n491 { + fill-color: rgb(255,00,19); +} + +node.n492 { + fill-color: rgb(255,00,18); +} + +node.n493 { + fill-color: rgb(255,00,17); +} + +node.n494 { + fill-color: rgb(255,00,16); +} + +node.n495 { + fill-color: rgb(255,00,15); +} + +node.n496 { + fill-color: rgb(255,00,14); +} + +node.n497 { + fill-color: rgb(255,00,13); +} + +node.n498 { + fill-color: rgb(255,00,12); +} + +node.n499 { + fill-color: rgb(255,00,11); +} + +node.n500 { + fill-color: rgb(255,00,10); +} + +node.n501 { + fill-color: rgb(255,00,9); +} + +node.n502 { + fill-color: rgb(255,00,8); +} + +node.n503 { + fill-color: rgb(255,00,7); +} + +node.n504 { + fill-color: rgb(255,00,6); +} + +node.n505 { + fill-color: rgb(255,00,5); +} + +node.n506 { + fill-color: rgb(255,00,4); +} + +node.n507 { + fill-color: rgb(255,00,3); +} + +node.n508 { + fill-color: rgb(255,00,2); +} + +node.n509 { + fill-color: rgb(255,00,1); +} + +node.n510 { + fill-color: rgb(255,00,0); +} + diff --git a/softwareconfiguration/mlplan/conf/searchgraph.css b/JAICore/jaicore-graphvisualizer/conf/searchgraph.css similarity index 82% rename from softwareconfiguration/mlplan/conf/searchgraph.css rename to JAICore/jaicore-graphvisualizer/conf/searchgraph.css index a04260e9e7..072f59d656 100644 --- a/softwareconfiguration/mlplan/conf/searchgraph.css +++ b/JAICore/jaicore-graphvisualizer/conf/searchgraph.css @@ -39,14 +39,6 @@ node.or_closed { fill-color: purple; } -node.or_exhausted { - fill-color: tomato; -} - -node.or_rollout { - fill-color: cyan; -} - node.or_pruned { shape: cross; fill-color: darkred; diff --git a/JAICore/jaicore-graphvisualizer/src/main/java/ai/libs/jaicore/graphvisualizer/plugin/graphview/GraphViewPluginModel.java b/JAICore/jaicore-graphvisualizer/src/main/java/ai/libs/jaicore/graphvisualizer/plugin/graphview/GraphViewPluginModel.java index 1cc4c77740..7f59cdbf50 100644 --- a/JAICore/jaicore-graphvisualizer/src/main/java/ai/libs/jaicore/graphvisualizer/plugin/graphview/GraphViewPluginModel.java +++ b/JAICore/jaicore-graphvisualizer/src/main/java/ai/libs/jaicore/graphvisualizer/plugin/graphview/GraphViewPluginModel.java @@ -12,10 +12,13 @@ import org.graphstream.graph.Node; import org.graphstream.graph.implementations.SingleGraph; +import ai.libs.jaicore.basic.ResourceUtil; import ai.libs.jaicore.graphvisualizer.plugin.IGUIPluginModel; public class GraphViewPluginModel implements IGUIPluginModel { + private static final String STYLESHEET_URL = "url('" + ResourceUtil.getResourceAsTempFile("searchgraph.css") + "')"; + private int nodeIdCounter; private GraphViewPluginView view; @@ -27,7 +30,7 @@ public class GraphViewPluginModel implements IGUIPluginModel { private ConcurrentMap> nodeToConnectedEdgesMap; public GraphViewPluginModel(final GraphViewPluginView view) { - this(view, "conf/searchgraph.css"); + this(view, STYLESHEET_URL); } public GraphViewPluginModel(final GraphViewPluginView view, final String searchGraphCSSPath) { @@ -40,9 +43,10 @@ public GraphViewPluginModel(final GraphViewPluginView view, final String searchG this.initializeGraph(searchGraphCSSPath); } - private void initializeGraph(final String searchGraphCSSPath) { + private void initializeGraph(final String styleSheetURL) { this.graph = new SingleGraph("Search Graph"); - this.graph.setAttribute("ui.stylesheet", "url('" + searchGraphCSSPath + "')"); + this.graph.setAttribute("ui.stylesheet", styleSheetURL); + System.out.println("Stylesheet URL " + STYLESHEET_URL); } public void addNode(final Object node, final List predecessorNodes, final String typeOfNode) throws ViewGraphManipulationException { @@ -134,7 +138,7 @@ public void removeNode(final Object node) throws ViewGraphManipulationException public void reset() { this.graph.clear(); - this.graph.setAttribute("ui.stylesheet", "url('conf/searchgraph.css')"); + this.graph.setAttribute("ui.stylesheet", STYLESHEET_URL); this.searchGraphNodesToViewGraphNodesMap.clear(); this.viewGraphNodesToSearchGraphNodesMap.clear(); this.nodeToConnectedEdgesMap.clear(); diff --git a/JAICore/jaicore-logic/build.gradle b/JAICore/jaicore-logic/build.gradle index cb31a2f406..0e70ba5662 100644 --- a/JAICore/jaicore-logic/build.gradle +++ b/JAICore/jaicore-logic/build.gradle @@ -5,12 +5,15 @@ dependencies { uploadArchives { repositories { mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } pom.project { @@ -46,8 +49,8 @@ uploadArchives { } developer { id 'ahetzer' - name 'Alexander Hetzer' - email 'alexander.hetzer@upb.de' + name 'Alexander Tornede' + email 'alexander.tornede@upb.de' } } } diff --git a/JAICore/jaicore-math/build.gradle b/JAICore/jaicore-math/build.gradle index 6f299a6917..5aba826f97 100644 --- a/JAICore/jaicore-math/build.gradle +++ b/JAICore/jaicore-math/build.gradle @@ -1,56 +1,59 @@ -dependencies { - compile project(":JAICore:jaicore-basic") - compile group: 'de.upb.isys', name: 'mtj', version: '0.0.1' -} -uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") - } - snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") - } - - pom.project { - name 'JAICore-Math' - packaging 'jar' - // optionally artifactId can be defined here - description 'This project provides fundamental utils for math operations.' - url 'https://libs.ai' - - scm { - connection 'scm:git:https://github.com/fmohr/AILibs.git' - developerConnection 'scm:git:https://github.com/fmohr/AILibs.git' - url 'https://github.com/fmohr/AILibs' - } - - licenses { - license { - name 'GPLv3' - url 'https://www.gnu.org/licenses/gpl-3.0.en.html' - } - } - - developers { - developer { - id 'fmohr' - name 'Felix Mohr' - email 'felix.mohr@upb.de' - } - developer { - id 'mwever' - name 'Marcel Wever' - email 'marcel.wever@upb.de' - } - developer { - id 'ahetzer' - name 'Alexander Hetzer' - email 'alexander.hetzer@upb.de' - } - } - } - } - } +dependencies { + compile project(":JAICore:jaicore-basic") + compile group: 'de.upb.isys', name: 'mtj', version: '0.0.1' +} +uploadArchives { + repositories { + mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + + pom.project { + name 'JAICore-Math' + packaging 'jar' + // optionally artifactId can be defined here + description 'This project provides fundamental utils for math operations.' + url 'https://libs.ai' + + scm { + connection 'scm:git:https://github.com/fmohr/AILibs.git' + developerConnection 'scm:git:https://github.com/fmohr/AILibs.git' + url 'https://github.com/fmohr/AILibs' + } + + licenses { + license { + name 'GPLv3' + url 'https://www.gnu.org/licenses/gpl-3.0.en.html' + } + } + + developers { + developer { + id 'fmohr' + name 'Felix Mohr' + email 'felix.mohr@upb.de' + } + developer { + id 'mwever' + name 'Marcel Wever' + email 'marcel.wever@upb.de' + } + developer { + id 'ahetzer' + name 'Alexander Hetzer' + email 'alexander.hetzer@upb.de' + } + } + } + } + } } \ No newline at end of file diff --git a/JAICore/jaicore-ml/build.gradle b/JAICore/jaicore-ml/build.gradle index 995019d127..81b8fc7404 100644 --- a/JAICore/jaicore-ml/build.gradle +++ b/JAICore/jaicore-ml/build.gradle @@ -8,7 +8,7 @@ dependencies { compile group: 'org.openml', name: 'apiconnector', version: '1.0.16' compile group: 'de.upb.isys', name: 'omlwebapp', version: '0.0.1' - compile ('de.upb.isys:meka:0.0.4') + compile ('ai.libs.thirdparty:interruptible-meka:0.1.0') // dependencies for meka @@ -21,12 +21,11 @@ dependencies { // weka requiring projects compile group: 'org.kramerlab', name: 'autoencoder', version: '0.1' compile group: 'com.github.fracpete', name: 'multisearch-weka-package', version: '2017.10.1' - compile ('net.sf.meka.thirdparty:mulan:1.4.0') // end dependencies for meka - compile ('de.upb.isys:interruptable-weka:0.0.17') { + compile ('ai.libs.thirdparty:interruptible-weka:0.1.0') { exclude group: 'log4j' exclude group: 'org.slf4j' } @@ -48,12 +47,15 @@ configurations.all { uploadArchives { repositories { mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } pom.project { @@ -89,8 +91,8 @@ uploadArchives { } developer { id 'ahetzer' - name 'Alexander Hetzer' - email 'alexander.hetzer@upb.de' + name 'Alexander Tornede' + email 'alexander.tornede@upb.de' } } } diff --git a/JAICore/jaicore-ml/conf/log4j.xml b/JAICore/jaicore-ml/conf/log4j.xml index d04fe35430..c282817a15 100644 --- a/JAICore/jaicore-ml/conf/log4j.xml +++ b/JAICore/jaicore-ml/conf/log4j.xml @@ -46,7 +46,7 @@ - + @@ -55,23 +55,23 @@ - + - + - + - + - + diff --git a/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/classification/multiclass/reduction/reducer/ReductionGraphGenerator.java b/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/classification/multiclass/reduction/reducer/ReductionGraphGenerator.java index 2d00279087..21fabc82a0 100644 --- a/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/classification/multiclass/reduction/reducer/ReductionGraphGenerator.java +++ b/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/classification/multiclass/reduction/reducer/ReductionGraphGenerator.java @@ -14,12 +14,12 @@ import ai.libs.jaicore.ml.classification.multiclass.reduction.EMCNodeType; import ai.libs.jaicore.ml.classification.multiclass.reduction.splitters.ISplitter; import ai.libs.jaicore.ml.classification.multiclass.reduction.splitters.RPNDSplitter; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; import weka.classifiers.AbstractClassifier; import weka.classifiers.Classifier; import weka.core.Instances; diff --git a/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/classification/multiclass/reduction/reducer/ReductionOptimizer.java b/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/classification/multiclass/reduction/reducer/ReductionOptimizer.java index 1b82283993..4636f70ff0 100644 --- a/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/classification/multiclass/reduction/reducer/ReductionOptimizer.java +++ b/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/classification/multiclass/reduction/reducer/ReductionOptimizer.java @@ -15,9 +15,9 @@ import ai.libs.jaicore.ml.classification.multiclass.reduction.EMCNodeType; import ai.libs.jaicore.ml.classification.multiclass.reduction.MCTreeNode; import ai.libs.jaicore.ml.classification.multiclass.reduction.MCTreeNodeLeaf; -import jaicore.search.algorithms.standard.bestfirst.BestFirstEpsilon; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.BestFirstEpsilon; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; import weka.classifiers.Classifier; import weka.classifiers.Evaluation; import weka.classifiers.rules.OneR; diff --git a/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/evaluation/evaluators/weka/MonteCarloCrossValidationEvaluator.java b/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/evaluation/evaluators/weka/MonteCarloCrossValidationEvaluator.java index 21a0c997fb..2bc98bba41 100644 --- a/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/evaluation/evaluators/weka/MonteCarloCrossValidationEvaluator.java +++ b/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/evaluation/evaluators/weka/MonteCarloCrossValidationEvaluator.java @@ -1,6 +1,8 @@ package ai.libs.jaicore.ml.evaluation.evaluators.weka; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.slf4j.Logger; @@ -13,6 +15,7 @@ import ai.libs.jaicore.basic.algorithm.exceptions.ObjectEvaluationFailedException; import ai.libs.jaicore.basic.events.IEvent; import ai.libs.jaicore.basic.events.IEventEmitter; +import ai.libs.jaicore.ml.WekaUtil; import ai.libs.jaicore.ml.evaluation.evaluators.weka.events.MCCVSplitEvaluationEvent; import ai.libs.jaicore.ml.evaluation.evaluators.weka.splitevaluation.AbstractSplitBasedClassifierEvaluator; import ai.libs.jaicore.ml.evaluation.evaluators.weka.splitevaluation.ISplitBasedClassifierEvaluator; @@ -45,6 +48,8 @@ public class MonteCarloCrossValidationEvaluator implements IClassifierEvaluator, /* Can either compute the loss or cache it */ private final ISplitBasedClassifierEvaluator splitBasedEvaluator; + private final Map> splitCache = new HashMap<>(); + public MonteCarloCrossValidationEvaluator(final ISplitBasedClassifierEvaluator splitBasedEvaluator, final IDatasetSplitter datasetSplitter, final int repeats, final Instances data, final double trainingPortion, final long seed) { super(); @@ -58,7 +63,7 @@ public MonteCarloCrossValidationEvaluator(final ISplitBasedClassifierEvaluator split = this.datasetSplitter.split(this.data, this.seed + i, this.trainingPortion); + + if (!this.splitCache.containsKey(this.seed + i)) { + this.splitCache.put(this.seed + i, this.datasetSplitter.split(this.data, this.seed + i, this.trainingPortion)); + } + List split = this.splitCache.get(this.seed + i); + try { long startTimeForSplitEvaluation = System.currentTimeMillis(); double score = this.splitBasedEvaluator.evaluateSplit(pl, split.get(0), split.get(1)); if (this.hasListeners) { - this.eventBus.post(new MCCVSplitEvaluationEvent(pl, split.get(0).size(), split.get(1).size(), (int)(System.currentTimeMillis() - startTimeForSplitEvaluation), score)); + this.eventBus.post(new MCCVSplitEvaluationEvent(pl, split.get(0).size(), split.get(1).size(), (int) (System.currentTimeMillis() - startTimeForSplitEvaluation), score)); } this.logger.info("Score for evaluation of {} with split #{}/{}: {} after {}ms", pl.getClass().getName(), i + 1, this.repeats, score, (System.currentTimeMillis() - startTimestamp)); stats.addValue(score); diff --git a/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/scikitwrapper/AProcessListener.java b/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/scikitwrapper/AProcessListener.java index cc4f3d9ca9..1205a61527 100644 --- a/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/scikitwrapper/AProcessListener.java +++ b/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/scikitwrapper/AProcessListener.java @@ -20,8 +20,7 @@ public void listenTo(final Process process) throws IOException, InterruptedExcep // While process is alive the output- and error stream is output. while (process.isAlive()) { if (Thread.currentThread().isInterrupted()) { - ProcessUtil.killProcess(ProcessUtil.getPID(process)); - process.destroyForcibly(); + ProcessUtil.killProcess(process); throw new InterruptedException("Process execution was interrupted."); } String line; diff --git a/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/scikitwrapper/ScikitLearnWrapper.java b/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/scikitwrapper/ScikitLearnWrapper.java index 38649c890f..42241960ae 100644 --- a/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/scikitwrapper/ScikitLearnWrapper.java +++ b/JAICore/jaicore-ml/src/main/java/ai/libs/jaicore/ml/scikitwrapper/ScikitLearnWrapper.java @@ -70,7 +70,7 @@ public class ScikitLearnWrapper implements IInstancesClassifier, Classifier { private static final File TMP_FOLDER = new File("tmp"); // Folder to put the serialized arff files and the scripts in. private static final String RES_SCIKIT_TEMPLATE_PATH = "sklearn/scikit_template.twig.py"; - private static final File SCIKIT_TEMPLATE = ResourceUtil.getResourceAsFile(RES_SCIKIT_TEMPLATE_PATH); // Path to the used python template. + private static final File SCIKIT_TEMPLATE = new File(ResourceUtil.getResourceAsTempFile(RES_SCIKIT_TEMPLATE_PATH)); // Path to the used python template. private static final File MODEL_DUMPS_DIRECTORY = new File(TMP_FOLDER, "model_dumps"); private static final boolean VERBOSE = false; // If true the output stream of the python process is printed. diff --git a/JAICore/jaicore-planning/build.gradle b/JAICore/jaicore-planning/build.gradle index 41c156dd1d..d59006f0bc 100644 --- a/JAICore/jaicore-planning/build.gradle +++ b/JAICore/jaicore-planning/build.gradle @@ -8,12 +8,15 @@ dependencies { uploadArchives { repositories { mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } pom.project { diff --git a/JAICore/jaicore-planning/conf/log4j.xml b/JAICore/jaicore-planning/conf/log4j.xml index b2b7377105..fd99e1fefc 100644 --- a/JAICore/jaicore-planning/conf/log4j.xml +++ b/JAICore/jaicore-planning/conf/log4j.xml @@ -46,7 +46,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/ISTRIPSPlanningGraphGeneratorDeriver.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/ISTRIPSPlanningGraphGeneratorDeriver.java index ed622c62c9..2f99d20bab 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/ISTRIPSPlanningGraphGeneratorDeriver.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/ISTRIPSPlanningGraphGeneratorDeriver.java @@ -3,8 +3,8 @@ import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; import ai.libs.jaicore.planning.classical.problems.strips.StripsPlanningProblem; import ai.libs.jaicore.planning.core.Plan; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.other.SearchGraphPath; public interface ISTRIPSPlanningGraphGeneratorDeriver extends AlgorithmicProblemReduction, SearchGraphPath> { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/STRIPSForwardSearchReducer.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/STRIPSForwardSearchReducer.java index cc324c0474..e61b606628 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/STRIPSForwardSearchReducer.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/STRIPSForwardSearchReducer.java @@ -6,8 +6,8 @@ import ai.libs.jaicore.planning.classical.problems.strips.StripsAction; import ai.libs.jaicore.planning.classical.problems.strips.StripsPlanningProblem; import ai.libs.jaicore.planning.core.Plan; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.other.SearchGraphPath; public class STRIPSForwardSearchReducer implements ISTRIPSPlanningGraphGeneratorDeriver { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/STRIPSPlanner.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/STRIPSPlanner.java index 8d06493f74..6669b14162 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/STRIPSPlanner.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/STRIPSPlanner.java @@ -21,12 +21,12 @@ import ai.libs.jaicore.planning.core.EvaluatedPlan; import ai.libs.jaicore.planning.core.Plan; import ai.libs.jaicore.planning.core.events.PlanFoundEvent; -import jaicore.search.algorithms.standard.bestfirst.BestFirst; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.core.interfaces.IPathInORGraphSearch; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.BestFirst; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.core.interfaces.IPathInORGraphSearch; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class STRIPSPlanner> extends AOptimizer, V> { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/StripsForwardPlanningGraphGenerator.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/StripsForwardPlanningGraphGenerator.java index 1c351a8a25..246278c298 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/StripsForwardPlanningGraphGenerator.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/classical/algorithms/strips/forward/StripsForwardPlanningGraphGenerator.java @@ -14,12 +14,12 @@ import ai.libs.jaicore.planning.classical.problems.strips.StripsAction; import ai.libs.jaicore.planning.classical.problems.strips.StripsPlanningDomain; import ai.libs.jaicore.planning.classical.problems.strips.StripsPlanningProblem; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SingleSuccessorGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SingleSuccessorGenerator; public class StripsForwardPlanningGraphGenerator implements GraphGenerator { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/core/EvaluatedSearchGraphBasedPlan.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/core/EvaluatedSearchGraphBasedPlan.java index 5a4a7356d2..7ad372ee4a 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/core/EvaluatedSearchGraphBasedPlan.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/core/EvaluatedSearchGraphBasedPlan.java @@ -2,7 +2,7 @@ import java.util.List; -import jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; public class EvaluatedSearchGraphBasedPlan, N> extends EvaluatedPlan { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/GraphSearchBasedHTNPlanningAlgorithm.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/GraphSearchBasedHTNPlanningAlgorithm.java index 346f1456b9..bd97ad456e 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/GraphSearchBasedHTNPlanningAlgorithm.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/GraphSearchBasedHTNPlanningAlgorithm.java @@ -23,11 +23,11 @@ import ai.libs.jaicore.planning.hierarchical.problems.htn.IHTNPlanningProblem; import ai.libs.jaicore.planning.hierarchical.problems.htn.IHierarchicalPlanningGraphGeneratorDeriver; import ai.libs.jaicore.planning.hierarchical.problems.stn.Method; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearch; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.builders.SearchProblemInputBuilder; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearch; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.builders.SearchProblemInputBuilder; /** * diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNBestFirstPlannerFactory.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNBestFirstPlannerFactory.java index 4309879acb..1be5861f49 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNBestFirstPlannerFactory.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNBestFirstPlannerFactory.java @@ -2,10 +2,10 @@ import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; import ai.libs.jaicore.planning.hierarchical.problems.htn.IHTNPlanningProblem; -import jaicore.search.algorithms.standard.bestfirst.BestFirstFactory; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; -import jaicore.search.probleminputs.builders.GraphSearchWithSubpathEvaluationsInputBuilder; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.BestFirstFactory; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.probleminputs.builders.GraphSearchWithSubpathEvaluationsInputBuilder; public class ForwardDecompositionHTNBestFirstPlannerFactory, ISearch extends GraphSearchWithSubpathEvaluationsInput> extends ForwardDecompositionHTNPlannerFactory> { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlanner.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlanner.java index edd986b178..9ffb96b85d 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlanner.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlanner.java @@ -3,9 +3,9 @@ import ai.libs.jaicore.planning.hierarchical.algorithms.GraphSearchBasedHTNPlanningAlgorithm; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; import ai.libs.jaicore.planning.hierarchical.problems.htn.IHTNPlanningProblem; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.builders.SearchProblemInputBuilder; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.builders.SearchProblemInputBuilder; /** * Hierarchically create an object of type T diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlannerBasedOnBestFirst.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlannerBasedOnBestFirst.java index 891115f66a..53b8dc7e6f 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlannerBasedOnBestFirst.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlannerBasedOnBestFirst.java @@ -2,10 +2,10 @@ import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; import ai.libs.jaicore.planning.hierarchical.problems.htn.IHTNPlanningProblem; -import jaicore.search.algorithms.standard.bestfirst.BestFirstFactory; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; -import jaicore.search.probleminputs.builders.GraphSearchWithSubpathEvaluationsInputBuilder; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.BestFirstFactory; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.probleminputs.builders.GraphSearchWithSubpathEvaluationsInputBuilder; public class ForwardDecompositionHTNPlannerBasedOnBestFirst> extends ForwardDecompositionHTNPlanner> { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlannerFactory.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlannerFactory.java index 219053b981..5a70b1d5e3 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlannerFactory.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionHTNPlannerFactory.java @@ -4,9 +4,9 @@ import ai.libs.jaicore.planning.core.EvaluatedSearchGraphBasedPlan; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; import ai.libs.jaicore.planning.hierarchical.problems.htn.IHTNPlanningProblem; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.builders.SearchProblemInputBuilder; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.builders.SearchProblemInputBuilder; public class ForwardDecompositionHTNPlannerFactory, ISearch extends GraphSearchInput> extends AAlgorithmFactory> { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionReducer.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionReducer.java index 1e75ec2b68..dbe16f3205 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionReducer.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/ForwardDecompositionReducer.java @@ -12,9 +12,9 @@ import ai.libs.jaicore.planning.hierarchical.problems.htn.IHTNPlanningProblem; import ai.libs.jaicore.planning.hierarchical.problems.htn.IHierarchicalPlanningGraphGeneratorDeriver; import ai.libs.jaicore.planning.hierarchical.problems.stn.STNPlanningProblem; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; public class ForwardDecompositionReducer implements IHierarchicalPlanningGraphGeneratorDeriver { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/graphgenerators/rtn/RTNGraphGenerator.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/graphgenerators/rtn/RTNGraphGenerator.java index 2ba355e94b..c2236ba1d4 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/graphgenerators/rtn/RTNGraphGenerator.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/graphgenerators/rtn/RTNGraphGenerator.java @@ -25,11 +25,11 @@ import ai.libs.jaicore.planning.hierarchical.problems.rtn.RTNPlanningProblem; import ai.libs.jaicore.planning.hierarchical.problems.stn.Method; import ai.libs.jaicore.planning.hierarchical.problems.stn.MethodInstance; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; public class RTNGraphGenerator implements GraphGenerator { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/graphgenerators/tfd/TFDGraphGenerator.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/graphgenerators/tfd/TFDGraphGenerator.java index 001f9b256b..0ef4aae802 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/graphgenerators/tfd/TFDGraphGenerator.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/algorithms/forwarddecomposition/graphgenerators/tfd/TFDGraphGenerator.java @@ -22,13 +22,13 @@ import ai.libs.jaicore.planning.hierarchical.problems.htn.IHTNPlanningProblem; import ai.libs.jaicore.planning.hierarchical.problems.stn.Method; import ai.libs.jaicore.planning.hierarchical.problems.stn.MethodInstance; -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; -import jaicore.search.core.interfaces.PathUnifyingGraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; +import ai.libs.jaicore.search.core.interfaces.PathUnifyingGraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; @SuppressWarnings("serial") public class TFDGraphGenerator implements SerializableGraphGenerator, PathUnifyingGraphGenerator { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/problems/htn/CostSensitivePlanningToSearchProblemTransformer.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/problems/htn/CostSensitivePlanningToSearchProblemTransformer.java index 033e7db01b..bc96543452 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/problems/htn/CostSensitivePlanningToSearchProblemTransformer.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/problems/htn/CostSensitivePlanningToSearchProblemTransformer.java @@ -3,9 +3,9 @@ import ai.libs.jaicore.basic.IObjectEvaluator; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; import ai.libs.jaicore.planning.core.EvaluatedPlan; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; public class CostSensitivePlanningToSearchProblemTransformer, N, A> implements AlgorithmicProblemReduction, EvaluatedPlan, GraphSearchWithPathEvaluationsInput, EvaluatedSearchGraphPath> { diff --git a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/problems/htn/IHierarchicalPlanningGraphGeneratorDeriver.java b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/problems/htn/IHierarchicalPlanningGraphGeneratorDeriver.java index 498e207f59..d871d74a03 100644 --- a/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/problems/htn/IHierarchicalPlanningGraphGeneratorDeriver.java +++ b/JAICore/jaicore-planning/src/main/java/ai/libs/jaicore/planning/hierarchical/problems/htn/IHierarchicalPlanningGraphGeneratorDeriver.java @@ -2,8 +2,8 @@ import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; import ai.libs.jaicore.planning.core.Plan; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; public interface IHierarchicalPlanningGraphGeneratorDeriver

extends AlgorithmicProblemReduction, SearchGraphPath> { diff --git a/JAICore/jaicore-processes/build.gradle b/JAICore/jaicore-processes/build.gradle index 16ca60ed98..9b9a4378bd 100644 --- a/JAICore/jaicore-processes/build.gradle +++ b/JAICore/jaicore-processes/build.gradle @@ -6,12 +6,15 @@ dependencies{ uploadArchives { repositories { mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } pom.project { diff --git a/JAICore/jaicore-processes/src/main/java/ai/libs/jaicore/processes/JavaMethodToProcessWrapper.java b/JAICore/jaicore-processes/src/main/java/ai/libs/jaicore/processes/JavaMethodToProcessWrapper.java index cb189a7bea..4b334c4bab 100644 --- a/JAICore/jaicore-processes/src/main/java/ai/libs/jaicore/processes/JavaMethodToProcessWrapper.java +++ b/JAICore/jaicore-processes/src/main/java/ai/libs/jaicore/processes/JavaMethodToProcessWrapper.java @@ -62,7 +62,7 @@ public static String getAbsoluteClasspath() { return null; } - public Object run(final String clazz, final String method, final Object target, final Object... inputs) throws IOException, InterruptedException, InvocationTargetException { + public Object run(final String clazz, final String method, final Object target, final Object... inputs) throws IOException, InterruptedException, InvocationTargetException, ProcessIDNotRetrievableException { return this.run(clazz, method, target, Arrays.asList(inputs)); } @@ -92,7 +92,7 @@ public Optional runWithTimeout(final String clazz, final String method, return (c != null) ? Optional.of(c) : Optional.empty(); } - public Object run(final String clazz, final String method, final Object target, final List inputs) throws IOException, InterruptedException, InvocationTargetException { + public Object run(final String clazz, final String method, final Object target, final List inputs) throws IOException, InterruptedException, InvocationTargetException, ProcessIDNotRetrievableException { /* create new id for the invocation */ String id = String.valueOf(random.nextLong()); diff --git a/JAICore/jaicore-processes/src/main/java/ai/libs/jaicore/processes/ProcessIDNotRetrievableException.java b/JAICore/jaicore-processes/src/main/java/ai/libs/jaicore/processes/ProcessIDNotRetrievableException.java new file mode 100644 index 0000000000..8be5f4b8ec --- /dev/null +++ b/JAICore/jaicore-processes/src/main/java/ai/libs/jaicore/processes/ProcessIDNotRetrievableException.java @@ -0,0 +1,18 @@ +package ai.libs.jaicore.processes; + +public class ProcessIDNotRetrievableException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -719315021772711013L; + + public ProcessIDNotRetrievableException(final String msg) { + super(msg); + } + + public ProcessIDNotRetrievableException(final String msg, final Throwable cause) { + super(msg, cause); + } + +} diff --git a/JAICore/jaicore-processes/src/main/java/ai/libs/jaicore/processes/ProcessUtil.java b/JAICore/jaicore-processes/src/main/java/ai/libs/jaicore/processes/ProcessUtil.java index 08411c5967..5b8d60f12b 100644 --- a/JAICore/jaicore-processes/src/main/java/ai/libs/jaicore/processes/ProcessUtil.java +++ b/JAICore/jaicore-processes/src/main/java/ai/libs/jaicore/processes/ProcessUtil.java @@ -5,6 +5,9 @@ import java.util.Collection; import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.sun.jna.Pointer; /** @@ -15,6 +18,9 @@ */ public class ProcessUtil { + /* Logging */ + private static final Logger logger = LoggerFactory.getLogger(ProcessUtil.class); + private ProcessUtil() { /* Intentionally left blank, just prevent an instantiation of this class. */ } @@ -63,8 +69,9 @@ public static Collection getRunningJavaProcesses() throws IOExcepti * Gets the operating system's process id of the given process. * @param process The process for which the process id shall be looked up. * @return The process id of the given process. + * @throws ProcessIDNotRetrievableException Thrown if the process id cannot be retrieved. */ - public static int getPID(final Process process) { + public static int getPID(final Process process) throws ProcessIDNotRetrievableException { Integer pid; try { if (process.getClass().getName().equals("java.lang.UNIXProcess")) { @@ -88,7 +95,7 @@ public static int getPID(final Process process) { return pid; } } catch (Throwable e) { - e.printStackTrace(); + throw new ProcessIDNotRetrievableException("Could not retrieve process ID", e); } throw new UnsupportedOperationException(); } @@ -113,6 +120,11 @@ public static void killProcess(final int pid) throws IOException { * @throws IOException Thrown if the system command could not be issued. */ public static void killProcess(final Process process) throws IOException { - killProcess(getPID(process)); + try { + killProcess(getPID(process)); + } catch (ProcessIDNotRetrievableException e) { + logger.warn("Cannot kill process with certainty. Thus try to kill the process via the process' destroy method.", e); + process.destroyForcibly(); + } } } diff --git a/JAICore/jaicore-search/build.gradle b/JAICore/jaicore-search/build.gradle index fb72dad8e9..16d2649766 100644 --- a/JAICore/jaicore-search/build.gradle +++ b/JAICore/jaicore-search/build.gradle @@ -9,12 +9,15 @@ dependencies { uploadArchives { repositories { mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } pom.project { diff --git a/JAICore/jaicore-search/conf/log4j.xml b/JAICore/jaicore-search/conf/log4j.xml index 88539ac93c..141290b74d 100644 --- a/JAICore/jaicore-search/conf/log4j.xml +++ b/JAICore/jaicore-search/conf/log4j.xml @@ -46,7 +46,7 @@ - + @@ -55,7 +55,7 @@ - + @@ -77,23 +77,23 @@ - + - + - + - + - + diff --git a/JAICore/jaicore-search/conf/searchgraph.css b/JAICore/jaicore-search/conf/searchgraph.css deleted file mode 100644 index a95d153afb..0000000000 --- a/JAICore/jaicore-search/conf/searchgraph.css +++ /dev/null @@ -1,69 +0,0 @@ -edge { - padding: 100px; -} - -node { - size-mode: fit; - fill-mode: plain; - fill-color: grey; - padding: 5px; -} - -node.root { - padding: 10px; - fill-color: black; -} - -node.expanding { - fill-color: blue; -} - - -node.or_pruned { - fill-color: red; -} - -node.or_distributed { - fill-color: orange; -} - -node.or_threaded { - fill-color: brown; -} - -node.and_closed { - shape: box; - padding: 6px; - fill-color: brown; -} - -node.and_open { - shape: box; - padding: 6px; - stroke-color: brown; - stroke-mode: plain; - fill-mode: none; -} - -node.or_closed { - shape: circle; - fill-color: purple; -} - -node.or_open { - shape: circle; - stroke-mode: plain; - fill-mode: none; - stroke-color: purple; -} - -node.and_solution { - shape: box; - padding: 6px; - fill-color: green; -} - -node.or_solution { - shape: circle; - fill-color: green; -} \ No newline at end of file diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/andor/AndORBottomUpFilter.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/andor/AndORBottomUpFilter.java similarity index 94% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/andor/AndORBottomUpFilter.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/andor/AndORBottomUpFilter.java index 928347af6a..56f6c8a78f 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/andor/AndORBottomUpFilter.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/andor/AndORBottomUpFilter.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.andor; +package ai.libs.jaicore.search.algorithms.andor; import java.util.ArrayList; import java.util.Collection; @@ -28,12 +28,12 @@ import ai.libs.jaicore.graph.Graph; import ai.libs.jaicore.graphvisualizer.events.graph.GraphInitializedEvent; import ai.libs.jaicore.graphvisualizer.events.graph.NodeAddedEvent; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; public class AndORBottomUpFilter> extends AAlgorithm, Graph> implements IGraphSearch, Graph, N, A> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedComputationResult.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedComputationResult.java similarity index 80% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedComputationResult.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedComputationResult.java index c6c962a19e..a36239fd02 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedComputationResult.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedComputationResult.java @@ -1,33 +1,33 @@ -package jaicore.search.algorithms.parallel.parallelexploration.distributed; - -import java.io.Serializable; -import java.util.Collection; - -import jaicore.search.model.travesaltree.Node; - -@SuppressWarnings("serial") -public class DistributedComputationResult> implements Serializable { - - private final String coworker; - private final Collection> open; - private final Collection> solutions; - - public DistributedComputationResult(String coworker, Collection> open, Collection> solutions) { - super(); - this.coworker = coworker; - this.open = open; - this.solutions = solutions; - } - - public String getCoworker() { - return coworker; - } - - public Collection> getOpen() { - return open; - } - - public Collection> getSolutions() { - return solutions; - } -} +package ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed; + +import java.io.Serializable; +import java.util.Collection; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +@SuppressWarnings("serial") +public class DistributedComputationResult> implements Serializable { + + private final String coworker; + private final Collection> open; + private final Collection> solutions; + + public DistributedComputationResult(String coworker, Collection> open, Collection> solutions) { + super(); + this.coworker = coworker; + this.open = open; + this.solutions = solutions; + } + + public String getCoworker() { + return coworker; + } + + public Collection> getOpen() { + return open; + } + + public Collection> getSolutions() { + return solutions; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearch.java similarity index 96% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearch.java index 86ae064ef1..96df025d96 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearch.java @@ -1,148 +1,149 @@ -//package jaicore.search.algorithms.parallel.parallelexploration.distributed; -// -//import java.util.ArrayList; -//import java.util.Collection; -// -//import org.slf4j.Logger; -//import org.slf4j.LoggerFactory; -// -//import com.google.common.eventbus.Subscribe; -// -//import jaicore.graphvisualizer.events.graphEvents.NodeTypeSwitchEvent; -//import jaicore.search.algorithms.parallel.parallelexploration.distributed.events.NodePassedToCoworkerEvent; -//import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.DistributedSearchCommunicationLayer; -//import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.DistributionSearchAdapter; -//import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; -//import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableNodeEvaluator; -//import jaicore.search.algorithms.standard.bestfirst.BestFirst; -//import jaicore.search.algorithms.standard.bestfirst.model.Node; -// -//public class DistributedOrSearch> extends BestFirst implements DistributionSearchAdapter { -// -// private static final Logger logger = LoggerFactory.getLogger(DistributedOrSearch.class); -// private final DistributedSearchManager manager; -// -// public DistributedOrSearch(SerializableGraphGenerator graphGenerator, SerializableNodeEvaluator pNodeEvaluator, -// DistributedSearchCommunicationLayer communicationLayer) { -// super(graphGenerator, pNodeEvaluator); -// -// /* initialize communication layer */ -// try { -// communicationLayer.init(); -// communicationLayer.setGraphGenerator(graphGenerator); -// communicationLayer.setNodeEvaluator(pNodeEvaluator); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// -// /* now start distributed manager */ -// this.manager = new DistributedSearchManager<>(communicationLayer, this); -// this.manager.getEventBus().register(this); -// } -// -// @Override -// protected boolean beforeSelection() { -// if (!super.beforeSelection()) -// return false; -// if (this.manager.getNumberOfHelpers() == this.manager.getNumbetOfIdleCoworkers()) { -// logger.info("There are no (busy) coworkers, continue exploring on my own."); -// return true; -// } -// logger.info("No further local exploration since there are sufficient busy coworkers ..."); -// try { -// Thread.sleep(1000); -// } catch (InterruptedException e) { -// e.printStackTrace(); -// } -// return false; -// } -// -// @Subscribe -// public void receiveNodeEvent(NodePassedToCoworkerEvent> e) { -// this.graphEventBus.post(new NodeTypeSwitchEvent<>(e.getNode(), "or_distributed")); -// } -// -// @Override -// public Collection> nextJob() { -// if (open.size() > 1) { -//// int helpers = manager.getNumbetOfIdleCoworkers() + manager.getNumbetOfPendingCoworkers(); -//// int pendingTasks = manager.getNumberOfUnprocessedJobs(); -//// int nodesToOutsource = Math.min(open.size() -1, helpers - pendingTasks); -//// logger.info("Finished node expansion, distributing min({} - 1, {} - {}) = {} nodes ...", open.size() - 1, helpers, pendingTasks, nodesToOutsource); -// Collection> nextJob = pollNodesForDistribution(1); -// logger.info("Passing next job with {} node(s) to the DistributedSearchManager.", nextJob.size()); -// return nextJob; -// } -// return null; -// } -// -// @Override -// protected boolean terminates() { -// if (!super.terminates()) -// return false; -// if (manager.isBusy()) -// return false; -// return true; -// } -// -// public void cancel() { -// super.cancel(); -// manager.shutdown(); -// } -// -// private Collection> pollNodesForDistribution(int helpers) { -// Collection> nodes = new ArrayList<>(); -// if (open.isEmpty()) -// return null; -//// int i = 0; -//// max = open.size(); -//// List> toPutBack = new ArrayList<>(); -//// while (!open.isEmpty() && nodes.size() <= 100000) { -//// if (i % helpers == 0) -//// nodes.add(open.poll()); -//// else -//// toPutBack.add(open.poll()); -//// i++; -//// } -// -// /* return all the not used paths to open */ -//// open.addAll(toPutBack); -//// logger.info("Distributing " + nodes.size() + " of " + max); -// nodes.add(open.peek()); -// open.remove(open.peek()); -// return nodes; -// } -// -// @Override -// public void processResult(Collection> job, DistributedComputationResult result) { -// -// logger.info("Processing result ..."); -// -// /* mark the nodes that was outsourced to this coworker as closed and update status */ -// for (Node node : job) { -// getEventBus().post(new NodeTypeSwitchEvent>(node, "or_closed")); -// } -// -// /* if neither a solution was found nor we add any nodes to open, report that no change was made to the node set */ -// if (result.getOpen().isEmpty() && result.getSolutions().isEmpty()) -// return; -// -// /* special hints if */ -// if (result.getOpen().isEmpty()) { -// logger.warn("No OPEN nodes were returned in this result. This produces a dead end node!"); -// } -// else { -// /* append open nodes */ -// for (Node p : result.getOpen()) { -// insertNodeIntoLocalGraph(p); -// open.add(getLocalVersionOfNode(p)); -// } -// logger.info("Added {} nodes to open (and a respective number was added in order to make them reachable).", result.getOpen().size()); -// } -// -// /* create solution graphs */ -// for (Node solution : result.getSolutions()) { -// insertNodeIntoLocalGraph(solution); // they will be automatically added to the set of solutions by this -// } -// } -//} +package ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed; +//package jaicore.search.algorithms.parallel.parallelexploration.distributed; +// +//import java.util.ArrayList; +//import java.util.Collection; +// +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +// +//import com.google.common.eventbus.Subscribe; +// +//import jaicore.graphvisualizer.events.graphEvents.NodeTypeSwitchEvent; +//import jaicore.search.algorithms.parallel.parallelexploration.distributed.events.NodePassedToCoworkerEvent; +//import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.DistributedSearchCommunicationLayer; +//import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.DistributionSearchAdapter; +//import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; +//import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableNodeEvaluator; +//import jaicore.search.algorithms.standard.bestfirst.BestFirst; +//import jaicore.search.algorithms.standard.bestfirst.model.Node; +// +//public class DistributedOrSearch> extends BestFirst implements DistributionSearchAdapter { +// +// private static final Logger logger = LoggerFactory.getLogger(DistributedOrSearch.class); +// private final DistributedSearchManager manager; +// +// public DistributedOrSearch(SerializableGraphGenerator graphGenerator, SerializableNodeEvaluator pNodeEvaluator, +// DistributedSearchCommunicationLayer communicationLayer) { +// super(graphGenerator, pNodeEvaluator); +// +// /* initialize communication layer */ +// try { +// communicationLayer.init(); +// communicationLayer.setGraphGenerator(graphGenerator); +// communicationLayer.setNodeEvaluator(pNodeEvaluator); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// /* now start distributed manager */ +// this.manager = new DistributedSearchManager<>(communicationLayer, this); +// this.manager.getEventBus().register(this); +// } +// +// @Override +// protected boolean beforeSelection() { +// if (!super.beforeSelection()) +// return false; +// if (this.manager.getNumberOfHelpers() == this.manager.getNumbetOfIdleCoworkers()) { +// logger.info("There are no (busy) coworkers, continue exploring on my own."); +// return true; +// } +// logger.info("No further local exploration since there are sufficient busy coworkers ..."); +// try { +// Thread.sleep(1000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// return false; +// } +// +// @Subscribe +// public void receiveNodeEvent(NodePassedToCoworkerEvent> e) { +// this.graphEventBus.post(new NodeTypeSwitchEvent<>(e.getNode(), "or_distributed")); +// } +// +// @Override +// public Collection> nextJob() { +// if (open.size() > 1) { +//// int helpers = manager.getNumbetOfIdleCoworkers() + manager.getNumbetOfPendingCoworkers(); +//// int pendingTasks = manager.getNumberOfUnprocessedJobs(); +//// int nodesToOutsource = Math.min(open.size() -1, helpers - pendingTasks); +//// logger.info("Finished node expansion, distributing min({} - 1, {} - {}) = {} nodes ...", open.size() - 1, helpers, pendingTasks, nodesToOutsource); +// Collection> nextJob = pollNodesForDistribution(1); +// logger.info("Passing next job with {} node(s) to the DistributedSearchManager.", nextJob.size()); +// return nextJob; +// } +// return null; +// } +// +// @Override +// protected boolean terminates() { +// if (!super.terminates()) +// return false; +// if (manager.isBusy()) +// return false; +// return true; +// } +// +// public void cancel() { +// super.cancel(); +// manager.shutdown(); +// } +// +// private Collection> pollNodesForDistribution(int helpers) { +// Collection> nodes = new ArrayList<>(); +// if (open.isEmpty()) +// return null; +//// int i = 0; +//// max = open.size(); +//// List> toPutBack = new ArrayList<>(); +//// while (!open.isEmpty() && nodes.size() <= 100000) { +//// if (i % helpers == 0) +//// nodes.add(open.poll()); +//// else +//// toPutBack.add(open.poll()); +//// i++; +//// } +// +// /* return all the not used paths to open */ +//// open.addAll(toPutBack); +//// logger.info("Distributing " + nodes.size() + " of " + max); +// nodes.add(open.peek()); +// open.remove(open.peek()); +// return nodes; +// } +// +// @Override +// public void processResult(Collection> job, DistributedComputationResult result) { +// +// logger.info("Processing result ..."); +// +// /* mark the nodes that was outsourced to this coworker as closed and update status */ +// for (Node node : job) { +// getEventBus().post(new NodeTypeSwitchEvent>(node, "or_closed")); +// } +// +// /* if neither a solution was found nor we add any nodes to open, report that no change was made to the node set */ +// if (result.getOpen().isEmpty() && result.getSolutions().isEmpty()) +// return; +// +// /* special hints if */ +// if (result.getOpen().isEmpty()) { +// logger.warn("No OPEN nodes were returned in this result. This produces a dead end node!"); +// } +// else { +// /* append open nodes */ +// for (Node p : result.getOpen()) { +// insertNodeIntoLocalGraph(p); +// open.add(getLocalVersionOfNode(p)); +// } +// logger.info("Added {} nodes to open (and a respective number was added in order to make them reachable).", result.getOpen().size()); +// } +// +// /* create solution graphs */ +// for (Node solution : result.getSolutions()) { +// insertNodeIntoLocalGraph(solution); // they will be automatically added to the set of solutions by this +// } +// } +//} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearchCoworker.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearchCoworker.java similarity index 96% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearchCoworker.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearchCoworker.java index 7c05b3bad7..07be5464f7 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearchCoworker.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedOrSearchCoworker.java @@ -1,3 +1,4 @@ +package ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed; //package jaicore.search.algorithms.parallel.parallelexploration.distributed; // //import java.nio.file.Path; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedSearchManager.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedSearchManager.java similarity index 90% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedSearchManager.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedSearchManager.java index 80f911a5eb..dcc714b16e 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedSearchManager.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/DistributedSearchManager.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.parallel.parallelexploration.distributed; +package ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed; import java.util.ArrayList; import java.util.Collection; @@ -17,10 +17,10 @@ import com.google.common.eventbus.EventBus; import ai.libs.jaicore.basic.sets.SetUtil; -import jaicore.search.algorithms.parallel.parallelexploration.distributed.events.NodePassedToCoworkerEvent; -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.DistributedSearchCommunicationLayer; -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.DistributionSearchAdapter; -import jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.events.NodePassedToCoworkerEvent; +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.DistributedSearchCommunicationLayer; +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.DistributionSearchAdapter; +import ai.libs.jaicore.search.model.travesaltree.Node; public class DistributedSearchManager> { private static final Logger logger = LoggerFactory.getLogger(DistributedSearchManager.class); diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/FolderBasedDistributedSearchCommunicationLayer.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/FolderBasedDistributedSearchCommunicationLayer.java similarity index 91% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/FolderBasedDistributedSearchCommunicationLayer.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/FolderBasedDistributedSearchCommunicationLayer.java index da581d72a6..0ec52649e4 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/FolderBasedDistributedSearchCommunicationLayer.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/FolderBasedDistributedSearchCommunicationLayer.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.parallel.parallelexploration.distributed; +package ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -26,11 +26,11 @@ import org.slf4j.LoggerFactory; import ai.libs.jaicore.basic.FileUtil; -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.DistributedSearchCommunicationLayer; -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.DistributedSearchCommunicationLayer; +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.model.travesaltree.Node; public class FolderBasedDistributedSearchCommunicationLayer> implements DistributedSearchCommunicationLayer { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/events/NodePassedToCoworkerEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/events/NodePassedToCoworkerEvent.java similarity index 64% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/events/NodePassedToCoworkerEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/events/NodePassedToCoworkerEvent.java index 71e14aee5c..7977e824f2 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/events/NodePassedToCoworkerEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/events/NodePassedToCoworkerEvent.java @@ -1,13 +1,13 @@ -package jaicore.search.algorithms.parallel.parallelexploration.distributed.events; - -public class NodePassedToCoworkerEvent { - private final T node; - - public NodePassedToCoworkerEvent(T node) { - super(); - this.node = node; - } - - public T getNode() { - return node; - }} +package ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.events; + +public class NodePassedToCoworkerEvent { + private final T node; + + public NodePassedToCoworkerEvent(T node) { + super(); + this.node = node; + } + + public T getNode() { + return node; + }} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributedSearchCommunicationLayer.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributedSearchCommunicationLayer.java similarity index 76% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributedSearchCommunicationLayer.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributedSearchCommunicationLayer.java index 3d52a26f19..904800e3e9 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributedSearchCommunicationLayer.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributedSearchCommunicationLayer.java @@ -1,32 +1,32 @@ -package jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces; - -import java.util.Collection; - -import jaicore.search.algorithms.parallel.parallelexploration.distributed.DistributedComputationResult; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.model.travesaltree.Node; - -public interface DistributedSearchCommunicationLayer> { - - /* infrastructural operations */ - public void close(); - - /* master operations */ - public void init(); - public Collection detectNewCoworkers(); - public void createNewJobForCoworker(String coworker, Collection> nodes); - public void attachCoworker(String coworker); - public void detachCoworker(String coworker); - public DistributedComputationResult readResult(String coworker); - public void setGraphGenerator(SerializableGraphGenerator generator) throws Exception; - public void setNodeEvaluator(SerializableNodeEvaluator evaluator) throws Exception; - - /* coworker operations */ - public void register(String coworker) throws InterruptedException; // registers the coworker on the bus and blocks him until it becomes attached - public void unregister(String coworker); - public boolean isAttached(String coworker); - public Collection> nextJob(String coworker) throws InterruptedException; - public SerializableGraphGenerator getGraphGenerator() throws Exception; - public INodeEvaluator getNodeEvaluator() throws Exception; - public void reportResult(String coworker, DistributedComputationResult results); -} +package ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces; + +import java.util.Collection; + +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.DistributedComputationResult; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.model.travesaltree.Node; + +public interface DistributedSearchCommunicationLayer> { + + /* infrastructural operations */ + public void close(); + + /* master operations */ + public void init(); + public Collection detectNewCoworkers(); + public void createNewJobForCoworker(String coworker, Collection> nodes); + public void attachCoworker(String coworker); + public void detachCoworker(String coworker); + public DistributedComputationResult readResult(String coworker); + public void setGraphGenerator(SerializableGraphGenerator generator) throws Exception; + public void setNodeEvaluator(SerializableNodeEvaluator evaluator) throws Exception; + + /* coworker operations */ + public void register(String coworker) throws InterruptedException; // registers the coworker on the bus and blocks him until it becomes attached + public void unregister(String coworker); + public boolean isAttached(String coworker); + public Collection> nextJob(String coworker) throws InterruptedException; + public SerializableGraphGenerator getGraphGenerator() throws Exception; + public INodeEvaluator getNodeEvaluator() throws Exception; + public void reportResult(String coworker, DistributedComputationResult results); +} diff --git a/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributionSearchAdapter.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributionSearchAdapter.java new file mode 100644 index 0000000000..aabd855e24 --- /dev/null +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributionSearchAdapter.java @@ -0,0 +1,11 @@ +package ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces; + +import java.util.Collection; + +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.DistributedComputationResult; +import ai.libs.jaicore.search.model.travesaltree.Node; + +public interface DistributionSearchAdapter> { + public Collection> nextJob(); + public void processResult(Collection> job, DistributedComputationResult result); +} diff --git a/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableGraphGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableGraphGenerator.java new file mode 100644 index 0000000000..031ec7f2fe --- /dev/null +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableGraphGenerator.java @@ -0,0 +1,9 @@ +package ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces; + +import java.io.Serializable; + +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; + +public interface SerializableGraphGenerator extends GraphGenerator, Serializable { + +} diff --git a/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableNodeEvaluator.java new file mode 100644 index 0000000000..906d5516a1 --- /dev/null +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableNodeEvaluator.java @@ -0,0 +1,9 @@ +package ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces; + +import java.io.Serializable; + +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; + +public interface SerializableNodeEvaluator> extends INodeEvaluator, Serializable { + +} diff --git a/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableRootGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableRootGenerator.java new file mode 100644 index 0000000000..2161b4fc02 --- /dev/null +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableRootGenerator.java @@ -0,0 +1,9 @@ +package ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces; + +import java.io.Serializable; + +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; + +public interface SerializableRootGenerator extends SingleRootGenerator, Serializable { + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/astar/AStar.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/astar/AStar.java similarity index 59% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/astar/AStar.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/astar/AStar.java index 50e5ac3417..6719801c20 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/astar/AStar.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/astar/AStar.java @@ -1,18 +1,18 @@ -package jaicore.search.algorithms.standard.astar; - -import jaicore.search.algorithms.standard.bestfirst.BestFirst; -import jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; - -/** - * A* algorithm implementation that is nothing else than BestFirst with a - * specific problem input. - * - * @author Felix Mohr - */ -public class AStar extends BestFirst, N, A, Double> { - - public AStar(GraphSearchWithNumberBasedAdditivePathEvaluation problem) { - super(problem); - } - +package ai.libs.jaicore.search.algorithms.standard.astar; + +import ai.libs.jaicore.search.algorithms.standard.bestfirst.BestFirst; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; + +/** + * A* algorithm implementation that is nothing else than BestFirst with a + * specific problem input. + * + * @author Felix Mohr + */ +public class AStar extends BestFirst, N, A, Double> { + + public AStar(GraphSearchWithNumberBasedAdditivePathEvaluation problem) { + super(problem); + } + } \ No newline at end of file diff --git a/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/astar/AStarEdgeCost.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/astar/AStarEdgeCost.java new file mode 100644 index 0000000000..34ecc3103c --- /dev/null +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/astar/AStarEdgeCost.java @@ -0,0 +1,7 @@ +package ai.libs.jaicore.search.algorithms.standard.astar; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +public interface AStarEdgeCost { + public double g(Node from, Node to); +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/astar/AStarFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/astar/AStarFactory.java similarity index 68% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/astar/AStarFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/astar/AStarFactory.java index 98fa881407..5429c83408 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/astar/AStarFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/astar/AStarFactory.java @@ -1,27 +1,27 @@ -package jaicore.search.algorithms.standard.astar; - -import jaicore.search.algorithms.standard.bestfirst.BestFirstFactory; -import jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; - -public class AStarFactory extends BestFirstFactory, T, A, Double> { - - public AStarFactory() { - super(); - } - - public AStarFactory(final int timeoutForFInMS) { - super(timeoutForFInMS); - } - - @Override - public AStar getAlgorithm() { - return this.getAlgorithm(this.getInput()); - } - - @Override - public AStar getAlgorithm(final GraphSearchWithNumberBasedAdditivePathEvaluation input) { - AStar search = new AStar<>(input); - this.setupAlgorithm(search); - return search; - } -} +package ai.libs.jaicore.search.algorithms.standard.astar; + +import ai.libs.jaicore.search.algorithms.standard.bestfirst.BestFirstFactory; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; + +public class AStarFactory extends BestFirstFactory, T, A, Double> { + + public AStarFactory() { + super(); + } + + public AStarFactory(final int timeoutForFInMS) { + super(timeoutForFInMS); + } + + @Override + public AStar getAlgorithm() { + return this.getAlgorithm(this.getInput()); + } + + @Override + public AStar getAlgorithm(final GraphSearchWithNumberBasedAdditivePathEvaluation input) { + AStar search = new AStar<>(input); + this.setupAlgorithm(search); + return search; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizer.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizer.java similarity index 76% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizer.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizer.java index 9a2a2176e9..9886ff57a8 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizer.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizer.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.auxilliary.iteratingoptimizer; +package ai.libs.jaicore.search.algorithms.standard.auxilliary.iteratingoptimizer; import com.google.common.eventbus.Subscribe; @@ -7,14 +7,14 @@ import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; import ai.libs.jaicore.basic.algorithm.exceptions.ObjectEvaluationFailedException; -import jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; -import jaicore.search.algorithms.standard.bestfirst.events.GraphSearchSolutionCandidateFoundEvent; -import jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.GraphSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; /** * This is a wrapper class to turn non-optimization algorithms into (uninformed working) optimizers. diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizerFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizerFactory.java similarity index 74% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizerFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizerFactory.java index 21707a25d0..66194e6368 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizerFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/auxilliary/iteratingoptimizer/IteratingGraphSearchOptimizerFactory.java @@ -1,12 +1,12 @@ -package jaicore.search.algorithms.standard.auxilliary.iteratingoptimizer; - -import jaicore.search.core.interfaces.IGraphSearchFactory; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.core.interfaces.StandardORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +package ai.libs.jaicore.search.algorithms.standard.auxilliary.iteratingoptimizer; + +import ai.libs.jaicore.search.core.interfaces.IGraphSearchFactory; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.core.interfaces.StandardORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; public class IteratingGraphSearchOptimizerFactory, N, A, V extends Comparable> extends StandardORGraphSearchFactory, N, A, V> implements IOptimalPathInORGraphSearchFactory { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/awastar/AWAStarFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/awastar/AWAStarFactory.java similarity index 58% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/awastar/AWAStarFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/awastar/AWAStarFactory.java index 184bbde1d2..8f8f0965a5 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/awastar/AWAStarFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/awastar/AWAStarFactory.java @@ -1,8 +1,8 @@ -package jaicore.search.algorithms.standard.awastar; +package ai.libs.jaicore.search.algorithms.standard.awastar; -import jaicore.search.core.interfaces.StandardORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.core.interfaces.StandardORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class AWAStarFactory, N, A, V extends Comparable> extends StandardORGraphSearchFactory, N, A, V> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/awastar/AwaStarSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/awastar/AwaStarSearch.java similarity index 86% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/awastar/AwaStarSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/awastar/AwaStarSearch.java index 6a76389ce6..7e7df6c5f9 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/awastar/AwaStarSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/awastar/AwaStarSearch.java @@ -1,295 +1,295 @@ -package jaicore.search.algorithms.standard.awastar; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.PriorityQueue; -import java.util.Queue; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.eventbus.Subscribe; - -import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; -import ai.libs.jaicore.basic.algorithm.events.AlgorithmEvent; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; -import ai.libs.jaicore.graphvisualizer.events.graph.GraphInitializedEvent; -import ai.libs.jaicore.graphvisualizer.events.graph.NodeAddedEvent; -import ai.libs.jaicore.graphvisualizer.events.graph.NodeTypeSwitchEvent; -import jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; -import jaicore.search.algorithms.standard.bestfirst.events.GraphSearchSolutionCandidateFoundEvent; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.ICancelableNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallySolutionReportingNodeEvaluator; -import jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.travesaltree.DefaultNodeComparator; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; -import jaicore.search.structure.graphgenerator.GoalTester; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.PathGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; - -/** - * This is a modified version of the AWA* algorithm for problems without admissible heuristic. - * Important differences are: - * - no early termination if a best-f-valued solution is found as f is not optimistic - * - * @inproceedings{ - * title={AWA*-A Window Constrained Anytime Heuristic Search Algorithm.}, - * author={Aine, Sandip and Chakrabarti, PP and Kumar, Rajeev}, - * booktitle={IJCAI}, - * pages={2250--2255}, - * year={2007} - * } - * - * @author lbrandt2 and fmohr - * - * @param - * @param - * @param - */ -public class AwaStarSearch, T, A, V extends Comparable> extends AOptimalPathInORGraphSearch { - - private Logger logger = LoggerFactory.getLogger(AwaStarSearch.class); - private String loggerName; - - private final SingleRootGenerator rootNodeGenerator; - private final SuccessorGenerator successorGenerator; - private final GoalTester goalTester; - private final INodeEvaluator nodeEvaluator; - private final Queue> closedList; - private final Queue> suspendList; - private final Queue> openList; - private int currentLevel = -1; - private int windowSize; - private final List> unconfirmedSolutions = new ArrayList<>(); // these are solutions emitted on the basis of the node evaluator but whose solutions have not been found in the original graph yet - private final List> unreturnedSolutionEvents = new ArrayList<>(); - - @SuppressWarnings("rawtypes") - public AwaStarSearch(final I problem) { - super(problem); - this.rootNodeGenerator = (SingleRootGenerator) problem.getGraphGenerator().getRootGenerator(); - this.successorGenerator = problem.getGraphGenerator().getSuccessorGenerator(); - this.goalTester = problem.getGraphGenerator().getGoalTester(); - this.nodeEvaluator = problem.getNodeEvaluator(); - - this.closedList = new PriorityQueue<>(new DefaultNodeComparator<>()); - this.suspendList = new PriorityQueue<>(new DefaultNodeComparator<>()); - this.openList = new PriorityQueue<>(new DefaultNodeComparator<>()); - this.windowSize = 0; - if (this.nodeEvaluator instanceof IPotentiallySolutionReportingNodeEvaluator) { - ((IPotentiallySolutionReportingNodeEvaluator) this.nodeEvaluator).registerSolutionListener(this); - } - } - - private void windowAStar() throws AlgorithmTimeoutedException, AlgorithmExecutionCanceledException, InterruptedException, AlgorithmException { - while (!this.openList.isEmpty()) { - this.checkAndConductTermination(); - if (!this.unreturnedSolutionEvents.isEmpty()) { - this.logger.info("Not doing anything because there are still unreturned solutions."); - return; - } - Node n = this.openList.peek(); - this.openList.remove(n); - this.closedList.add(n); - if (!n.isGoal()) { - this.post(new NodeTypeSwitchEvent<>(this.getId(), n, "or_closed")); - } - - /* check whether this node is outside the window and suspend it */ - int nLevel = n.externalPath().size() - 1; - if (nLevel <= (this.currentLevel - this.windowSize)) { - this.closedList.remove(n); - this.suspendList.add(n); - this.logger.info("Suspending node {} with level {}, which is lower than {}", n, nLevel, this.currentLevel - this.windowSize); - this.post(new NodeTypeSwitchEvent<>(this.getId(), n, "or_suspended")); - continue; - } - - /* if the level should even be increased, do this now */ - if (nLevel > this.currentLevel) { - this.logger.info("Switching level from {} to {}", this.currentLevel, nLevel); - this.currentLevel = nLevel; - } - this.checkAndConductTermination(); - - /* compute successors of the expanded node */ - this.logger.debug("Expanding {}. Starting successor generation.", n.getPoint()); - Collection> successors = this.computeTimeoutAware(() -> this.successorGenerator.generateSuccessors(n.getPoint()), "Successor generation timeouted" , true); - this.logger.debug("Successor generation finished. Identified {} successors.", successors.size()); - for (NodeExpansionDescription expansionDescription : successors) { - this.checkAndConductTermination(); - Node nPrime = new Node<>(n, expansionDescription.getTo()); - if (this.goalTester instanceof NodeGoalTester) { - nPrime.setGoal(((NodeGoalTester) this.goalTester).isGoal(nPrime.getPoint())); - } else if (this.goalTester instanceof PathGoalTester) { - nPrime.setGoal(((PathGoalTester) this.goalTester).isGoal(nPrime.externalPath())); - } - V nPrimeScore = this.nodeEvaluator.f(nPrime); - - /* ignore nodes whose value cannot be determined */ - if (nPrimeScore == null) { - this.logger.debug("Discarding node {} for which no f-value could be computed.", nPrime); - continue; - } - - /* determine whether this is a goal node */ - if (nPrime.isGoal()) { - List newSolution = nPrime.externalPath(); - EvaluatedSearchGraphPath solution = new EvaluatedSearchGraphPath<>(newSolution, null, nPrimeScore); - this.registerNewSolutionCandidate(solution); - } - - if (!this.openList.contains(nPrime) && !this.closedList.contains(nPrime) && !this.suspendList.contains(nPrime)) { - nPrime.setParent(n); - nPrime.setInternalLabel(nPrimeScore); - if (!nPrime.isGoal()) { - this.openList.add(nPrime); - } - this.post(new NodeAddedEvent<>(this.getId(), n, nPrime, nPrime.isGoal() ? "or_solution" : "or_open")); - } else if (this.openList.contains(nPrime) || this.suspendList.contains(nPrime)) { - V oldScore = nPrime.getInternalLabel(); - if (oldScore != null && oldScore.compareTo(nPrimeScore) > 0) { - nPrime.setParent(n); - nPrime.setInternalLabel(nPrimeScore); - } - } else if (this.closedList.contains(nPrime)) { - V oldScore = nPrime.getInternalLabel(); - if (oldScore != null && oldScore.compareTo(nPrimeScore) > 0) { - nPrime.setParent(n); - nPrime.setInternalLabel(nPrimeScore); - } - if (!nPrime.isGoal()) { - this.openList.add(nPrime); - } - } - } - } - } - - @Subscribe - public void receiveSolutionEvent(final EvaluatedSearchSolutionCandidateFoundEvent solutionEvent) { - this.registerNewSolutionCandidate(solutionEvent.getSolutionCandidate()); - this.unconfirmedSolutions.add(solutionEvent.getSolutionCandidate()); - } - - public EvaluatedSearchSolutionCandidateFoundEvent registerNewSolutionCandidate(final EvaluatedSearchGraphPath solution) { - EvaluatedSearchSolutionCandidateFoundEvent event = this.registerSolution(solution); - this.unreturnedSolutionEvents.add(event); - return event; - } - - @Override - public AlgorithmEvent nextWithException() throws InterruptedException, AlgorithmExecutionCanceledException, AlgorithmTimeoutedException, AlgorithmException { - try { - this.registerActiveThread(); - this.logger.debug("Next step in {}. State is {}", this.getId(), this.getState()); - this.checkAndConductTermination(); - switch (this.getState()) { - case created: - T externalRootNode = this.rootNodeGenerator.getRoot(); - Node rootNode = new Node<>(null, externalRootNode); - this.logger.info("Initializing graph and OPEN with {}.", rootNode); - this.openList.add(rootNode); - this.post(new GraphInitializedEvent<>(this.getId(), rootNode)); - rootNode.setInternalLabel(this.nodeEvaluator.f(rootNode)); - return this.activate(); - - case active: - AlgorithmEvent event; - this.logger.info("Searching for next solution."); - - /* return pending solutions if there are any */ - while (this.unreturnedSolutionEvents.isEmpty()) { - this.checkAndConductTermination(); - - /* if the current graph has been exhausted, add all suspended nodes to OPEN and increase window size */ - if (this.openList.isEmpty()) { - if (this.suspendList.isEmpty()) { - this.logger.info("The whole graph has been exhausted. No more solutions can be found!"); - return this.terminate(); - } else { - this.logger.info("Search with window size {} is exhausted. Reactivating {} suspended nodes and incrementing window size.", this.windowSize, this.suspendList.size()); - this.openList.addAll(this.suspendList); - this.suspendList.clear(); - this.windowSize++; - this.currentLevel = -1; - } - } - this.logger.info("Running core algorithm with window size {} and current level {}. {} items are in OPEN", this.windowSize, this.currentLevel, this.openList.size()); - this.windowAStar(); - } - - /* if we reached this point, there is at least one item in the result list. We return it */ - event = this.unreturnedSolutionEvents.get(0); - this.unreturnedSolutionEvents.remove(0); - if (!(event instanceof GraphSearchSolutionCandidateFoundEvent)) { // solution events are sent directly over the event bus - this.post(event); - } - return event; - - default: - throw new IllegalStateException("Cannot do anything in state " + this.getState()); - } - } - finally { - this.unregisterActiveThread(); - } - } - - @Override - protected void shutdown() { - - if (this.isShutdownInitialized()) { - return; - } - - /* set state to inactive*/ - this.logger.info("Invoking shutdown routine ..."); - - super.shutdown(); - - /* cancel node evaluator */ - if (this.nodeEvaluator instanceof ICancelableNodeEvaluator) { - this.logger.info("Canceling node evaluator."); - ((ICancelableNodeEvaluator) this.nodeEvaluator).cancelActiveTasks(); - } - - } - - @Override - public void setNumCPUs(final int numberOfCPUs) { - this.logger.warn("Currently no support for parallelization"); - } - - @Override - public int getNumCPUs() { - return 1; - } - - @Override - public GraphGenerator getGraphGenerator() { - return this.getInput().getGraphGenerator(); - } - - @Override - public void setLoggerName(final String name) { - this.logger.info("Switching logger to {}", name); - this.loggerName = name; - this.logger = LoggerFactory.getLogger(name); - this.logger.info("Switched to logger {}", name); - super.setLoggerName(this.loggerName + "._orgraphsearch"); - } - - @Override - public String getLoggerName() { - return this.loggerName; - } -} +package ai.libs.jaicore.search.algorithms.standard.awastar; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.PriorityQueue; +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.eventbus.Subscribe; + +import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; +import ai.libs.jaicore.basic.algorithm.events.AlgorithmEvent; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; +import ai.libs.jaicore.graphvisualizer.events.graph.GraphInitializedEvent; +import ai.libs.jaicore.graphvisualizer.events.graph.NodeAddedEvent; +import ai.libs.jaicore.graphvisualizer.events.graph.NodeTypeSwitchEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.GraphSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.ICancelableNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallySolutionReportingNodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.travesaltree.DefaultNodeComparator; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.structure.graphgenerator.GoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.PathGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; + +/** + * This is a modified version of the AWA* algorithm for problems without admissible heuristic. + * Important differences are: + * - no early termination if a best-f-valued solution is found as f is not optimistic + * + * @inproceedings{ + * title={AWA*-A Window Constrained Anytime Heuristic Search Algorithm.}, + * author={Aine, Sandip and Chakrabarti, PP and Kumar, Rajeev}, + * booktitle={IJCAI}, + * pages={2250--2255}, + * year={2007} + * } + * + * @author lbrandt2 and fmohr + * + * @param + * @param + * @param + */ +public class AwaStarSearch, T, A, V extends Comparable> extends AOptimalPathInORGraphSearch { + + private Logger logger = LoggerFactory.getLogger(AwaStarSearch.class); + private String loggerName; + + private final SingleRootGenerator rootNodeGenerator; + private final SuccessorGenerator successorGenerator; + private final GoalTester goalTester; + private final INodeEvaluator nodeEvaluator; + private final Queue> closedList; + private final Queue> suspendList; + private final Queue> openList; + private int currentLevel = -1; + private int windowSize; + private final List> unconfirmedSolutions = new ArrayList<>(); // these are solutions emitted on the basis of the node evaluator but whose solutions have not been found in the original graph yet + private final List> unreturnedSolutionEvents = new ArrayList<>(); + + @SuppressWarnings("rawtypes") + public AwaStarSearch(final I problem) { + super(problem); + this.rootNodeGenerator = (SingleRootGenerator) problem.getGraphGenerator().getRootGenerator(); + this.successorGenerator = problem.getGraphGenerator().getSuccessorGenerator(); + this.goalTester = problem.getGraphGenerator().getGoalTester(); + this.nodeEvaluator = problem.getNodeEvaluator(); + + this.closedList = new PriorityQueue<>(new DefaultNodeComparator<>()); + this.suspendList = new PriorityQueue<>(new DefaultNodeComparator<>()); + this.openList = new PriorityQueue<>(new DefaultNodeComparator<>()); + this.windowSize = 0; + if (this.nodeEvaluator instanceof IPotentiallySolutionReportingNodeEvaluator) { + ((IPotentiallySolutionReportingNodeEvaluator) this.nodeEvaluator).registerSolutionListener(this); + } + } + + private void windowAStar() throws AlgorithmTimeoutedException, AlgorithmExecutionCanceledException, InterruptedException, AlgorithmException { + while (!this.openList.isEmpty()) { + this.checkAndConductTermination(); + if (!this.unreturnedSolutionEvents.isEmpty()) { + this.logger.info("Not doing anything because there are still unreturned solutions."); + return; + } + Node n = this.openList.peek(); + this.openList.remove(n); + this.closedList.add(n); + if (!n.isGoal()) { + this.post(new NodeTypeSwitchEvent<>(this.getId(), n, "or_closed")); + } + + /* check whether this node is outside the window and suspend it */ + int nLevel = n.externalPath().size() - 1; + if (nLevel <= (this.currentLevel - this.windowSize)) { + this.closedList.remove(n); + this.suspendList.add(n); + this.logger.info("Suspending node {} with level {}, which is lower than {}", n, nLevel, this.currentLevel - this.windowSize); + this.post(new NodeTypeSwitchEvent<>(this.getId(), n, "or_suspended")); + continue; + } + + /* if the level should even be increased, do this now */ + if (nLevel > this.currentLevel) { + this.logger.info("Switching level from {} to {}", this.currentLevel, nLevel); + this.currentLevel = nLevel; + } + this.checkAndConductTermination(); + + /* compute successors of the expanded node */ + this.logger.debug("Expanding {}. Starting successor generation.", n.getPoint()); + Collection> successors = this.computeTimeoutAware(() -> this.successorGenerator.generateSuccessors(n.getPoint()), "Successor generation timeouted" , true); + this.logger.debug("Successor generation finished. Identified {} successors.", successors.size()); + for (NodeExpansionDescription expansionDescription : successors) { + this.checkAndConductTermination(); + Node nPrime = new Node<>(n, expansionDescription.getTo()); + if (this.goalTester instanceof NodeGoalTester) { + nPrime.setGoal(((NodeGoalTester) this.goalTester).isGoal(nPrime.getPoint())); + } else if (this.goalTester instanceof PathGoalTester) { + nPrime.setGoal(((PathGoalTester) this.goalTester).isGoal(nPrime.externalPath())); + } + V nPrimeScore = this.nodeEvaluator.f(nPrime); + + /* ignore nodes whose value cannot be determined */ + if (nPrimeScore == null) { + this.logger.debug("Discarding node {} for which no f-value could be computed.", nPrime); + continue; + } + + /* determine whether this is a goal node */ + if (nPrime.isGoal()) { + List newSolution = nPrime.externalPath(); + EvaluatedSearchGraphPath solution = new EvaluatedSearchGraphPath<>(newSolution, null, nPrimeScore); + this.registerNewSolutionCandidate(solution); + } + + if (!this.openList.contains(nPrime) && !this.closedList.contains(nPrime) && !this.suspendList.contains(nPrime)) { + nPrime.setParent(n); + nPrime.setInternalLabel(nPrimeScore); + if (!nPrime.isGoal()) { + this.openList.add(nPrime); + } + this.post(new NodeAddedEvent<>(this.getId(), n, nPrime, nPrime.isGoal() ? "or_solution" : "or_open")); + } else if (this.openList.contains(nPrime) || this.suspendList.contains(nPrime)) { + V oldScore = nPrime.getInternalLabel(); + if (oldScore != null && oldScore.compareTo(nPrimeScore) > 0) { + nPrime.setParent(n); + nPrime.setInternalLabel(nPrimeScore); + } + } else if (this.closedList.contains(nPrime)) { + V oldScore = nPrime.getInternalLabel(); + if (oldScore != null && oldScore.compareTo(nPrimeScore) > 0) { + nPrime.setParent(n); + nPrime.setInternalLabel(nPrimeScore); + } + if (!nPrime.isGoal()) { + this.openList.add(nPrime); + } + } + } + } + } + + @Subscribe + public void receiveSolutionEvent(final EvaluatedSearchSolutionCandidateFoundEvent solutionEvent) { + this.registerNewSolutionCandidate(solutionEvent.getSolutionCandidate()); + this.unconfirmedSolutions.add(solutionEvent.getSolutionCandidate()); + } + + public EvaluatedSearchSolutionCandidateFoundEvent registerNewSolutionCandidate(final EvaluatedSearchGraphPath solution) { + EvaluatedSearchSolutionCandidateFoundEvent event = this.registerSolution(solution); + this.unreturnedSolutionEvents.add(event); + return event; + } + + @Override + public AlgorithmEvent nextWithException() throws InterruptedException, AlgorithmExecutionCanceledException, AlgorithmTimeoutedException, AlgorithmException { + try { + this.registerActiveThread(); + this.logger.debug("Next step in {}. State is {}", this.getId(), this.getState()); + this.checkAndConductTermination(); + switch (this.getState()) { + case created: + T externalRootNode = this.rootNodeGenerator.getRoot(); + Node rootNode = new Node<>(null, externalRootNode); + this.logger.info("Initializing graph and OPEN with {}.", rootNode); + this.openList.add(rootNode); + this.post(new GraphInitializedEvent<>(this.getId(), rootNode)); + rootNode.setInternalLabel(this.nodeEvaluator.f(rootNode)); + return this.activate(); + + case active: + AlgorithmEvent event; + this.logger.info("Searching for next solution."); + + /* return pending solutions if there are any */ + while (this.unreturnedSolutionEvents.isEmpty()) { + this.checkAndConductTermination(); + + /* if the current graph has been exhausted, add all suspended nodes to OPEN and increase window size */ + if (this.openList.isEmpty()) { + if (this.suspendList.isEmpty()) { + this.logger.info("The whole graph has been exhausted. No more solutions can be found!"); + return this.terminate(); + } else { + this.logger.info("Search with window size {} is exhausted. Reactivating {} suspended nodes and incrementing window size.", this.windowSize, this.suspendList.size()); + this.openList.addAll(this.suspendList); + this.suspendList.clear(); + this.windowSize++; + this.currentLevel = -1; + } + } + this.logger.info("Running core algorithm with window size {} and current level {}. {} items are in OPEN", this.windowSize, this.currentLevel, this.openList.size()); + this.windowAStar(); + } + + /* if we reached this point, there is at least one item in the result list. We return it */ + event = this.unreturnedSolutionEvents.get(0); + this.unreturnedSolutionEvents.remove(0); + if (!(event instanceof GraphSearchSolutionCandidateFoundEvent)) { // solution events are sent directly over the event bus + this.post(event); + } + return event; + + default: + throw new IllegalStateException("Cannot do anything in state " + this.getState()); + } + } + finally { + this.unregisterActiveThread(); + } + } + + @Override + protected void shutdown() { + + if (this.isShutdownInitialized()) { + return; + } + + /* set state to inactive*/ + this.logger.info("Invoking shutdown routine ..."); + + super.shutdown(); + + /* cancel node evaluator */ + if (this.nodeEvaluator instanceof ICancelableNodeEvaluator) { + this.logger.info("Canceling node evaluator."); + ((ICancelableNodeEvaluator) this.nodeEvaluator).cancelActiveTasks(); + } + + } + + @Override + public void setNumCPUs(final int numberOfCPUs) { + this.logger.warn("Currently no support for parallelization"); + } + + @Override + public int getNumCPUs() { + return 1; + } + + @Override + public GraphGenerator getGraphGenerator() { + return this.getInput().getGraphGenerator(); + } + + @Override + public void setLoggerName(final String name) { + this.logger.info("Switching logger to {}", name); + this.loggerName = name; + this.logger = LoggerFactory.getLogger(name); + this.logger.info("Switched to logger {}", name); + super.setLoggerName(this.loggerName + "._orgraphsearch"); + } + + @Override + public String getLoggerName() { + return this.loggerName; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/BestFirst.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/BestFirst.java similarity index 93% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/BestFirst.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/BestFirst.java index 9c4e3738a2..846db30e9a 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/BestFirst.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/BestFirst.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst; +package ai.libs.jaicore.search.algorithms.standard.bestfirst; import java.util.ArrayList; import java.util.Collection; @@ -47,33 +47,33 @@ import ai.libs.jaicore.interrupt.InterruptionTimerTask; import ai.libs.jaicore.logging.LoggerUtil; import ai.libs.jaicore.logging.ToJSONStringUtil; -import jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; -import jaicore.search.algorithms.standard.bestfirst.events.NodeAnnotationEvent; -import jaicore.search.algorithms.standard.bestfirst.events.NodeExpansionCompletedEvent; -import jaicore.search.algorithms.standard.bestfirst.events.NodeExpansionJobSubmittedEvent; -import jaicore.search.algorithms.standard.bestfirst.events.RemovedGoalNodeFromOpenEvent; -import jaicore.search.algorithms.standard.bestfirst.events.RolloutEvent; -import jaicore.search.algorithms.standard.bestfirst.events.SolutionAnnotationEvent; -import jaicore.search.algorithms.standard.bestfirst.events.SuccessorComputationCompletedEvent; -import jaicore.search.algorithms.standard.bestfirst.exceptions.ControlledNodeEvaluationException; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.DecoratingNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.ICancelableNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallyGraphDependentNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallySolutionReportingNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallyUncertaintyAnnotatingNodeEvaluator; -import jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; -import jaicore.search.structure.graphgenerator.MultipleRootGenerator; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.PathGoalTester; -import jaicore.search.structure.graphgenerator.RootGenerator; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.NodeAnnotationEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.NodeExpansionCompletedEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.NodeExpansionJobSubmittedEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.RemovedGoalNodeFromOpenEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.RolloutEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.SolutionAnnotationEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.SuccessorComputationCompletedEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.ControlledNodeEvaluationException; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.DecoratingNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.ICancelableNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallyGraphDependentNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallySolutionReportingNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallyUncertaintyAnnotatingNodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.structure.graphgenerator.MultipleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.PathGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.RootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; /** * diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/BestFirstEpsilon.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/BestFirstEpsilon.java similarity index 90% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/BestFirstEpsilon.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/BestFirstEpsilon.java index 0af02e2ffc..b3d1ac5edd 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/BestFirstEpsilon.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/BestFirstEpsilon.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst; +package ai.libs.jaicore.search.algorithms.standard.bestfirst; import java.util.Collection; import java.util.HashMap; @@ -10,9 +10,9 @@ import org.slf4j.LoggerFactory; import ai.libs.jaicore.basic.ILoggingCustomizable; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; /** * A* algorithm implementation using the method design pattern. diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/BestFirstFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/BestFirstFactory.java similarity index 79% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/BestFirstFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/BestFirstFactory.java index c4cd19d765..521624743d 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/BestFirstFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/BestFirstFactory.java @@ -1,75 +1,75 @@ -package jaicore.search.algorithms.standard.bestfirst; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.core.interfaces.StandardORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; - -public class BestFirstFactory

, N, A, V extends Comparable> extends StandardORGraphSearchFactory, N, A, V> -implements IOptimalPathInORGraphSearchFactory { - - private int timeoutForFInMS; - private INodeEvaluator timeoutEvaluator; - private Logger logger = LoggerFactory.getLogger(BestFirstFactory.class); - - public BestFirstFactory() { - super(); - } - - public BestFirstFactory(final int timeoutForFInMS) { - this(); - if (timeoutForFInMS > 0) { - this.timeoutForFInMS = timeoutForFInMS; - } - } - - @Override - public BestFirst getAlgorithm() { - if (this.getInput().getGraphGenerator() == null) { - throw new IllegalStateException("Cannot produce BestFirst searches before the graph generator is set in the problem."); - } - if (this.getInput().getNodeEvaluator() == null) { - throw new IllegalStateException("Cannot produce BestFirst searches before the node evaluator is set."); - } - return this.getAlgorithm(this.getInput()); - } - - public void setTimeoutForFComputation(final int timeoutInMS, final INodeEvaluator timeoutEvaluator) { - this.timeoutForFInMS = timeoutInMS; - this.timeoutEvaluator = timeoutEvaluator; - } - - public int getTimeoutForFInMS() { - return this.timeoutForFInMS; - } - - public INodeEvaluator getTimeoutEvaluator() { - return this.timeoutEvaluator; - } - - public String getLoggerName() { - return this.logger.getName(); - } - - public void setLoggerName(final String loggerName) { - this.logger = LoggerFactory.getLogger(loggerName); - } - - @Override - public BestFirst getAlgorithm(final P problem) { - BestFirst search = new BestFirst<>(problem); - this.setupAlgorithm(search); - return search; - } - - protected void setupAlgorithm(final BestFirst algorithm) { - algorithm.setTimeoutForComputationOfF(this.timeoutForFInMS, this.timeoutEvaluator); - if (this.getLoggerName() != null && this.getLoggerName().length() > 0) { - algorithm.setLoggerName(this.getLoggerName()); - } - } -} +package ai.libs.jaicore.search.algorithms.standard.bestfirst; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.core.interfaces.StandardORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; + +public class BestFirstFactory

, N, A, V extends Comparable> extends StandardORGraphSearchFactory, N, A, V> +implements IOptimalPathInORGraphSearchFactory { + + private int timeoutForFInMS; + private INodeEvaluator timeoutEvaluator; + private Logger logger = LoggerFactory.getLogger(BestFirstFactory.class); + + public BestFirstFactory() { + super(); + } + + public BestFirstFactory(final int timeoutForFInMS) { + this(); + if (timeoutForFInMS > 0) { + this.timeoutForFInMS = timeoutForFInMS; + } + } + + @Override + public BestFirst getAlgorithm() { + if (this.getInput().getGraphGenerator() == null) { + throw new IllegalStateException("Cannot produce BestFirst searches before the graph generator is set in the problem."); + } + if (this.getInput().getNodeEvaluator() == null) { + throw new IllegalStateException("Cannot produce BestFirst searches before the node evaluator is set."); + } + return this.getAlgorithm(this.getInput()); + } + + public void setTimeoutForFComputation(final int timeoutInMS, final INodeEvaluator timeoutEvaluator) { + this.timeoutForFInMS = timeoutInMS; + this.timeoutEvaluator = timeoutEvaluator; + } + + public int getTimeoutForFInMS() { + return this.timeoutForFInMS; + } + + public INodeEvaluator getTimeoutEvaluator() { + return this.timeoutEvaluator; + } + + public String getLoggerName() { + return this.logger.getName(); + } + + public void setLoggerName(final String loggerName) { + this.logger = LoggerFactory.getLogger(loggerName); + } + + @Override + public BestFirst getAlgorithm(final P problem) { + BestFirst search = new BestFirst<>(problem); + this.setupAlgorithm(search); + return search; + } + + protected void setupAlgorithm(final BestFirst algorithm) { + algorithm.setTimeoutForComputationOfF(this.timeoutForFInMS, this.timeoutEvaluator); + if (this.getLoggerName() != null && this.getLoggerName().length() > 0) { + algorithm.setLoggerName(this.getLoggerName()); + } + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/IBestFirstConfig.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/IBestFirstConfig.java similarity index 67% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/IBestFirstConfig.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/IBestFirstConfig.java index 8f168dbf30..64910242a9 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/IBestFirstConfig.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/IBestFirstConfig.java @@ -1,7 +1,7 @@ -package jaicore.search.algorithms.standard.bestfirst; +package ai.libs.jaicore.search.algorithms.standard.bestfirst; import ai.libs.jaicore.basic.algorithm.IAlgorithmConfig; -import jaicore.search.algorithms.standard.bestfirst.BestFirst.ParentDiscarding; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.BestFirst.ParentDiscarding; public interface IBestFirstConfig extends IAlgorithmConfig { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/StandardBestFirst.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/StandardBestFirst.java similarity index 61% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/StandardBestFirst.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/StandardBestFirst.java index a9260ab7e5..3e7edfb764 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/StandardBestFirst.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/StandardBestFirst.java @@ -1,6 +1,6 @@ -package jaicore.search.algorithms.standard.bestfirst; +package ai.libs.jaicore.search.algorithms.standard.bestfirst; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class StandardBestFirst> extends BestFirst, N, A, V> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/StandardBestFirstFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/StandardBestFirstFactory.java similarity index 86% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/StandardBestFirstFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/StandardBestFirstFactory.java index 270915f5a9..127dc27ee2 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/StandardBestFirstFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/StandardBestFirstFactory.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst; +package ai.libs.jaicore.search.algorithms.standard.bestfirst; import java.util.HashMap; import java.util.Map; @@ -8,10 +8,10 @@ import ai.libs.jaicore.basic.ILoggingCustomizable; import ai.libs.jaicore.logging.ToJSONStringUtil; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class StandardBestFirstFactory> extends BestFirstFactory, N, A, V> implements ILoggingCustomizable { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/BestFirstEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/BestFirstEvent.java similarity index 70% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/BestFirstEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/BestFirstEvent.java index 6e41d5b052..929b68caeb 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/BestFirstEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/BestFirstEvent.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst.events; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.events; import ai.libs.jaicore.basic.algorithm.events.AAlgorithmEvent; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/EvaluatedSearchSolutionCandidateFoundEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/EvaluatedSearchSolutionCandidateFoundEvent.java similarity index 80% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/EvaluatedSearchSolutionCandidateFoundEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/EvaluatedSearchSolutionCandidateFoundEvent.java index 0d656a9a18..d4bd4fa254 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/EvaluatedSearchSolutionCandidateFoundEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/EvaluatedSearchSolutionCandidateFoundEvent.java @@ -1,7 +1,7 @@ -package jaicore.search.algorithms.standard.bestfirst.events; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.events; import ai.libs.jaicore.basic.algorithm.events.ScoredSolutionCandidateFoundEvent; -import jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; public class EvaluatedSearchSolutionCandidateFoundEvent> extends GraphSearchSolutionCandidateFoundEvent> implements ScoredSolutionCandidateFoundEvent, V> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/GraphSearchSolutionCandidateFoundEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/GraphSearchSolutionCandidateFoundEvent.java similarity index 75% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/GraphSearchSolutionCandidateFoundEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/GraphSearchSolutionCandidateFoundEvent.java index d8b67185c6..32f7d39d0c 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/GraphSearchSolutionCandidateFoundEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/GraphSearchSolutionCandidateFoundEvent.java @@ -1,7 +1,7 @@ -package jaicore.search.algorithms.standard.bestfirst.events; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.events; import ai.libs.jaicore.basic.algorithm.events.ASolutionCandidateFoundEvent; -import jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; /** * diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/LastEventBeforeTermination.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/LastEventBeforeTermination.java similarity index 73% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/LastEventBeforeTermination.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/LastEventBeforeTermination.java index f002806daf..830c188c79 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/LastEventBeforeTermination.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/LastEventBeforeTermination.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst.events; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.events; import ai.libs.jaicore.basic.algorithm.events.AAlgorithmEvent; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/NodeAnnotationEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/NodeAnnotationEvent.java similarity index 85% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/NodeAnnotationEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/NodeAnnotationEvent.java index 3be34a697a..a3561e7bea 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/NodeAnnotationEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/NodeAnnotationEvent.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst.events; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.events; public class NodeAnnotationEvent extends BestFirstEvent { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionCompletedEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionCompletedEvent.java similarity index 81% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionCompletedEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionCompletedEvent.java index b4e0c744dd..b898a4e305 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionCompletedEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionCompletedEvent.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst.events; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.events; import ai.libs.jaicore.basic.algorithm.events.AAlgorithmEvent; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionJobSubmittedEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionJobSubmittedEvent.java similarity index 72% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionJobSubmittedEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionJobSubmittedEvent.java index b962185a03..272805b2e0 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionJobSubmittedEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/NodeExpansionJobSubmittedEvent.java @@ -1,9 +1,9 @@ -package jaicore.search.algorithms.standard.bestfirst.events; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.events; import java.util.List; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; public class NodeExpansionJobSubmittedEvent> extends BestFirstEvent { private final Node expandedNode; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/RemovedGoalNodeFromOpenEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/RemovedGoalNodeFromOpenEvent.java similarity index 74% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/RemovedGoalNodeFromOpenEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/RemovedGoalNodeFromOpenEvent.java index 8d1b3c83f5..3349fe84c5 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/RemovedGoalNodeFromOpenEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/RemovedGoalNodeFromOpenEvent.java @@ -1,7 +1,7 @@ -package jaicore.search.algorithms.standard.bestfirst.events; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.events; import ai.libs.jaicore.basic.algorithm.events.AAlgorithmEvent; -import jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.model.travesaltree.Node; public class RemovedGoalNodeFromOpenEvent> extends AAlgorithmEvent { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/RolloutEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/RolloutEvent.java similarity index 82% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/RolloutEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/RolloutEvent.java index 53a51e51c1..2dd80d63c2 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/RolloutEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/RolloutEvent.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst.events; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.events; import java.util.List; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/SolutionAnnotationEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/SolutionAnnotationEvent.java similarity index 81% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/SolutionAnnotationEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/SolutionAnnotationEvent.java index a2a09b4627..c0c619a495 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/SolutionAnnotationEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/SolutionAnnotationEvent.java @@ -1,6 +1,6 @@ -package jaicore.search.algorithms.standard.bestfirst.events; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.events; -import jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; public class SolutionAnnotationEvent> extends BestFirstEvent { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/SuccessorComputationCompletedEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/SuccessorComputationCompletedEvent.java similarity index 78% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/SuccessorComputationCompletedEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/SuccessorComputationCompletedEvent.java index 132f8ab69e..e1ca9d929b 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/events/SuccessorComputationCompletedEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/events/SuccessorComputationCompletedEvent.java @@ -1,9 +1,9 @@ -package jaicore.search.algorithms.standard.bestfirst.events; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.events; import java.util.List; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; public class SuccessorComputationCompletedEvent extends BestFirstEvent { private Node node; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/exceptions/ControlledNodeEvaluationException.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/exceptions/ControlledNodeEvaluationException.java similarity index 77% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/exceptions/ControlledNodeEvaluationException.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/exceptions/ControlledNodeEvaluationException.java index 0947119e59..22e227a856 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/exceptions/ControlledNodeEvaluationException.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/exceptions/ControlledNodeEvaluationException.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst.exceptions; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions; /** * Use this exception if the node evaluation was rejected on purpose. diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/exceptions/NodeEvaluationException.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/exceptions/NodeEvaluationException.java similarity index 79% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/exceptions/NodeEvaluationException.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/exceptions/NodeEvaluationException.java index 4484228cd8..cb6dae648c 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/exceptions/NodeEvaluationException.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/exceptions/NodeEvaluationException.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst.exceptions; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions; import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/AlternativeNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/AlternativeNodeEvaluator.java similarity index 88% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/AlternativeNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/AlternativeNodeEvaluator.java index e902307070..64040cc536 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/AlternativeNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/AlternativeNodeEvaluator.java @@ -1,13 +1,13 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; import java.util.HashMap; import java.util.Map; import ai.libs.jaicore.basic.ILoggingCustomizable; import ai.libs.jaicore.logging.ToJSONStringUtil; -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.Node; /** * This node evaluator can be used diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/DecoratingNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/DecoratingNodeEvaluator.java similarity index 90% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/DecoratingNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/DecoratingNodeEvaluator.java index 9a8aca27af..96931aecd0 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/DecoratingNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/DecoratingNodeEvaluator.java @@ -1,12 +1,12 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ai.libs.jaicore.basic.ILoggingCustomizable; -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.Node; public abstract class DecoratingNodeEvaluator> implements INodeEvaluator, ICancelableNodeEvaluator, ILoggingCustomizable, IPotentiallyGraphDependentNodeEvaluator, IPotentiallySolutionReportingNodeEvaluator { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/ICancelableNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/ICancelableNodeEvaluator.java similarity index 50% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/ICancelableNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/ICancelableNodeEvaluator.java index 16d0ffa07b..aaa582fc35 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/ICancelableNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/ICancelableNodeEvaluator.java @@ -1,6 +1,6 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; - -public interface ICancelableNodeEvaluator { - - public void cancelActiveTasks(); -} +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; + +public interface ICancelableNodeEvaluator { + + public void cancelActiveTasks(); +} diff --git a/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/INodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/INodeEvaluator.java new file mode 100644 index 0000000000..4d0d26ea06 --- /dev/null +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/INodeEvaluator.java @@ -0,0 +1,8 @@ +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; + +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.model.travesaltree.Node; + +public interface INodeEvaluator> { + public V f(Node node) throws NodeEvaluationException, InterruptedException; +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyGraphDependentNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyGraphDependentNodeEvaluator.java similarity index 60% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyGraphDependentNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyGraphDependentNodeEvaluator.java index 2376c73213..a982f31047 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyGraphDependentNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyGraphDependentNodeEvaluator.java @@ -1,8 +1,8 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; - -import jaicore.search.core.interfaces.GraphGenerator; - -public interface IPotentiallyGraphDependentNodeEvaluator> extends INodeEvaluator { - public boolean requiresGraphGenerator(); - public void setGenerator(GraphGenerator generator); -} +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; + +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; + +public interface IPotentiallyGraphDependentNodeEvaluator> extends INodeEvaluator { + public boolean requiresGraphGenerator(); + public void setGenerator(GraphGenerator generator); +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallySolutionReportingNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallySolutionReportingNodeEvaluator.java similarity index 86% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallySolutionReportingNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallySolutionReportingNodeEvaluator.java index 9c8bce7ec8..674a2eb6b6 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallySolutionReportingNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallySolutionReportingNodeEvaluator.java @@ -1,16 +1,16 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; - -/** - * This interface suggests that the node evaluator MAY report solutions that he finds under a node. - * However, not every such solution NEEDS to be reported. - * In particular, algorithms using solution reports must anticipate that solutions are found that were not already reported by the node evaluator. - * - * @author fmohr - * - * @param - * @param - */ -public interface IPotentiallySolutionReportingNodeEvaluator> extends INodeEvaluator { - public void registerSolutionListener(Object listener); - public boolean reportsSolutions(); -} +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; + +/** + * This interface suggests that the node evaluator MAY report solutions that he finds under a node. + * However, not every such solution NEEDS to be reported. + * In particular, algorithms using solution reports must anticipate that solutions are found that were not already reported by the node evaluator. + * + * @author fmohr + * + * @param + * @param + */ +public interface IPotentiallySolutionReportingNodeEvaluator> extends INodeEvaluator { + public void registerSolutionListener(Object listener); + public boolean reportsSolutions(); +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyUncertaintyAnnotatingNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyUncertaintyAnnotatingNodeEvaluator.java similarity index 59% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyUncertaintyAnnotatingNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyUncertaintyAnnotatingNodeEvaluator.java index afcfb1bb2b..da503068f9 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyUncertaintyAnnotatingNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/IPotentiallyUncertaintyAnnotatingNodeEvaluator.java @@ -1,6 +1,6 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; -import jaicore.search.algorithms.standard.uncertainty.IUncertaintySource; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.IUncertaintySource; public interface IPotentiallyUncertaintyAnnotatingNodeEvaluator> extends INodeEvaluator { public void setUncertaintySource(IUncertaintySource uncertaintySource); diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/LinearCombiningNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/LinearCombiningNodeEvaluator.java similarity index 74% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/LinearCombiningNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/LinearCombiningNodeEvaluator.java index 91446afb0d..4e003bcbca 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/LinearCombiningNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/LinearCombiningNodeEvaluator.java @@ -1,34 +1,34 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; - -import java.util.Map; - -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.model.travesaltree.Node; - -public class LinearCombiningNodeEvaluator implements INodeEvaluator { - - private final Map, Double> evaluators; - - public LinearCombiningNodeEvaluator(Map, Double> evaluators) { - super(); - this.evaluators = evaluators; - } - - @Override - public Double f(Node node) throws NodeEvaluationException, InterruptedException { - double score = 0; - double incr; - for (INodeEvaluator evaluator : evaluators.keySet()) { - if (evaluators.get(evaluator) != 0) { - incr = evaluator.f(node); - if (incr == Integer.MAX_VALUE) { - score = Integer.MAX_VALUE; - break; - } - else - score += incr * evaluators.get(evaluator); - } - } - return score; - } -} +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; + +import java.util.Map; + +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.model.travesaltree.Node; + +public class LinearCombiningNodeEvaluator implements INodeEvaluator { + + private final Map, Double> evaluators; + + public LinearCombiningNodeEvaluator(Map, Double> evaluators) { + super(); + this.evaluators = evaluators; + } + + @Override + public Double f(Node node) throws NodeEvaluationException, InterruptedException { + double score = 0; + double incr; + for (INodeEvaluator evaluator : evaluators.keySet()) { + if (evaluators.get(evaluator) != 0) { + incr = evaluator.f(node); + if (incr == Integer.MAX_VALUE) { + score = Integer.MAX_VALUE; + break; + } + else + score += incr * evaluators.get(evaluator); + } + } + return score; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomCompletionBasedNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomCompletionBasedNodeEvaluator.java similarity index 90% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomCompletionBasedNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomCompletionBasedNodeEvaluator.java index eb799230d7..59add40865 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomCompletionBasedNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomCompletionBasedNodeEvaluator.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; import java.util.ArrayList; import java.util.Collections; @@ -31,24 +31,24 @@ import ai.libs.jaicore.basic.sets.SetUtil.Pair; import ai.libs.jaicore.logging.LoggerUtil; import ai.libs.jaicore.logging.ToJSONStringUtil; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.NodeAnnotationEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.NodeExpansionCompletedEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.RolloutEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.algorithms.standard.gbf.SolutionEventBus; +import ai.libs.jaicore.search.algorithms.standard.random.RandomSearch; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.IUncertaintySource; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; import ai.libs.jaicore.timing.TimedComputation; -import jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; -import jaicore.search.algorithms.standard.bestfirst.events.NodeAnnotationEvent; -import jaicore.search.algorithms.standard.bestfirst.events.NodeExpansionCompletedEvent; -import jaicore.search.algorithms.standard.bestfirst.events.RolloutEvent; -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.algorithms.standard.gbf.SolutionEventBus; -import jaicore.search.algorithms.standard.random.RandomSearch; -import jaicore.search.algorithms.standard.uncertainty.IUncertaintySource; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; -import jaicore.search.structure.graphgenerator.NodeGoalTester; public class RandomCompletionBasedNodeEvaluator> extends TimeAwareNodeEvaluator -implements IPotentiallyGraphDependentNodeEvaluator, IPotentiallySolutionReportingNodeEvaluator, ICancelableNodeEvaluator, IPotentiallyUncertaintyAnnotatingNodeEvaluator, ILoggingCustomizable { + implements IPotentiallyGraphDependentNodeEvaluator, IPotentiallySolutionReportingNodeEvaluator, ICancelableNodeEvaluator, IPotentiallyUncertaintyAnnotatingNodeEvaluator, ILoggingCustomizable { private static final String ALGORITHM_ID = "RandomCompletion"; private static final boolean LOG_FAILURES_AS_ERRORS = false; @@ -165,7 +165,8 @@ protected V fTimeouted(final Node n, final int timeout) throws Interrupted if (n.getParent() != null && this.completer.getExploredGraph().hasItem(n.getParent().getPoint())) { boolean parentHasFValue = this.fValues.containsKey(n.getParent()); assert parentHasFValue || n.getParent().getParent() == null : "No f-value has been stored for the parent of node with hash code " + n.hashCode() + " (hash code of parent is " + n.getParent().hashCode() - + ") whose f-value we may want to reuse.\nThis is only allowed for top-level nodes, but the actual path is: " + n.path().stream().map(k -> "\n\t" + k.hashCode() + "\t(f-value: " + k.getInternalLabel() + ")").collect(Collectors.joining()); + + ") whose f-value we may want to reuse.\nThis is only allowed for top-level nodes, but the actual path is: " + + n.path().stream().map(k -> "\n\t" + k.hashCode() + "\t(f-value: " + k.getInternalLabel() + ")").collect(Collectors.joining()); boolean nodeHasSibling = this.completer.getExploredGraph().getSuccessors(n.getParent().getPoint()).size() > 1; if (path.size() > 1 && !nodeHasSibling && parentHasFValue) { V score = this.fValues.get(n.getParent()); @@ -185,7 +186,7 @@ protected V fTimeouted(final Node n, final int timeout) throws Interrupted } Node current = n.getParent(); while (current != null && !this.fValues.containsKey(current)) { - this.fValues.put(current, (V)current.getInternalLabel()); + this.fValues.put(current, (V) current.getInternalLabel()); this.logger.debug("Filling up the f-value of {} with {}", current.hashCode(), current.getInternalLabel()); current = current.getParent(); } @@ -343,7 +344,9 @@ protected V fTimeouted(final Node n, final int timeout) throws Interrupted private void updateMapOfBestScoreFoundSoFar(final List nodeInCompleterGraph, final V scoreOnOriginalBenchmark) { V bestKnownScore = this.bestKnownScoreUnderNodeInCompleterGraph.get(nodeInCompleterGraph); if (bestKnownScore == null || scoreOnOriginalBenchmark.compareTo(bestKnownScore) < 0) { - this.logger.debug("Updating best score of path, because score {} is better than previously observed best score {} under path {}", scoreOnOriginalBenchmark, bestKnownScore, nodeInCompleterGraph); + if (this.logger.isDebugEnabled()) { + this.logger.debug("Updating best score of path, because score {} is better than previously observed best score {} under path {}", scoreOnOriginalBenchmark, bestKnownScore, nodeInCompleterGraph); + } this.bestKnownScoreUnderNodeInCompleterGraph.put(nodeInCompleterGraph, scoreOnOriginalBenchmark); if (nodeInCompleterGraph.size() > 1) { this.updateMapOfBestScoreFoundSoFar(nodeInCompleterGraph.subList(0, nodeInCompleterGraph.size() - 1), scoreOnOriginalBenchmark); @@ -505,7 +508,8 @@ public void setLoggerName(final String name) { this.completer.setLoggerName(name + ".randomsearch"); } this.logger.info("Switched logger (name) of {} to {}", this, name); - this.logger.info("Reprinting RandomCompletionEvaluator configuration after logger switch: timeout {}ms for single evaluations and {}ms in total per node", this.timeoutForSingleCompletionEvaluationInMS, this.getTimeoutForNodeEvaluationInMS()); + this.logger.info("Reprinting RandomCompletionEvaluator configuration after logger switch: timeout {}ms for single evaluations and {}ms in total per node", this.timeoutForSingleCompletionEvaluationInMS, + this.getTimeoutForNodeEvaluationInMS()); } @Override diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomizedDepthFirstNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomizedDepthFirstNodeEvaluator.java similarity index 59% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomizedDepthFirstNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomizedDepthFirstNodeEvaluator.java index 05ca1e3136..a58aa3db09 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomizedDepthFirstNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/RandomizedDepthFirstNodeEvaluator.java @@ -1,22 +1,22 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; - -import java.util.Random; - -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableNodeEvaluator; -import jaicore.search.model.travesaltree.Node; - -@SuppressWarnings("serial") -public class RandomizedDepthFirstNodeEvaluator implements SerializableNodeEvaluator { - - private final Random rand; - - public RandomizedDepthFirstNodeEvaluator(Random rand) { - super(); - this.rand = rand; - } - - @Override - public Double f(Node node) { - return (double) (-1 * (node.path().size() * 1000 + rand.nextInt(100))); - } -} +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; + +import java.util.Random; + +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableNodeEvaluator; +import ai.libs.jaicore.search.model.travesaltree.Node; + +@SuppressWarnings("serial") +public class RandomizedDepthFirstNodeEvaluator implements SerializableNodeEvaluator { + + private final Random rand; + + public RandomizedDepthFirstNodeEvaluator(Random rand) { + super(); + this.rand = rand; + } + + @Override + public Double f(Node node) { + return (double) (-1 * (node.path().size() * 1000 + rand.nextInt(100))); + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/SkippingNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/SkippingNodeEvaluator.java similarity index 79% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/SkippingNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/SkippingNodeEvaluator.java index 48aae4cee8..1f47751b7b 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/SkippingNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/SkippingNodeEvaluator.java @@ -1,45 +1,45 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; - -import java.util.HashMap; -import java.util.Map; -import java.util.Random; - -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.model.travesaltree.Node; - -public class SkippingNodeEvaluator> implements INodeEvaluator { - - private final INodeEvaluator actualEvaluator; - private final Random rand; - private final float coin; - private final Map, V> fCache = new HashMap<>(); - - public SkippingNodeEvaluator(INodeEvaluator actualEvaluator, Random rand, float coin) { - super(); - this.actualEvaluator = actualEvaluator; - this.rand = rand; - this.coin = coin; - } - - @Override - public V f(Node node) throws NodeEvaluationException, InterruptedException { - int depth = node.path().size() - 1; - if (!fCache.containsKey(node)) { - if (depth == 0) { - fCache.put(node, actualEvaluator.f(node)); - } else { - if (rand.nextFloat() >= coin) { - fCache.put(node, actualEvaluator.f(node)); - } else { - fCache.put(node, f(node.getParent())); - } - } - } - return fCache.get(node); - } - - @Override - public String toString() { - return "SkippingEvaluator [actualEvaluator=" + actualEvaluator + "]"; - } +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.model.travesaltree.Node; + +public class SkippingNodeEvaluator> implements INodeEvaluator { + + private final INodeEvaluator actualEvaluator; + private final Random rand; + private final float coin; + private final Map, V> fCache = new HashMap<>(); + + public SkippingNodeEvaluator(INodeEvaluator actualEvaluator, Random rand, float coin) { + super(); + this.actualEvaluator = actualEvaluator; + this.rand = rand; + this.coin = coin; + } + + @Override + public V f(Node node) throws NodeEvaluationException, InterruptedException { + int depth = node.path().size() - 1; + if (!fCache.containsKey(node)) { + if (depth == 0) { + fCache.put(node, actualEvaluator.f(node)); + } else { + if (rand.nextFloat() >= coin) { + fCache.put(node, actualEvaluator.f(node)); + } else { + fCache.put(node, f(node.getParent())); + } + } + } + return fCache.get(node); + } + + @Override + public String toString() { + return "SkippingEvaluator [actualEvaluator=" + actualEvaluator + "]"; + } } \ No newline at end of file diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeAwareNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeAwareNodeEvaluator.java similarity index 92% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeAwareNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeAwareNodeEvaluator.java index e48d711c0f..3ca66c534a 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeAwareNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeAwareNodeEvaluator.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; import java.util.concurrent.ExecutionException; @@ -7,9 +7,9 @@ import ai.libs.jaicore.basic.ILoggingCustomizable; import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.model.travesaltree.Node; import ai.libs.jaicore.timing.TimedComputation; -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.model.travesaltree.Node; /** * This class can be used to create node evaluators with a time limit for the evaluation of each node. diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeLoggingNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeLoggingNodeEvaluator.java similarity index 75% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeLoggingNodeEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeLoggingNodeEvaluator.java index fab68611df..7540b20676 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeLoggingNodeEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/TimeLoggingNodeEvaluator.java @@ -1,30 +1,30 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.model.travesaltree.Node; - -public class TimeLoggingNodeEvaluator> extends DecoratingNodeEvaluator { - - private final Map, Integer> times = new ConcurrentHashMap<>(); - - public TimeLoggingNodeEvaluator(INodeEvaluator baseEvaluator) { - super(baseEvaluator); - } - - public int getMSRequiredForComputation(Node node) { - if (!times.containsKey(node)) - throw new IllegalArgumentException("No f-value has been computed for node: " + node); - return times.get(node); - } - - @Override - public V f(Node node) throws NodeEvaluationException, InterruptedException { - long start = System.currentTimeMillis(); - V f = super.f(node); - times.put(node, (int) (System.currentTimeMillis() - start)); - return f; - } -} +package ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.model.travesaltree.Node; + +public class TimeLoggingNodeEvaluator> extends DecoratingNodeEvaluator { + + private final Map, Integer> times = new ConcurrentHashMap<>(); + + public TimeLoggingNodeEvaluator(INodeEvaluator baseEvaluator) { + super(baseEvaluator); + } + + public int getMSRequiredForComputation(Node node) { + if (!times.containsKey(node)) + throw new IllegalArgumentException("No f-value has been computed for node: " + node); + return times.get(node); + } + + @Override + public V f(Node node) throws NodeEvaluationException, InterruptedException { + long start = System.currentTimeMillis(); + V f = super.f(node); + times.put(node, (int) (System.currentTimeMillis() - start)); + return f; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/dfs/DepthFirstSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/dfs/DepthFirstSearch.java similarity index 90% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/dfs/DepthFirstSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/dfs/DepthFirstSearch.java index a532d6333d..7dc5171e33 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/dfs/DepthFirstSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/dfs/DepthFirstSearch.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.dfs; +package ai.libs.jaicore.search.algorithms.standard.dfs; import java.util.ArrayList; import java.util.Collections; @@ -18,16 +18,16 @@ import ai.libs.jaicore.graphvisualizer.events.graph.GraphInitializedEvent; import ai.libs.jaicore.graphvisualizer.events.graph.NodeAddedEvent; import ai.libs.jaicore.graphvisualizer.events.graph.NodeTypeSwitchEvent; -import jaicore.search.algorithms.standard.bestfirst.events.GraphSearchSolutionCandidateFoundEvent; -import jaicore.search.algorithms.standard.bestfirst.events.NodeExpansionCompletedEvent; -import jaicore.search.algorithms.standard.random.RandomSearch; -import jaicore.search.core.interfaces.AAnyPathInORGraphSearch; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.GraphSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.NodeExpansionCompletedEvent; +import ai.libs.jaicore.search.algorithms.standard.random.RandomSearch; +import ai.libs.jaicore.search.core.interfaces.AAnyPathInORGraphSearch; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; /** * diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/dfs/DepthFirstSearchFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/dfs/DepthFirstSearchFactory.java similarity index 73% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/dfs/DepthFirstSearchFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/dfs/DepthFirstSearchFactory.java index 2a1eb4ba6f..24029e0a50 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/dfs/DepthFirstSearchFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/dfs/DepthFirstSearchFactory.java @@ -1,35 +1,35 @@ -package jaicore.search.algorithms.standard.dfs; - -import jaicore.search.core.interfaces.StandardORGraphSearchFactory; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; - -public class DepthFirstSearchFactory extends StandardORGraphSearchFactory, SearchGraphPath,N, A, Double> { - - private String loggerName; - - public DepthFirstSearchFactory() { - super(); - } - - @Override - public DepthFirstSearch getAlgorithm() { - if (this.getInput().getGraphGenerator() == null) { - throw new IllegalStateException("Cannot produce RandomSearch searches before the graph generator is set in the problem."); - } - return this.getAlgorithm(this.getInput()); - } - - @Override - public DepthFirstSearch getAlgorithm(final GraphSearchInput input) { - return new DepthFirstSearch<>(input); - } - - public String getLoggerName() { - return this.loggerName; - } - - public void setLoggerName(final String loggerName) { - this.loggerName = loggerName; - } -} +package ai.libs.jaicore.search.algorithms.standard.dfs; + +import ai.libs.jaicore.search.core.interfaces.StandardORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; + +public class DepthFirstSearchFactory extends StandardORGraphSearchFactory, SearchGraphPath,N, A, Double> { + + private String loggerName; + + public DepthFirstSearchFactory() { + super(); + } + + @Override + public DepthFirstSearch getAlgorithm() { + if (this.getInput().getGraphGenerator() == null) { + throw new IllegalStateException("Cannot produce RandomSearch searches before the graph generator is set in the problem."); + } + return this.getAlgorithm(this.getInput()); + } + + @Override + public DepthFirstSearch getAlgorithm(final GraphSearchInput input) { + return new DepthFirstSearch<>(input); + } + + public String getLoggerName() { + return this.loggerName; + } + + public void setLoggerName(final String loggerName) { + this.loggerName = loggerName; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/ANDORGraphSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/ANDORGraphSearch.java similarity index 99% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/ANDORGraphSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/ANDORGraphSearch.java index df1299e433..7dc41a0d4b 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/ANDORGraphSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/ANDORGraphSearch.java @@ -1,3 +1,4 @@ +package ai.libs.jaicore.search.algorithms.standard.gbf; //package jaicore.search.algorithms.standard.gbf; // //import java.util.Collection; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirst.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirst.java similarity index 96% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirst.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirst.java index 1ea0303dbf..61642f863d 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirst.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirst.java @@ -1,3 +1,4 @@ +package ai.libs.jaicore.search.algorithms.standard.gbf; //package jaicore.search.algorithms.standard.gbf; // //import java.util.ArrayList; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationAggregation.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationAggregation.java similarity index 54% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationAggregation.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationAggregation.java index 72b43de575..d1827cba93 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationAggregation.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationAggregation.java @@ -1,9 +1,9 @@ -package jaicore.search.algorithms.standard.gbf; - -import java.util.Map; - -import jaicore.search.model.travesaltree.Node; - -public interface GeneralBestFirstEvaluationAggregation { - public int aggregate(Map,Integer> nodes); -} +package ai.libs.jaicore.search.algorithms.standard.gbf; + +import java.util.Map; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +public interface GeneralBestFirstEvaluationAggregation { + public int aggregate(Map,Integer> nodes); +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationOrSelector.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationOrSelector.java similarity index 61% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationOrSelector.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationOrSelector.java index 680a1b5514..7e8ad53aec 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationOrSelector.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirstEvaluationOrSelector.java @@ -1,10 +1,10 @@ -package jaicore.search.algorithms.standard.gbf; - -import java.util.List; -import java.util.Map; - -import jaicore.search.model.travesaltree.Node; - -public interface GeneralBestFirstEvaluationOrSelector { - public List> getSuccessorRanking(Map,Integer> nodes); -} +package ai.libs.jaicore.search.algorithms.standard.gbf; + +import java.util.List; +import java.util.Map; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +public interface GeneralBestFirstEvaluationOrSelector { + public List> getSuccessorRanking(Map,Integer> nodes); +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirstTester.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirstTester.java similarity index 95% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirstTester.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirstTester.java index 7c53d046b2..df71ca4575 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/GeneralBestFirstTester.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/GeneralBestFirstTester.java @@ -1,148 +1,149 @@ -//package jaicore.search.algorithms.standard.gbf; -// -//import static org.junit.Assert.assertNotNull; -// -//import java.util.ArrayList; -// -//import org.junit.Test; -// -//import jaicore.graph.Graph; -//import jaicore.graphvisualizer.gui.VisualizationWindow; -//import jaicore.search.algorithms.standard.bestfirst.model.GraphGenerator; -//import jaicore.search.algorithms.standard.bestfirst.model.Node; -//import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -//import jaicore.search.structure.graphgenerator.NodeGoalTester; -//import jaicore.search.structure.graphgenerator.SingleRootGenerator; -//import jaicore.search.structure.graphgenerator.SuccessorGenerator; -// -//public class GeneralBestFirstTester { -// -// private static final boolean VISUALIZE = true; -// -// static class GameNode { -// -// final boolean active; -// final int remaining; -// public GameNode(boolean active, int remaining) { -// super(); -// this.active = active; -// this.remaining = remaining; -// } -// @Override -// public int hashCode() { -// final int prime = 31; -// int result = 1; -// result = prime * result + (active ? 1231 : 1237); -// result = prime * result + remaining; -// return result; -// } -// @Override -// public boolean equals(Object obj) { -// if (this == obj) -// return true; -// if (obj == null) -// return false; -// if (getClass() != obj.getClass()) -// return false; -// GameNode other = (GameNode) obj; -// if (active != other.active) -// return false; -// if (remaining != other.remaining) -// return false; -// return true; -// } -// -// @Override -// public String toString() { -// return "GameNode [active=" + active + ", remaining=" + remaining + "]"; -// } -// } -// -// static class GameAction { -// final String name; -// -// public GameAction(String name) { -// super(); -// this.name = name; -// } -// } -// -// @Test -// public void test() { -// -// GraphGenerator gen = new GraphGenerator() { -// -// @Override -// public SingleRootGenerator getRootGenerator() { -// return () -> new GameNode(true, 20); -// } -// -// @Override -// public SuccessorGenerator getSuccessorGenerator() { -// return n -> { -// return new ArrayList<>(); -//// if (n instanceof OrNode) { -//// List> successors = new ArrayList<>(); -//// GameNode g = n.getPoint(); -//// for (int i = 0; i < 4; i++) -//// if (g.remaining > i) -//// successors.add(new NodeExpansionDescription<>(n.getPoint(), new GameNode(false, g.remaining - i - 1), new GameAction("Take " + (i + 1)), NodeType.AND)); -//// return successors; -//// } -//// else { -//// List> successors = new ArrayList<>(); -//// GameNode g = n.getPoint(); -//// for (int i = 0; i < 2; i++) -//// if (g.remaining > i) -//// successors.add(new NodeExpansionDescription<>(n.getPoint(), new GameNode(true, g.remaining - i - 1), new GameAction("Enemy takes " + (i + 1)), NodeType.OR)); -//// return successors; -//// } -// }; -// } -// -// @Override -// public NodeGoalTester getGoalTester() { -// return l -> l.active && l.remaining == 0; -// } -// -// @Override -// public boolean isSelfContained() { -// return false; -// } -// -// @Override -// public void setNodeNumbering(boolean nodenumbering) { -// // TODO Auto-generated method stub -// -// } -// }; -// -// INodeEvaluator evaluator = new INodeEvaluator() { -// @Override -// public Integer f(Node path) { -// return 0; -// } -// }; -// -// GeneralBestFirst gbf = new GeneralBestFirst(gen, map -> new ArrayList<>(map.keySet()), l -> 0, evaluator); -// -// -// /* find solution */ -// if (VISUALIZE) { -// new VisualizationWindow<>(gbf); -// } -// Graph solutionGraph = gbf.getSolution(); -// assertNotNull(solutionGraph); -// System.out.println("Generated " + gbf.getCreatedCounter() + " nodes."); -// if (VISUALIZE) { -// new VisualizationWindow(solutionGraph); -// int j = 0; -// int i = 0; -// while (j >= 0) -// i = i + 1; -// } -// } -// -// -// -//} +package ai.libs.jaicore.search.algorithms.standard.gbf; +//package jaicore.search.algorithms.standard.gbf; +// +//import static org.junit.Assert.assertNotNull; +// +//import java.util.ArrayList; +// +//import org.junit.Test; +// +//import jaicore.graph.Graph; +//import jaicore.graphvisualizer.gui.VisualizationWindow; +//import jaicore.search.algorithms.standard.bestfirst.model.GraphGenerator; +//import jaicore.search.algorithms.standard.bestfirst.model.Node; +//import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +//import jaicore.search.structure.graphgenerator.NodeGoalTester; +//import jaicore.search.structure.graphgenerator.SingleRootGenerator; +//import jaicore.search.structure.graphgenerator.SuccessorGenerator; +// +//public class GeneralBestFirstTester { +// +// private static final boolean VISUALIZE = true; +// +// static class GameNode { +// +// final boolean active; +// final int remaining; +// public GameNode(boolean active, int remaining) { +// super(); +// this.active = active; +// this.remaining = remaining; +// } +// @Override +// public int hashCode() { +// final int prime = 31; +// int result = 1; +// result = prime * result + (active ? 1231 : 1237); +// result = prime * result + remaining; +// return result; +// } +// @Override +// public boolean equals(Object obj) { +// if (this == obj) +// return true; +// if (obj == null) +// return false; +// if (getClass() != obj.getClass()) +// return false; +// GameNode other = (GameNode) obj; +// if (active != other.active) +// return false; +// if (remaining != other.remaining) +// return false; +// return true; +// } +// +// @Override +// public String toString() { +// return "GameNode [active=" + active + ", remaining=" + remaining + "]"; +// } +// } +// +// static class GameAction { +// final String name; +// +// public GameAction(String name) { +// super(); +// this.name = name; +// } +// } +// +// @Test +// public void test() { +// +// GraphGenerator gen = new GraphGenerator() { +// +// @Override +// public SingleRootGenerator getRootGenerator() { +// return () -> new GameNode(true, 20); +// } +// +// @Override +// public SuccessorGenerator getSuccessorGenerator() { +// return n -> { +// return new ArrayList<>(); +//// if (n instanceof OrNode) { +//// List> successors = new ArrayList<>(); +//// GameNode g = n.getPoint(); +//// for (int i = 0; i < 4; i++) +//// if (g.remaining > i) +//// successors.add(new NodeExpansionDescription<>(n.getPoint(), new GameNode(false, g.remaining - i - 1), new GameAction("Take " + (i + 1)), NodeType.AND)); +//// return successors; +//// } +//// else { +//// List> successors = new ArrayList<>(); +//// GameNode g = n.getPoint(); +//// for (int i = 0; i < 2; i++) +//// if (g.remaining > i) +//// successors.add(new NodeExpansionDescription<>(n.getPoint(), new GameNode(true, g.remaining - i - 1), new GameAction("Enemy takes " + (i + 1)), NodeType.OR)); +//// return successors; +//// } +// }; +// } +// +// @Override +// public NodeGoalTester getGoalTester() { +// return l -> l.active && l.remaining == 0; +// } +// +// @Override +// public boolean isSelfContained() { +// return false; +// } +// +// @Override +// public void setNodeNumbering(boolean nodenumbering) { +// // TODO Auto-generated method stub +// +// } +// }; +// +// INodeEvaluator evaluator = new INodeEvaluator() { +// @Override +// public Integer f(Node path) { +// return 0; +// } +// }; +// +// GeneralBestFirst gbf = new GeneralBestFirst(gen, map -> new ArrayList<>(map.keySet()), l -> 0, evaluator); +// +// +// /* find solution */ +// if (VISUALIZE) { +// new VisualizationWindow<>(gbf); +// } +// Graph solutionGraph = gbf.getSolution(); +// assertNotNull(solutionGraph); +// System.out.println("Generated " + gbf.getCreatedCounter() + " nodes."); +// if (VISUALIZE) { +// new VisualizationWindow(solutionGraph); +// int j = 0; +// int i = 0; +// while (j >= 0) +// i = i + 1; +// } +// } +// +// +// +//} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/RandomizedAndOrSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/RandomizedAndOrSearch.java similarity index 95% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/RandomizedAndOrSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/RandomizedAndOrSearch.java index b227ec509d..a3b9f41cbe 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/RandomizedAndOrSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/RandomizedAndOrSearch.java @@ -1,75 +1,76 @@ -//package jaicore.search.algorithms.standard.gbf; -// -//import java.util.ArrayList; -//import java.util.Collection; -//import java.util.LinkedList; -//import java.util.Queue; -// -//import jaicore.graph.Graph; -//import jaicore.search.algorithms.standard.bestfirst.model.Node; -//import jaicore.search.algorithms.standard.bestfirst.model.NodeExpansionDescription; -//import jaicore.search.algorithms.standard.bestfirst.model.NodeType; -//import jaicore.search.structure.graphgenerator.GoalTester; -//import jaicore.search.structure.graphgenerator.SingleRootGenerator; -//import jaicore.search.structure.graphgenerator.SuccessorGenerator; -// -///** -// * A* algorithm implementation using the method design pattern. -// * -// * @author Felix Mohr -// */ -//public class RandomizedAndOrSearch extends ANDORGraphSearch { -// -// -// private Node root; -// private final Queue> open = new LinkedList<>(); -// -// public RandomizedAndOrSearch(SingleRootGenerator rootGenerator, SuccessorGenerator successorGenerator, GoalTester goalTester) { -// super(rootGenerator, successorGenerator, goalTester); -// } -// -// @Override -// protected Node initialize() { -// root = getOrNode(null, rootGenerator.getRoot(), null); -// open.add(root); -// return root; -// } -// -// @Override -// protected Graph> nextSolutionBase() { -// return null; -// } -// -// @Override -// protected Node nextNode(Graph> solutionBase) { -// return open.poll(); -// } -// -// @Override -// protected Collection> expand(Node expanded) { -// Collection> successorNodes = successorGenerator.generateSuccessors(expanded.getPoint()); -// Collection> successors = new ArrayList<>(); -// for (NodeExpansionDescription successorDescription : successorNodes) { -// -// /* no reopening of nodes we already know */ -// T successor = successorDescription.getTo(); -// boolean isKnown = ext2int.containsKey(successor); -// Node node = null; -// NodeType type = successorDescription.getTypeOfToNode(); -// if (type == NodeType.AND) -// node = getAndNode(expanded, successor, successorDescription.getAction()); -// if (type == NodeType.OR) -// node = getOrNode(expanded, successor, successorDescription.getAction()); -// successors.add(node); -// if (!isKnown && !goalTester.isGoal(node.getPoint())) { -// open.add(node); -// } -// } -// return successors; -// } -// -// @Override -// protected int getNumberOfOpenNodesInSolutionBase(Graph> solutionBase) { -// return open.size(); -// } +package ai.libs.jaicore.search.algorithms.standard.gbf; +//package jaicore.search.algorithms.standard.gbf; +// +//import java.util.ArrayList; +//import java.util.Collection; +//import java.util.LinkedList; +//import java.util.Queue; +// +//import jaicore.graph.Graph; +//import jaicore.search.algorithms.standard.bestfirst.model.Node; +//import jaicore.search.algorithms.standard.bestfirst.model.NodeExpansionDescription; +//import jaicore.search.algorithms.standard.bestfirst.model.NodeType; +//import jaicore.search.structure.graphgenerator.GoalTester; +//import jaicore.search.structure.graphgenerator.SingleRootGenerator; +//import jaicore.search.structure.graphgenerator.SuccessorGenerator; +// +///** +// * A* algorithm implementation using the method design pattern. +// * +// * @author Felix Mohr +// */ +//public class RandomizedAndOrSearch extends ANDORGraphSearch { +// +// +// private Node root; +// private final Queue> open = new LinkedList<>(); +// +// public RandomizedAndOrSearch(SingleRootGenerator rootGenerator, SuccessorGenerator successorGenerator, GoalTester goalTester) { +// super(rootGenerator, successorGenerator, goalTester); +// } +// +// @Override +// protected Node initialize() { +// root = getOrNode(null, rootGenerator.getRoot(), null); +// open.add(root); +// return root; +// } +// +// @Override +// protected Graph> nextSolutionBase() { +// return null; +// } +// +// @Override +// protected Node nextNode(Graph> solutionBase) { +// return open.poll(); +// } +// +// @Override +// protected Collection> expand(Node expanded) { +// Collection> successorNodes = successorGenerator.generateSuccessors(expanded.getPoint()); +// Collection> successors = new ArrayList<>(); +// for (NodeExpansionDescription successorDescription : successorNodes) { +// +// /* no reopening of nodes we already know */ +// T successor = successorDescription.getTo(); +// boolean isKnown = ext2int.containsKey(successor); +// Node node = null; +// NodeType type = successorDescription.getTypeOfToNode(); +// if (type == NodeType.AND) +// node = getAndNode(expanded, successor, successorDescription.getAction()); +// if (type == NodeType.OR) +// node = getOrNode(expanded, successor, successorDescription.getAction()); +// successors.add(node); +// if (!isKnown && !goalTester.isGoal(node.getPoint())) { +// open.add(node); +// } +// } +// return successors; +// } +// +// @Override +// protected int getNumberOfOpenNodesInSolutionBase(Graph> solutionBase) { +// return open.size(); +// } //} \ No newline at end of file diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/SolutionEventBus.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/SolutionEventBus.java similarity index 61% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/SolutionEventBus.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/SolutionEventBus.java index fde66f2513..daad4694d5 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/gbf/SolutionEventBus.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/gbf/SolutionEventBus.java @@ -1,7 +1,7 @@ -package jaicore.search.algorithms.standard.gbf; - -import com.google.common.eventbus.EventBus; - -public class SolutionEventBus extends EventBus { - -} +package ai.libs.jaicore.search.algorithms.standard.gbf; + +import com.google.common.eventbus.EventBus; + +public class SolutionEventBus extends EventBus { + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearch.java similarity index 84% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearch.java index 37ec1d9638..f85ad058d3 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearch.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.lds; +package ai.libs.jaicore.search.algorithms.standard.lds; import java.util.Comparator; import java.util.HashMap; @@ -21,15 +21,15 @@ import ai.libs.jaicore.basic.algorithm.events.SolutionCandidateFoundEvent; import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; -import jaicore.search.algorithms.standard.bestfirst.events.SuccessorComputationCompletedEvent; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.SuccessorComputationCompletedEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; /** * This class conducts a limited discrepancy search by running a best first algorithm with list-based node evaluations. diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearchFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearchFactory.java similarity index 69% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearchFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearchFactory.java index 2896752ec0..3d5a2cc2d0 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearchFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearchFactory.java @@ -1,8 +1,8 @@ -package jaicore.search.algorithms.standard.lds; +package ai.libs.jaicore.search.algorithms.standard.lds; -import jaicore.search.core.interfaces.StandardORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; +import ai.libs.jaicore.search.core.interfaces.StandardORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; public class BestFirstLimitedDiscrepancySearchFactory> extends StandardORGraphSearchFactory, EvaluatedSearchGraphPath, N, A, V> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearch.java similarity index 91% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearch.java index b3ef14ac11..dc9bdb97df 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearch.java @@ -1,226 +1,226 @@ -package jaicore.search.algorithms.standard.lds; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.stream.Collectors; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; -import ai.libs.jaicore.basic.algorithm.events.ASolutionCandidateFoundEvent; -import ai.libs.jaicore.basic.algorithm.events.AlgorithmEvent; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; -import ai.libs.jaicore.graph.TreeNode; -import ai.libs.jaicore.graphvisualizer.events.graph.GraphInitializedEvent; -import ai.libs.jaicore.graphvisualizer.events.graph.NodeAddedEvent; -import jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.PathGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; - -/** - * Implementation of the algorithm presented in - * - * @inproceedings{harvey1995, title={Limited discrepancy search}, author={Harvey, William D and Ginsberg, Matthew L}, booktitle={IJCAI (1)}, pages={607--615}, year={1995} } - * - * @author fmohr - * - */ -public class LimitedDiscrepancySearch> extends AOptimalPathInORGraphSearch, T, A, V> { - - /* logging */ - private Logger logger = LoggerFactory.getLogger(LimitedDiscrepancySearch.class); - private String loggerName; - - /* communication */ - protected TreeNode traversalTree; - protected Collection> expanded = new HashSet<>(); - protected Collection> exhausted = new HashSet<>(); - - /* graph construction helpers */ - protected final SingleRootGenerator rootGenerator; - protected final SuccessorGenerator successorGenerator; - protected final boolean checkGoalPropertyOnEntirePath; - protected final PathGoalTester pathGoalTester; - protected final NodeGoalTester nodeGoalTester; - - /* graph traversal helpers */ - protected final Comparator heuristic; - - /* algorithm state */ - private int maxK = 0; - private int currentK = 0; - - public LimitedDiscrepancySearch(final GraphSearchWithNodeRecommenderInput problemInput) { - super(problemInput); - this.rootGenerator = (SingleRootGenerator) this.getInput().getGraphGenerator().getRootGenerator(); - this.successorGenerator = this.getInput().getGraphGenerator().getSuccessorGenerator(); - this.checkGoalPropertyOnEntirePath = !(this.getInput().getGraphGenerator().getGoalTester() instanceof NodeGoalTester); - if (this.checkGoalPropertyOnEntirePath) { - this.nodeGoalTester = null; - this.pathGoalTester = (PathGoalTester) this.getInput().getGraphGenerator().getGoalTester(); - } else { - this.nodeGoalTester = (NodeGoalTester) this.getInput().getGraphGenerator().getGoalTester(); - this.pathGoalTester = null; - } - this.heuristic = problemInput.getRecommender(); - } - - @Override - public AlgorithmEvent nextWithException() throws InterruptedException, AlgorithmTimeoutedException, AlgorithmExecutionCanceledException, AlgorithmException { - this.registerActiveThread(); - try { - switch (this.getState()) { - case created: - this.traversalTree = this.newNode(null, this.rootGenerator.getRoot()); - this.post(new GraphInitializedEvent<>(this.getId(), this.traversalTree)); - return this.activate(); - - case active: - this.currentK = this.maxK; - AlgorithmEvent event = this.ldsProbe(this.traversalTree); - if (event instanceof NoMoreNodesOnLevelEvent) { - if (this.currentK == 0) { // if all deviations have been used, increase number of maximum deviations - this.logger.info("Probe process has no more nodes to be considered, restarting with augmented k {}", this.maxK + 1); - this.maxK++; - return event; - } - else { - return this.terminate(); // otherwise, terminate (allowing for more deviations will not yield more results) - } - } else { - this.logger.info("Returning event {}", event); - this.post(event); - return event; - } - default: - throw new IllegalStateException("The algorithm cannot do anything in state " + this.getState()); - } - } - finally { - this.unregisterActiveThread(); - } - } - - private void updateExhaustMap(final TreeNode node) { - if (node == null) { - return; - } - if (this.exhausted.contains(node)) { - this.updateExhaustMap(node.getParent()); - } - if (this.exhausted.containsAll(node.getChildren())) { - this.exhausted.add(node); - this.updateExhaustMap(node.getParent()); - } - } - - /** - * Computes a solution path that deviates k times from the heuristic (if possible) - * - * @param node - * @param k - * @return - * @throws InterruptedException - * @throws AlgorithmExecutionCanceledException - * @throws AlgorithmTimeoutedException - * @throws AlgorithmException - */ - private AlgorithmEvent ldsProbe(final TreeNode node) throws InterruptedException, AlgorithmTimeoutedException, AlgorithmExecutionCanceledException, AlgorithmException { - this.logger.debug("Probing under node {} with k = {}. Exhausted: {}", node.getValue(), this.currentK, this.exhausted.contains(node)); - - /* return solution event if this is a solution node */ - if (this.nodeGoalTester.isGoal(node.getValue())) { - this.updateExhaustMap(node); - List path = node.getValuesOnPathFromRoot(); - EvaluatedSearchGraphPath solution = new EvaluatedSearchGraphPath<>(path, null, null); - this.updateBestSeenSolution(solution); - this.logger.debug("Found solution {}.", node.getValue()); - return new ASolutionCandidateFoundEvent<>(this.getId(), solution); - } - - /* if this node has not been expanded, compute successors and the priorities among them and attach them to search graph */ - if (!this.expanded.contains(node)) { - this.expanded.add(node); - this.logger.debug("Starting successor generation of {}", node.getValue()); - long start = System.currentTimeMillis(); - Collection> succ = this.computeTimeoutAware(() -> this.successorGenerator.generateSuccessors(node.getValue()), "Successor generation" , true); - if (succ == null || succ.isEmpty()) { - this.logger.debug("No successors were generated."); - return new NoMoreNodesOnLevelEvent(this.getId()); - } - this.logger.debug("Computed {} successors in {}ms. Attaching the nodes to the local model.", succ.size(), System.currentTimeMillis() - start); - List> prioSucc = succ.stream().sorted((d1, d2) -> this.heuristic.compare(d1.getTo(), d2.getTo())).collect(Collectors.toList()); - this.checkAndConductTermination(); - List> generatedNodes = new ArrayList<>(); - long lastCheck = System.currentTimeMillis(); - for (NodeExpansionDescription successorDescription : prioSucc) { - if (System.currentTimeMillis() - lastCheck > 10) { - this.checkAndConductTermination(); - lastCheck = System.currentTimeMillis(); - } - TreeNode newNode = this.newNode(node, successorDescription.getTo()); - generatedNodes.add(newNode); - } - this.logger.debug("Local model updated."); - this.checkAndConductTermination(); - } else { - this.logger.info("Not expanding node {} again.", node.getValue()); - } - List> children = node.getChildren(); - if (children.isEmpty()) { - return new NoMoreNodesOnLevelEvent(this.getId()); - } - - /* if no deviation is allowed, return the probe for the first child (unless that child is already exhausted) */ - if (this.currentK == 0 || children.size() == 1) { - boolean onlyAdmissibleChildExhausted = this.exhausted.contains(children.get(0)); - this.logger.debug("No deviation allowed or only one child node. Probing this child (if not, the reason is that it is exhausted already): {}", !onlyAdmissibleChildExhausted); - return !onlyAdmissibleChildExhausted ? this.ldsProbe(children.get(0)) : new NoMoreNodesOnLevelEvent(this.getId()); - } - - /* deviate from the heuristic. If no more discrepancies are allowed, keep searching under the first child unless that child has been exhausted */ - this.currentK--; - this.logger.debug("Deviating from heuristic. Decreased current k to {}", this.currentK); - if (this.exhausted.contains(children.get(1))) { - return new NoMoreNodesOnLevelEvent(this.getId()); - } - return this.ldsProbe(children.get(1)); - } - - protected synchronized TreeNode newNode(final TreeNode parent, final T newNode) { - - /* attach new node to traversal tree */ - TreeNode newTree = parent != null ? parent.addChild(newNode) : new TreeNode<>(newNode); - - /* send events for this new node */ - if (parent != null) { - boolean isGoal = this.nodeGoalTester.isGoal(newNode); - this.post(new NodeAddedEvent>(this.getId(), parent, newTree, "or_" + (isGoal ? "solution" : "created"))); - } - return newTree; - } - - @Override - public String getLoggerName() { - return this.loggerName; - } - - @Override - public void setLoggerName(final String name) { - this.logger.info("Switching logger from {} to {}", this.logger.getName(), name); - this.loggerName = name; - this.logger = LoggerFactory.getLogger(name); - this.logger.info("Activated logger {} with name {}", name, this.logger.getName()); - super.setLoggerName(this.loggerName + "._orgraphsearch"); - } -} +package ai.libs.jaicore.search.algorithms.standard.lds; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; +import ai.libs.jaicore.basic.algorithm.events.ASolutionCandidateFoundEvent; +import ai.libs.jaicore.basic.algorithm.events.AlgorithmEvent; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; +import ai.libs.jaicore.graph.TreeNode; +import ai.libs.jaicore.graphvisualizer.events.graph.GraphInitializedEvent; +import ai.libs.jaicore.graphvisualizer.events.graph.NodeAddedEvent; +import ai.libs.jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.PathGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; + +/** + * Implementation of the algorithm presented in + * + * @inproceedings{harvey1995, title={Limited discrepancy search}, author={Harvey, William D and Ginsberg, Matthew L}, booktitle={IJCAI (1)}, pages={607--615}, year={1995} } + * + * @author fmohr + * + */ +public class LimitedDiscrepancySearch> extends AOptimalPathInORGraphSearch, T, A, V> { + + /* logging */ + private Logger logger = LoggerFactory.getLogger(LimitedDiscrepancySearch.class); + private String loggerName; + + /* communication */ + protected TreeNode traversalTree; + protected Collection> expanded = new HashSet<>(); + protected Collection> exhausted = new HashSet<>(); + + /* graph construction helpers */ + protected final SingleRootGenerator rootGenerator; + protected final SuccessorGenerator successorGenerator; + protected final boolean checkGoalPropertyOnEntirePath; + protected final PathGoalTester pathGoalTester; + protected final NodeGoalTester nodeGoalTester; + + /* graph traversal helpers */ + protected final Comparator heuristic; + + /* algorithm state */ + private int maxK = 0; + private int currentK = 0; + + public LimitedDiscrepancySearch(final GraphSearchWithNodeRecommenderInput problemInput) { + super(problemInput); + this.rootGenerator = (SingleRootGenerator) this.getInput().getGraphGenerator().getRootGenerator(); + this.successorGenerator = this.getInput().getGraphGenerator().getSuccessorGenerator(); + this.checkGoalPropertyOnEntirePath = !(this.getInput().getGraphGenerator().getGoalTester() instanceof NodeGoalTester); + if (this.checkGoalPropertyOnEntirePath) { + this.nodeGoalTester = null; + this.pathGoalTester = (PathGoalTester) this.getInput().getGraphGenerator().getGoalTester(); + } else { + this.nodeGoalTester = (NodeGoalTester) this.getInput().getGraphGenerator().getGoalTester(); + this.pathGoalTester = null; + } + this.heuristic = problemInput.getRecommender(); + } + + @Override + public AlgorithmEvent nextWithException() throws InterruptedException, AlgorithmTimeoutedException, AlgorithmExecutionCanceledException, AlgorithmException { + this.registerActiveThread(); + try { + switch (this.getState()) { + case created: + this.traversalTree = this.newNode(null, this.rootGenerator.getRoot()); + this.post(new GraphInitializedEvent<>(this.getId(), this.traversalTree)); + return this.activate(); + + case active: + this.currentK = this.maxK; + AlgorithmEvent event = this.ldsProbe(this.traversalTree); + if (event instanceof NoMoreNodesOnLevelEvent) { + if (this.currentK == 0) { // if all deviations have been used, increase number of maximum deviations + this.logger.info("Probe process has no more nodes to be considered, restarting with augmented k {}", this.maxK + 1); + this.maxK++; + return event; + } + else { + return this.terminate(); // otherwise, terminate (allowing for more deviations will not yield more results) + } + } else { + this.logger.info("Returning event {}", event); + this.post(event); + return event; + } + default: + throw new IllegalStateException("The algorithm cannot do anything in state " + this.getState()); + } + } + finally { + this.unregisterActiveThread(); + } + } + + private void updateExhaustMap(final TreeNode node) { + if (node == null) { + return; + } + if (this.exhausted.contains(node)) { + this.updateExhaustMap(node.getParent()); + } + if (this.exhausted.containsAll(node.getChildren())) { + this.exhausted.add(node); + this.updateExhaustMap(node.getParent()); + } + } + + /** + * Computes a solution path that deviates k times from the heuristic (if possible) + * + * @param node + * @param k + * @return + * @throws InterruptedException + * @throws AlgorithmExecutionCanceledException + * @throws AlgorithmTimeoutedException + * @throws AlgorithmException + */ + private AlgorithmEvent ldsProbe(final TreeNode node) throws InterruptedException, AlgorithmTimeoutedException, AlgorithmExecutionCanceledException, AlgorithmException { + this.logger.debug("Probing under node {} with k = {}. Exhausted: {}", node.getValue(), this.currentK, this.exhausted.contains(node)); + + /* return solution event if this is a solution node */ + if (this.nodeGoalTester.isGoal(node.getValue())) { + this.updateExhaustMap(node); + List path = node.getValuesOnPathFromRoot(); + EvaluatedSearchGraphPath solution = new EvaluatedSearchGraphPath<>(path, null, null); + this.updateBestSeenSolution(solution); + this.logger.debug("Found solution {}.", node.getValue()); + return new ASolutionCandidateFoundEvent<>(this.getId(), solution); + } + + /* if this node has not been expanded, compute successors and the priorities among them and attach them to search graph */ + if (!this.expanded.contains(node)) { + this.expanded.add(node); + this.logger.debug("Starting successor generation of {}", node.getValue()); + long start = System.currentTimeMillis(); + Collection> succ = this.computeTimeoutAware(() -> this.successorGenerator.generateSuccessors(node.getValue()), "Successor generation" , true); + if (succ == null || succ.isEmpty()) { + this.logger.debug("No successors were generated."); + return new NoMoreNodesOnLevelEvent(this.getId()); + } + this.logger.debug("Computed {} successors in {}ms. Attaching the nodes to the local model.", succ.size(), System.currentTimeMillis() - start); + List> prioSucc = succ.stream().sorted((d1, d2) -> this.heuristic.compare(d1.getTo(), d2.getTo())).collect(Collectors.toList()); + this.checkAndConductTermination(); + List> generatedNodes = new ArrayList<>(); + long lastCheck = System.currentTimeMillis(); + for (NodeExpansionDescription successorDescription : prioSucc) { + if (System.currentTimeMillis() - lastCheck > 10) { + this.checkAndConductTermination(); + lastCheck = System.currentTimeMillis(); + } + TreeNode newNode = this.newNode(node, successorDescription.getTo()); + generatedNodes.add(newNode); + } + this.logger.debug("Local model updated."); + this.checkAndConductTermination(); + } else { + this.logger.info("Not expanding node {} again.", node.getValue()); + } + List> children = node.getChildren(); + if (children.isEmpty()) { + return new NoMoreNodesOnLevelEvent(this.getId()); + } + + /* if no deviation is allowed, return the probe for the first child (unless that child is already exhausted) */ + if (this.currentK == 0 || children.size() == 1) { + boolean onlyAdmissibleChildExhausted = this.exhausted.contains(children.get(0)); + this.logger.debug("No deviation allowed or only one child node. Probing this child (if not, the reason is that it is exhausted already): {}", !onlyAdmissibleChildExhausted); + return !onlyAdmissibleChildExhausted ? this.ldsProbe(children.get(0)) : new NoMoreNodesOnLevelEvent(this.getId()); + } + + /* deviate from the heuristic. If no more discrepancies are allowed, keep searching under the first child unless that child has been exhausted */ + this.currentK--; + this.logger.debug("Deviating from heuristic. Decreased current k to {}", this.currentK); + if (this.exhausted.contains(children.get(1))) { + return new NoMoreNodesOnLevelEvent(this.getId()); + } + return this.ldsProbe(children.get(1)); + } + + protected synchronized TreeNode newNode(final TreeNode parent, final T newNode) { + + /* attach new node to traversal tree */ + TreeNode newTree = parent != null ? parent.addChild(newNode) : new TreeNode<>(newNode); + + /* send events for this new node */ + if (parent != null) { + boolean isGoal = this.nodeGoalTester.isGoal(newNode); + this.post(new NodeAddedEvent>(this.getId(), parent, newTree, "or_" + (isGoal ? "solution" : "created"))); + } + return newTree; + } + + @Override + public String getLoggerName() { + return this.loggerName; + } + + @Override + public void setLoggerName(final String name) { + this.logger.info("Switching logger from {} to {}", this.logger.getName(), name); + this.loggerName = name; + this.logger = LoggerFactory.getLogger(name); + this.logger.info("Activated logger {} with name {}", name, this.logger.getName()); + super.setLoggerName(this.loggerName + "._orgraphsearch"); + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearchFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearchFactory.java similarity index 67% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearchFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearchFactory.java index b21b62758e..1ede8641b8 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearchFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/LimitedDiscrepancySearchFactory.java @@ -1,8 +1,8 @@ -package jaicore.search.algorithms.standard.lds; +package ai.libs.jaicore.search.algorithms.standard.lds; -import jaicore.search.core.interfaces.StandardORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; +import ai.libs.jaicore.search.core.interfaces.StandardORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; public class LimitedDiscrepancySearchFactory> extends StandardORGraphSearchFactory, EvaluatedSearchGraphPath, N, A, V> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/NoMoreNodesOnLevelEvent.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/NoMoreNodesOnLevelEvent.java similarity index 75% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/NoMoreNodesOnLevelEvent.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/NoMoreNodesOnLevelEvent.java index 9e7e630412..3c5991545c 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/NoMoreNodesOnLevelEvent.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/NoMoreNodesOnLevelEvent.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.lds; +package ai.libs.jaicore.search.algorithms.standard.lds; import ai.libs.jaicore.basic.algorithm.events.AAlgorithmEvent; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/NodeOrderList.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/NodeOrderList.java similarity index 93% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/NodeOrderList.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/NodeOrderList.java index 16e96b7fe3..b49543b090 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/lds/NodeOrderList.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/lds/NodeOrderList.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.lds; +package ai.libs.jaicore.search.algorithms.standard.lds; import java.util.ArrayList; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/ActionPredictionFailedException.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/ActionPredictionFailedException.java similarity index 80% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/ActionPredictionFailedException.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/ActionPredictionFailedException.java index 62d32f9458..5b165e1053 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/ActionPredictionFailedException.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/ActionPredictionFailedException.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.mcts; +package ai.libs.jaicore.search.algorithms.standard.mcts; @SuppressWarnings("serial") public class ActionPredictionFailedException extends Exception { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/IPathUpdatablePolicy.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/IPathUpdatablePolicy.java similarity index 72% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/IPathUpdatablePolicy.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/IPathUpdatablePolicy.java index 00fea8f512..ab975c7d57 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/IPathUpdatablePolicy.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/IPathUpdatablePolicy.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.mcts; +package ai.libs.jaicore.search.algorithms.standard.mcts; import java.util.List; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/IPolicy.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/IPolicy.java similarity index 73% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/IPolicy.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/IPolicy.java index 5939f22964..e4373cdd09 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/IPolicy.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/IPolicy.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.mcts; +package ai.libs.jaicore.search.algorithms.standard.mcts; import java.util.Map; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/MCTS.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/MCTS.java similarity index 94% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/MCTS.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/MCTS.java index ba8ddf39ab..c5895d38b2 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/MCTS.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/MCTS.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.mcts; +package ai.libs.jaicore.search.algorithms.standard.mcts; import java.util.ArrayList; import java.util.Collection; @@ -26,19 +26,19 @@ import ai.libs.jaicore.graphvisualizer.events.graph.GraphInitializedEvent; import ai.libs.jaicore.graphvisualizer.events.graph.NodeAddedEvent; import ai.libs.jaicore.graphvisualizer.events.graph.NodeTypeSwitchEvent; -import jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.PathGoalTester; -import jaicore.search.structure.graphgenerator.RootGenerator; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; -import jaicore.search.structure.graphgenerator.TimeAwareSuccessorGenerator; +import ai.libs.jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.PathGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.RootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.TimeAwareSuccessorGenerator; /** * MCTS algorithm implementation. diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/MCTSFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/MCTSFactory.java similarity index 79% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/MCTSFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/MCTSFactory.java index 58801ee481..188ab0a179 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/MCTSFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/MCTSFactory.java @@ -1,9 +1,9 @@ -package jaicore.search.algorithms.standard.mcts; +package ai.libs.jaicore.search.algorithms.standard.mcts; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.core.interfaces.StandardORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.core.interfaces.StandardORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; public class MCTSFactory> extends StandardORGraphSearchFactory, EvaluatedSearchGraphPath, N, A, V> implements IOptimalPathInORGraphSearchFactory, N, A, V> { private IPathUpdatablePolicy treePolicy; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UCBPolicy.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UCBPolicy.java similarity index 96% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UCBPolicy.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UCBPolicy.java index 13db2c7341..924b80d8ca 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UCBPolicy.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UCBPolicy.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.mcts; +package ai.libs.jaicore.search.algorithms.standard.mcts; import java.util.Collection; import java.util.HashMap; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UCT.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UCT.java similarity index 79% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UCT.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UCT.java index 28754bb234..6c4d4de102 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UCT.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UCT.java @@ -1,8 +1,8 @@ -package jaicore.search.algorithms.standard.mcts; +package ai.libs.jaicore.search.algorithms.standard.mcts; import java.util.Random; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; public class UCT extends MCTS { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UCTFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UCTFactory.java similarity index 84% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UCTFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UCTFactory.java index 8160b19e5d..93ceebfd94 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UCTFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UCTFactory.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.mcts; +package ai.libs.jaicore.search.algorithms.standard.mcts; public class UCTFactory extends MCTSFactory { private int seed; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UniformRandomPolicy.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UniformRandomPolicy.java similarity index 92% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UniformRandomPolicy.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UniformRandomPolicy.java index fde9f76d52..ba726dec60 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/mcts/UniformRandomPolicy.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/mcts/UniformRandomPolicy.java @@ -1,39 +1,39 @@ -package jaicore.search.algorithms.standard.mcts; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class UniformRandomPolicy> implements IPolicy { - - private static final Logger logger = LoggerFactory.getLogger(UniformRandomPolicy.class); - private final Random r; - - public UniformRandomPolicy(Random r) { - super(); - this.r = r; - } - - @Override - public A getAction(T node, Map actionsWithTheirSuccessors) { - logger.debug("Deriving action for node {}. Options are: {}", node, actionsWithTheirSuccessors); - - if (actionsWithTheirSuccessors.isEmpty()) - throw new IllegalArgumentException("Cannot determine action if no actions are given!"); - if (actionsWithTheirSuccessors.size() == 1) - return actionsWithTheirSuccessors.keySet().iterator().next(); - List keys = new ArrayList<>(actionsWithTheirSuccessors.keySet()); - A choice = keys.get(r.nextInt(keys.size() - 1)); - logger.info("Recommending action {}", choice); - return choice; - } - - public void updatePath(List path, V score) { - logger.debug("Updating path {} with score {}", path, score); - } -} +package ai.libs.jaicore.search.algorithms.standard.mcts; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class UniformRandomPolicy> implements IPolicy { + + private static final Logger logger = LoggerFactory.getLogger(UniformRandomPolicy.class); + private final Random r; + + public UniformRandomPolicy(Random r) { + super(); + this.r = r; + } + + @Override + public A getAction(T node, Map actionsWithTheirSuccessors) { + logger.debug("Deriving action for node {}. Options are: {}", node, actionsWithTheirSuccessors); + + if (actionsWithTheirSuccessors.isEmpty()) + throw new IllegalArgumentException("Cannot determine action if no actions are given!"); + if (actionsWithTheirSuccessors.size() == 1) + return actionsWithTheirSuccessors.keySet().iterator().next(); + List keys = new ArrayList<>(actionsWithTheirSuccessors.keySet()); + A choice = keys.get(r.nextInt(keys.size() - 1)); + logger.info("Recommending action {}", choice); + return choice; + } + + public void updatePath(List path, V score) { + logger.debug("Updating path {} with score {}", path, score); + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/opencollections/EnforcedExplorationOpenSelection.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/opencollections/EnforcedExplorationOpenSelection.java similarity index 90% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/opencollections/EnforcedExplorationOpenSelection.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/opencollections/EnforcedExplorationOpenSelection.java index b7c6757cd6..1f5a619e80 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/opencollections/EnforcedExplorationOpenSelection.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/opencollections/EnforcedExplorationOpenSelection.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.opencollections; +package ai.libs.jaicore.search.algorithms.standard.opencollections; import java.util.ArrayList; import java.util.Collection; @@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory; import ai.libs.jaicore.basic.sets.SetUtil; -import jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.model.travesaltree.Node; /** * This OPEN selection allows to enforce that the search is restricted to be searched under a given node diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/opencollections/TimedEnforcedExplorationOpenSelection.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/opencollections/TimedEnforcedExplorationOpenSelection.java similarity index 95% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/opencollections/TimedEnforcedExplorationOpenSelection.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/opencollections/TimedEnforcedExplorationOpenSelection.java index ce5674ac99..2bfe6fc7e5 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/opencollections/TimedEnforcedExplorationOpenSelection.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/opencollections/TimedEnforcedExplorationOpenSelection.java @@ -1,170 +1,171 @@ -//package jaicore.search.algorithms.standard.opencollections; -// -//import java.util.Collection; -//import java.util.Iterator; -// -//import org.slf4j.Logger; -//import org.slf4j.LoggerFactory; -// -//import jaicore.search.algorithms.standard.bestfirst.model.OpenCollection; -//import jaicore.search.algorithms.standard.bestfirst.model.PriorityQueueOpen; -//import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -//import jaicore.search.model.travesaltree.Node; -// -///** -// * This is like EnforcedExplorationOpenSelection except that there is a fixed rule how the restriction on exploration is set. -// * -// * @author fmohr -// * -// * @param -// * @param -// * @param -// */ -//public class TimedEnforcedExplorationOpenSelection,W extends Comparable> extends EnforcedExplorationOpenSelection { -// -// private static final Logger logger = LoggerFactory.getLogger(TimedEnforcedExplorationOpenSelection.class); -// -// private final PriorityQueueOpen> secondaryOpen = new PriorityQueueOpen<>(); -// private final INodeEvaluator explorationEvaluator; -// private int explorationPhaseLength = 10; -// private int exploitationPhaseLength = 50; -// private int selectedNodes = 0; -// private int exploredNodes = 0; -// private boolean exploring = false; -// -// public TimedEnforcedExplorationOpenSelection(OpenCollection> primaryOpen, INodeEvaluator explorationEvaluator, int explorationPhaseLength, int exploitationPhaseLength) { -// super(primaryOpen); -// this.explorationEvaluator = explorationEvaluator; -// this.explorationPhaseLength = explorationPhaseLength; -// this.exploitationPhaseLength = exploitationPhaseLength; -// } -// -// @Override -// public Node peek() { -// -// if (!exploring) { -// selectedNodes++; -// if (selectedNodes % exploitationPhaseLength != 0) { -// // System.out.println("Exploiting ..."); -// return primaryOpen.peek(); -// } -// -// /* now chose particular node for expansion */ -// Node nodeToBeExplored = primaryOpen.stream().min((n1, n2) -> { -// try { -// return explorationEvaluator.f(n1).compareTo(explorationEvaluator.f(n2)); -// } catch (Throwable e) { -// e.printStackTrace(); -// } -// return 0; -// }).get(); -// -// /* enable exploration with the node selected by the explorer evaluator */ -// try { -// if (logger.isInfoEnabled()) -// logger.info("Entering exploration phase under {} with exploration value: {}", nodeToBeExplored, explorationEvaluator.f(nodeToBeExplored)); -// } catch (Throwable e) { -// e.printStackTrace(); -// } -// exploring = true; -// exploredNodes = 0; -// primaryOpen.remove(nodeToBeExplored); -// secondaryOpen.clear(); -// secondaryOpen.add(nodeToBeExplored); -// return nodeToBeExplored; -// } else { -// exploredNodes++; -// if (exploredNodes > explorationPhaseLength || secondaryOpen.isEmpty()) { -// exploring = false; -// primaryOpen.addAll(secondaryOpen); -// secondaryOpen.clear(); -// return primaryOpen.peek(); -// } -// return secondaryOpen.peek(); -// } -// } -// -// @Override -// public boolean add(Node node) { -// assert !contains(node) : "Node " + node + " is already there!"; -// if (exploring) { -// return secondaryOpen.add(node); -// } else -// return primaryOpen.add(node); -// } -// -// @Override -// public boolean remove(Object node) { -// assert !(primaryOpen.contains(node) && secondaryOpen.contains(node)) : "A node (" + node + ") that is to be removed is in BOTH open lists!"; -// if (exploring) { -// return secondaryOpen.remove(node) || primaryOpen.remove(node); -// } else { -// return primaryOpen.remove(node) || secondaryOpen.remove(node); -// } -// } -// -// @Override -// public boolean addAll(Collection> arg0) { -// if (exploring) { -// return secondaryOpen.addAll(arg0); -// } else -// return primaryOpen.addAll(arg0); -// } -// -// @Override -// public void clear() { -// primaryOpen.clear(); -// secondaryOpen.clear(); -// } -// -// @Override -// public boolean contains(Object arg0) { -// return primaryOpen.contains(arg0) || secondaryOpen.contains(arg0); -// } -// -// @Override -// public boolean containsAll(Collection arg0) { -// for (Object o : arg0) { -// if (!contains(o)) -// return false; -// } -// return true; -// } -// -// @Override -// public boolean isEmpty() { -// return primaryOpen.isEmpty() && secondaryOpen.isEmpty(); -// } -// -// @Override -// public Iterator> iterator() { -// return null; -// } -// -// @Override -// public boolean removeAll(Collection arg0) { -// return primaryOpen.removeAll(arg0) && secondaryOpen.removeAll(arg0); -// } -// -// @Override -// public boolean retainAll(Collection arg0) { -// return primaryOpen.retainAll(arg0) && secondaryOpen.retainAll(arg0); -// } -// -// @Override -// public int size() { -// return primaryOpen.size() + secondaryOpen.size(); -// } -// -// @Override -// public Object[] toArray() { -// return primaryOpen.toArray(); -// } -// -// @SuppressWarnings("unchecked") -// @Override -// public T[] toArray(T[] arg0) { -// return (T[]) primaryOpen.toArray(); -// } -// -//} +package ai.libs.jaicore.search.algorithms.standard.opencollections; +//package jaicore.search.algorithms.standard.opencollections; +// +//import java.util.Collection; +//import java.util.Iterator; +// +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +// +//import jaicore.search.algorithms.standard.bestfirst.model.OpenCollection; +//import jaicore.search.algorithms.standard.bestfirst.model.PriorityQueueOpen; +//import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +//import jaicore.search.model.travesaltree.Node; +// +///** +// * This is like EnforcedExplorationOpenSelection except that there is a fixed rule how the restriction on exploration is set. +// * +// * @author fmohr +// * +// * @param +// * @param +// * @param +// */ +//public class TimedEnforcedExplorationOpenSelection,W extends Comparable> extends EnforcedExplorationOpenSelection { +// +// private static final Logger logger = LoggerFactory.getLogger(TimedEnforcedExplorationOpenSelection.class); +// +// private final PriorityQueueOpen> secondaryOpen = new PriorityQueueOpen<>(); +// private final INodeEvaluator explorationEvaluator; +// private int explorationPhaseLength = 10; +// private int exploitationPhaseLength = 50; +// private int selectedNodes = 0; +// private int exploredNodes = 0; +// private boolean exploring = false; +// +// public TimedEnforcedExplorationOpenSelection(OpenCollection> primaryOpen, INodeEvaluator explorationEvaluator, int explorationPhaseLength, int exploitationPhaseLength) { +// super(primaryOpen); +// this.explorationEvaluator = explorationEvaluator; +// this.explorationPhaseLength = explorationPhaseLength; +// this.exploitationPhaseLength = exploitationPhaseLength; +// } +// +// @Override +// public Node peek() { +// +// if (!exploring) { +// selectedNodes++; +// if (selectedNodes % exploitationPhaseLength != 0) { +// // System.out.println("Exploiting ..."); +// return primaryOpen.peek(); +// } +// +// /* now chose particular node for expansion */ +// Node nodeToBeExplored = primaryOpen.stream().min((n1, n2) -> { +// try { +// return explorationEvaluator.f(n1).compareTo(explorationEvaluator.f(n2)); +// } catch (Throwable e) { +// e.printStackTrace(); +// } +// return 0; +// }).get(); +// +// /* enable exploration with the node selected by the explorer evaluator */ +// try { +// if (logger.isInfoEnabled()) +// logger.info("Entering exploration phase under {} with exploration value: {}", nodeToBeExplored, explorationEvaluator.f(nodeToBeExplored)); +// } catch (Throwable e) { +// e.printStackTrace(); +// } +// exploring = true; +// exploredNodes = 0; +// primaryOpen.remove(nodeToBeExplored); +// secondaryOpen.clear(); +// secondaryOpen.add(nodeToBeExplored); +// return nodeToBeExplored; +// } else { +// exploredNodes++; +// if (exploredNodes > explorationPhaseLength || secondaryOpen.isEmpty()) { +// exploring = false; +// primaryOpen.addAll(secondaryOpen); +// secondaryOpen.clear(); +// return primaryOpen.peek(); +// } +// return secondaryOpen.peek(); +// } +// } +// +// @Override +// public boolean add(Node node) { +// assert !contains(node) : "Node " + node + " is already there!"; +// if (exploring) { +// return secondaryOpen.add(node); +// } else +// return primaryOpen.add(node); +// } +// +// @Override +// public boolean remove(Object node) { +// assert !(primaryOpen.contains(node) && secondaryOpen.contains(node)) : "A node (" + node + ") that is to be removed is in BOTH open lists!"; +// if (exploring) { +// return secondaryOpen.remove(node) || primaryOpen.remove(node); +// } else { +// return primaryOpen.remove(node) || secondaryOpen.remove(node); +// } +// } +// +// @Override +// public boolean addAll(Collection> arg0) { +// if (exploring) { +// return secondaryOpen.addAll(arg0); +// } else +// return primaryOpen.addAll(arg0); +// } +// +// @Override +// public void clear() { +// primaryOpen.clear(); +// secondaryOpen.clear(); +// } +// +// @Override +// public boolean contains(Object arg0) { +// return primaryOpen.contains(arg0) || secondaryOpen.contains(arg0); +// } +// +// @Override +// public boolean containsAll(Collection arg0) { +// for (Object o : arg0) { +// if (!contains(o)) +// return false; +// } +// return true; +// } +// +// @Override +// public boolean isEmpty() { +// return primaryOpen.isEmpty() && secondaryOpen.isEmpty(); +// } +// +// @Override +// public Iterator> iterator() { +// return null; +// } +// +// @Override +// public boolean removeAll(Collection arg0) { +// return primaryOpen.removeAll(arg0) && secondaryOpen.removeAll(arg0); +// } +// +// @Override +// public boolean retainAll(Collection arg0) { +// return primaryOpen.retainAll(arg0) && secondaryOpen.retainAll(arg0); +// } +// +// @Override +// public int size() { +// return primaryOpen.size() + secondaryOpen.size(); +// } +// +// @Override +// public Object[] toArray() { +// return primaryOpen.toArray(); +// } +// +// @SuppressWarnings("unchecked") +// @Override +// public T[] toArray(T[] arg0) { +// return (T[]) primaryOpen.toArray(); +// } +// +//} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/random/RandomSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/random/RandomSearch.java similarity index 93% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/random/RandomSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/random/RandomSearch.java index e491d40b77..a1bb659eb6 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/random/RandomSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/random/RandomSearch.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.random; +package ai.libs.jaicore.search.algorithms.standard.random; import java.util.ArrayList; import java.util.Collection; @@ -22,15 +22,15 @@ import ai.libs.jaicore.graphvisualizer.events.graph.GraphInitializedEvent; import ai.libs.jaicore.graphvisualizer.events.graph.NodeAddedEvent; import ai.libs.jaicore.graphvisualizer.events.graph.NodeTypeSwitchEvent; -import jaicore.search.algorithms.standard.bestfirst.events.GraphSearchSolutionCandidateFoundEvent; -import jaicore.search.core.interfaces.AAnyPathInORGraphSearch; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SingleSuccessorGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.GraphSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.core.interfaces.AAnyPathInORGraphSearch; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SingleSuccessorGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; /** * This search randomly draws paths from the root. At every node, each successor is chosen with the same probability except if a priority predicate is defined. A priority predicate says whether or not a node lies on a path that has diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/random/RandomSearchFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/random/RandomSearchFactory.java similarity index 75% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/random/RandomSearchFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/random/RandomSearchFactory.java index 03006f3153..9b04422ba3 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/random/RandomSearchFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/random/RandomSearchFactory.java @@ -1,44 +1,44 @@ -package jaicore.search.algorithms.standard.random; - -import jaicore.search.core.interfaces.StandardORGraphSearchFactory; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; - -public class RandomSearchFactory extends StandardORGraphSearchFactory, SearchGraphPath,N, A, Double> { - - private String loggerName; - private int seed; - - public RandomSearchFactory() { - super(); - } - - @Override - public RandomSearch getAlgorithm() { - if (this.getInput().getGraphGenerator() == null) { - throw new IllegalStateException("Cannot produce RandomSearch searches before the graph generator is set in the problem."); - } - return this.getAlgorithm(this.getInput()); - } - - @Override - public RandomSearch getAlgorithm(final GraphSearchInput input) { - return new RandomSearch<>(input, this.seed); - } - - public int getSeed() { - return this.seed; - } - - public void setSeed(final int seed) { - this.seed = seed; - } - - public String getLoggerName() { - return this.loggerName; - } - - public void setLoggerName(final String loggerName) { - this.loggerName = loggerName; - } -} +package ai.libs.jaicore.search.algorithms.standard.random; + +import ai.libs.jaicore.search.core.interfaces.StandardORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; + +public class RandomSearchFactory extends StandardORGraphSearchFactory, SearchGraphPath,N, A, Double> { + + private String loggerName; + private int seed; + + public RandomSearchFactory() { + super(); + } + + @Override + public RandomSearch getAlgorithm() { + if (this.getInput().getGraphGenerator() == null) { + throw new IllegalStateException("Cannot produce RandomSearch searches before the graph generator is set in the problem."); + } + return this.getAlgorithm(this.getInput()); + } + + @Override + public RandomSearch getAlgorithm(final GraphSearchInput input) { + return new RandomSearch<>(input, this.seed); + } + + public int getSeed() { + return this.seed; + } + + public void setSeed(final int seed) { + this.seed = seed; + } + + public String getLoggerName() { + return this.loggerName; + } + + public void setLoggerName(final String loggerName) { + this.loggerName = loggerName; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rdfs/RandomizedDepthFirstSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rdfs/RandomizedDepthFirstSearch.java similarity index 68% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rdfs/RandomizedDepthFirstSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rdfs/RandomizedDepthFirstSearch.java index 72c42e00d4..773f9c49f2 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rdfs/RandomizedDepthFirstSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rdfs/RandomizedDepthFirstSearch.java @@ -1,14 +1,14 @@ -package jaicore.search.algorithms.standard.rdfs; +package ai.libs.jaicore.search.algorithms.standard.rdfs; import java.util.Random; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomizedDepthFirstNodeEvaluator; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomizedDepthFirstNodeEvaluator; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class RandomizedDepthFirstSearch extends StandardBestFirst { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/GammaNode.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/GammaNode.java similarity index 90% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/GammaNode.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/GammaNode.java index 7c148f9abf..a9e4a025ed 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/GammaNode.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/GammaNode.java @@ -1,95 +1,95 @@ -package jaicore.search.algorithms.standard.rstar; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; - -import jaicore.search.model.travesaltree.Node; - -/** - * Node wrapper for usage in R*. - * - * Every node is equipped with path to its backpointer i.e. parent, the g-value and - * the AVOID label. - * - * @author fischor, fmohr, mwever - * - * @param problem state type - * @param internal label type (in R* its RStarK) - */ -public class GammaNode extends Node { - - private double g = Double.MAX_VALUE; - private boolean avoid = false; - - /** - * List of all predecessors for this node. - * Initialized here and then filled throughout R* processes. - */ - private Collection> predecessors = new ArrayList<>(); - - /** - * Maps from each successor s_ to the lowest cost for path(this, s_). - * This is either a heuristic estimate or the actual known lowest cost. - */ - protected HashMap, Double> cLow = new HashMap<>(); - - /** - * Constructor. - * Ignores parent node because we use the backpointer attribute. - * - * @param point - */ - public GammaNode(final T point) { - super(null, point); - } - - @Override - public GammaNode getParent() { - return (GammaNode) super.getParent(); - } - - /** - * Add a predecessor to this node. - * @param n The predecessor to be added. - * @return Returns true iff the predecessor could be added successfully. - */ - public boolean addPredecessor(final GammaNode n) { - return this.predecessors.add(n); - } - - /** - * @return The collection of all predecessors of this node. - */ - public Collection> getPredecessors() { - return this.predecessors; - } - - /** - * @return The value of g. - */ - public double getG() { - return this.g; - } - - /** - * @param g The new value of g. - */ - public void setG(final double g) { - this.g = g; - } - - /** - * @return The value of the avoid flag of this node. - */ - public boolean getAvoid() { - return this.avoid; - } - - /** - * @param avoid The new value of the avoid flag of this node. - */ - public void setAvoid(final boolean avoid) { - this.avoid = avoid; - } -} +package ai.libs.jaicore.search.algorithms.standard.rstar; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +/** + * Node wrapper for usage in R*. + * + * Every node is equipped with path to its backpointer i.e. parent, the g-value and + * the AVOID label. + * + * @author fischor, fmohr, mwever + * + * @param problem state type + * @param internal label type (in R* its RStarK) + */ +public class GammaNode extends Node { + + private double g = Double.MAX_VALUE; + private boolean avoid = false; + + /** + * List of all predecessors for this node. + * Initialized here and then filled throughout R* processes. + */ + private Collection> predecessors = new ArrayList<>(); + + /** + * Maps from each successor s_ to the lowest cost for path(this, s_). + * This is either a heuristic estimate or the actual known lowest cost. + */ + protected HashMap, Double> cLow = new HashMap<>(); + + /** + * Constructor. + * Ignores parent node because we use the backpointer attribute. + * + * @param point + */ + public GammaNode(final T point) { + super(null, point); + } + + @Override + public GammaNode getParent() { + return (GammaNode) super.getParent(); + } + + /** + * Add a predecessor to this node. + * @param n The predecessor to be added. + * @return Returns true iff the predecessor could be added successfully. + */ + public boolean addPredecessor(final GammaNode n) { + return this.predecessors.add(n); + } + + /** + * @return The collection of all predecessors of this node. + */ + public Collection> getPredecessors() { + return this.predecessors; + } + + /** + * @return The value of g. + */ + public double getG() { + return this.g; + } + + /** + * @param g The new value of g. + */ + public void setG(final double g) { + this.g = g; + } + + /** + * @return The value of the avoid flag of this node. + */ + public boolean getAvoid() { + return this.avoid; + } + + /** + * @param avoid The new value of the avoid flag of this node. + */ + public void setAvoid(final boolean avoid) { + this.avoid = avoid; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/GraphBasedDistantSuccessorGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/GraphBasedDistantSuccessorGenerator.java similarity index 86% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/GraphBasedDistantSuccessorGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/GraphBasedDistantSuccessorGenerator.java index 7baf9d4cb3..d95d09b4f8 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/GraphBasedDistantSuccessorGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/GraphBasedDistantSuccessorGenerator.java @@ -1,4 +1,4 @@ -package jaicore.search.algorithms.standard.rstar; +package ai.libs.jaicore.search.algorithms.standard.rstar; import java.util.ArrayList; import java.util.List; @@ -9,11 +9,11 @@ import ai.libs.jaicore.basic.ILoggingCustomizable; import ai.libs.jaicore.basic.IMetric; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.DistantSuccessorGenerator; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.DistantSuccessorGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; public class GraphBasedDistantSuccessorGenerator implements DistantSuccessorGenerator, ILoggingCustomizable { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/RStar.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStar.java similarity index 90% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/RStar.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStar.java index 940fb860b5..de6ecc5175 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/RStar.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStar.java @@ -1,405 +1,405 @@ -package jaicore.search.algorithms.standard.rstar; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.PriorityQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.stream.Collectors; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import ai.libs.jaicore.basic.ILoggingCustomizable; -import ai.libs.jaicore.basic.IMetric; -import ai.libs.jaicore.basic.TimeOut; -import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; -import ai.libs.jaicore.basic.algorithm.IAlgorithm; -import ai.libs.jaicore.basic.algorithm.events.AlgorithmEvent; -import ai.libs.jaicore.basic.algorithm.events.AlgorithmInitializedEvent; -import ai.libs.jaicore.basic.algorithm.events.SolutionCandidateFoundEvent; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; -import ai.libs.jaicore.basic.sets.SetUtil; -import ai.libs.jaicore.basic.sets.SetUtil.Pair; -import jaicore.search.algorithms.standard.astar.AStar; -import jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; -import jaicore.search.algorithms.standard.bestfirst.events.NodeExpansionCompletedEvent; -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; -import jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic; -import jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.DistantSuccessorGenerator; -import jaicore.search.structure.graphgenerator.MultipleRootGenerator; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.RootGenerator; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; - -/** - * Implementation of the R* algorithm. - * - * @author fischor, fmohr, mwever - * - * @param a nodes external label i.e. a state of a problem - * @param action (action space of problem) - */ -public class RStar extends AOptimalPathInORGraphSearch, T, A, Double> { - - /* Open list. */ - protected PriorityQueue> open = new PriorityQueue<>((n1, n2) -> (n1.getInternalLabel().compareTo(n2.getInternalLabel()))); - - /* Closed list of already expanded states. */ - protected ArrayList> closed = new ArrayList<>(); - - private final INodeEvaluator h; - private final GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.PathCostEstimator hPath; - - /* For actual search problem */ - private final int k; - protected final double w; - private final double delta; - private final IMetric metricOverStates; - - private GammaNode bestSeenGoalNode; - private final Map, GammaNode>, SearchGraphPath> externalPathsBetweenGammaNodes = new HashMap<>(); // the pairs should always be in a parent-child relation - - private List>> unreturnedSolutionEvents = new LinkedList<>(); - - private Collection> activeAStarSubroutines = new ArrayList<>(); - - private Logger logger = LoggerFactory.getLogger(RStar.class); - - /** - * - * @param gammaGraphGenerator - * @param w - * @param k - * @param delta - */ - public RStar(final GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic problem, final double w, final int k, final double delta) { - super(problem); - this.h = ((GraphSearchWithNumberBasedAdditivePathEvaluation.FComputer) this.getInput().getNodeEvaluator()).getH(); - this.hPath = ((GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.SubPathEvaluationBasedFComputer) this.getInput().getNodeEvaluator()).gethPath(); - this.w = w; - this.k = k; - this.metricOverStates = this.getInput().getMetricOverStates(); - this.delta = delta; - } - - /** - * Updates a state i.e. node n in the open list. - * Lines 1 - 5 in the paper. - * - * @param n - * @throws InterruptedException - * @throws NodeEvaluationException - */ - private void updateState(final GammaNode n) throws NodeEvaluationException, InterruptedException { - if ((n.getG() > this.w * this.h.f(n)) || ((n.getParent() == null || !this.isPathRealizationKnownForAbstractEdgeToNode(n)) && n.getAvoid())) { - n.setInternalLabel(new RStarK(true, n.getG() + this.w * this.h.f(n))); - } else { - n.setInternalLabel(new RStarK(false, n.getG() + this.w * this.h.f(n))); - } - this.open.add(n); - } - - /** - * Tries to compute the local path - * Lines 6 - 12 in the paper. - * - * @param n - * @throws InterruptedException - * @throws AlgorithmException - * @throws TimeoutException - * @throws AlgorithmExecutionCanceledException - */ - private void reevaluateState(final GammaNode n) throws InterruptedException, AlgorithmExecutionCanceledException, AlgorithmTimeoutedException, AlgorithmException { - - /* Line 7: Try to compute the local path from bp(n) to n. (we use AStar for this) */ - this.logger.debug("Reevaluating node {}", n); - if (n.getParent() == null) { - throw new IllegalArgumentException("Can only re-evaluate nodes that have a parent!"); - } - GraphGenerator subProblemGraphGenerator = new SubPathGraphGenerator<>(this.getInput().getGraphGenerator(), n.getParent().getPoint(), n.getPoint()); - AStar astar = new AStar<>(new GraphSearchWithNumberBasedAdditivePathEvaluation<>(subProblemGraphGenerator, (GraphSearchWithNumberBasedAdditivePathEvaluation.FComputer) this.getInput().getNodeEvaluator())); - astar.setLoggerName(this.getLoggerName() + ".astar"); - astar.setTimeout(new TimeOut(this.getRemainingTimeToDeadline().milliseconds(), TimeUnit.MILLISECONDS)); - this.logger.trace("Invoking AStar with root {} and only goal node {}", n.getParent().getPoint(), n.getPoint()); - this.activeAStarSubroutines.add(astar); - EvaluatedSearchGraphPath optimalPath = astar.call(); - this.checkAndConductTermination(); - this.activeAStarSubroutines.remove(astar); - this.externalPathsBetweenGammaNodes.put(new Pair<>(n.getParent(), n), optimalPath); - double bestKnownValueFromParentToNode = optimalPath != null ? optimalPath.getScore() : Double.MAX_VALUE; - n.getParent().cLow.put(n, bestKnownValueFromParentToNode); - - /** - * If no path bp(n)->n could be computed or - * the g = "cost from n_start to bp(n)" + the cost of the found path is greater than w*h(n_start, n) - * the state n should be avoided. - */ - // Line 8 - if (!n.isGoal() && (optimalPath == null || (n.getParent().getG() + bestKnownValueFromParentToNode > this.w * this.hPath.h(n.getParent(), n)))) { - n.setParent(this.argminCostToStateOverPredecessors(n)); - n.setAvoid(true); - } - n.setG(n.getParent().getG() + n.getParent().cLow.get(n)); - if (!n.isGoal()) { - this.updateState(n); - } - } - - @Override - public AlgorithmEvent nextWithException() throws InterruptedException, AlgorithmException, AlgorithmExecutionCanceledException, AlgorithmTimeoutedException { - try { - - this.registerActiveThread(); - this.logger.debug("Performing next step. Current state is {}", this.getState()); - this.checkAndConductTermination(); - switch (this.getState()) { - case created: - AlgorithmInitializedEvent initializationEvent = this.activate(); - - /* Lines 14 to 17 */ - RootGenerator rootGenerator = this.getInput().getGraphGenerator().getRootGenerator(); - if (rootGenerator instanceof MultipleRootGenerator) { - for (T root : ((MultipleRootGenerator) rootGenerator).getRoots()) { - GammaNode internalRoot = new GammaNode<>(root); - internalRoot.setInternalLabel(new RStarK(false, this.w * this.h.f(internalRoot))); - internalRoot.setG(0); - this.open.add(internalRoot); - } - } else if (rootGenerator instanceof SingleRootGenerator) { - GammaNode internalRoot = new GammaNode<>(((SingleRootGenerator) rootGenerator).getRoot()); - internalRoot.setInternalLabel(new RStarK(false, this.w * this.h.f(internalRoot))); - internalRoot.setG(0); - this.open.add(internalRoot); - } else { - assert false : "Only MultipleRootGenerator or SingleRootGenerators allowed."; - } - assert !this.open.isEmpty() : "OPEN must not be empty after initialization!"; - return initializationEvent; - - case active: - - /* return unreturned solutions if such exist */ - if (!this.unreturnedSolutionEvents.isEmpty()) { - this.logger.info("Returning known solution from solution cache!"); - return this.unreturnedSolutionEvents.remove(0); - } - - /** - * Run while the open list is not empty and there exists a node in the open list - * with higher priority i.e. less k than k_n_goal (if the highest priority is a - * goal node, then we return in th next lines). - */ - // Lines 18 & 19 - GammaNode n = this.open.poll(); - this.logger.debug("Selected {} for expansion.", n); - if (n == null || (this.bestSeenGoalNode != null && n.getInternalLabel().compareTo(this.bestSeenGoalNode.getInternalLabel()) > 0)) { - this.logger.info("Terminating RStar."); - return this.terminate(); - } - - // Lines 20 & 21 - if (n.getParent() != null && !this.isPathRealizationKnownForAbstractEdgeToNode(n)) { - - /* The path that corresponds to the edge bp(s)->s has not been computed yet. Try to compute it using reevaluateState. */ - this.reevaluateState(n); - - /* put the node on OPEN again */ - this.logger.debug("Putting node {} on OPEN again", n); - this.open.add(n); - - } else { // The path from bp(s)->s has already been computed. - - // Line 23. - this.closed.add(n); - - /* Line 24 to 27: Compute successors */ - this.logger.debug("Starting generation of successors of {}", n); - Collection> successors = this.generateGammaSuccessors(n); - this.logger.debug("Generated {} successors.", successors.size()); - for (GammaNode n_ : successors) { // Line 28 - - /* Line 29: Initialize successors by setting the path from s to s_ to null, and by estimating the lowest cost from s to s_ with the heuristic h(s, s_). */ - n.cLow.put(n_, this.hPath.h(n, n_)); - - /* Lines 30 and 31 of the algorithm can be omitted here. They contain further initialization of - the successors, but This is done implicitly in the generation process of the Gamma successors. */ - - /* - * If the generated successor n_ i.e. s_ has never been visited yet (n_.getParent() == null) - * or the actual cost to s (n.g) plus the (estimated) cost from s to s_ (c_low(s, s_)) is better - * than the actual known cost (n_.g) to s_, then we have to update these values for s_ (because - * with s we found a better predecessor for s_). - */ - // Line 32 - boolean isNewNode = n_.getParent() == null; - if (isNewNode || (n.getG() + n.cLow.get(n_) < n_.getG())) { - n_.setG(n.getG() + n.cLow.get(n_)); - n_.setParent(n); - this.updateState(n_); // updates priority of n_ in open list. - if (isNewNode) { - this.logger.debug("Adding new node {} to OPEN.", n_); - this.open.add(n_); - } - } - } - } - return new NodeExpansionCompletedEvent<>(this.getId(), n.getPoint()); - - default: - throw new IllegalStateException("Cannot do anything in state " + this.getState()); - } - } - finally { - this.unregisterActiveThread(); - } - } - - private boolean isPathRealizationKnownForAbstractEdgeToNode(final GammaNode node) { - return this.externalPathsBetweenGammaNodes.containsKey(new Pair<>(node.getParent(), node)); - } - - /** - * Calculates the path in the original graph that corresponds to the reduced gamma graph using the established path witnesses. - * - * @param n - * @return - */ - private EvaluatedSearchGraphPath getFullExternalPath(final GammaNode n) { - List nodes = new ArrayList<>(); - List edges = new ArrayList<>(); - GammaNode current = n; - nodes.add(n.getPoint()); - while (current.getParent() != null) { - Pair, GammaNode> pair = new Pair<>(current.getParent(), current); - assert this.externalPathsBetweenGammaNodes.containsKey(pair); - SearchGraphPath externalPath = this.externalPathsBetweenGammaNodes.get(pair); - nodes.addAll(0, externalPath.getNodes()); - List concreteEdges = externalPath.getEdges(); - if (concreteEdges == null) { - concreteEdges = new ArrayList<>(); - int m = externalPath.getNodes().size(); - for (int i = 0; i < m; i++) { - concreteEdges.add(null); - } - } - edges.addAll(0, concreteEdges); - current = current.getParent(); - } - return new EvaluatedSearchGraphPath<>(nodes, edges, n.getG()); - } - - /** - * - * @param n - * @return - */ - private GammaNode argminCostToStateOverPredecessors(final GammaNode n) { - GammaNode argmin = null; - for (GammaNode p : n.getPredecessors()) { - if ((argmin == null) || (p.getG() + p.cLow.get(n) < argmin.getG() + argmin.cLow.get(n))) { - argmin = p; - } - } - return argmin; - } - - /** - * @throws AlgorithmExecutionCanceledException - * @throws AlgorithmException - * @throws AlgorithmTimeoutedException - * Generates this.RStarK Gamma graph successors for a state s within distance this.delta. - * Queries the this.gammaSuccessorGenerator and checks if a generate state has been - * visited i.e. generated in Gamma before. If yes, it takes the old reference from - * the this.alreadyGeneratedStates list. - * Also maintains the predecessor set of nodes. - * - * @param n Gamma node to generate successors for. - * @return List of Gamma nodes. - * @throws InterruptedException - * @throws - */ - private Collection> generateGammaSuccessors(final GammaNode n) throws InterruptedException, AlgorithmTimeoutedException, AlgorithmException, AlgorithmExecutionCanceledException { - - /* first create a list of k nodes that are in reach of delta of the current node */ - this.logger.trace("Invoking distant successor generator timeout-aware."); - List randomDistantSuccessors = this.computeTimeoutAware(() -> this.getInput().getDistantSuccessorGenerator().getDistantSuccessors(n.getPoint(), this.k, this.metricOverStates, this.delta), "Computing distant successors", true); - assert randomDistantSuccessors.size() == new HashSet<>(randomDistantSuccessors).size() : "Distant successor generator has created the same successor ar least twice: \n\t " - + SetUtil.getMultiplyContainedItems(randomDistantSuccessors).stream().map(T::toString).collect(Collectors.joining("\n\t")); - this.logger.trace("Distant successor generator generated {}/{} successors.", randomDistantSuccessors.size(), this.k); - - /* remove nodes for which a node is already on CLOSED (no reopening in this algorithm) */ - randomDistantSuccessors.removeIf(childNode -> this.closed.stream().anyMatch(closedNode -> closedNode.getPoint().equals(childNode))); - this.logger.trace("{} successors are still considered after having removed nodes that already are on CLOSED, which holds {} item(s).", randomDistantSuccessors.size(), this.closed.size()); - - /* now transform these node into (possibly existing) GammaNode objects */ - ArrayList> succWithoutClosed = new ArrayList<>(); - for (T childNode : randomDistantSuccessors) { - Optional> representantOnOpen = this.open.stream().filter(closedNode -> closedNode.getPoint().equals(childNode)).findFirst(); - GammaNode gammaNodeForThisChild; - if (representantOnOpen.isPresent()) { - gammaNodeForThisChild = representantOnOpen.get(); - } else { - gammaNodeForThisChild = new GammaNode<>(childNode); - gammaNodeForThisChild.setGoal(((NodeGoalTester) this.getGraphGenerator().getGoalTester()).isGoal(childNode)); - } - - /* if this is a solution, add it as a new solution */ - if (gammaNodeForThisChild.isGoal()) { - this.logger.info("Found new solution. Adding it to the solution set."); - if (this.bestSeenGoalNode == null || this.bestSeenGoalNode.getG() > n.getG()) { - this.bestSeenGoalNode = n; - this.updateBestSeenSolution(this.getFullExternalPath(n)); - } - EvaluatedSearchSolutionCandidateFoundEvent solutionEvent = new EvaluatedSearchSolutionCandidateFoundEvent<>(this.getId(), this.getFullExternalPath(gammaNodeForThisChild)); - this.post(solutionEvent); - this.unreturnedSolutionEvents.add(solutionEvent); - } - gammaNodeForThisChild.addPredecessor(n); - succWithoutClosed.add(gammaNodeForThisChild); - } - return succWithoutClosed; - } - - @Override - public void setLoggerName(final String name) { - this.logger = LoggerFactory.getLogger(name); - super.setLoggerName(name + "._orgraphsearch"); - - /* set logger name of the graph generator */ - if (this.getGraphGenerator() instanceof ILoggingCustomizable) { - ((ILoggingCustomizable) this.getGraphGenerator()).setLoggerName(name + ".graphgenerator"); - } - - /* set logger name of the distant graph generator */ - DistantSuccessorGenerator distantSuccessorGenerator = this.getInput().getDistantSuccessorGenerator(); - if (distantSuccessorGenerator instanceof ILoggingCustomizable) { - ((ILoggingCustomizable) distantSuccessorGenerator).setLoggerName(name + ".distantsuccessorgenerator"); - } - } - - @Override - public String getLoggerName() { - return this.logger.getName(); - } - - @Override - public void cancel() { - this.logger.info("RStar received cancel. Now invoking shutdown routing and cancel the AStar subroutines."); - super.cancel(); - this.activeAStarSubroutines.forEach(IAlgorithm::cancel); - } -} +package ai.libs.jaicore.search.algorithms.standard.rstar; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.PriorityQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ai.libs.jaicore.basic.ILoggingCustomizable; +import ai.libs.jaicore.basic.IMetric; +import ai.libs.jaicore.basic.TimeOut; +import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; +import ai.libs.jaicore.basic.algorithm.IAlgorithm; +import ai.libs.jaicore.basic.algorithm.events.AlgorithmEvent; +import ai.libs.jaicore.basic.algorithm.events.AlgorithmInitializedEvent; +import ai.libs.jaicore.basic.algorithm.events.SolutionCandidateFoundEvent; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; +import ai.libs.jaicore.basic.sets.SetUtil; +import ai.libs.jaicore.basic.sets.SetUtil.Pair; +import ai.libs.jaicore.search.algorithms.standard.astar.AStar; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.NodeExpansionCompletedEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.DistantSuccessorGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.MultipleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.RootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; + +/** + * Implementation of the R* algorithm. + * + * @author fischor, fmohr, mwever + * + * @param a nodes external label i.e. a state of a problem + * @param action (action space of problem) + */ +public class RStar extends AOptimalPathInORGraphSearch, T, A, Double> { + + /* Open list. */ + protected PriorityQueue> open = new PriorityQueue<>((n1, n2) -> (n1.getInternalLabel().compareTo(n2.getInternalLabel()))); + + /* Closed list of already expanded states. */ + protected ArrayList> closed = new ArrayList<>(); + + private final INodeEvaluator h; + private final GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.PathCostEstimator hPath; + + /* For actual search problem */ + private final int k; + protected final double w; + private final double delta; + private final IMetric metricOverStates; + + private GammaNode bestSeenGoalNode; + private final Map, GammaNode>, SearchGraphPath> externalPathsBetweenGammaNodes = new HashMap<>(); // the pairs should always be in a parent-child relation + + private List>> unreturnedSolutionEvents = new LinkedList<>(); + + private Collection> activeAStarSubroutines = new ArrayList<>(); + + private Logger logger = LoggerFactory.getLogger(RStar.class); + + /** + * + * @param gammaGraphGenerator + * @param w + * @param k + * @param delta + */ + public RStar(final GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic problem, final double w, final int k, final double delta) { + super(problem); + this.h = ((GraphSearchWithNumberBasedAdditivePathEvaluation.FComputer) this.getInput().getNodeEvaluator()).getH(); + this.hPath = ((GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.SubPathEvaluationBasedFComputer) this.getInput().getNodeEvaluator()).gethPath(); + this.w = w; + this.k = k; + this.metricOverStates = this.getInput().getMetricOverStates(); + this.delta = delta; + } + + /** + * Updates a state i.e. node n in the open list. + * Lines 1 - 5 in the paper. + * + * @param n + * @throws InterruptedException + * @throws NodeEvaluationException + */ + private void updateState(final GammaNode n) throws NodeEvaluationException, InterruptedException { + if ((n.getG() > this.w * this.h.f(n)) || ((n.getParent() == null || !this.isPathRealizationKnownForAbstractEdgeToNode(n)) && n.getAvoid())) { + n.setInternalLabel(new RStarK(true, n.getG() + this.w * this.h.f(n))); + } else { + n.setInternalLabel(new RStarK(false, n.getG() + this.w * this.h.f(n))); + } + this.open.add(n); + } + + /** + * Tries to compute the local path + * Lines 6 - 12 in the paper. + * + * @param n + * @throws InterruptedException + * @throws AlgorithmException + * @throws TimeoutException + * @throws AlgorithmExecutionCanceledException + */ + private void reevaluateState(final GammaNode n) throws InterruptedException, AlgorithmExecutionCanceledException, AlgorithmTimeoutedException, AlgorithmException { + + /* Line 7: Try to compute the local path from bp(n) to n. (we use AStar for this) */ + this.logger.debug("Reevaluating node {}", n); + if (n.getParent() == null) { + throw new IllegalArgumentException("Can only re-evaluate nodes that have a parent!"); + } + GraphGenerator subProblemGraphGenerator = new SubPathGraphGenerator<>(this.getInput().getGraphGenerator(), n.getParent().getPoint(), n.getPoint()); + AStar astar = new AStar<>(new GraphSearchWithNumberBasedAdditivePathEvaluation<>(subProblemGraphGenerator, (GraphSearchWithNumberBasedAdditivePathEvaluation.FComputer) this.getInput().getNodeEvaluator())); + astar.setLoggerName(this.getLoggerName() + ".astar"); + astar.setTimeout(new TimeOut(this.getRemainingTimeToDeadline().milliseconds(), TimeUnit.MILLISECONDS)); + this.logger.trace("Invoking AStar with root {} and only goal node {}", n.getParent().getPoint(), n.getPoint()); + this.activeAStarSubroutines.add(astar); + EvaluatedSearchGraphPath optimalPath = astar.call(); + this.checkAndConductTermination(); + this.activeAStarSubroutines.remove(astar); + this.externalPathsBetweenGammaNodes.put(new Pair<>(n.getParent(), n), optimalPath); + double bestKnownValueFromParentToNode = optimalPath != null ? optimalPath.getScore() : Double.MAX_VALUE; + n.getParent().cLow.put(n, bestKnownValueFromParentToNode); + + /** + * If no path bp(n)->n could be computed or + * the g = "cost from n_start to bp(n)" + the cost of the found path is greater than w*h(n_start, n) + * the state n should be avoided. + */ + // Line 8 + if (!n.isGoal() && (optimalPath == null || (n.getParent().getG() + bestKnownValueFromParentToNode > this.w * this.hPath.h(n.getParent(), n)))) { + n.setParent(this.argminCostToStateOverPredecessors(n)); + n.setAvoid(true); + } + n.setG(n.getParent().getG() + n.getParent().cLow.get(n)); + if (!n.isGoal()) { + this.updateState(n); + } + } + + @Override + public AlgorithmEvent nextWithException() throws InterruptedException, AlgorithmException, AlgorithmExecutionCanceledException, AlgorithmTimeoutedException { + try { + + this.registerActiveThread(); + this.logger.debug("Performing next step. Current state is {}", this.getState()); + this.checkAndConductTermination(); + switch (this.getState()) { + case created: + AlgorithmInitializedEvent initializationEvent = this.activate(); + + /* Lines 14 to 17 */ + RootGenerator rootGenerator = this.getInput().getGraphGenerator().getRootGenerator(); + if (rootGenerator instanceof MultipleRootGenerator) { + for (T root : ((MultipleRootGenerator) rootGenerator).getRoots()) { + GammaNode internalRoot = new GammaNode<>(root); + internalRoot.setInternalLabel(new RStarK(false, this.w * this.h.f(internalRoot))); + internalRoot.setG(0); + this.open.add(internalRoot); + } + } else if (rootGenerator instanceof SingleRootGenerator) { + GammaNode internalRoot = new GammaNode<>(((SingleRootGenerator) rootGenerator).getRoot()); + internalRoot.setInternalLabel(new RStarK(false, this.w * this.h.f(internalRoot))); + internalRoot.setG(0); + this.open.add(internalRoot); + } else { + assert false : "Only MultipleRootGenerator or SingleRootGenerators allowed."; + } + assert !this.open.isEmpty() : "OPEN must not be empty after initialization!"; + return initializationEvent; + + case active: + + /* return unreturned solutions if such exist */ + if (!this.unreturnedSolutionEvents.isEmpty()) { + this.logger.info("Returning known solution from solution cache!"); + return this.unreturnedSolutionEvents.remove(0); + } + + /** + * Run while the open list is not empty and there exists a node in the open list + * with higher priority i.e. less k than k_n_goal (if the highest priority is a + * goal node, then we return in th next lines). + */ + // Lines 18 & 19 + GammaNode n = this.open.poll(); + this.logger.debug("Selected {} for expansion.", n); + if (n == null || (this.bestSeenGoalNode != null && n.getInternalLabel().compareTo(this.bestSeenGoalNode.getInternalLabel()) > 0)) { + this.logger.info("Terminating RStar."); + return this.terminate(); + } + + // Lines 20 & 21 + if (n.getParent() != null && !this.isPathRealizationKnownForAbstractEdgeToNode(n)) { + + /* The path that corresponds to the edge bp(s)->s has not been computed yet. Try to compute it using reevaluateState. */ + this.reevaluateState(n); + + /* put the node on OPEN again */ + this.logger.debug("Putting node {} on OPEN again", n); + this.open.add(n); + + } else { // The path from bp(s)->s has already been computed. + + // Line 23. + this.closed.add(n); + + /* Line 24 to 27: Compute successors */ + this.logger.debug("Starting generation of successors of {}", n); + Collection> successors = this.generateGammaSuccessors(n); + this.logger.debug("Generated {} successors.", successors.size()); + for (GammaNode n_ : successors) { // Line 28 + + /* Line 29: Initialize successors by setting the path from s to s_ to null, and by estimating the lowest cost from s to s_ with the heuristic h(s, s_). */ + n.cLow.put(n_, this.hPath.h(n, n_)); + + /* Lines 30 and 31 of the algorithm can be omitted here. They contain further initialization of + the successors, but This is done implicitly in the generation process of the Gamma successors. */ + + /* + * If the generated successor n_ i.e. s_ has never been visited yet (n_.getParent() == null) + * or the actual cost to s (n.g) plus the (estimated) cost from s to s_ (c_low(s, s_)) is better + * than the actual known cost (n_.g) to s_, then we have to update these values for s_ (because + * with s we found a better predecessor for s_). + */ + // Line 32 + boolean isNewNode = n_.getParent() == null; + if (isNewNode || (n.getG() + n.cLow.get(n_) < n_.getG())) { + n_.setG(n.getG() + n.cLow.get(n_)); + n_.setParent(n); + this.updateState(n_); // updates priority of n_ in open list. + if (isNewNode) { + this.logger.debug("Adding new node {} to OPEN.", n_); + this.open.add(n_); + } + } + } + } + return new NodeExpansionCompletedEvent<>(this.getId(), n.getPoint()); + + default: + throw new IllegalStateException("Cannot do anything in state " + this.getState()); + } + } + finally { + this.unregisterActiveThread(); + } + } + + private boolean isPathRealizationKnownForAbstractEdgeToNode(final GammaNode node) { + return this.externalPathsBetweenGammaNodes.containsKey(new Pair<>(node.getParent(), node)); + } + + /** + * Calculates the path in the original graph that corresponds to the reduced gamma graph using the established path witnesses. + * + * @param n + * @return + */ + private EvaluatedSearchGraphPath getFullExternalPath(final GammaNode n) { + List nodes = new ArrayList<>(); + List edges = new ArrayList<>(); + GammaNode current = n; + nodes.add(n.getPoint()); + while (current.getParent() != null) { + Pair, GammaNode> pair = new Pair<>(current.getParent(), current); + assert this.externalPathsBetweenGammaNodes.containsKey(pair); + SearchGraphPath externalPath = this.externalPathsBetweenGammaNodes.get(pair); + nodes.addAll(0, externalPath.getNodes()); + List concreteEdges = externalPath.getEdges(); + if (concreteEdges == null) { + concreteEdges = new ArrayList<>(); + int m = externalPath.getNodes().size(); + for (int i = 0; i < m; i++) { + concreteEdges.add(null); + } + } + edges.addAll(0, concreteEdges); + current = current.getParent(); + } + return new EvaluatedSearchGraphPath<>(nodes, edges, n.getG()); + } + + /** + * + * @param n + * @return + */ + private GammaNode argminCostToStateOverPredecessors(final GammaNode n) { + GammaNode argmin = null; + for (GammaNode p : n.getPredecessors()) { + if ((argmin == null) || (p.getG() + p.cLow.get(n) < argmin.getG() + argmin.cLow.get(n))) { + argmin = p; + } + } + return argmin; + } + + /** + * @throws AlgorithmExecutionCanceledException + * @throws AlgorithmException + * @throws AlgorithmTimeoutedException + * Generates this.RStarK Gamma graph successors for a state s within distance this.delta. + * Queries the this.gammaSuccessorGenerator and checks if a generate state has been + * visited i.e. generated in Gamma before. If yes, it takes the old reference from + * the this.alreadyGeneratedStates list. + * Also maintains the predecessor set of nodes. + * + * @param n Gamma node to generate successors for. + * @return List of Gamma nodes. + * @throws InterruptedException + * @throws + */ + private Collection> generateGammaSuccessors(final GammaNode n) throws InterruptedException, AlgorithmTimeoutedException, AlgorithmException, AlgorithmExecutionCanceledException { + + /* first create a list of k nodes that are in reach of delta of the current node */ + this.logger.trace("Invoking distant successor generator timeout-aware."); + List randomDistantSuccessors = this.computeTimeoutAware(() -> this.getInput().getDistantSuccessorGenerator().getDistantSuccessors(n.getPoint(), this.k, this.metricOverStates, this.delta), "Computing distant successors", true); + assert randomDistantSuccessors.size() == new HashSet<>(randomDistantSuccessors).size() : "Distant successor generator has created the same successor ar least twice: \n\t " + + SetUtil.getMultiplyContainedItems(randomDistantSuccessors).stream().map(T::toString).collect(Collectors.joining("\n\t")); + this.logger.trace("Distant successor generator generated {}/{} successors.", randomDistantSuccessors.size(), this.k); + + /* remove nodes for which a node is already on CLOSED (no reopening in this algorithm) */ + randomDistantSuccessors.removeIf(childNode -> this.closed.stream().anyMatch(closedNode -> closedNode.getPoint().equals(childNode))); + this.logger.trace("{} successors are still considered after having removed nodes that already are on CLOSED, which holds {} item(s).", randomDistantSuccessors.size(), this.closed.size()); + + /* now transform these node into (possibly existing) GammaNode objects */ + ArrayList> succWithoutClosed = new ArrayList<>(); + for (T childNode : randomDistantSuccessors) { + Optional> representantOnOpen = this.open.stream().filter(closedNode -> closedNode.getPoint().equals(childNode)).findFirst(); + GammaNode gammaNodeForThisChild; + if (representantOnOpen.isPresent()) { + gammaNodeForThisChild = representantOnOpen.get(); + } else { + gammaNodeForThisChild = new GammaNode<>(childNode); + gammaNodeForThisChild.setGoal(((NodeGoalTester) this.getGraphGenerator().getGoalTester()).isGoal(childNode)); + } + + /* if this is a solution, add it as a new solution */ + if (gammaNodeForThisChild.isGoal()) { + this.logger.info("Found new solution. Adding it to the solution set."); + if (this.bestSeenGoalNode == null || this.bestSeenGoalNode.getG() > n.getG()) { + this.bestSeenGoalNode = n; + this.updateBestSeenSolution(this.getFullExternalPath(n)); + } + EvaluatedSearchSolutionCandidateFoundEvent solutionEvent = new EvaluatedSearchSolutionCandidateFoundEvent<>(this.getId(), this.getFullExternalPath(gammaNodeForThisChild)); + this.post(solutionEvent); + this.unreturnedSolutionEvents.add(solutionEvent); + } + gammaNodeForThisChild.addPredecessor(n); + succWithoutClosed.add(gammaNodeForThisChild); + } + return succWithoutClosed; + } + + @Override + public void setLoggerName(final String name) { + this.logger = LoggerFactory.getLogger(name); + super.setLoggerName(name + "._orgraphsearch"); + + /* set logger name of the graph generator */ + if (this.getGraphGenerator() instanceof ILoggingCustomizable) { + ((ILoggingCustomizable) this.getGraphGenerator()).setLoggerName(name + ".graphgenerator"); + } + + /* set logger name of the distant graph generator */ + DistantSuccessorGenerator distantSuccessorGenerator = this.getInput().getDistantSuccessorGenerator(); + if (distantSuccessorGenerator instanceof ILoggingCustomizable) { + ((ILoggingCustomizable) distantSuccessorGenerator).setLoggerName(name + ".distantsuccessorgenerator"); + } + } + + @Override + public String getLoggerName() { + return this.logger.getName(); + } + + @Override + public void cancel() { + this.logger.info("RStar received cancel. Now invoking shutdown routing and cancel the AStar subroutines."); + super.cancel(); + this.activeAStarSubroutines.forEach(IAlgorithm::cancel); + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/RStarFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStarFactory.java similarity index 78% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/RStarFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStarFactory.java index f6d9a9177a..54b3751e18 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/RStarFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStarFactory.java @@ -1,86 +1,86 @@ -package jaicore.search.algorithms.standard.rstar; - -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.core.interfaces.StandardORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic; - -public class RStarFactory extends StandardORGraphSearchFactory, EvaluatedSearchGraphPath, T, A, Double> { - - private int timeoutForFInMS; - private INodeEvaluator timeoutEvaluator; - private String loggerName; - private double w = 1.0; - private int k = 3; - private double delta = 0.0; - - public RStarFactory() { - super(); - } - - public RStarFactory(final int timeoutForFInMS) { - this(); - if (timeoutForFInMS > 0) { - this.timeoutForFInMS = timeoutForFInMS; - } - } - - public double getW() { - return this.w; - } - - public void setW(final double w) { - this.w = w; - } - - public int getK() { - return this.k; - } - - public void setK(final int k) { - this.k = k; - } - - public double getDelta() { - return this.delta; - } - - public void setDelta(final double delta) { - this.delta = delta; - } - - @Override - public RStar getAlgorithm() { - return this.getAlgorithm(this.getInput()); - } - - @Override - public RStar getAlgorithm(final GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic input) { - RStar search = new RStar<>(input, this.w, this.k, this.delta); - if (this.loggerName != null && this.loggerName.length() > 0) { - search.setLoggerName(this.loggerName); - } - return search; - } - - public void setTimeoutForFComputation(final int timeoutInMS, final INodeEvaluator timeoutEvaluator) { - this.timeoutForFInMS = timeoutInMS; - this.timeoutEvaluator = timeoutEvaluator; - } - - public int getTimeoutForFInMS() { - return this.timeoutForFInMS; - } - - public INodeEvaluator getTimeoutEvaluator() { - return this.timeoutEvaluator; - } - - public String getLoggerName() { - return this.loggerName; - } - - public void setLoggerName(final String loggerName) { - this.loggerName = loggerName; - } -} +package ai.libs.jaicore.search.algorithms.standard.rstar; + +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.StandardORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic; + +public class RStarFactory extends StandardORGraphSearchFactory, EvaluatedSearchGraphPath, T, A, Double> { + + private int timeoutForFInMS; + private INodeEvaluator timeoutEvaluator; + private String loggerName; + private double w = 1.0; + private int k = 3; + private double delta = 0.0; + + public RStarFactory() { + super(); + } + + public RStarFactory(final int timeoutForFInMS) { + this(); + if (timeoutForFInMS > 0) { + this.timeoutForFInMS = timeoutForFInMS; + } + } + + public double getW() { + return this.w; + } + + public void setW(final double w) { + this.w = w; + } + + public int getK() { + return this.k; + } + + public void setK(final int k) { + this.k = k; + } + + public double getDelta() { + return this.delta; + } + + public void setDelta(final double delta) { + this.delta = delta; + } + + @Override + public RStar getAlgorithm() { + return this.getAlgorithm(this.getInput()); + } + + @Override + public RStar getAlgorithm(final GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic input) { + RStar search = new RStar<>(input, this.w, this.k, this.delta); + if (this.loggerName != null && this.loggerName.length() > 0) { + search.setLoggerName(this.loggerName); + } + return search; + } + + public void setTimeoutForFComputation(final int timeoutInMS, final INodeEvaluator timeoutEvaluator) { + this.timeoutForFInMS = timeoutInMS; + this.timeoutEvaluator = timeoutEvaluator; + } + + public int getTimeoutForFInMS() { + return this.timeoutForFInMS; + } + + public INodeEvaluator getTimeoutEvaluator() { + return this.timeoutEvaluator; + } + + public String getLoggerName() { + return this.loggerName; + } + + public void setLoggerName(final String loggerName) { + this.loggerName = loggerName; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/RStarK.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStarK.java similarity index 90% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/RStarK.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStarK.java index f6e597faa7..288721874f 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/RStarK.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStarK.java @@ -1,39 +1,39 @@ -package jaicore.search.algorithms.standard.rstar; - -/** - * k-Values (Priorities used for expansion from open.) - */ -public class RStarK implements Comparable{ - - boolean avoid; - double f; - - RStarK(boolean avoid, double f) { - this.avoid = avoid; - this.f = f; - } - - @Override - /** - * Compare to k-values i.e. provide a natural ordering for them. - * E.g.: [false, 0.9] < [false, 2.2] < [true, 0.1] < [true, 2.0] - * - * @return -1 if this < o, 0 iff this == o, +1 iff this > 0 - */ - public int compareTo(RStarK o) { - // Compare first AVOID flag. - if (!this.avoid && o.avoid) { - return -1; - } - if (this.avoid && !o.avoid) { - return +1; - } - // Then compare f-values. - return Double.compare(this.f, o.f); - } - - @Override - public String toString() { - return String.format("[%b, %g]", this.avoid, this.f); - } -} +package ai.libs.jaicore.search.algorithms.standard.rstar; + +/** + * k-Values (Priorities used for expansion from open.) + */ +public class RStarK implements Comparable{ + + boolean avoid; + double f; + + RStarK(boolean avoid, double f) { + this.avoid = avoid; + this.f = f; + } + + @Override + /** + * Compare to k-values i.e. provide a natural ordering for them. + * E.g.: [false, 0.9] < [false, 2.2] < [true, 0.1] < [true, 2.0] + * + * @return -1 if this < o, 0 iff this == o, +1 iff this > 0 + */ + public int compareTo(RStarK o) { + // Compare first AVOID flag. + if (!this.avoid && o.avoid) { + return -1; + } + if (this.avoid && !o.avoid) { + return +1; + } + // Then compare f-values. + return Double.compare(this.f, o.f); + } + + @Override + public String toString() { + return String.format("[%b, %g]", this.avoid, this.f); + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/SubPathGraphGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/SubPathGraphGenerator.java similarity index 61% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/SubPathGraphGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/SubPathGraphGenerator.java index 4ff515a6a3..68283e1920 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/rstar/SubPathGraphGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/rstar/SubPathGraphGenerator.java @@ -1,11 +1,11 @@ -package jaicore.search.algorithms.standard.rstar; - -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.structure.graphgenerator.GoalTester; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.RootGenerator; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +package ai.libs.jaicore.search.algorithms.standard.rstar; + +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.GoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.RootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; public class SubPathGraphGenerator implements GraphGenerator { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/BasicUncertaintySource.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/BasicUncertaintySource.java similarity index 89% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/BasicUncertaintySource.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/BasicUncertaintySource.java index ab9140b75d..cbca479214 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/BasicUncertaintySource.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/BasicUncertaintySource.java @@ -1,59 +1,59 @@ -package jaicore.search.algorithms.standard.uncertainty; - -import java.util.List; - -import jaicore.search.model.travesaltree.Node; - -public class BasicUncertaintySource> implements IUncertaintySource { - - @Override - public double calculateUncertainty(Node n, List> simulationPaths, List simulationEvaluations) { - - double uncertainty = 1.0d; - - if (simulationPaths != null && !simulationPaths.isEmpty()) { - T t = n.getPoint(); - double meanDepth = 0.0d; - for (List path : simulationPaths) { - if (path.contains(t) && !path.isEmpty()) { - double post = 0.0d; - boolean startsCounting = false; - for (T pe : path) { - if (startsCounting) { - post++; - } - if (pe.equals(t)) { - startsCounting = true; - } - } - - meanDepth += post / (double) path.size(); - } - } - if (meanDepth != 0.0d) { - uncertainty = meanDepth / ((double) simulationPaths.size()); - } - } - - if (simulationEvaluations != null && simulationEvaluations.size() > 1 - && simulationEvaluations.get(0) instanceof Double) { - double mean = 0.0d; - double sampleVariance = 0.0d; - for (V f : simulationEvaluations) { - mean += (Double) f; - } - mean /= simulationEvaluations.size(); - for (V f : simulationEvaluations) { - sampleVariance += ((Double) f - mean) * ((Double) f - mean); - } - sampleVariance = Math.sqrt(sampleVariance / (simulationEvaluations.size() - 1)); - if (mean != 0.0d) { - double coefficientOfVariation = sampleVariance / mean; - coefficientOfVariation = Math.max(Math.abs(coefficientOfVariation), 1.0d); - uncertainty *= coefficientOfVariation; - } - } - return uncertainty; - } - -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty; + +import java.util.List; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +public class BasicUncertaintySource> implements IUncertaintySource { + + @Override + public double calculateUncertainty(Node n, List> simulationPaths, List simulationEvaluations) { + + double uncertainty = 1.0d; + + if (simulationPaths != null && !simulationPaths.isEmpty()) { + T t = n.getPoint(); + double meanDepth = 0.0d; + for (List path : simulationPaths) { + if (path.contains(t) && !path.isEmpty()) { + double post = 0.0d; + boolean startsCounting = false; + for (T pe : path) { + if (startsCounting) { + post++; + } + if (pe.equals(t)) { + startsCounting = true; + } + } + + meanDepth += post / (double) path.size(); + } + } + if (meanDepth != 0.0d) { + uncertainty = meanDepth / ((double) simulationPaths.size()); + } + } + + if (simulationEvaluations != null && simulationEvaluations.size() > 1 + && simulationEvaluations.get(0) instanceof Double) { + double mean = 0.0d; + double sampleVariance = 0.0d; + for (V f : simulationEvaluations) { + mean += (Double) f; + } + mean /= simulationEvaluations.size(); + for (V f : simulationEvaluations) { + sampleVariance += ((Double) f - mean) * ((Double) f - mean); + } + sampleVariance = Math.sqrt(sampleVariance / (simulationEvaluations.size() - 1)); + if (mean != 0.0d) { + double coefficientOfVariation = sampleVariance / mean; + coefficientOfVariation = Math.max(Math.abs(coefficientOfVariation), 1.0d); + uncertainty *= coefficientOfVariation; + } + } + return uncertainty; + } + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/ISolutionDistanceMetric.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/ISolutionDistanceMetric.java similarity index 70% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/ISolutionDistanceMetric.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/ISolutionDistanceMetric.java index 5fedc5aade..b79c4397ad 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/ISolutionDistanceMetric.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/ISolutionDistanceMetric.java @@ -1,10 +1,10 @@ -package jaicore.search.algorithms.standard.uncertainty; - -import java.util.List; - -@FunctionalInterface -public interface ISolutionDistanceMetric { - - public double calculateSolutionDistance(List solution1, List solution2); - -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty; + +import java.util.List; + +@FunctionalInterface +public interface ISolutionDistanceMetric { + + public double calculateSolutionDistance(List solution1, List solution2); + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/IUncertaintySource.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/IUncertaintySource.java similarity index 63% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/IUncertaintySource.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/IUncertaintySource.java index c5504904b7..664a363df9 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/IUncertaintySource.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/IUncertaintySource.java @@ -1,12 +1,12 @@ -package jaicore.search.algorithms.standard.uncertainty; - -import java.util.List; - -import jaicore.search.model.travesaltree.Node; - -@FunctionalInterface -public interface IUncertaintySource >{ - - public double calculateUncertainty (Node n, List> simulationPaths, List simulationEvaluations); - -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty; + +import java.util.List; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +@FunctionalInterface +public interface IUncertaintySource >{ + + public double calculateUncertainty (Node n, List> simulationPaths, List simulationEvaluations); + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/OversearchAvoidanceConfig.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/OversearchAvoidanceConfig.java similarity index 89% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/OversearchAvoidanceConfig.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/OversearchAvoidanceConfig.java index 72fd4ed681..5ab905e5fc 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/OversearchAvoidanceConfig.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/OversearchAvoidanceConfig.java @@ -1,101 +1,101 @@ -package jaicore.search.algorithms.standard.uncertainty; - -import jaicore.search.algorithms.standard.uncertainty.paretosearch.FirstInFirstOutComparator; -import jaicore.search.model.travesaltree.Node; - -import java.util.Comparator; - -public class OversearchAvoidanceConfig> { - - public enum OversearchAvoidanceMode { - PARETO_FRONT_SELECTION, TWO_PHASE_SELECTION, NONE - } - - private OversearchAvoidanceMode oversearchAvoidanceMode; - private long seed; - private boolean adjustPhaseLengthsDynamically = false; - private long timeout; - private int interval = 50; - private double exploitationScoreThreshold = 0.1d; - private double explorationUncertaintyThreshold = 0.1d; - private double minimumSolutionDistanceForExploration = 0.0d; - private ISolutionDistanceMetric solutionDistanceMetric = (s1, s2) -> 1.0d; - private Comparator> paretoComparator = new FirstInFirstOutComparator<>(); - - public OversearchAvoidanceConfig(OversearchAvoidanceMode mode, long seed) { - this.oversearchAvoidanceMode = mode; - this.seed = seed; - } - - public OversearchAvoidanceMode getOversearchAvoidanceMode() { - return oversearchAvoidanceMode; - } - - public ISolutionDistanceMetric getSolutionDistanceMetric() { - return solutionDistanceMetric; - } - - public OversearchAvoidanceConfig setSolutionDistanceMetric( - ISolutionDistanceMetric solutionDistanceMetric) { - this.solutionDistanceMetric = solutionDistanceMetric; - return this; - } - - public boolean getAdjustPhaseLengthsDynamically() { - return adjustPhaseLengthsDynamically; - } - - public void activateDynamicPhaseLengthsAdjustment(long timeout) { - this.adjustPhaseLengthsDynamically = true; - this.timeout = timeout; - } - - public long getTimeout() { - return this.timeout; - } - - public int getInterval() { - return interval; - } - - public void setInterval(int interval) { - this.interval = interval; - } - - public double getExploitationScoreThreshold() { - return exploitationScoreThreshold; - } - - public void setExploitationScoreThreshold(double exploitationScoreThreshold) { - this.exploitationScoreThreshold = exploitationScoreThreshold; - } - - public double getExplorationUncertaintyThreshold() { - return explorationUncertaintyThreshold; - } - - public void setExplorationUncertaintyThreshold(double explorationUncertaintyThreshold) { - this.explorationUncertaintyThreshold = explorationUncertaintyThreshold; - } - - public double getMinimumSolutionDistanceForExploration() { - return minimumSolutionDistanceForExploration; - } - - public void setMinimumSolutionDistanceForExploration(double minimumSolutionDistanceForExploration) { - this.minimumSolutionDistanceForExploration = minimumSolutionDistanceForExploration; - } - - public long getSeed() { - return this.seed; - } - - public void setParetoComparator(Comparator> paretoComparator) { - this.paretoComparator = paretoComparator; - } - - public Comparator> getParetoComperator() { - return this.paretoComparator; - } - +package ai.libs.jaicore.search.algorithms.standard.uncertainty; + +import java.util.Comparator; + +import ai.libs.jaicore.search.algorithms.standard.uncertainty.paretosearch.FirstInFirstOutComparator; +import ai.libs.jaicore.search.model.travesaltree.Node; + +public class OversearchAvoidanceConfig> { + + public enum OversearchAvoidanceMode { + PARETO_FRONT_SELECTION, TWO_PHASE_SELECTION, NONE + } + + private OversearchAvoidanceMode oversearchAvoidanceMode; + private long seed; + private boolean adjustPhaseLengthsDynamically = false; + private long timeout; + private int interval = 50; + private double exploitationScoreThreshold = 0.1d; + private double explorationUncertaintyThreshold = 0.1d; + private double minimumSolutionDistanceForExploration = 0.0d; + private ISolutionDistanceMetric solutionDistanceMetric = (s1, s2) -> 1.0d; + private Comparator> paretoComparator = new FirstInFirstOutComparator<>(); + + public OversearchAvoidanceConfig(OversearchAvoidanceMode mode, long seed) { + this.oversearchAvoidanceMode = mode; + this.seed = seed; + } + + public OversearchAvoidanceMode getOversearchAvoidanceMode() { + return oversearchAvoidanceMode; + } + + public ISolutionDistanceMetric getSolutionDistanceMetric() { + return solutionDistanceMetric; + } + + public OversearchAvoidanceConfig setSolutionDistanceMetric( + ISolutionDistanceMetric solutionDistanceMetric) { + this.solutionDistanceMetric = solutionDistanceMetric; + return this; + } + + public boolean getAdjustPhaseLengthsDynamically() { + return adjustPhaseLengthsDynamically; + } + + public void activateDynamicPhaseLengthsAdjustment(long timeout) { + this.adjustPhaseLengthsDynamically = true; + this.timeout = timeout; + } + + public long getTimeout() { + return this.timeout; + } + + public int getInterval() { + return interval; + } + + public void setInterval(int interval) { + this.interval = interval; + } + + public double getExploitationScoreThreshold() { + return exploitationScoreThreshold; + } + + public void setExploitationScoreThreshold(double exploitationScoreThreshold) { + this.exploitationScoreThreshold = exploitationScoreThreshold; + } + + public double getExplorationUncertaintyThreshold() { + return explorationUncertaintyThreshold; + } + + public void setExplorationUncertaintyThreshold(double explorationUncertaintyThreshold) { + this.explorationUncertaintyThreshold = explorationUncertaintyThreshold; + } + + public double getMinimumSolutionDistanceForExploration() { + return minimumSolutionDistanceForExploration; + } + + public void setMinimumSolutionDistanceForExploration(double minimumSolutionDistanceForExploration) { + this.minimumSolutionDistanceForExploration = minimumSolutionDistanceForExploration; + } + + public long getSeed() { + return this.seed; + } + + public void setParetoComparator(Comparator> paretoComparator) { + this.paretoComparator = paretoComparator; + } + + public Comparator> getParetoComperator() { + return this.paretoComparator; + } + } \ No newline at end of file diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/UncertaintyORGraphSearchFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/UncertaintyORGraphSearchFactory.java similarity index 77% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/UncertaintyORGraphSearchFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/UncertaintyORGraphSearchFactory.java index 8dff55da8e..ff8735cf85 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/UncertaintyORGraphSearchFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/UncertaintyORGraphSearchFactory.java @@ -1,103 +1,103 @@ -package jaicore.search.algorithms.standard.uncertainty; - -import java.util.PriorityQueue; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import jaicore.search.algorithms.standard.bestfirst.BestFirst; -import jaicore.search.algorithms.standard.bestfirst.BestFirstFactory; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallyUncertaintyAnnotatingNodeEvaluator; -import jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch.BasicClockModelPhaseLengthAdjuster; -import jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch.BasicExplorationCandidateSelector; -import jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch.IPhaseLengthAdjuster; -import jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch.UncertaintyExplorationOpenSelection; -import jaicore.search.algorithms.standard.uncertainty.paretosearch.ParetoSelection; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.probleminputs.GraphSearchWithUncertaintyBasedSubpathEvaluationInput; - -public class UncertaintyORGraphSearchFactory> - extends BestFirstFactory, N, A, V> { - - private static final Logger logger = LoggerFactory.getLogger(UncertaintyORGraphSearchFactory.class); - - private OversearchAvoidanceConfig oversearchAvoidanceConfig; - - @Override - public BestFirst, N, A, V> getAlgorithm() { - if (this.oversearchAvoidanceConfig == null) { - throw new IllegalStateException("Uncertainty Config has not been set yet."); - } - - /* - * let the best first factory configure general aspects of the best first search - */ - BestFirst, N, A, V> search = super.getAlgorithm(); - - /* check that node evaluator supports uncertainty */ - if (!(search.getNodeEvaluator() instanceof IPotentiallyUncertaintyAnnotatingNodeEvaluator)) { - throw new UnsupportedOperationException("Cannot create uncertainty based search with node evaluator " + search.getNodeEvaluator().getClass().getName() + ", which does not implement " + IPotentiallyUncertaintyAnnotatingNodeEvaluator.class.getName()); - } - if (!((IPotentiallyUncertaintyAnnotatingNodeEvaluator)search.getNodeEvaluator()).annotatesUncertainty()) { - throw new UnsupportedOperationException("The given node evaluator supports uncertainty annotation, but it declares that it will not annotate uncertainty. Maybe no uncertainty source has been defined."); - } - - /* now set uncertainty-specific behavior */ - switch (this.oversearchAvoidanceConfig.getOversearchAvoidanceMode()) { - case NONE: - logger.warn("Usage of OversearchAvoidanceMode.NONE is deprecated! Use StandardBestFirst search instead."); - break; - case TWO_PHASE_SELECTION: - if (this.oversearchAvoidanceConfig.getAdjustPhaseLengthsDynamically()) { - search.setOpen(new UncertaintyExplorationOpenSelection( - this.oversearchAvoidanceConfig.getTimeout(), - this.oversearchAvoidanceConfig.getInterval(), - this.oversearchAvoidanceConfig.getExploitationScoreThreshold(), - this.oversearchAvoidanceConfig.getExplorationUncertaintyThreshold(), - new BasicClockModelPhaseLengthAdjuster(), - this.oversearchAvoidanceConfig.getSolutionDistanceMetric(), - new BasicExplorationCandidateSelector(this.oversearchAvoidanceConfig.getMinimumSolutionDistanceForExploration()) - )); - } else { - search.setOpen(new UncertaintyExplorationOpenSelection( - this.oversearchAvoidanceConfig.getTimeout(), - this.oversearchAvoidanceConfig.getInterval(), - this.oversearchAvoidanceConfig.getExploitationScoreThreshold(), - this.oversearchAvoidanceConfig.getExplorationUncertaintyThreshold(), - new IPhaseLengthAdjuster() { - - @Override - public int[] getInitialPhaseLengths(final int interval) { - return new int[] {interval / 2, interval - (interval / 2)}; - } - - @Override - public int[] adjustPhaseLength(final int currentExplorationLength, final int currentExploitationLength, final long passedTime, - final long timeout) { - return new int[] {currentExplorationLength, currentExploitationLength}; - } - }, - this.oversearchAvoidanceConfig.getSolutionDistanceMetric(), - new BasicExplorationCandidateSelector(this.oversearchAvoidanceConfig.getMinimumSolutionDistanceForExploration()) - )); - } - break; - case PARETO_FRONT_SELECTION: - PriorityQueue> pareto = new PriorityQueue<>(oversearchAvoidanceConfig.getParetoComperator()); - search.setOpen(new ParetoSelection<>(pareto)); - break; - default: - throw new UnsupportedOperationException("Mode " + this.oversearchAvoidanceConfig.getOversearchAvoidanceMode() + " is currently not supported."); - } - - return search; - } - - public OversearchAvoidanceConfig getConfig() { - return this.oversearchAvoidanceConfig; - } - - public void setConfig(final OversearchAvoidanceConfig config) { - this.oversearchAvoidanceConfig = config; - } -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty; + +import java.util.PriorityQueue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ai.libs.jaicore.search.algorithms.standard.bestfirst.BestFirst; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.BestFirstFactory; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallyUncertaintyAnnotatingNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch.BasicClockModelPhaseLengthAdjuster; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch.BasicExplorationCandidateSelector; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch.IPhaseLengthAdjuster; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch.UncertaintyExplorationOpenSelection; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.paretosearch.ParetoSelection; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithUncertaintyBasedSubpathEvaluationInput; + +public class UncertaintyORGraphSearchFactory> + extends BestFirstFactory, N, A, V> { + + private static final Logger logger = LoggerFactory.getLogger(UncertaintyORGraphSearchFactory.class); + + private OversearchAvoidanceConfig oversearchAvoidanceConfig; + + @Override + public BestFirst, N, A, V> getAlgorithm() { + if (this.oversearchAvoidanceConfig == null) { + throw new IllegalStateException("Uncertainty Config has not been set yet."); + } + + /* + * let the best first factory configure general aspects of the best first search + */ + BestFirst, N, A, V> search = super.getAlgorithm(); + + /* check that node evaluator supports uncertainty */ + if (!(search.getNodeEvaluator() instanceof IPotentiallyUncertaintyAnnotatingNodeEvaluator)) { + throw new UnsupportedOperationException("Cannot create uncertainty based search with node evaluator " + search.getNodeEvaluator().getClass().getName() + ", which does not implement " + IPotentiallyUncertaintyAnnotatingNodeEvaluator.class.getName()); + } + if (!((IPotentiallyUncertaintyAnnotatingNodeEvaluator)search.getNodeEvaluator()).annotatesUncertainty()) { + throw new UnsupportedOperationException("The given node evaluator supports uncertainty annotation, but it declares that it will not annotate uncertainty. Maybe no uncertainty source has been defined."); + } + + /* now set uncertainty-specific behavior */ + switch (this.oversearchAvoidanceConfig.getOversearchAvoidanceMode()) { + case NONE: + logger.warn("Usage of OversearchAvoidanceMode.NONE is deprecated! Use StandardBestFirst search instead."); + break; + case TWO_PHASE_SELECTION: + if (this.oversearchAvoidanceConfig.getAdjustPhaseLengthsDynamically()) { + search.setOpen(new UncertaintyExplorationOpenSelection( + this.oversearchAvoidanceConfig.getTimeout(), + this.oversearchAvoidanceConfig.getInterval(), + this.oversearchAvoidanceConfig.getExploitationScoreThreshold(), + this.oversearchAvoidanceConfig.getExplorationUncertaintyThreshold(), + new BasicClockModelPhaseLengthAdjuster(), + this.oversearchAvoidanceConfig.getSolutionDistanceMetric(), + new BasicExplorationCandidateSelector(this.oversearchAvoidanceConfig.getMinimumSolutionDistanceForExploration()) + )); + } else { + search.setOpen(new UncertaintyExplorationOpenSelection( + this.oversearchAvoidanceConfig.getTimeout(), + this.oversearchAvoidanceConfig.getInterval(), + this.oversearchAvoidanceConfig.getExploitationScoreThreshold(), + this.oversearchAvoidanceConfig.getExplorationUncertaintyThreshold(), + new IPhaseLengthAdjuster() { + + @Override + public int[] getInitialPhaseLengths(final int interval) { + return new int[] {interval / 2, interval - (interval / 2)}; + } + + @Override + public int[] adjustPhaseLength(final int currentExplorationLength, final int currentExploitationLength, final long passedTime, + final long timeout) { + return new int[] {currentExplorationLength, currentExploitationLength}; + } + }, + this.oversearchAvoidanceConfig.getSolutionDistanceMetric(), + new BasicExplorationCandidateSelector(this.oversearchAvoidanceConfig.getMinimumSolutionDistanceForExploration()) + )); + } + break; + case PARETO_FRONT_SELECTION: + PriorityQueue> pareto = new PriorityQueue<>(oversearchAvoidanceConfig.getParetoComperator()); + search.setOpen(new ParetoSelection<>(pareto)); + break; + default: + throw new UnsupportedOperationException("Mode " + this.oversearchAvoidanceConfig.getOversearchAvoidanceMode() + " is currently not supported."); + } + + return search; + } + + public OversearchAvoidanceConfig getConfig() { + return this.oversearchAvoidanceConfig; + } + + public void setConfig(final OversearchAvoidanceConfig config) { + this.oversearchAvoidanceConfig = config; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicClockModelPhaseLengthAdjuster.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicClockModelPhaseLengthAdjuster.java similarity index 85% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicClockModelPhaseLengthAdjuster.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicClockModelPhaseLengthAdjuster.java index b710415ed5..247cc40535 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicClockModelPhaseLengthAdjuster.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicClockModelPhaseLengthAdjuster.java @@ -1,21 +1,21 @@ -package jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch; - -public class BasicClockModelPhaseLengthAdjuster implements IPhaseLengthAdjuster { - - private int interval; - - @Override - public int[] getInitialPhaseLengths(int interval) { - this.interval = interval; - return new int[]{this.interval - 1, 1}; - } - - @Override - public int[] adjustPhaseLength(int currentExplorationLength, int currentExploitationLength, long passedTime, long timeout) { - double alpha = ((double) Math.min(passedTime, timeout))/((double) timeout) * 0.5 * Math.PI; - int exploration = (int)(Math.cos(alpha) * (double)interval); - int exploitation = this.interval - exploration; - return new int[]{Math.max(exploration, 1), Math.max(exploitation, 1)}; - } - -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch; + +public class BasicClockModelPhaseLengthAdjuster implements IPhaseLengthAdjuster { + + private int interval; + + @Override + public int[] getInitialPhaseLengths(int interval) { + this.interval = interval; + return new int[]{this.interval - 1, 1}; + } + + @Override + public int[] adjustPhaseLength(int currentExplorationLength, int currentExploitationLength, long passedTime, long timeout) { + double alpha = ((double) Math.min(passedTime, timeout))/((double) timeout) * 0.5 * Math.PI; + int exploration = (int)(Math.cos(alpha) * (double)interval); + int exploitation = this.interval - exploration; + return new int[]{Math.max(exploration, 1), Math.max(exploitation, 1)}; + } + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicExplorationCandidateSelector.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicExplorationCandidateSelector.java similarity index 78% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicExplorationCandidateSelector.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicExplorationCandidateSelector.java index 7f611938c8..2d3a6eb7fa 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicExplorationCandidateSelector.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/BasicExplorationCandidateSelector.java @@ -1,29 +1,29 @@ -package jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch; - -import java.util.List; -import java.util.Queue; -import java.util.stream.Collectors; - -import jaicore.search.algorithms.standard.uncertainty.ISolutionDistanceMetric; -import jaicore.search.model.travesaltree.Node; - -public class BasicExplorationCandidateSelector> implements IExplorationCandidateSelector { - - private double minimumSolutionDistanceForExploration; - - public BasicExplorationCandidateSelector(double minimumSolutionDistanceForExploration) { - this.minimumSolutionDistanceForExploration = minimumSolutionDistanceForExploration; - } - - @Override - public List> selectExplorationCandidates(Queue> allCandidates, Node bestCandidate, ISolutionDistanceMetric solutionDistanceMetric) { - return allCandidates.stream().filter(n -> { - if (bestCandidate == n) { - return false; - } - double solutionDistance = solutionDistanceMetric.calculateSolutionDistance(n.externalPath(), bestCandidate.externalPath()); - return solutionDistance >= minimumSolutionDistanceForExploration; - }).collect(Collectors.toList()); - } - -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch; + +import java.util.List; +import java.util.Queue; +import java.util.stream.Collectors; + +import ai.libs.jaicore.search.algorithms.standard.uncertainty.ISolutionDistanceMetric; +import ai.libs.jaicore.search.model.travesaltree.Node; + +public class BasicExplorationCandidateSelector> implements IExplorationCandidateSelector { + + private double minimumSolutionDistanceForExploration; + + public BasicExplorationCandidateSelector(double minimumSolutionDistanceForExploration) { + this.minimumSolutionDistanceForExploration = minimumSolutionDistanceForExploration; + } + + @Override + public List> selectExplorationCandidates(Queue> allCandidates, Node bestCandidate, ISolutionDistanceMetric solutionDistanceMetric) { + return allCandidates.stream().filter(n -> { + if (bestCandidate == n) { + return false; + } + double solutionDistance = solutionDistanceMetric.calculateSolutionDistance(n.externalPath(), bestCandidate.externalPath()); + return solutionDistance >= minimumSolutionDistanceForExploration; + }).collect(Collectors.toList()); + } + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IExplorationCandidateSelector.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IExplorationCandidateSelector.java similarity index 55% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IExplorationCandidateSelector.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IExplorationCandidateSelector.java index e4ed57a530..9787aa6a6a 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IExplorationCandidateSelector.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IExplorationCandidateSelector.java @@ -1,14 +1,14 @@ -package jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch; - -import java.util.List; -import java.util.Queue; - -import jaicore.search.algorithms.standard.uncertainty.ISolutionDistanceMetric; -import jaicore.search.model.travesaltree.Node; - -@FunctionalInterface -public interface IExplorationCandidateSelector> { - - public List> selectExplorationCandidates (Queue> allCandidates, Node bestCandidate, ISolutionDistanceMetric solutionDistanceMetric); - -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch; + +import java.util.List; +import java.util.Queue; + +import ai.libs.jaicore.search.algorithms.standard.uncertainty.ISolutionDistanceMetric; +import ai.libs.jaicore.search.model.travesaltree.Node; + +@FunctionalInterface +public interface IExplorationCandidateSelector> { + + public List> selectExplorationCandidates (Queue> allCandidates, Node bestCandidate, ISolutionDistanceMetric solutionDistanceMetric); + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IPhaseLengthAdjuster.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IPhaseLengthAdjuster.java similarity index 89% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IPhaseLengthAdjuster.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IPhaseLengthAdjuster.java index ed0765f9f3..23b509204f 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IPhaseLengthAdjuster.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/IPhaseLengthAdjuster.java @@ -1,21 +1,21 @@ -package jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch; - -public interface IPhaseLengthAdjuster { - - /** - * Called before the search to set the phase lengths initially. - * @param interval Overall length of both phases combined. - * @return An array with two elements [newExplorationPhaseLength, newExploitationPhaseLength] to adjust the phase lengths. - */ - public int[] getInitialPhaseLengths(int interval); - - /** - * Called on every complete iteration of an exploration and an exploitation phase to determine how to change the phase lengths. - * @param currentExplorationLength Current length of the exploration phase. - * @param currentExploitationLength Current length of the exploitation phase. - * @param passedTime Passed time of the search. - * @param timout Timeout for the search. - * @return An array with two elements [newExplorationPhaseLength, newExploitationPhaseLength] to adjust the phase lengths. - */ - public int[] adjustPhaseLength (int currentExplorationLength, int currentExploitationLength, long passedTime, long timeout); -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch; + +public interface IPhaseLengthAdjuster { + + /** + * Called before the search to set the phase lengths initially. + * @param interval Overall length of both phases combined. + * @return An array with two elements [newExplorationPhaseLength, newExploitationPhaseLength] to adjust the phase lengths. + */ + public int[] getInitialPhaseLengths(int interval); + + /** + * Called on every complete iteration of an exploration and an exploitation phase to determine how to change the phase lengths. + * @param currentExplorationLength Current length of the exploration phase. + * @param currentExploitationLength Current length of the exploitation phase. + * @param passedTime Passed time of the search. + * @param timout Timeout for the search. + * @return An array with two elements [newExplorationPhaseLength, newExploitationPhaseLength] to adjust the phase lengths. + */ + public int[] adjustPhaseLength (int currentExplorationLength, int currentExploitationLength, long passedTime, long timeout); +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/UncertaintyExplorationOpenSelection.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/UncertaintyExplorationOpenSelection.java similarity index 93% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/UncertaintyExplorationOpenSelection.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/UncertaintyExplorationOpenSelection.java index f5d0f956f7..e21a2be84d 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/UncertaintyExplorationOpenSelection.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/explorationexploitationsearch/UncertaintyExplorationOpenSelection.java @@ -1,263 +1,263 @@ -package jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.PriorityQueue; -import java.util.Queue; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import jaicore.search.algorithms.standard.uncertainty.ISolutionDistanceMetric; -import jaicore.search.model.travesaltree.DefaultNodeComparator; -import jaicore.search.model.travesaltree.Node; - -public class UncertaintyExplorationOpenSelection> implements Queue> { - - private static final Logger logger = LoggerFactory.getLogger(UncertaintyExplorationOpenSelection.class); - - private final Queue> exploitationOpen = new PriorityQueue<>(new DefaultNodeComparator<>()); - private final PriorityQueue> explorationOpen = new PriorityQueue<>(new DefaultNodeComparator<>()); - private final ISolutionDistanceMetric solutionDistanceMetric; - private final IPhaseLengthAdjuster phaseLengthAdjuster; - private final IExplorationCandidateSelector candidateSelector; - private int explorationPhaseLength; - private int exploitationPhaseLength; - double exploitationScoreThreshold; - double explorationUncertaintyThreshold; - private int selectedNodes = 0; - private int exploredNodes = 0; - private long timeout; - private long startTime; - private boolean exploring = true; - - public UncertaintyExplorationOpenSelection(final long timeout, final int phaseInterval, final double exploitationScoreThreshold, - final double explorationUncertaintyThreshold, final IPhaseLengthAdjuster phaseLengthAdjuster, - final ISolutionDistanceMetric solutionDistanceMetric, final IExplorationCandidateSelector candidateSelector) { - super(); - this.timeout = timeout; - this.startTime = System.currentTimeMillis(); - int[] phaseLenghts = phaseLengthAdjuster.getInitialPhaseLengths(phaseInterval); - assert phaseLenghts.length == 2; - this.explorationPhaseLength = phaseLenghts[0]; - this.exploitationPhaseLength = phaseLenghts[1]; - this.exploitationScoreThreshold = exploitationScoreThreshold; - this.explorationUncertaintyThreshold = explorationUncertaintyThreshold; - this.phaseLengthAdjuster = phaseLengthAdjuster; - this.solutionDistanceMetric = solutionDistanceMetric; - this.candidateSelector = candidateSelector; - } - - @Override - public Node peek() { - return this.selectCandidate(this.exploring); - } - - private synchronized Node selectCandidate(final boolean isExploring) { - Comparator> comparator = (n1, n2) -> { - try { - Double u1 = (Double) n1.getAnnotation("uncertainty"); - Double u2 = (Double) n2.getAnnotation("uncertainty"); - V v1 = n1.getInternalLabel(); - V v2 = n2.getInternalLabel(); - if (isExploring) { - if (Math.abs(u1 - u2) <= this.explorationUncertaintyThreshold) { - return -1 * v1.compareTo(v2); - } else { - return Double.compare(u1, u2); - } - } else { - if (v1 instanceof Double && v2 instanceof Double) { - Double s1 = (Double) v1; - Double s2 = (Double) v2; - if (Math.abs(s1 - s2) <= this.exploitationScoreThreshold) { - return Double.compare(u1, u2); - } else { - return Double.compare(s1, s2); - } - } else { - if (v1 instanceof Double && v2 instanceof Double) { - Double s1 = (Double) v1; - Double s2 = (Double) v2; - if (Math.abs(s1 - s2) <= this.exploitationScoreThreshold) { - return Double.compare(u1, u2); - } else { - return v1.compareTo(v2); - } - } else { - return v1.compareTo(v2); - } - } - } - } catch (Exception e) { - logger.error(e.getMessage()); - return 0; - } - }; - if (isExploring) { - return this.explorationOpen.stream().max(comparator).orElse(this.explorationOpen.peek()); - } else { - return this.exploitationOpen.stream().min(comparator).orElse(this.exploitationOpen.peek()); - } - } - - private void adjustPhaseLengths(final long passedTime) { - int[] newPhaseLengths = this.phaseLengthAdjuster.adjustPhaseLength(this.explorationPhaseLength, - this.exploitationPhaseLength, passedTime, this.timeout); - assert newPhaseLengths.length == 2; - this.explorationPhaseLength = newPhaseLengths[0]; - this.exploitationPhaseLength = newPhaseLengths[1]; - } - - @Override - public synchronized boolean add(final Node node) { - if (node == null) - throw new IllegalArgumentException("Cannot add node NULL to OPEN"); - if (!this.contains(node)) - throw new IllegalArgumentException("Node " + node + " is already there!"); - if (this.exploring) { - return this.explorationOpen.add(node); - } else { - return this.exploitationOpen.add(node); - } - } - - @Override - public synchronized boolean remove(final Object node) { - if (this.exploitationOpen.contains(node) && this.explorationOpen.contains(node)) - throw new IllegalStateException("A node (" + node + ") that is to be removed is in BOTH open lists!"); - if (this.exploring) { - return this.explorationOpen.remove(node) || this.exploitationOpen.remove(node); - } else { - return this.exploitationOpen.remove(node) || this.explorationOpen.remove(node); - } - } - - @Override - public synchronized boolean addAll(final Collection> arg0) { - assert this.exploitationOpen != null : "Primary OPEN is NULL!"; - if (arg0 == null) { - throw new IllegalArgumentException("Cannot add NULL collection"); - } - if (this.exploring) { - return this.explorationOpen.addAll(arg0); - } else { - return this.exploitationOpen.addAll(arg0); - } - } - - @Override - public synchronized void clear() { - this.exploitationOpen.clear(); - this.explorationOpen.clear(); - } - - @Override - public synchronized boolean contains(final Object arg0) { - return this.exploitationOpen.contains(arg0) || this.explorationOpen.contains(arg0); - } - - @Override - public boolean containsAll(final Collection arg0) { - for (Object o : arg0) { - if (!this.contains(o)) { - return false; - } - } - return true; - } - - @Override - public synchronized boolean isEmpty() { - return this.exploitationOpen.isEmpty() && this.explorationOpen.isEmpty(); - } - - @Override - public Iterator> iterator() { - return this.exploring ? this.explorationOpen.iterator() : this.exploitationOpen.iterator(); - } - - @Override - public synchronized boolean removeAll(final Collection arg0) { - return this.exploitationOpen.removeAll(arg0) && this.explorationOpen.removeAll(arg0); - } - - @Override - public synchronized boolean retainAll(final Collection arg0) { - return this.exploitationOpen.retainAll(arg0) && this.explorationOpen.retainAll(arg0); - } - - @Override - public synchronized int size() { - return this.exploitationOpen.size() + this.explorationOpen.size(); - } - - @Override - public Object[] toArray() { - return this.exploitationOpen.toArray(); - } - - @SuppressWarnings("unchecked") - @Override - public X[] toArray(final X[] arg0) { - return (X[]) this.exploitationOpen.toArray(); - } - - @Override - public Node element() { - return this.peek(); - } - - @Override - public boolean offer(final Node e) { - return this.add(e); - } - - @Override - public Node poll() { - return this.remove(); - } - - @Override - public synchronized Node remove() { - - /* determine element to be returned and remove it from the respective list */ - Node peek = this.peek(); - this.remove(peek); - - /* update internal state */ - if (!this.exploring) { - this.selectedNodes++; - if (this.selectedNodes % this.exploitationPhaseLength == 0) { - List> explorationCandidates = this.candidateSelector.selectExplorationCandidates(this.exploitationOpen, - this.exploitationOpen.peek(), this.solutionDistanceMetric); - - /* enable exploration with the node selected by the explorer evaluator */ - try { - logger.info("Entering exploration phase under {}", explorationCandidates); - } catch (Exception e) { - logger.error(e.getMessage()); - } - this.exploring = true; - this.exploredNodes = 0; - this.exploitationOpen.removeAll(explorationCandidates); - this.explorationOpen.clear(); - this.explorationOpen.addAll(explorationCandidates); - } - } else { - this.exploredNodes++; - if (this.exploredNodes > this.explorationPhaseLength || this.explorationOpen.isEmpty()) { - this.adjustPhaseLengths(System.currentTimeMillis() - this.startTime); - this.exploring = false; - this.exploitationOpen.addAll(this.explorationOpen); - this.explorationOpen.clear(); - logger.info("Entering exploitation phase"); - } - } - - /* return the peeked element */ - return peek; - } -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty.explorationexploitationsearch; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.PriorityQueue; +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ai.libs.jaicore.search.algorithms.standard.uncertainty.ISolutionDistanceMetric; +import ai.libs.jaicore.search.model.travesaltree.DefaultNodeComparator; +import ai.libs.jaicore.search.model.travesaltree.Node; + +public class UncertaintyExplorationOpenSelection> implements Queue> { + + private static final Logger logger = LoggerFactory.getLogger(UncertaintyExplorationOpenSelection.class); + + private final Queue> exploitationOpen = new PriorityQueue<>(new DefaultNodeComparator<>()); + private final PriorityQueue> explorationOpen = new PriorityQueue<>(new DefaultNodeComparator<>()); + private final ISolutionDistanceMetric solutionDistanceMetric; + private final IPhaseLengthAdjuster phaseLengthAdjuster; + private final IExplorationCandidateSelector candidateSelector; + private int explorationPhaseLength; + private int exploitationPhaseLength; + double exploitationScoreThreshold; + double explorationUncertaintyThreshold; + private int selectedNodes = 0; + private int exploredNodes = 0; + private long timeout; + private long startTime; + private boolean exploring = true; + + public UncertaintyExplorationOpenSelection(final long timeout, final int phaseInterval, final double exploitationScoreThreshold, + final double explorationUncertaintyThreshold, final IPhaseLengthAdjuster phaseLengthAdjuster, + final ISolutionDistanceMetric solutionDistanceMetric, final IExplorationCandidateSelector candidateSelector) { + super(); + this.timeout = timeout; + this.startTime = System.currentTimeMillis(); + int[] phaseLenghts = phaseLengthAdjuster.getInitialPhaseLengths(phaseInterval); + assert phaseLenghts.length == 2; + this.explorationPhaseLength = phaseLenghts[0]; + this.exploitationPhaseLength = phaseLenghts[1]; + this.exploitationScoreThreshold = exploitationScoreThreshold; + this.explorationUncertaintyThreshold = explorationUncertaintyThreshold; + this.phaseLengthAdjuster = phaseLengthAdjuster; + this.solutionDistanceMetric = solutionDistanceMetric; + this.candidateSelector = candidateSelector; + } + + @Override + public Node peek() { + return this.selectCandidate(this.exploring); + } + + private synchronized Node selectCandidate(final boolean isExploring) { + Comparator> comparator = (n1, n2) -> { + try { + Double u1 = (Double) n1.getAnnotation("uncertainty"); + Double u2 = (Double) n2.getAnnotation("uncertainty"); + V v1 = n1.getInternalLabel(); + V v2 = n2.getInternalLabel(); + if (isExploring) { + if (Math.abs(u1 - u2) <= this.explorationUncertaintyThreshold) { + return -1 * v1.compareTo(v2); + } else { + return Double.compare(u1, u2); + } + } else { + if (v1 instanceof Double && v2 instanceof Double) { + Double s1 = (Double) v1; + Double s2 = (Double) v2; + if (Math.abs(s1 - s2) <= this.exploitationScoreThreshold) { + return Double.compare(u1, u2); + } else { + return Double.compare(s1, s2); + } + } else { + if (v1 instanceof Double && v2 instanceof Double) { + Double s1 = (Double) v1; + Double s2 = (Double) v2; + if (Math.abs(s1 - s2) <= this.exploitationScoreThreshold) { + return Double.compare(u1, u2); + } else { + return v1.compareTo(v2); + } + } else { + return v1.compareTo(v2); + } + } + } + } catch (Exception e) { + logger.error(e.getMessage()); + return 0; + } + }; + if (isExploring) { + return this.explorationOpen.stream().max(comparator).orElse(this.explorationOpen.peek()); + } else { + return this.exploitationOpen.stream().min(comparator).orElse(this.exploitationOpen.peek()); + } + } + + private void adjustPhaseLengths(final long passedTime) { + int[] newPhaseLengths = this.phaseLengthAdjuster.adjustPhaseLength(this.explorationPhaseLength, + this.exploitationPhaseLength, passedTime, this.timeout); + assert newPhaseLengths.length == 2; + this.explorationPhaseLength = newPhaseLengths[0]; + this.exploitationPhaseLength = newPhaseLengths[1]; + } + + @Override + public synchronized boolean add(final Node node) { + if (node == null) + throw new IllegalArgumentException("Cannot add node NULL to OPEN"); + if (!this.contains(node)) + throw new IllegalArgumentException("Node " + node + " is already there!"); + if (this.exploring) { + return this.explorationOpen.add(node); + } else { + return this.exploitationOpen.add(node); + } + } + + @Override + public synchronized boolean remove(final Object node) { + if (this.exploitationOpen.contains(node) && this.explorationOpen.contains(node)) + throw new IllegalStateException("A node (" + node + ") that is to be removed is in BOTH open lists!"); + if (this.exploring) { + return this.explorationOpen.remove(node) || this.exploitationOpen.remove(node); + } else { + return this.exploitationOpen.remove(node) || this.explorationOpen.remove(node); + } + } + + @Override + public synchronized boolean addAll(final Collection> arg0) { + assert this.exploitationOpen != null : "Primary OPEN is NULL!"; + if (arg0 == null) { + throw new IllegalArgumentException("Cannot add NULL collection"); + } + if (this.exploring) { + return this.explorationOpen.addAll(arg0); + } else { + return this.exploitationOpen.addAll(arg0); + } + } + + @Override + public synchronized void clear() { + this.exploitationOpen.clear(); + this.explorationOpen.clear(); + } + + @Override + public synchronized boolean contains(final Object arg0) { + return this.exploitationOpen.contains(arg0) || this.explorationOpen.contains(arg0); + } + + @Override + public boolean containsAll(final Collection arg0) { + for (Object o : arg0) { + if (!this.contains(o)) { + return false; + } + } + return true; + } + + @Override + public synchronized boolean isEmpty() { + return this.exploitationOpen.isEmpty() && this.explorationOpen.isEmpty(); + } + + @Override + public Iterator> iterator() { + return this.exploring ? this.explorationOpen.iterator() : this.exploitationOpen.iterator(); + } + + @Override + public synchronized boolean removeAll(final Collection arg0) { + return this.exploitationOpen.removeAll(arg0) && this.explorationOpen.removeAll(arg0); + } + + @Override + public synchronized boolean retainAll(final Collection arg0) { + return this.exploitationOpen.retainAll(arg0) && this.explorationOpen.retainAll(arg0); + } + + @Override + public synchronized int size() { + return this.exploitationOpen.size() + this.explorationOpen.size(); + } + + @Override + public Object[] toArray() { + return this.exploitationOpen.toArray(); + } + + @SuppressWarnings("unchecked") + @Override + public X[] toArray(final X[] arg0) { + return (X[]) this.exploitationOpen.toArray(); + } + + @Override + public Node element() { + return this.peek(); + } + + @Override + public boolean offer(final Node e) { + return this.add(e); + } + + @Override + public Node poll() { + return this.remove(); + } + + @Override + public synchronized Node remove() { + + /* determine element to be returned and remove it from the respective list */ + Node peek = this.peek(); + this.remove(peek); + + /* update internal state */ + if (!this.exploring) { + this.selectedNodes++; + if (this.selectedNodes % this.exploitationPhaseLength == 0) { + List> explorationCandidates = this.candidateSelector.selectExplorationCandidates(this.exploitationOpen, + this.exploitationOpen.peek(), this.solutionDistanceMetric); + + /* enable exploration with the node selected by the explorer evaluator */ + try { + logger.info("Entering exploration phase under {}", explorationCandidates); + } catch (Exception e) { + logger.error(e.getMessage()); + } + this.exploring = true; + this.exploredNodes = 0; + this.exploitationOpen.removeAll(explorationCandidates); + this.explorationOpen.clear(); + this.explorationOpen.addAll(explorationCandidates); + } + } else { + this.exploredNodes++; + if (this.exploredNodes > this.explorationPhaseLength || this.explorationOpen.isEmpty()) { + this.adjustPhaseLengths(System.currentTimeMillis() - this.startTime); + this.exploring = false; + this.exploitationOpen.addAll(this.explorationOpen); + this.explorationOpen.clear(); + logger.info("Entering exploitation phase"); + } + } + + /* return the peeked element */ + return peek; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/CosinusDistanceComparator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/CosinusDistanceComparator.java similarity index 88% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/CosinusDistanceComparator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/CosinusDistanceComparator.java index b977fccc0a..6e17a9b860 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/CosinusDistanceComparator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/CosinusDistanceComparator.java @@ -1,49 +1,49 @@ -package jaicore.search.algorithms.standard.uncertainty.paretosearch; - -import java.util.Comparator; - -import jaicore.search.model.travesaltree.Node; - -public class CosinusDistanceComparator> implements Comparator> { - - public final double x1; - public final double x2; - - public CosinusDistanceComparator(double x1, double x2) { - this.x1 = x1; - this.x2 = x2; - } - - /** - * Compares the cosine distance of two nodes to x. - * @param first - * @param second - * @return negative iff first < second, 0 iff first == second, positive iff first > second - */ - public int compare(Node first, Node second) { - - Double firstF = (Double) first.getAnnotation("f"); - Double firstU = (Double) first.getAnnotation("uncertainty"); - - Double secondF = (Double) second.getAnnotation("f"); - Double secondU = (Double) second.getAnnotation("uncertainty"); - - double cosDistanceFirst = 1 - this.cosineSimilarity(firstF, firstU); - double cosDistanceSecond = 1 - this.cosineSimilarity(secondF, secondU); - - return (int)((cosDistanceFirst - cosDistanceSecond) * 10000); - } - - /** - * Cosine similarity to x. - * @param f - * @param u - * @return - */ - public double cosineSimilarity(double f, double u) { - return (this.x1*f + this.x2*u)/(Math.sqrt(f*f + u*u)*Math.sqrt(this.x1*this.x1 + this.x2*this.x2)); - } - -} - - +package ai.libs.jaicore.search.algorithms.standard.uncertainty.paretosearch; + +import java.util.Comparator; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +public class CosinusDistanceComparator> implements Comparator> { + + public final double x1; + public final double x2; + + public CosinusDistanceComparator(double x1, double x2) { + this.x1 = x1; + this.x2 = x2; + } + + /** + * Compares the cosine distance of two nodes to x. + * @param first + * @param second + * @return negative iff first < second, 0 iff first == second, positive iff first > second + */ + public int compare(Node first, Node second) { + + Double firstF = (Double) first.getAnnotation("f"); + Double firstU = (Double) first.getAnnotation("uncertainty"); + + Double secondF = (Double) second.getAnnotation("f"); + Double secondU = (Double) second.getAnnotation("uncertainty"); + + double cosDistanceFirst = 1 - this.cosineSimilarity(firstF, firstU); + double cosDistanceSecond = 1 - this.cosineSimilarity(secondF, secondU); + + return (int)((cosDistanceFirst - cosDistanceSecond) * 10000); + } + + /** + * Cosine similarity to x. + * @param f + * @param u + * @return + */ + public double cosineSimilarity(double f, double u) { + return (this.x1*f + this.x2*u)/(Math.sqrt(f*f + u*u)*Math.sqrt(this.x1*this.x1 + this.x2*this.x2)); + } + +} + + diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/FirstInFirstOutComparator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/FirstInFirstOutComparator.java similarity index 77% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/FirstInFirstOutComparator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/FirstInFirstOutComparator.java index adf4859e86..d5d7a8415e 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/FirstInFirstOutComparator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/FirstInFirstOutComparator.java @@ -1,19 +1,19 @@ -package jaicore.search.algorithms.standard.uncertainty.paretosearch; - -import java.util.Comparator; - -import jaicore.search.model.travesaltree.Node; - -public class FirstInFirstOutComparator> implements Comparator> { - - /** - * Compares two Pareto nodes on time of insertion (n). FIFO behaviour. - * @param first - * @param second - * @return negative iff first.n < second.n, 0 iff fist.n == second.n, positive iff first.n > second.n - */ - public int compare(Node first, Node second) { - return (int)first.getAnnotation("n") - (int)second.getAnnotation("n"); - } - -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty.paretosearch; + +import java.util.Comparator; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +public class FirstInFirstOutComparator> implements Comparator> { + + /** + * Compares two Pareto nodes on time of insertion (n). FIFO behaviour. + * @param first + * @param second + * @return negative iff first.n < second.n, 0 iff fist.n == second.n, positive iff first.n > second.n + */ + public int compare(Node first, Node second) { + return (int)first.getAnnotation("n") - (int)second.getAnnotation("n"); + } + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoFrontVisualizer.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoFrontVisualizer.java similarity index 92% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoFrontVisualizer.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoFrontVisualizer.java index 13bf74ba56..7781862fc2 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoFrontVisualizer.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoFrontVisualizer.java @@ -1,68 +1,68 @@ -package jaicore.search.algorithms.standard.uncertainty.paretosearch; - -import java.util.ArrayList; -import java.util.List; -import org.knowm.xchart.SwingWrapper; -import org.knowm.xchart.XYChart; -import org.knowm.xchart.XYChartBuilder; -import org.knowm.xchart.XYSeries.XYSeriesRenderStyle; -import org.knowm.xchart.style.Styler.ChartTheme; -import org.knowm.xchart.style.Styler.LegendPosition; - -public class ParetoFrontVisualizer { - - final XYChart chart; - final SwingWrapper vis; - final List fValues; - final List uncertainties; - - public ParetoFrontVisualizer () { - chart = new XYChartBuilder() - .width(600) - .height(500) - .title("Paretofront Visualizer") - .theme(ChartTheme.Matlab) - .xAxisTitle("Uncertainty") - .yAxisTitle("F Value") - .build(); - - chart.getStyler().setYAxisMin(0.0d); - chart.getStyler().setXAxisMin(0.0d); - chart.getStyler().setYAxisMax(1.0d); - chart.getStyler().setXAxisMax(1.0d); - chart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Scatter); - chart.getStyler().setLegendPosition(LegendPosition.OutsideS); - chart.getStyler().setMarkerSize(4); - chart.addSeries("Paretofront Candidates", new double[] {1}, new double[] {1}); - - vis = new SwingWrapper<>(chart); - - fValues = new ArrayList<>(); - uncertainties = new ArrayList<>(); - } - - public void show () { - vis.displayChart(); - } - - public void update (double fValue, double uncertainty) { - fValues.add(fValue); - uncertainties.add(uncertainty); - - if (fValues.size() == uncertainties.size()) { - double[] f = new double[fValues.size()]; - double[] u = new double[uncertainties.size()]; - for (int i = 0; i < fValues.size(); i++) { - f[i] = fValues.get(i); - u[i] = uncertainties.get(i); - } - javax.swing.SwingUtilities.invokeLater(() -> { - chart.updateXYSeries("Paretofront Candidates", u, f, null); - vis.repaintChart(); - }); - } else { - System.out.println("ERROR: Unqueal value amounts"); - } - } - -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty.paretosearch; + +import java.util.ArrayList; +import java.util.List; +import org.knowm.xchart.SwingWrapper; +import org.knowm.xchart.XYChart; +import org.knowm.xchart.XYChartBuilder; +import org.knowm.xchart.XYSeries.XYSeriesRenderStyle; +import org.knowm.xchart.style.Styler.ChartTheme; +import org.knowm.xchart.style.Styler.LegendPosition; + +public class ParetoFrontVisualizer { + + final XYChart chart; + final SwingWrapper vis; + final List fValues; + final List uncertainties; + + public ParetoFrontVisualizer () { + chart = new XYChartBuilder() + .width(600) + .height(500) + .title("Paretofront Visualizer") + .theme(ChartTheme.Matlab) + .xAxisTitle("Uncertainty") + .yAxisTitle("F Value") + .build(); + + chart.getStyler().setYAxisMin(0.0d); + chart.getStyler().setXAxisMin(0.0d); + chart.getStyler().setYAxisMax(1.0d); + chart.getStyler().setXAxisMax(1.0d); + chart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Scatter); + chart.getStyler().setLegendPosition(LegendPosition.OutsideS); + chart.getStyler().setMarkerSize(4); + chart.addSeries("Paretofront Candidates", new double[] {1}, new double[] {1}); + + vis = new SwingWrapper<>(chart); + + fValues = new ArrayList<>(); + uncertainties = new ArrayList<>(); + } + + public void show () { + vis.displayChart(); + } + + public void update (double fValue, double uncertainty) { + fValues.add(fValue); + uncertainties.add(uncertainty); + + if (fValues.size() == uncertainties.size()) { + double[] f = new double[fValues.size()]; + double[] u = new double[uncertainties.size()]; + for (int i = 0; i < fValues.size(); i++) { + f[i] = fValues.get(i); + u[i] = uncertainties.get(i); + } + javax.swing.SwingUtilities.invokeLater(() -> { + chart.updateXYSeries("Paretofront Candidates", u, f, null); + vis.repaintChart(); + }); + } else { + System.out.println("ERROR: Unqueal value amounts"); + } + } + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoNode.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoNode.java similarity index 87% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoNode.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoNode.java index 3af4b2ad99..1e83500b28 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoNode.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoNode.java @@ -1,73 +1,73 @@ -package jaicore.search.algorithms.standard.uncertainty.paretosearch; - -import java.util.HashSet; - -import jaicore.search.model.travesaltree.Node; - -/** - * Internal representation of nodes to maintain pareto front. - */ -public class ParetoNode> { - - final Node node; - - /* Number of creation of this pareto node. */ - final int n; - final HashSet> dominates; - final HashSet> dominatedBy; - - - public ParetoNode(final Node node, final int n) { - this.node = node; - if (n < 0) { - throw new IllegalArgumentException("n has to be non-negative"); - } - this.n = n; - this.dominates = new HashSet<>(); - this.dominatedBy = new HashSet<>(); - } - - @Override - public String toString() { - String s = "{" + this.node.getPoint() + "] dominated by {"; - for (ParetoNode p : this.dominatedBy) { - s += p.node.getPoint() + ","; - } - s += "} dominates { "; - for (ParetoNode p : this.dominates) { - s += p.node.getPoint() + ","; - } - s += "}"; - return s; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.node == null) ? 0 : this.node.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (this.getClass() != obj.getClass()) { - return false; - } - ParetoNode other = (ParetoNode) obj; - if (this.node == null) { - if (other.node != null) { - return false; - } - } else if (!this.node.equals(other.node)) { - return false; - } - return true; - } -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty.paretosearch; + +import java.util.HashSet; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +/** + * Internal representation of nodes to maintain pareto front. + */ +public class ParetoNode> { + + final Node node; + + /* Number of creation of this pareto node. */ + final int n; + final HashSet> dominates; + final HashSet> dominatedBy; + + + public ParetoNode(final Node node, final int n) { + this.node = node; + if (n < 0) { + throw new IllegalArgumentException("n has to be non-negative"); + } + this.n = n; + this.dominates = new HashSet<>(); + this.dominatedBy = new HashSet<>(); + } + + @Override + public String toString() { + String s = "{" + this.node.getPoint() + "] dominated by {"; + for (ParetoNode p : this.dominatedBy) { + s += p.node.getPoint() + ","; + } + s += "} dominates { "; + for (ParetoNode p : this.dominates) { + s += p.node.getPoint() + ","; + } + s += "}"; + return s; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.node == null) ? 0 : this.node.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (this.getClass() != obj.getClass()) { + return false; + } + ParetoNode other = (ParetoNode) obj; + if (this.node == null) { + if (other.node != null) { + return false; + } + } else if (!this.node.equals(other.node)) { + return false; + } + return true; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoSelection.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoSelection.java similarity index 93% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoSelection.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoSelection.java index a6b16a4185..75bf726d25 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoSelection.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/ParetoSelection.java @@ -1,259 +1,259 @@ -package jaicore.search.algorithms.standard.uncertainty.paretosearch; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Queue; - -import jaicore.search.model.travesaltree.Node; - -/** - * Open collection pareto front implementation. - * - * @param - * internal label of node - * @param - * external label of node - */ -public class ParetoSelection> implements Queue> { - - private static final String UNCERTAINTY = "uncertainty"; - private static final String DOMINATES = "dominates"; - private static final String DOMINATED_BY = "dominatedBy"; - - /* Contains all open nodes. */ - private final LinkedList> open; - - /* Contains all maximal open nodes. */ - private final Queue> pareto; - - /* Node counter. */ - private int n = 0; - - /** - * Constructor. - * - * @param pareto - * Pareto set implementation. - */ - public ParetoSelection(final Queue> pareto) { - this.open = new LinkedList<>(); - this.pareto = pareto; - } - - /** - * Tests if p dominates q. - * - * @param p - * @param q - * @return true if p dominates q. False, otherwise. - */ - @SuppressWarnings("unchecked") - private boolean dominates(final Node p, final Node q) { - if (!p.getAnnotations().containsKey(UNCERTAINTY)) { - throw new IllegalArgumentException("Node " + p + " has no uncertainty information."); - } - if (!q.getAnnotations().containsKey(UNCERTAINTY)) { - throw new IllegalArgumentException("Node " + q + " has no uncertainty information."); - } - // Get f and u values of nodes - V p_f = (V) p.getAnnotation("f"); - double p_u = (double) p.getAnnotation(UNCERTAINTY); - V q_f = (V) q.getAnnotation("f"); - double q_u = (double) q.getAnnotation(UNCERTAINTY); - - // p dominates q <=> (q.f < p.f AND q.u <= p.u) OR (q.f <= p.f AND q.u < p.u) - return ((p_f.compareTo(q_f) < 0) && (p_u <= q_u)) || ((p_f.compareTo(q_f) <= 0) && (p_u < q_u)); - } - - /** - * Tests if p is maximal. - * - * @param n - * @return - */ - @SuppressWarnings("unchecked") - private boolean isMaximal(final Node n) { - return ((HashSet>) n.getAnnotation(DOMINATED_BY)).size() == 0; - } - - /** - * Adds a node to the open list and, if its not dominated by any other point - * also to the pareto front. - * - * @param n - * @return - */ - @Override - public boolean add(final Node n) { - if (n.getInternalLabel() == null) { - throw new IllegalArgumentException("Cannot add nodes with value NULL to OPEN!"); - } - - // Initialize annotations necessary for pareto queue. - n.setAnnotation("n", this.n++); - n.setAnnotation(DOMINATES, new HashSet>()); - n.setAnnotation(DOMINATED_BY, new HashSet>()); - - for (Node q : this.open) { - // n dominates q - if (this.dominates(n, q)) { - ((HashSet>) n.getAnnotation(DOMINATES)).add(q); - ((HashSet>) q.getAnnotation(DOMINATED_BY)).add(n); - - // Remove q from pareto front if its now dominated i.e. not maximal anymore. - if (!this.isMaximal(q)) { - this.pareto.remove(q); - } - } - // n dominated by q - if (this.dominates(q, n)) { - ((HashSet>) n.getAnnotation(DOMINATES)).add(q); - ((HashSet>) q.getAnnotation(DOMINATED_BY)).add(n); - } - } - - // If n is not dominated by any other point, add it to pareto front. - if (this.isMaximal(n)) { - this.pareto.add(n); - } - - return this.open.add(n); - } - - @Override - public boolean addAll(final Collection> c) { - boolean changed = false; - for (Node p : c) { - changed |= this.add(p); - } - return changed; - } - - @Override - public void clear() { - this.open.clear(); - } - - @Override - public boolean contains(final Object o) { - return this.open.contains(o); - } - - @Override - public boolean containsAll(final Collection c) { - return this.open.containsAll(c); - } - - @Override - public boolean isEmpty() { - return this.open.isEmpty(); - } - - @Override - public Iterator> iterator() { - return this.pareto.iterator(); - } - - @Override - public boolean removeAll(final Collection c) { - return this.open.removeAll(c); - } - - @Override - public boolean retainAll(final Collection c) { - return this.open.retainAll(c); - } - - @Override - public int size() { - return this.open.size(); - } - - @Override - public Object[] toArray() { - return this.open.toArray(); - } - - @Override - public X[] toArray(final X[] a) { - return this.open.toArray(a); - } - - /** - * Return a node from pareto front. - */ - @Override - public Node peek() { - return this.pareto.isEmpty() ? null : this.pareto.peek(); - } - - /** - * Removes an Node from - * - * @param o - * @return - */ - @Override - public boolean remove(final Object o) { - if (o instanceof Node) { - Node node = (Node) o; - // Remove all associations of n. - for (Node q : (HashSet>) node.getAnnotation(DOMINATES)) { - ((HashSet>) q.getAnnotation(DOMINATED_BY)).remove(node); - // Add q to pareto if its now no longer dominated by any other point. - if (this.isMaximal(q)) { - this.pareto.add(q); - } - } - for (Node q : (HashSet>) node.getAnnotation(DOMINATED_BY)) { - ((HashSet>) q.getAnnotation(DOMINATES)).remove(node); // TODO: Is this even necessary? - } - // Remove n from Pareto set and Open list. - this.pareto.remove(node); - return this.open.remove(node); - } else { - return false; - } - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("OPEN LIST: \n"); - for (Node p : this.open) { - sb.append(p.toString()); - sb.append("\n"); - } - sb.append("PARETO = ["); - for (Node p : this.pareto) { - sb.append(p.getPoint()); - sb.append(", "); - } - sb.append("]"); - return sb.toString(); - } - - @Override - public Node element() { - return this.peek(); - } - - @Override - public boolean offer(final Node arg0) { - return this.add(arg0); - } - - @Override - public Node poll() { - Node node = this.peek(); - this.remove(node); - return node; - } - - @Override - public Node remove() { - return this.poll(); - } -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty.paretosearch; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Queue; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +/** + * Open collection pareto front implementation. + * + * @param + * internal label of node + * @param + * external label of node + */ +public class ParetoSelection> implements Queue> { + + private static final String UNCERTAINTY = "uncertainty"; + private static final String DOMINATES = "dominates"; + private static final String DOMINATED_BY = "dominatedBy"; + + /* Contains all open nodes. */ + private final LinkedList> open; + + /* Contains all maximal open nodes. */ + private final Queue> pareto; + + /* Node counter. */ + private int n = 0; + + /** + * Constructor. + * + * @param pareto + * Pareto set implementation. + */ + public ParetoSelection(final Queue> pareto) { + this.open = new LinkedList<>(); + this.pareto = pareto; + } + + /** + * Tests if p dominates q. + * + * @param p + * @param q + * @return true if p dominates q. False, otherwise. + */ + @SuppressWarnings("unchecked") + private boolean dominates(final Node p, final Node q) { + if (!p.getAnnotations().containsKey(UNCERTAINTY)) { + throw new IllegalArgumentException("Node " + p + " has no uncertainty information."); + } + if (!q.getAnnotations().containsKey(UNCERTAINTY)) { + throw new IllegalArgumentException("Node " + q + " has no uncertainty information."); + } + // Get f and u values of nodes + V p_f = (V) p.getAnnotation("f"); + double p_u = (double) p.getAnnotation(UNCERTAINTY); + V q_f = (V) q.getAnnotation("f"); + double q_u = (double) q.getAnnotation(UNCERTAINTY); + + // p dominates q <=> (q.f < p.f AND q.u <= p.u) OR (q.f <= p.f AND q.u < p.u) + return ((p_f.compareTo(q_f) < 0) && (p_u <= q_u)) || ((p_f.compareTo(q_f) <= 0) && (p_u < q_u)); + } + + /** + * Tests if p is maximal. + * + * @param n + * @return + */ + @SuppressWarnings("unchecked") + private boolean isMaximal(final Node n) { + return ((HashSet>) n.getAnnotation(DOMINATED_BY)).size() == 0; + } + + /** + * Adds a node to the open list and, if its not dominated by any other point + * also to the pareto front. + * + * @param n + * @return + */ + @Override + public boolean add(final Node n) { + if (n.getInternalLabel() == null) { + throw new IllegalArgumentException("Cannot add nodes with value NULL to OPEN!"); + } + + // Initialize annotations necessary for pareto queue. + n.setAnnotation("n", this.n++); + n.setAnnotation(DOMINATES, new HashSet>()); + n.setAnnotation(DOMINATED_BY, new HashSet>()); + + for (Node q : this.open) { + // n dominates q + if (this.dominates(n, q)) { + ((HashSet>) n.getAnnotation(DOMINATES)).add(q); + ((HashSet>) q.getAnnotation(DOMINATED_BY)).add(n); + + // Remove q from pareto front if its now dominated i.e. not maximal anymore. + if (!this.isMaximal(q)) { + this.pareto.remove(q); + } + } + // n dominated by q + if (this.dominates(q, n)) { + ((HashSet>) n.getAnnotation(DOMINATES)).add(q); + ((HashSet>) q.getAnnotation(DOMINATED_BY)).add(n); + } + } + + // If n is not dominated by any other point, add it to pareto front. + if (this.isMaximal(n)) { + this.pareto.add(n); + } + + return this.open.add(n); + } + + @Override + public boolean addAll(final Collection> c) { + boolean changed = false; + for (Node p : c) { + changed |= this.add(p); + } + return changed; + } + + @Override + public void clear() { + this.open.clear(); + } + + @Override + public boolean contains(final Object o) { + return this.open.contains(o); + } + + @Override + public boolean containsAll(final Collection c) { + return this.open.containsAll(c); + } + + @Override + public boolean isEmpty() { + return this.open.isEmpty(); + } + + @Override + public Iterator> iterator() { + return this.pareto.iterator(); + } + + @Override + public boolean removeAll(final Collection c) { + return this.open.removeAll(c); + } + + @Override + public boolean retainAll(final Collection c) { + return this.open.retainAll(c); + } + + @Override + public int size() { + return this.open.size(); + } + + @Override + public Object[] toArray() { + return this.open.toArray(); + } + + @Override + public X[] toArray(final X[] a) { + return this.open.toArray(a); + } + + /** + * Return a node from pareto front. + */ + @Override + public Node peek() { + return this.pareto.isEmpty() ? null : this.pareto.peek(); + } + + /** + * Removes an Node from + * + * @param o + * @return + */ + @Override + public boolean remove(final Object o) { + if (o instanceof Node) { + Node node = (Node) o; + // Remove all associations of n. + for (Node q : (HashSet>) node.getAnnotation(DOMINATES)) { + ((HashSet>) q.getAnnotation(DOMINATED_BY)).remove(node); + // Add q to pareto if its now no longer dominated by any other point. + if (this.isMaximal(q)) { + this.pareto.add(q); + } + } + for (Node q : (HashSet>) node.getAnnotation(DOMINATED_BY)) { + ((HashSet>) q.getAnnotation(DOMINATES)).remove(node); // TODO: Is this even necessary? + } + // Remove n from Pareto set and Open list. + this.pareto.remove(node); + return this.open.remove(node); + } else { + return false; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("OPEN LIST: \n"); + for (Node p : this.open) { + sb.append(p.toString()); + sb.append("\n"); + } + sb.append("PARETO = ["); + for (Node p : this.pareto) { + sb.append(p.getPoint()); + sb.append(", "); + } + sb.append("]"); + return sb.toString(); + } + + @Override + public Node element() { + return this.peek(); + } + + @Override + public boolean offer(final Node arg0) { + return this.add(arg0); + } + + @Override + public Node poll() { + Node node = this.peek(); + this.remove(node); + return node; + } + + @Override + public Node remove() { + return this.poll(); + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/RandomComparator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/RandomComparator.java similarity index 80% rename from JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/RandomComparator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/RandomComparator.java index eb5fb7a7aa..a956f27b3a 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/uncertainty/paretosearch/RandomComparator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/paretosearch/RandomComparator.java @@ -1,25 +1,25 @@ -package jaicore.search.algorithms.standard.uncertainty.paretosearch; - -import java.util.Comparator; -import java.util.Random; - -import jaicore.search.model.travesaltree.Node; - -public class RandomComparator> implements Comparator> { - - /** - * Randomly outputs a negative or positive integer. (Never zero). - * @param first - * @param second - * @return negative iff first.n < second.n, 0 iff fist.n == second.n, positive iff first.n > second.n - */ - public int compare(Node first, Node second) { - Random random = new Random(); - int r = random.nextInt(2); // This is either 0 or 1. - if (r==0) - return -1; - else - return 1; - } - -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty.paretosearch; + +import java.util.Comparator; +import java.util.Random; + +import ai.libs.jaicore.search.model.travesaltree.Node; + +public class RandomComparator> implements Comparator> { + + /** + * Randomly outputs a negative or positive integer. (Never zero). + * @param first + * @param second + * @return negative iff first.n < second.n, 0 iff fist.n == second.n, positive iff first.n > second.n + */ + public int compare(Node first, Node second) { + Random random = new Random(); + int r = random.nextInt(2); // This is either 0 or 1. + if (r==0) + return -1; + else + return 1; + } + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/AAnyPathInORGraphSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/AAnyPathInORGraphSearch.java similarity index 84% rename from JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/AAnyPathInORGraphSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/AAnyPathInORGraphSearch.java index af0eb1ddfe..5d42bbcbf7 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/AAnyPathInORGraphSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/AAnyPathInORGraphSearch.java @@ -1,4 +1,4 @@ -package jaicore.search.core.interfaces; +package ai.libs.jaicore.search.core.interfaces; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -6,9 +6,9 @@ import ai.libs.jaicore.basic.algorithm.AAlgorithm; import ai.libs.jaicore.basic.algorithm.ASolutionCandidateIterator; import ai.libs.jaicore.basic.algorithm.IAlgorithmConfig; -import jaicore.search.algorithms.standard.bestfirst.events.GraphSearchSolutionCandidateFoundEvent; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.GraphSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; /** * This is a template for algorithms that aim at finding paths from a root to diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/AOptimalPathInORGraphSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/AOptimalPathInORGraphSearch.java similarity index 88% rename from JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/AOptimalPathInORGraphSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/AOptimalPathInORGraphSearch.java index 3fe0954b04..b0433aba9c 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/AOptimalPathInORGraphSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/AOptimalPathInORGraphSearch.java @@ -1,4 +1,4 @@ -package jaicore.search.core.interfaces; +package ai.libs.jaicore.search.core.interfaces; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -9,9 +9,9 @@ import ai.libs.jaicore.basic.algorithm.IAlgorithmConfig; import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; -import jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; /** * This is a template for algorithms that aim at finding paths from a root to diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/EdgeCountingSolutionEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/EdgeCountingSolutionEvaluator.java similarity index 77% rename from JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/EdgeCountingSolutionEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/EdgeCountingSolutionEvaluator.java index a734a92deb..9480006f2b 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/EdgeCountingSolutionEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/EdgeCountingSolutionEvaluator.java @@ -1,7 +1,7 @@ -package jaicore.search.core.interfaces; +package ai.libs.jaicore.search.core.interfaces; import ai.libs.jaicore.basic.IObjectEvaluator; -import jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; /** * Uses Double to be compliant with algorithms that MUST work with double instead of Integer (such as AStar) diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/GraphGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/GraphGenerator.java similarity index 74% rename from JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/GraphGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/GraphGenerator.java index bd6aec396f..13ec6ed9ac 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/GraphGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/GraphGenerator.java @@ -1,38 +1,38 @@ -package jaicore.search.core.interfaces; - -import jaicore.search.structure.graphgenerator.GoalTester; -import jaicore.search.structure.graphgenerator.RootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; - -public interface GraphGenerator { - - public RootGenerator getRootGenerator(); - - public SuccessorGenerator getSuccessorGenerator(); - - public GoalTester getGoalTester(); - - /** - * Indicates if the nodes are selfcontained for the solution or if the solution path is needed. - * - * @return - * true if every node contains every information needed for the solution, - * false otherwise. - * - */ - public boolean isSelfContained(); - - - /** - * Indicates whether the nodes should get a unique id, or if all should get the same id -1 - * This is important if one wants to guarantee that the explored graph is expanded as a tree - * - * @return - * true if every node should get an unique id, otherwise return false - */ - public void setNodeNumbering(boolean nodenumbering); - - - - -} +package ai.libs.jaicore.search.core.interfaces; + +import ai.libs.jaicore.search.structure.graphgenerator.GoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.RootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; + +public interface GraphGenerator { + + public RootGenerator getRootGenerator(); + + public SuccessorGenerator getSuccessorGenerator(); + + public GoalTester getGoalTester(); + + /** + * Indicates if the nodes are selfcontained for the solution or if the solution path is needed. + * + * @return + * true if every node contains every information needed for the solution, + * false otherwise. + * + */ + public boolean isSelfContained(); + + + /** + * Indicates whether the nodes should get a unique id, or if all should get the same id -1 + * This is important if one wants to guarantee that the explored graph is expanded as a tree + * + * @return + * true if every node should get an unique id, otherwise return false + */ + public void setNodeNumbering(boolean nodenumbering); + + + + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IGraphSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IGraphSearch.java similarity index 80% rename from JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IGraphSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IGraphSearch.java index 3c5ea4e5eb..d9e1644067 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IGraphSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IGraphSearch.java @@ -1,7 +1,7 @@ -package jaicore.search.core.interfaces; +package ai.libs.jaicore.search.core.interfaces; import ai.libs.jaicore.basic.algorithm.IAlgorithm; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; /** * Graph search algorithms take a graph that is given in the form of a graph generator and search it. diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IGraphSearchFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IGraphSearchFactory.java similarity index 71% rename from JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IGraphSearchFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IGraphSearchFactory.java index 9db1bd81b5..b40688e679 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IGraphSearchFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IGraphSearchFactory.java @@ -1,13 +1,13 @@ -package jaicore.search.core.interfaces; - -import ai.libs.jaicore.basic.algorithm.IAlgorithmFactory; -import jaicore.search.probleminputs.GraphSearchInput; - -public interface IGraphSearchFactory, O, N, A> extends IAlgorithmFactory { - - @Override - public IGraphSearch getAlgorithm(); - - @Override - public IGraphSearch getAlgorithm(I problem); -} +package ai.libs.jaicore.search.core.interfaces; + +import ai.libs.jaicore.basic.algorithm.IAlgorithmFactory; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; + +public interface IGraphSearchFactory, O, N, A> extends IAlgorithmFactory { + + @Override + public IGraphSearch getAlgorithm(); + + @Override + public IGraphSearch getAlgorithm(I problem); +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IOptimalPathInORGraphSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IOptimalPathInORGraphSearch.java similarity index 78% rename from JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IOptimalPathInORGraphSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IOptimalPathInORGraphSearch.java index 0d5ce2c307..d6a8b3888b 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IOptimalPathInORGraphSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IOptimalPathInORGraphSearch.java @@ -1,8 +1,8 @@ -package jaicore.search.core.interfaces; +package ai.libs.jaicore.search.core.interfaces; import ai.libs.jaicore.basic.algorithm.IOptimizationAlgorithm; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; /** * This is a template for algorithms that aim at finding paths from a root to diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IOptimalPathInORGraphSearchFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IOptimalPathInORGraphSearchFactory.java similarity index 67% rename from JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IOptimalPathInORGraphSearchFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IOptimalPathInORGraphSearchFactory.java index 5ea9db8f2c..7a553dbb69 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IOptimalPathInORGraphSearchFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IOptimalPathInORGraphSearchFactory.java @@ -1,8 +1,8 @@ -package jaicore.search.core.interfaces; +package ai.libs.jaicore.search.core.interfaces; import ai.libs.jaicore.basic.algorithm.IAlgorithmFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; public interface IOptimalPathInORGraphSearchFactory,N, A, V extends Comparable> extends IAlgorithmFactory> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IPathInORGraphSearch.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IPathInORGraphSearch.java similarity index 58% rename from JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IPathInORGraphSearch.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IPathInORGraphSearch.java index 9bd3f4929c..c05ec224e1 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/IPathInORGraphSearch.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/IPathInORGraphSearch.java @@ -1,8 +1,8 @@ -package jaicore.search.core.interfaces; +package ai.libs.jaicore.search.core.interfaces; import ai.libs.jaicore.basic.algorithm.ISolutionCandidateIterator; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; public interface IPathInORGraphSearch, O extends SearchGraphPath, N, A> extends IGraphSearch, ISolutionCandidateIterator { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/PathUnifyingGraphGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/PathUnifyingGraphGenerator.java similarity index 89% rename from JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/PathUnifyingGraphGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/PathUnifyingGraphGenerator.java index 90a7622631..c3c47e1e46 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/PathUnifyingGraphGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/PathUnifyingGraphGenerator.java @@ -1,4 +1,4 @@ -package jaicore.search.core.interfaces; +package ai.libs.jaicore.search.core.interfaces; import java.util.List; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/StandardORGraphSearchFactory.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/StandardORGraphSearchFactory.java similarity index 68% rename from JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/StandardORGraphSearchFactory.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/StandardORGraphSearchFactory.java index b0fcc402c6..578460c721 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/core/interfaces/StandardORGraphSearchFactory.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/core/interfaces/StandardORGraphSearchFactory.java @@ -1,7 +1,7 @@ -package jaicore.search.core.interfaces; +package ai.libs.jaicore.search.core.interfaces; import ai.libs.jaicore.basic.algorithm.AAlgorithmFactory; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; public abstract class StandardORGraphSearchFactory, O, N, A, V extends Comparable> extends AAlgorithmFactory implements IGraphSearchFactory { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPlugin.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPlugin.java similarity index 81% rename from JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPlugin.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPlugin.java index f9ce04e344..d447ab8045 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPlugin.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPlugin.java @@ -1,4 +1,4 @@ -package jaicore.search.gui.plugins.rollouthistograms; +package ai.libs.jaicore.search.gui.plugins.rollouthistograms; import ai.libs.jaicore.graphvisualizer.plugin.ASimpleMVCPlugin; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginController.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginController.java similarity index 89% rename from JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginController.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginController.java index 60960b6c4b..9baeaea420 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginController.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginController.java @@ -1,4 +1,4 @@ -package jaicore.search.gui.plugins.rollouthistograms; +package ai.libs.jaicore.search.gui.plugins.rollouthistograms; import ai.libs.jaicore.basic.algorithm.events.AlgorithmEvent; import ai.libs.jaicore.graphvisualizer.events.gui.GUIEvent; @@ -6,7 +6,7 @@ import ai.libs.jaicore.graphvisualizer.plugin.controlbar.ResetEvent; import ai.libs.jaicore.graphvisualizer.plugin.graphview.NodeClickedEvent; import ai.libs.jaicore.graphvisualizer.plugin.timeslider.GoToTimeStepEvent; -import jaicore.search.algorithms.standard.bestfirst.events.RolloutEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.RolloutEvent; public class SearchRolloutHistogramPluginController extends ASimpleMVCPluginController, SearchRolloutHistogramPluginView> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginModel.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginModel.java similarity index 92% rename from JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginModel.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginModel.java index aa83f49c27..f2a3395fd4 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginModel.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginModel.java @@ -1,4 +1,4 @@ -package jaicore.search.gui.plugins.rollouthistograms; +package ai.libs.jaicore.search.gui.plugins.rollouthistograms; import java.util.Collections; import java.util.HashMap; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginView.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginView.java similarity index 92% rename from JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginView.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginView.java index b3b5535427..8602695a49 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginView.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/gui/plugins/rollouthistograms/SearchRolloutHistogramPluginView.java @@ -1,4 +1,4 @@ -package jaicore.search.gui.plugins.rollouthistograms; +package ai.libs.jaicore.search.gui.plugins.rollouthistograms; import ai.libs.jaicore.graphvisualizer.events.gui.Histogram; import ai.libs.jaicore.graphvisualizer.plugin.ASimpleMVCPluginView; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/other/AgnosticPathEvaluator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/other/AgnosticPathEvaluator.java similarity index 81% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/other/AgnosticPathEvaluator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/other/AgnosticPathEvaluator.java index fdcfbc31f7..f09636d170 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/other/AgnosticPathEvaluator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/other/AgnosticPathEvaluator.java @@ -1,4 +1,4 @@ -package jaicore.search.model.other; +package ai.libs.jaicore.search.model.other; import ai.libs.jaicore.basic.IObjectEvaluator; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/other/EvaluatedSearchGraphPath.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/other/EvaluatedSearchGraphPath.java similarity index 92% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/other/EvaluatedSearchGraphPath.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/other/EvaluatedSearchGraphPath.java index 3f45d9de95..f3ec65138f 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/other/EvaluatedSearchGraphPath.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/other/EvaluatedSearchGraphPath.java @@ -1,4 +1,4 @@ -package jaicore.search.model.other; +package ai.libs.jaicore.search.model.other; import java.util.List; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/other/SearchGraphPath.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/other/SearchGraphPath.java similarity index 94% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/other/SearchGraphPath.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/other/SearchGraphPath.java index 54da156b3a..94cacf0d97 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/other/SearchGraphPath.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/other/SearchGraphPath.java @@ -1,4 +1,4 @@ -package jaicore.search.model.other; +package ai.libs.jaicore.search.model.other; import java.util.ArrayList; import java.util.Collections; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/AbstractGraphGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/AbstractGraphGenerator.java similarity index 88% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/AbstractGraphGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/AbstractGraphGenerator.java index 2b5db1c95f..6bb036cfbd 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/AbstractGraphGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/AbstractGraphGenerator.java @@ -1,60 +1,60 @@ -package jaicore.search.model.travesaltree; - -import java.util.Random; - -import jaicore.search.core.interfaces.GraphGenerator; - -public abstract class AbstractGraphGenerator implements GraphGenerator { - - //variables needed for creating ids; - private boolean nodeNumbering; - Random rnd; - - public AbstractGraphGenerator() { - this(1); - } - - /** - * Constructor for an AbstractGraphGenerator, which implements versioning, with a given seed. - * @param seed - * The seed for the random generator, which generates the ids. - */ - public AbstractGraphGenerator(int seed) { - this. nodeNumbering = false; - this.rnd = new Random(seed); - } - - /** - * Method which enables or dissables the nodenumbering and therefore directly influences the id of nodes - * @param nodeNumbering - * true to enable nodenumbering false else - */ - public void setNodeNumbering(boolean nodeNumbering) { - this.nodeNumbering = nodeNumbering; - } - - /** - * Creates the next id for a node. - * - * The id is a random integer greater 0 if nodenumbering is enabled, otherwise it is -1 - * @return - * next id for a node - */ - protected int nextID() { - if(nodeNumbering) - return rnd.nextInt(Integer.MAX_VALUE); - else - return -1; - } - - /** - * Creates a new Random generator with the given seed - * @param seed - * The seed for the random generator. - */ - - public void reset(int seed) { - this.rnd = new Random(seed); - } - -} +package ai.libs.jaicore.search.model.travesaltree; + +import java.util.Random; + +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; + +public abstract class AbstractGraphGenerator implements GraphGenerator { + + //variables needed for creating ids; + private boolean nodeNumbering; + Random rnd; + + public AbstractGraphGenerator() { + this(1); + } + + /** + * Constructor for an AbstractGraphGenerator, which implements versioning, with a given seed. + * @param seed + * The seed for the random generator, which generates the ids. + */ + public AbstractGraphGenerator(int seed) { + this. nodeNumbering = false; + this.rnd = new Random(seed); + } + + /** + * Method which enables or dissables the nodenumbering and therefore directly influences the id of nodes + * @param nodeNumbering + * true to enable nodenumbering false else + */ + public void setNodeNumbering(boolean nodeNumbering) { + this.nodeNumbering = nodeNumbering; + } + + /** + * Creates the next id for a node. + * + * The id is a random integer greater 0 if nodenumbering is enabled, otherwise it is -1 + * @return + * next id for a node + */ + protected int nextID() { + if(nodeNumbering) + return rnd.nextInt(Integer.MAX_VALUE); + else + return -1; + } + + /** + * Creates a new Random generator with the given seed + * @param seed + * The seed for the random generator. + */ + + public void reset(int seed) { + this.rnd = new Random(seed); + } + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/AbstractNode.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/AbstractNode.java similarity index 86% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/AbstractNode.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/AbstractNode.java index 03638dbd84..b3ef5a1c2b 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/AbstractNode.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/AbstractNode.java @@ -1,39 +1,39 @@ -package jaicore.search.model.travesaltree; -/** - * abstract class for nodeobjects which only contains a simple equals method and the id - * @author jkoepe - * - */ -public abstract class AbstractNode { - - //the id of the node - protected int id; - - public AbstractNode() { - this.id = 0; - } - - public AbstractNode(int id) { - this.id = id; - } - - - /** - * Method to set the id, if it was not set in the construction - * @param id - * The id the node should get. - */ - public void setId(int id) { - if(this.id == 0) { - this.id = id; - } - } - - /** - * @return the id - */ - public int getId() { - return id; - } - -} +package ai.libs.jaicore.search.model.travesaltree; +/** + * abstract class for nodeobjects which only contains a simple equals method and the id + * @author jkoepe + * + */ +public abstract class AbstractNode { + + //the id of the node + protected int id; + + public AbstractNode() { + this.id = 0; + } + + public AbstractNode(int id) { + this.id = id; + } + + + /** + * Method to set the id, if it was not set in the construction + * @param id + * The id the node should get. + */ + public void setId(int id) { + if(this.id == 0) { + this.id = id; + } + } + + /** + * @return the id + */ + public int getId() { + return id; + } + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/DefaultNodeComparator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/DefaultNodeComparator.java similarity index 82% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/DefaultNodeComparator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/DefaultNodeComparator.java index fc79a5090a..72b3be558f 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/DefaultNodeComparator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/DefaultNodeComparator.java @@ -1,4 +1,4 @@ -package jaicore.search.model.travesaltree; +package ai.libs.jaicore.search.model.travesaltree; import java.util.Comparator; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/Edge.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/Edge.java similarity index 90% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/Edge.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/Edge.java index 15c8e0e271..3e3ec6e2de 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/Edge.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/Edge.java @@ -1,52 +1,52 @@ -package jaicore.search.model.travesaltree; - -public class Edge> { - - private final Node from, to; - - public Edge(Node from, Node to) { - super(); - this.from = from; - this.to = to; - } - - public Node getFrom() { - return from; - } - - public Node getTo() { - return to; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((from == null) ? 0 : from.hashCode()); - result = prime * result + ((to == null) ? 0 : to.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - @SuppressWarnings("unchecked") - Edge other = (Edge) obj; - if (from == null) { - if (other.from != null) - return false; - } else if (!from.equals(other.from)) - return false; - if (to == null) { - if (other.to != null) - return false; - } else if (!to.equals(other.to)) - return false; - return true; - } -} +package ai.libs.jaicore.search.model.travesaltree; + +public class Edge> { + + private final Node from, to; + + public Edge(Node from, Node to) { + super(); + this.from = from; + this.to = to; + } + + public Node getFrom() { + return from; + } + + public Node getTo() { + return to; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((from == null) ? 0 : from.hashCode()); + result = prime * result + ((to == null) ? 0 : to.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + @SuppressWarnings("unchecked") + Edge other = (Edge) obj; + if (from == null) { + if (other.from != null) + return false; + } else if (!from.equals(other.from)) + return false; + if (to == null) { + if (other.to != null) + return false; + } else if (!to.equals(other.to)) + return false; + return true; + } +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/GraphEventBus.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/GraphEventBus.java similarity index 62% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/GraphEventBus.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/GraphEventBus.java index 6aee0cfb45..4ed6058fad 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/GraphEventBus.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/GraphEventBus.java @@ -1,7 +1,7 @@ -package jaicore.search.model.travesaltree; - -import com.google.common.eventbus.EventBus; - -public class GraphEventBus extends EventBus { - -} +package ai.libs.jaicore.search.model.travesaltree; + +import com.google.common.eventbus.EventBus; + +public class GraphEventBus extends EventBus { + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/JaicoreNodeInfoGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/JaicoreNodeInfoGenerator.java similarity index 95% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/JaicoreNodeInfoGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/JaicoreNodeInfoGenerator.java index db88bb4067..5fef1cac84 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/JaicoreNodeInfoGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/JaicoreNodeInfoGenerator.java @@ -1,4 +1,4 @@ -package jaicore.search.model.travesaltree; +package ai.libs.jaicore.search.model.travesaltree; import java.lang.reflect.InvocationTargetException; import java.util.List; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/Node.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/Node.java similarity index 93% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/Node.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/Node.java index 26755cb663..a2d227613f 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/Node.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/Node.java @@ -1,4 +1,4 @@ -package jaicore.search.model.travesaltree; +package ai.libs.jaicore.search.model.travesaltree; import java.util.ArrayList; import java.util.HashMap; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/NodeExpansionDescription.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/NodeExpansionDescription.java similarity index 92% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/NodeExpansionDescription.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/NodeExpansionDescription.java index 0174fd47ce..64707a782d 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/NodeExpansionDescription.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/NodeExpansionDescription.java @@ -1,73 +1,73 @@ -package jaicore.search.model.travesaltree; - -public class NodeExpansionDescription { - - private final S from, to; - private final A action; - private final NodeType typeOfToNode; - - public NodeExpansionDescription(S from, S to, A action, NodeType typeOfToNode) { - super(); - this.from = from; - this.to = to; - this.action = action; - this.typeOfToNode = typeOfToNode; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((action == null) ? 0 : action.hashCode()); - result = prime * result + ((from == null) ? 0 : from.hashCode()); - result = prime * result + ((to == null) ? 0 : to.hashCode()); - result = prime * result + ((typeOfToNode == null) ? 0 : typeOfToNode.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - NodeExpansionDescription other = (NodeExpansionDescription) obj; - if (action == null) { - if (other.action != null) - return false; - } else if (!action.equals(other.action)) - return false; - if (from == null) { - if (other.from != null) - return false; - } else if (!from.equals(other.from)) - return false; - if (to == null) { - if (other.to != null) - return false; - } else if (!to.equals(other.to)) - return false; - if (typeOfToNode != other.typeOfToNode) - return false; - return true; - } - - public S getFrom() { - return from; - } - - public S getTo() { - return to; - } - - public A getAction() { - return action; - } - - public NodeType getTypeOfToNode() { - return typeOfToNode; - } - -} +package ai.libs.jaicore.search.model.travesaltree; + +public class NodeExpansionDescription { + + private final S from, to; + private final A action; + private final NodeType typeOfToNode; + + public NodeExpansionDescription(S from, S to, A action, NodeType typeOfToNode) { + super(); + this.from = from; + this.to = to; + this.action = action; + this.typeOfToNode = typeOfToNode; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((action == null) ? 0 : action.hashCode()); + result = prime * result + ((from == null) ? 0 : from.hashCode()); + result = prime * result + ((to == null) ? 0 : to.hashCode()); + result = prime * result + ((typeOfToNode == null) ? 0 : typeOfToNode.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NodeExpansionDescription other = (NodeExpansionDescription) obj; + if (action == null) { + if (other.action != null) + return false; + } else if (!action.equals(other.action)) + return false; + if (from == null) { + if (other.from != null) + return false; + } else if (!from.equals(other.from)) + return false; + if (to == null) { + if (other.to != null) + return false; + } else if (!to.equals(other.to)) + return false; + if (typeOfToNode != other.typeOfToNode) + return false; + return true; + } + + public S getFrom() { + return from; + } + + public S getTo() { + return to; + } + + public A getAction() { + return action; + } + + public NodeType getTypeOfToNode() { + return typeOfToNode; + } + +} diff --git a/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/NodeType.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/NodeType.java new file mode 100644 index 0000000000..21f51ba003 --- /dev/null +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/NodeType.java @@ -0,0 +1,5 @@ +package ai.libs.jaicore.search.model.travesaltree; + +public enum NodeType { + AND, OR +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/VersionedDomainNode.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/VersionedDomainNode.java similarity index 87% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/VersionedDomainNode.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/VersionedDomainNode.java index e7dc0db276..37670d2dfc 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/VersionedDomainNode.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/VersionedDomainNode.java @@ -1,58 +1,58 @@ -package jaicore.search.model.travesaltree; - -/** - * Wrapper class which adds an ID to the node - * @author jkoepe - * - * @param - */ -public class VersionedDomainNode { - - //variables - only the node and the id of the node - private T node; - private int id; - - public VersionedDomainNode(T node) { - this.node = node; - this.id = 0; - } - - public VersionedDomainNode(T node, int id) { - this.node = node; - this.id = id; - } - - /** - * @return the node - */ - public T getNode() { - return node; - } - - /** - * @param node the node to set - */ - public void setNode(T node) { - this.node = node; - } - - /** - * @return the id - */ - public int getId() { - return id; - } - - /** - * @param id the id to set - */ - public void setId(int id) { - if (id == 0) - this.id = id; - } - - - - - -} +package ai.libs.jaicore.search.model.travesaltree; + +/** + * Wrapper class which adds an ID to the node + * @author jkoepe + * + * @param + */ +public class VersionedDomainNode { + + //variables - only the node and the id of the node + private T node; + private int id; + + public VersionedDomainNode(T node) { + this.node = node; + this.id = 0; + } + + public VersionedDomainNode(T node, int id) { + this.node = node; + this.id = id; + } + + /** + * @return the node + */ + public T getNode() { + return node; + } + + /** + * @param node the node to set + */ + public void setNode(T node) { + this.node = node; + } + + /** + * @return the id + */ + public int getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(int id) { + if (id == 0) + this.id = id; + } + + + + + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/VersionedGraphGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/VersionedGraphGenerator.java similarity index 86% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/VersionedGraphGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/VersionedGraphGenerator.java index cbae30dff9..76d0924aa9 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/VersionedGraphGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/VersionedGraphGenerator.java @@ -1,4 +1,4 @@ -package jaicore.search.model.travesaltree; +package ai.libs.jaicore.search.model.travesaltree; import java.util.ArrayList; @@ -6,12 +6,12 @@ import java.util.List; import java.util.Random; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.structure.graphgenerator.MultipleRootGenerator; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.PathGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.MultipleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.PathGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; /** * Class which wraps up a normal GraphGenerator and is adding a id to every node diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/VersionedGraphGeneratorInterface.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/VersionedGraphGeneratorInterface.java similarity index 64% rename from JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/VersionedGraphGeneratorInterface.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/VersionedGraphGeneratorInterface.java index 80a2ef4ada..39b78c0dc4 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/VersionedGraphGeneratorInterface.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/model/travesaltree/VersionedGraphGeneratorInterface.java @@ -1,18 +1,18 @@ -/** - * - */ -package jaicore.search.model.travesaltree; - -import jaicore.search.core.interfaces.GraphGenerator; - -/** - * A Graphgenerator which is extended by versioning - * @author jkoepe - * - */ -public interface VersionedGraphGeneratorInterface extends GraphGenerator { - - public void setNodeNumbering(boolean numbering); - - -} +/** + * + */ +package ai.libs.jaicore.search.model.travesaltree; + +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; + +/** + * A Graphgenerator which is extended by versioning + * @author jkoepe + * + */ +public interface VersionedGraphGeneratorInterface extends GraphGenerator { + + public void setNodeNumbering(boolean numbering); + + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchInput.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchInput.java similarity index 80% rename from JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchInput.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchInput.java index 33cb949a99..2fffe83b89 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchInput.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchInput.java @@ -1,6 +1,6 @@ -package jaicore.search.probleminputs; +package ai.libs.jaicore.search.probleminputs; -import jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; /** * This input is provided to algorithms that should find a solution path in a graph without path cost. diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithNodeRecommenderInput.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithNodeRecommenderInput.java similarity index 76% rename from JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithNodeRecommenderInput.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithNodeRecommenderInput.java index 861a1c7b91..a3e983b9d8 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithNodeRecommenderInput.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithNodeRecommenderInput.java @@ -1,8 +1,8 @@ -package jaicore.search.probleminputs; +package ai.libs.jaicore.search.probleminputs; import java.util.Comparator; -import jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; public class GraphSearchWithNodeRecommenderInput extends GraphSearchInput { private final Comparator recommender; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluation.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluation.java similarity index 82% rename from JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluation.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluation.java index b29527bd03..c23b488748 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluation.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluation.java @@ -1,12 +1,12 @@ -package jaicore.search.probleminputs; +package ai.libs.jaicore.search.probleminputs; import java.util.Iterator; import java.util.List; -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.Node; public class GraphSearchWithNumberBasedAdditivePathEvaluation extends GraphSearchWithSubpathEvaluationsInput { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.java similarity index 86% rename from JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.java index 3a44ae9251..e0815fa323 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic.java @@ -1,11 +1,11 @@ -package jaicore.search.probleminputs; +package ai.libs.jaicore.search.probleminputs; import java.util.List; import ai.libs.jaicore.basic.IMetric; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.Node; public class GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic extends GraphSearchWithNumberBasedAdditivePathEvaluation { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithPathEvaluationsInput.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithPathEvaluationsInput.java similarity index 86% rename from JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithPathEvaluationsInput.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithPathEvaluationsInput.java index 18cdaf7d41..2795647a14 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithPathEvaluationsInput.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithPathEvaluationsInput.java @@ -1,12 +1,12 @@ -package jaicore.search.probleminputs; +package ai.libs.jaicore.search.probleminputs; import java.util.HashMap; import java.util.Map; import ai.libs.jaicore.basic.IObjectEvaluator; import ai.libs.jaicore.logging.ToJSONStringUtil; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.other.SearchGraphPath; /** * In AILibs, a graph search problem always aims at identifying one or more paths from diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithSubpathEvaluationsInput.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithSubpathEvaluationsInput.java similarity index 80% rename from JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithSubpathEvaluationsInput.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithSubpathEvaluationsInput.java index 1bc418af9a..42a1305ae7 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithSubpathEvaluationsInput.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithSubpathEvaluationsInput.java @@ -1,7 +1,7 @@ -package jaicore.search.probleminputs; +package ai.libs.jaicore.search.probleminputs; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; /** * Many algorithms such as best first and A* use a traversal tree to browse the underlying diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithUncertaintyBasedSubpathEvaluationInput.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithUncertaintyBasedSubpathEvaluationInput.java similarity index 60% rename from JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithUncertaintyBasedSubpathEvaluationInput.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithUncertaintyBasedSubpathEvaluationInput.java index f854817686..c225c15932 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/GraphSearchWithUncertaintyBasedSubpathEvaluationInput.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/GraphSearchWithUncertaintyBasedSubpathEvaluationInput.java @@ -1,7 +1,7 @@ -package jaicore.search.probleminputs; +package ai.libs.jaicore.search.probleminputs; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallyUncertaintyAnnotatingNodeEvaluator; -import jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallyUncertaintyAnnotatingNodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; public class GraphSearchWithUncertaintyBasedSubpathEvaluationInput> extends GraphSearchWithSubpathEvaluationsInput { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/builders/GraphSearchWithSubpathEvaluationsInputBuilder.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/builders/GraphSearchWithSubpathEvaluationsInputBuilder.java similarity index 75% rename from JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/builders/GraphSearchWithSubpathEvaluationsInputBuilder.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/builders/GraphSearchWithSubpathEvaluationsInputBuilder.java index b847124f53..4b3a6639a6 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/builders/GraphSearchWithSubpathEvaluationsInputBuilder.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/builders/GraphSearchWithSubpathEvaluationsInputBuilder.java @@ -1,7 +1,7 @@ -package jaicore.search.probleminputs.builders; +package ai.libs.jaicore.search.probleminputs.builders; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class GraphSearchWithSubpathEvaluationsInputBuilder> extends SearchProblemInputBuilder> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/builders/SearchProblemInputBuilder.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/builders/SearchProblemInputBuilder.java similarity index 65% rename from JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/builders/SearchProblemInputBuilder.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/builders/SearchProblemInputBuilder.java index 280a2768f9..39c11c37a9 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/probleminputs/builders/SearchProblemInputBuilder.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/probleminputs/builders/SearchProblemInputBuilder.java @@ -1,7 +1,7 @@ -package jaicore.search.probleminputs.builders; +package ai.libs.jaicore.search.probleminputs.builders; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; public abstract class SearchProblemInputBuilder> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformer.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformer.java similarity index 77% rename from JAICore/jaicore-search/src/main/java/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformer.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformer.java index 693cb09d18..848620b276 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformer.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformer.java @@ -1,10 +1,10 @@ -package jaicore.search.problemtransformers; +package ai.libs.jaicore.search.problemtransformers; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformer> implements AlgorithmicProblemReduction, EvaluatedSearchGraphPath, GraphSearchWithSubpathEvaluationsInput, EvaluatedSearchGraphPath> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS.java similarity index 80% rename from JAICore/jaicore-search/src/main/java/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS.java index 5500e0f477..c886b53384 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS.java @@ -1,13 +1,13 @@ -package jaicore.search.problemtransformers; +package ai.libs.jaicore.search.problemtransformers; import java.util.Random; import java.util.function.Predicate; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS> extends GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformer { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationViaUninformedness.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationViaUninformedness.java similarity index 67% rename from JAICore/jaicore-search/src/main/java/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationViaUninformedness.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationViaUninformedness.java index 8f92784d48..bf098f8fc9 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationViaUninformedness.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/problemtransformers/GraphSearchProblemInputToGraphSearchWithSubpathEvaluationViaUninformedness.java @@ -1,10 +1,10 @@ -package jaicore.search.problemtransformers; +package ai.libs.jaicore.search.problemtransformers; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class GraphSearchProblemInputToGraphSearchWithSubpathEvaluationViaUninformedness implements AlgorithmicProblemReduction, SearchGraphPath, GraphSearchWithSubpathEvaluationsInput, EvaluatedSearchGraphPath> { diff --git a/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/GoalTester.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/GoalTester.java new file mode 100644 index 0000000000..85755eb1a8 --- /dev/null +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/GoalTester.java @@ -0,0 +1,5 @@ +package ai.libs.jaicore.search.structure.graphgenerator; + +public interface GoalTester { + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/MultipleRootGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/MultipleRootGenerator.java similarity index 68% rename from JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/MultipleRootGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/MultipleRootGenerator.java index 034967a29d..86202a51d0 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/MultipleRootGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/MultipleRootGenerator.java @@ -1,7 +1,7 @@ -package jaicore.search.structure.graphgenerator; - -import java.util.Collection; - -public interface MultipleRootGenerator extends RootGenerator { - public Collection getRoots(); -} +package ai.libs.jaicore.search.structure.graphgenerator; + +import java.util.Collection; + +public interface MultipleRootGenerator extends RootGenerator { + public Collection getRoots(); +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/NodeGoalTester.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/NodeGoalTester.java similarity index 80% rename from JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/NodeGoalTester.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/NodeGoalTester.java index c4d3f23397..8470bc1313 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/NodeGoalTester.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/NodeGoalTester.java @@ -1,13 +1,13 @@ -package jaicore.search.structure.graphgenerator; - -public interface NodeGoalTester extends GoalTester { - - /** - * Check if the current node is a goal for the problem. - * - * @param node - * The node to check. - * @return true if it is a goal, false otherwise. - */ - public boolean isGoal(T node); -} +package ai.libs.jaicore.search.structure.graphgenerator; + +public interface NodeGoalTester extends GoalTester { + + /** + * Check if the current node is a goal for the problem. + * + * @param node + * The node to check. + * @return true if it is a goal, false otherwise. + */ + public boolean isGoal(T node); +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/PathGoalTester.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/PathGoalTester.java similarity index 81% rename from JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/PathGoalTester.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/PathGoalTester.java index c7bcf88854..4407b1833d 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/PathGoalTester.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/PathGoalTester.java @@ -1,15 +1,15 @@ -package jaicore.search.structure.graphgenerator; - -import java.util.List; - -public interface PathGoalTester extends GoalTester { - - /** - * Check if the current node is a goal for the problem. - * - * @param node - * The node to check. - * @return true if it is a goal, false otherwise. - */ - public boolean isGoal(List node); -} +package ai.libs.jaicore.search.structure.graphgenerator; + +import java.util.List; + +public interface PathGoalTester extends GoalTester { + + /** + * Check if the current node is a goal for the problem. + * + * @param node + * The node to check. + * @return true if it is a goal, false otherwise. + */ + public boolean isGoal(List node); +} diff --git a/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/RootGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/RootGenerator.java new file mode 100644 index 0000000000..d2c225d3f2 --- /dev/null +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/RootGenerator.java @@ -0,0 +1,5 @@ +package ai.libs.jaicore.search.structure.graphgenerator; + +public interface RootGenerator { + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SelfContained.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SelfContained.java similarity index 82% rename from JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SelfContained.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SelfContained.java index c423d5b4d4..835ead7c1e 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SelfContained.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SelfContained.java @@ -1,15 +1,15 @@ -package jaicore.search.structure.graphgenerator; - -public interface SelfContained { - - /** - * Indicates if the nodes are selfcontained for the solution or if the solution path is needed. - * - * @return - * true if every node contains every information needed for the solution, - * false otherwise. - * - */ - public boolean isSelfContained(); - -} +package ai.libs.jaicore.search.structure.graphgenerator; + +public interface SelfContained { + + /** + * Indicates if the nodes are selfcontained for the solution or if the solution path is needed. + * + * @return + * true if every node contains every information needed for the solution, + * false otherwise. + * + */ + public boolean isSelfContained(); + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SingleRootGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SingleRootGenerator.java similarity index 59% rename from JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SingleRootGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SingleRootGenerator.java index 2618cdba12..d2d368efdc 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SingleRootGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SingleRootGenerator.java @@ -1,5 +1,5 @@ -package jaicore.search.structure.graphgenerator; - -public interface SingleRootGenerator extends RootGenerator { - public T getRoot(); -} +package ai.libs.jaicore.search.structure.graphgenerator; + +public interface SingleRootGenerator extends RootGenerator { + public T getRoot(); +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SingleSuccessorGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SingleSuccessorGenerator.java similarity index 76% rename from JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SingleSuccessorGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SingleSuccessorGenerator.java index 1f53a8c06d..11b9d4a690 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SingleSuccessorGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SingleSuccessorGenerator.java @@ -1,18 +1,18 @@ -package jaicore.search.structure.graphgenerator; - -import jaicore.search.model.travesaltree.NodeExpansionDescription; - -public interface SingleSuccessorGenerator extends SuccessorGenerator { - - /** - * generate the (i%N)-th ungenerated successor of the given node where N is the number of existing successors that have not been generated before. - * - * returns null if no more successors exist. - * - * @param i - * @return - */ - public NodeExpansionDescription generateSuccessor(T node, int i) throws InterruptedException; - - public boolean allSuccessorsComputed(T node); -} +package ai.libs.jaicore.search.structure.graphgenerator; + +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; + +public interface SingleSuccessorGenerator extends SuccessorGenerator { + + /** + * generate the (i%N)-th ungenerated successor of the given node where N is the number of existing successors that have not been generated before. + * + * returns null if no more successors exist. + * + * @param i + * @return + */ + public NodeExpansionDescription generateSuccessor(T node, int i) throws InterruptedException; + + public boolean allSuccessorsComputed(T node); +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SubGraphGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SubGraphGenerator.java similarity index 86% rename from JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SubGraphGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SubGraphGenerator.java index b117ea0aef..e01294a333 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SubGraphGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SubGraphGenerator.java @@ -1,6 +1,6 @@ -package jaicore.search.structure.graphgenerator; +package ai.libs.jaicore.search.structure.graphgenerator; -import jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; /** * This is a graph generator that takes another graph generator and generates its sub-graph under a given root node diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SuccessorGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SuccessorGenerator.java similarity index 68% rename from JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SuccessorGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SuccessorGenerator.java index 00931750ee..0404c4b6c9 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/SuccessorGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/SuccessorGenerator.java @@ -1,20 +1,20 @@ -package jaicore.search.structure.graphgenerator; - -import java.util.List; - -import jaicore.search.model.travesaltree.NodeExpansionDescription; - -public interface SuccessorGenerator { - - - - /** - * Generate the successors for a given node. - * - * @param node The node we want to expand. - * @return A list of possible next steps. - */ - public List> generateSuccessors(T node) throws InterruptedException; - - -} +package ai.libs.jaicore.search.structure.graphgenerator; + +import java.util.List; + +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; + +public interface SuccessorGenerator { + + + + /** + * Generate the successors for a given node. + * + * @param node The node we want to expand. + * @return A list of possible next steps. + */ + public List> generateSuccessors(T node) throws InterruptedException; + + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/TimeAwareSuccessorGenerator.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/TimeAwareSuccessorGenerator.java similarity index 76% rename from JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/TimeAwareSuccessorGenerator.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/TimeAwareSuccessorGenerator.java index 8bb44c5f33..1cc4e66b2b 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/TimeAwareSuccessorGenerator.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/structure/graphgenerator/TimeAwareSuccessorGenerator.java @@ -1,20 +1,20 @@ -package jaicore.search.structure.graphgenerator; - -import java.util.Collection; -import java.util.concurrent.TimeoutException; - -import jaicore.search.model.travesaltree.NodeExpansionDescription; - -/** - * Successor generation may be costly. - * TimeAware successor generators can generate successors until a certain time bound is hit. - * - * @author fmohr - * - * @param - * @param - */ -public interface TimeAwareSuccessorGenerator extends SuccessorGenerator { - - public Collection> generateSuccessors(N node, long timeAvailable) throws InterruptedException, TimeoutException; -} +package ai.libs.jaicore.search.structure.graphgenerator; + +import java.util.Collection; +import java.util.concurrent.TimeoutException; + +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; + +/** + * Successor generation may be costly. + * TimeAware successor generators can generate successors until a certain time bound is hit. + * + * @author fmohr + * + * @param + * @param + */ +public interface TimeAwareSuccessorGenerator extends SuccessorGenerator { + + public Collection> generateSuccessors(N node, long timeAvailable) throws InterruptedException, TimeoutException; +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/util/CycleDetectedResult.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/CycleDetectedResult.java similarity index 89% rename from JAICore/jaicore-search/src/main/java/jaicore/search/util/CycleDetectedResult.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/CycleDetectedResult.java index 236ac64093..35c33bd6c4 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/util/CycleDetectedResult.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/CycleDetectedResult.java @@ -1,4 +1,4 @@ -package jaicore.search.util; +package ai.libs.jaicore.search.util; import java.util.List; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/util/DeadEndDetectedResult.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/DeadEndDetectedResult.java similarity index 85% rename from JAICore/jaicore-search/src/main/java/jaicore/search/util/DeadEndDetectedResult.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/DeadEndDetectedResult.java index 1c8efe1aaf..21028c372d 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/util/DeadEndDetectedResult.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/DeadEndDetectedResult.java @@ -1,4 +1,4 @@ -package jaicore.search.util; +package ai.libs.jaicore.search.util; public class DeadEndDetectedResult extends SanityCheckResult { private final N deadEnd; diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/util/GraphSanityChecker.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/GraphSanityChecker.java similarity index 86% rename from JAICore/jaicore-search/src/main/java/jaicore/search/util/GraphSanityChecker.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/GraphSanityChecker.java index a729bf2bbd..0c1f556522 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/util/GraphSanityChecker.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/GraphSanityChecker.java @@ -1,4 +1,4 @@ -package jaicore.search.util; +package ai.libs.jaicore.search.util; import java.util.List; import java.util.Stack; @@ -10,12 +10,12 @@ import ai.libs.jaicore.graphvisualizer.events.graph.GraphInitializedEvent; import ai.libs.jaicore.graphvisualizer.events.graph.NodeAddedEvent; import ai.libs.jaicore.graphvisualizer.events.graph.NodeTypeSwitchEvent; -import jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.core.interfaces.AOptimalPathInORGraphSearch; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; public class GraphSanityChecker extends AOptimalPathInORGraphSearch, N, A, Double> { diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/util/GraphSeemsSaneResult.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/GraphSeemsSaneResult.java similarity index 61% rename from JAICore/jaicore-search/src/main/java/jaicore/search/util/GraphSeemsSaneResult.java rename to JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/GraphSeemsSaneResult.java index 242372a6fb..dc393a9efd 100644 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/util/GraphSeemsSaneResult.java +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/GraphSeemsSaneResult.java @@ -1,4 +1,4 @@ -package jaicore.search.util; +package ai.libs.jaicore.search.util; public class GraphSeemsSaneResult extends SanityCheckResult { diff --git a/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/SanityCheckResult.java b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/SanityCheckResult.java new file mode 100644 index 0000000000..7db407ffe9 --- /dev/null +++ b/JAICore/jaicore-search/src/main/java/ai/libs/jaicore/search/util/SanityCheckResult.java @@ -0,0 +1,5 @@ +package ai.libs.jaicore.search.util; + +public class SanityCheckResult { + +} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributionSearchAdapter.java b/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributionSearchAdapter.java deleted file mode 100644 index 5ac9bc8540..0000000000 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/DistributionSearchAdapter.java +++ /dev/null @@ -1,11 +0,0 @@ -package jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces; - -import java.util.Collection; - -import jaicore.search.algorithms.parallel.parallelexploration.distributed.DistributedComputationResult; -import jaicore.search.model.travesaltree.Node; - -public interface DistributionSearchAdapter> { - public Collection> nextJob(); - public void processResult(Collection> job, DistributedComputationResult result); -} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableGraphGenerator.java b/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableGraphGenerator.java deleted file mode 100644 index 76102c6ec8..0000000000 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableGraphGenerator.java +++ /dev/null @@ -1,9 +0,0 @@ -package jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces; - -import java.io.Serializable; - -import jaicore.search.core.interfaces.GraphGenerator; - -public interface SerializableGraphGenerator extends GraphGenerator, Serializable { - -} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableNodeEvaluator.java b/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableNodeEvaluator.java deleted file mode 100644 index 987759cf84..0000000000 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableNodeEvaluator.java +++ /dev/null @@ -1,9 +0,0 @@ -package jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces; - -import java.io.Serializable; - -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; - -public interface SerializableNodeEvaluator> extends INodeEvaluator, Serializable { - -} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableRootGenerator.java b/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableRootGenerator.java deleted file mode 100644 index b97d3844fc..0000000000 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/parallel/parallelexploration/distributed/interfaces/SerializableRootGenerator.java +++ /dev/null @@ -1,9 +0,0 @@ -package jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces; - -import java.io.Serializable; - -import jaicore.search.structure.graphgenerator.SingleRootGenerator; - -public interface SerializableRootGenerator extends SingleRootGenerator, Serializable { - -} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/astar/AStarEdgeCost.java b/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/astar/AStarEdgeCost.java deleted file mode 100644 index 4d2bd72bac..0000000000 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/astar/AStarEdgeCost.java +++ /dev/null @@ -1,7 +0,0 @@ -package jaicore.search.algorithms.standard.astar; - -import jaicore.search.model.travesaltree.Node; - -public interface AStarEdgeCost { - public double g(Node from, Node to); -} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/INodeEvaluator.java b/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/INodeEvaluator.java deleted file mode 100644 index 212b186feb..0000000000 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/algorithms/standard/bestfirst/nodeevaluation/INodeEvaluator.java +++ /dev/null @@ -1,8 +0,0 @@ -package jaicore.search.algorithms.standard.bestfirst.nodeevaluation; - -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.model.travesaltree.Node; - -public interface INodeEvaluator> { - public V f(Node node) throws NodeEvaluationException, InterruptedException; -} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/NodeType.java b/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/NodeType.java deleted file mode 100644 index fbeed09e38..0000000000 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/model/travesaltree/NodeType.java +++ /dev/null @@ -1,5 +0,0 @@ -package jaicore.search.model.travesaltree; - -public enum NodeType { - AND, OR -} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/GoalTester.java b/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/GoalTester.java deleted file mode 100644 index 3bcd2c7262..0000000000 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/GoalTester.java +++ /dev/null @@ -1,5 +0,0 @@ -package jaicore.search.structure.graphgenerator; - -public interface GoalTester { - -} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/RootGenerator.java b/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/RootGenerator.java deleted file mode 100644 index a80253e3c1..0000000000 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/structure/graphgenerator/RootGenerator.java +++ /dev/null @@ -1,5 +0,0 @@ -package jaicore.search.structure.graphgenerator; - -public interface RootGenerator { - -} diff --git a/JAICore/jaicore-search/src/main/java/jaicore/search/util/SanityCheckResult.java b/JAICore/jaicore-search/src/main/java/jaicore/search/util/SanityCheckResult.java deleted file mode 100644 index efc55698b6..0000000000 --- a/JAICore/jaicore-search/src/main/java/jaicore/search/util/SanityCheckResult.java +++ /dev/null @@ -1,5 +0,0 @@ -package jaicore.search.util; - -public class SanityCheckResult { - -} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/GraphGeneratorTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/GraphGeneratorTester.java index bb406faec1..5f59c24d7c 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/GraphGeneratorTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/GraphGeneratorTester.java @@ -11,10 +11,10 @@ import ai.libs.jaicore.basic.sets.SetUtil.Pair; import ai.libs.jaicore.graph.LabeledGraph; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; public abstract class GraphGeneratorTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GeneralGraphSearchAlgorithmTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GeneralGraphSearchAlgorithmTester.java index 07ed1130b1..86f8b44e15 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GeneralGraphSearchAlgorithmTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GeneralGraphSearchAlgorithmTester.java @@ -9,11 +9,11 @@ import ai.libs.jaicore.basic.algorithm.GeneralAlgorithmTester; import ai.libs.jaicore.basic.algorithm.IAlgorithm; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; import ai.libs.jaicore.search.testproblems.enhancedttsp.EnhancedTTSPAsGraphSearchSet; import ai.libs.jaicore.search.testproblems.knapsack.KnapsackProblemAsGraphSearchSet; import ai.libs.jaicore.search.testproblems.nqueens.NQueensProblemAsGraphSearchSet; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchInput; public abstract class GeneralGraphSearchAlgorithmTester extends GeneralAlgorithmTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchSingleSolutionTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchSingleSolutionTester.java index 3d581aa549..a9d8b6ecc1 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchSingleSolutionTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchSingleSolutionTester.java @@ -9,11 +9,11 @@ import ai.libs.jaicore.basic.algorithm.IAlgorithm; import ai.libs.jaicore.basic.algorithm.SolutionCandidateFinderTester; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; import ai.libs.jaicore.search.testproblems.enhancedttsp.EnhancedTTSPAsGraphSearchSet; import ai.libs.jaicore.search.testproblems.knapsack.KnapsackProblemAsGraphSearchSet; import ai.libs.jaicore.search.testproblems.nqueens.NQueensProblemAsGraphSearchSet; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchInput; public abstract class GraphSearchSingleSolutionTester extends SolutionCandidateFinderTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchSolutionIteratorTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchSolutionIteratorTester.java index 6bc41c7072..0c930c56ab 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchSolutionIteratorTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchSolutionIteratorTester.java @@ -9,11 +9,11 @@ import ai.libs.jaicore.basic.algorithm.IAlgorithm; import ai.libs.jaicore.basic.algorithm.SolutionCandidateIteratorTester; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; import ai.libs.jaicore.search.testproblems.enhancedttsp.EnhancedTTSPAsGraphSearchSet; import ai.libs.jaicore.search.testproblems.knapsack.KnapsackProblemAsGraphSearchSet; import ai.libs.jaicore.search.testproblems.nqueens.NQueensProblemAsGraphSearchSet; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchInput; public abstract class GraphSearchSolutionIteratorTester extends SolutionCandidateIteratorTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchWithSubPathEvaluationUninformedTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchWithSubPathEvaluationUninformedTester.java index 005984bdf4..7a4b71cf77 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchWithSubPathEvaluationUninformedTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/GraphSearchWithSubPathEvaluationUninformedTester.java @@ -1,8 +1,8 @@ package ai.libs.jaicore.search.algorithms; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public abstract class GraphSearchWithSubPathEvaluationUninformedTester extends GraphSearchSolutionIteratorTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/andor/AndOrTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/andor/AndOrTester.java index 54429cc28e..1e6f8033fd 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/andor/AndOrTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/andor/AndOrTester.java @@ -6,11 +6,11 @@ import ai.libs.jaicore.basic.IObjectEvaluator; import ai.libs.jaicore.graph.Graph; +import ai.libs.jaicore.search.algorithms.andor.AndORBottomUpFilter; import ai.libs.jaicore.search.algorithms.andor.SyntheticAndGrid.NodeLabel; -import jaicore.search.algorithms.andor.AndORBottomUpFilter; -import jaicore.search.algorithms.standard.bestfirst.BestFirst; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.BestFirst; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class AndOrTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/andor/SyntheticAndGrid.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/andor/SyntheticAndGrid.java index 803ff6efea..d157f82508 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/andor/SyntheticAndGrid.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/andor/SyntheticAndGrid.java @@ -4,12 +4,12 @@ import java.util.List; import ai.libs.jaicore.search.algorithms.andor.SyntheticAndGrid.NodeLabel; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; public class SyntheticAndGrid implements GraphGenerator { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/clustertest/DistributedBestFirstClusterTesterGenerator.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/clustertest/DistributedBestFirstClusterTesterGenerator.java index a91757dc80..bf2e2fd418 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/clustertest/DistributedBestFirstClusterTesterGenerator.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/parallel/parallelexploration/distributed/clustertest/DistributedBestFirstClusterTesterGenerator.java @@ -3,13 +3,13 @@ import java.util.ArrayList; import java.util.List; -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableRootGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.RootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableRootGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.RootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; @SuppressWarnings("serial") public class DistributedBestFirstClusterTesterGenerator implements SerializableGraphGenerator { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/astar/AStarTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/astar/AStarTester.java index e668563b53..8cf8fbd526 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/astar/AStarTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/astar/AStarTester.java @@ -1,10 +1,10 @@ package ai.libs.jaicore.search.algorithms.standard.astar; import ai.libs.jaicore.search.algorithms.GraphSearchSolutionIteratorTester; -import jaicore.search.algorithms.standard.astar.AStar; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; +import ai.libs.jaicore.search.algorithms.standard.astar.AStar; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; public class AStarTester extends GraphSearchSolutionIteratorTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/awastar/AwaTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/awastar/AwaTester.java index 0a5bb81513..c35f310422 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/awastar/AwaTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/awastar/AwaTester.java @@ -1,9 +1,9 @@ package ai.libs.jaicore.search.algorithms.standard.awastar; import ai.libs.jaicore.search.algorithms.GraphSearchWithSubPathEvaluationUninformedTester; -import jaicore.search.algorithms.standard.awastar.AwaStarSearch; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.awastar.AwaStarSearch; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class AwaTester extends GraphSearchWithSubPathEvaluationUninformedTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/NodeEvaluatorTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/NodeEvaluatorTester.java index 57748327fa..04f448c056 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/NodeEvaluatorTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/NodeEvaluatorTester.java @@ -1,76 +1,76 @@ -package ai.libs.jaicore.search.algorithms.standard.bestfirst; - -import static org.junit.Assert.assertTrue; - -import java.util.Collection; -import java.util.Timer; -import java.util.TimerTask; - -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import ai.libs.jaicore.basic.ILoggingCustomizable; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; -import ai.libs.jaicore.interrupt.Interrupter; -import ai.libs.jaicore.interrupt.InterruptionTimerTask; -import ai.libs.jaicore.search.testproblems.nqueens.NQueensGraphGenerator; -import ai.libs.jaicore.search.testproblems.nqueens.QueenNode; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; - -public abstract class NodeEvaluatorTester> { - - private static final Logger logger = LoggerFactory.getLogger(NodeEvaluatorTester.class); - private static final int INTERRUPT_TRIGGER = 3000; - private static final int INTERRUPT_TOLERANCE = 50; - - public abstract N getNodeEvaluator(); - - public abstract N getBusyNodeEvaluator(); - - public abstract Collection> getNodesToTest(N nodeEvaluator); - - @Test - public void testInterruptibility() - throws InterruptedException, AlgorithmException { - - N ne = this.getBusyNodeEvaluator(); - if (ne instanceof ILoggingCustomizable) { - ((ILoggingCustomizable) ne).setLoggerName("testednodeevaluator"); - } - for (Node node : this.getNodesToTest(ne)) { - - Timer t = new Timer(); - TimerTask task = new InterruptionTimerTask("Interrupting busy evaluator"); - t.schedule(task, INTERRUPT_TRIGGER); - long start = System.currentTimeMillis(); - try { - logger.info("Starting evaluation of root"); - ne.f(node); - assert false : "Either the node evaluation has caught and suppressed the InterruptedException, or the evaluation only took " - + (System.currentTimeMillis() - start) + "ms, which was not enough to trigger the interrupt."; - } catch (InterruptedException e) { - if (Interrupter.get().hasCurrentThreadBeenInterruptedWithReason(task)) { - long runtime = System.currentTimeMillis() - start; - assertTrue("The interrupt took " + (runtime - INTERRUPT_TRIGGER) + "ms to be processed.", - runtime < INTERRUPT_TRIGGER + INTERRUPT_TOLERANCE); - logger.info("Interruption registered. Runtime was {}ms", runtime); - } else { - throw e; - } - } - t.cancel(); - } - } - - public StandardBestFirst getBF(final INodeEvaluator ne) { - GraphSearchWithSubpathEvaluationsInput input = new GraphSearchWithSubpathEvaluationsInput<>( - new NQueensGraphGenerator(5), ne); // there will be 10 solutions - StandardBestFirst bf = new StandardBestFirst<>(input); - bf.setNumCPUs(1); - return bf; - } -} +package ai.libs.jaicore.search.algorithms.standard.bestfirst; + +import static org.junit.Assert.assertTrue; + +import java.util.Collection; +import java.util.Timer; +import java.util.TimerTask; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ai.libs.jaicore.basic.ILoggingCustomizable; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; +import ai.libs.jaicore.interrupt.Interrupter; +import ai.libs.jaicore.interrupt.InterruptionTimerTask; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.testproblems.nqueens.NQueensGraphGenerator; +import ai.libs.jaicore.search.testproblems.nqueens.QueenNode; + +public abstract class NodeEvaluatorTester> { + + private static final Logger logger = LoggerFactory.getLogger(NodeEvaluatorTester.class); + private static final int INTERRUPT_TRIGGER = 3000; + private static final int INTERRUPT_TOLERANCE = 50; + + public abstract N getNodeEvaluator(); + + public abstract N getBusyNodeEvaluator(); + + public abstract Collection> getNodesToTest(N nodeEvaluator); + + @Test + public void testInterruptibility() + throws InterruptedException, AlgorithmException { + + N ne = this.getBusyNodeEvaluator(); + if (ne instanceof ILoggingCustomizable) { + ((ILoggingCustomizable) ne).setLoggerName("testednodeevaluator"); + } + for (Node node : this.getNodesToTest(ne)) { + + Timer t = new Timer(); + TimerTask task = new InterruptionTimerTask("Interrupting busy evaluator"); + t.schedule(task, INTERRUPT_TRIGGER); + long start = System.currentTimeMillis(); + try { + logger.info("Starting evaluation of root"); + ne.f(node); + assert false : "Either the node evaluation has caught and suppressed the InterruptedException, or the evaluation only took " + + (System.currentTimeMillis() - start) + "ms, which was not enough to trigger the interrupt."; + } catch (InterruptedException e) { + if (Interrupter.get().hasCurrentThreadBeenInterruptedWithReason(task)) { + long runtime = System.currentTimeMillis() - start; + assertTrue("The interrupt took " + (runtime - INTERRUPT_TRIGGER) + "ms to be processed.", + runtime < INTERRUPT_TRIGGER + INTERRUPT_TOLERANCE); + logger.info("Interruption registered. Runtime was {}ms", runtime); + } else { + throw e; + } + } + t.cancel(); + } + } + + public StandardBestFirst getBF(final INodeEvaluator ne) { + GraphSearchWithSubpathEvaluationsInput input = new GraphSearchWithSubpathEvaluationsInput<>( + new NQueensGraphGenerator(5), ne); // there will be 10 solutions + StandardBestFirst bf = new StandardBestFirst<>(input); + bf.setNumCPUs(1); + return bf; + } +} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/RandomCompletionNodeEvaluatorTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/RandomCompletionNodeEvaluatorTester.java index 55ef8a4490..8dc1d11a3f 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/RandomCompletionNodeEvaluatorTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/RandomCompletionNodeEvaluatorTester.java @@ -1,164 +1,164 @@ -package ai.libs.jaicore.search.algorithms.standard.bestfirst; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Random; -import java.util.Set; - -import org.junit.Test; - -import com.google.common.eventbus.Subscribe; - -import ai.libs.jaicore.basic.BusyObjectEvaluator; -import ai.libs.jaicore.basic.IObjectEvaluator; -import ai.libs.jaicore.basic.PartiallyFailingObjectEvaluator; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; -import ai.libs.jaicore.basic.algorithm.exceptions.ObjectEvaluationFailedException; -import ai.libs.jaicore.basic.sets.SetUtil; -import ai.libs.jaicore.search.testproblems.nqueens.QueenNode; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; -import jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.model.travesaltree.Node; - -public class RandomCompletionNodeEvaluatorTester extends TimeAwareNodeEvaluatorTester> { - - @Test - public void testThatEvaluationDependsOnSeed() throws NodeEvaluationException, InterruptedException { - - Set seenScores = new HashSet<>(); - for (int seed = 0; seed < 5; seed++) { - RandomCompletionBasedNodeEvaluator ne = this.getSeededNodeEvaluator(seed, 10); - for (Node node : this.getNodesToTest(ne)) { - Double score = ne.f(node); - assertTrue("Score " + score + " has already been seen.", !seenScores.contains(score)); - seenScores.add(score); - } - } - } - - @Test - /** - * This tests over several invocations that all solutions are produced exactly - * once. - * - * This includes, as a special case, that a single call will not produce and - * evaluation any solution more than once - * - * @throws NodeEvaluationException - * @throws InterruptedException - */ - public void testDuplicateFreeEnumeration() throws NodeEvaluationException, InterruptedException { - - /* this is cheap, test it several times */ - for (int seed = 0; seed < 5; seed++) { - List> seenSolutions = new ArrayList<>(); - RandomCompletionBasedNodeEvaluator ne = this.getSeededNodeEvaluator(seed, 20); // draw (up to 20 examples), but only 10 solutions exist - ne.setLoggerName("testednodeevaluator"); - ne.registerSolutionListener(new Object() { - @Subscribe - public void receiveSolution(final EvaluatedSearchSolutionCandidateFoundEvent e) { - List solution = e.getSolutionCandidate().getNodes(); - seenSolutions.add(solution); - } - }); - Collection> openNodes = this.getNodesToTest(ne); - assert openNodes.size() == 5 : "open size should be 2 but is " + openNodes.size(); - - /* now collect solutions */ - for (Node node : openNodes) { - ne.f(node); - } - - /* check that all solutions have been enumerated exactly once */ - Set> solutionSet = new HashSet<>(seenSolutions); - assertEquals("The number of found solutions deviates from the sample size!", 10, seenSolutions.size()); - assertEquals("The items " + SetUtil.intersection(solutionSet, seenSolutions) + " solutions found by the completer.", solutionSet.size(), seenSolutions.size()); - } - } - - @Test - public void testThatAScoreIsReturnedIfExactlyOneSampleSucceeds() throws NodeEvaluationException, InterruptedException { - int numSamples = 1; - for (int seed = 0; seed < 1; seed++) { - for (int successfulInvocation = 1; successfulInvocation <= numSamples; successfulInvocation++) { - Set> seenSolutions = new HashSet<>(); - List seenScores = new ArrayList<>(); - List successfulInvocations = new ArrayList<>(); - successfulInvocations.add(successfulInvocation); - RandomCompletionBasedNodeEvaluator ne = this.getNodeEvaluator(new PartiallyFailingObjectEvaluator<>(successfulInvocations, 0.0), seed, numSamples, -1); - ne.setLoggerName("testednodeevaluator"); - ne.registerSolutionListener(new Object() { - @Subscribe - public void receiveSolution(final EvaluatedSearchSolutionCandidateFoundEvent e) { - List solution = e.getSolutionCandidate().getNodes(); - seenSolutions.add(solution); - } - }); - for (Node node : this.getNodesToTest(ne)) { - try { - Double score = ne.f(node); - seenScores.add(score); - } catch (NodeEvaluationException e) { - - /* we expect this to happen for some cases */ - if (!(e.getCause() instanceof NoSuchElementException)) - throw e; - } - } - assertEquals("There should be exactly one solution.", 1, seenSolutions.size()); - assertEquals(1, seenScores.size()); - } - } - } - - public RandomCompletionBasedNodeEvaluator getNodeEvaluator(final IObjectEvaluator, Double> oe, final int seed, final int numSamples, final int timeoutForNodeEvaluationInMs) { - IObjectEvaluator, Double> se = new IObjectEvaluator, Double>() { - - @Override - public Double evaluate(final SearchGraphPath solutionPath) throws InterruptedException, ObjectEvaluationFailedException { - return oe.evaluate(solutionPath); - } - }; - return new RandomCompletionBasedNodeEvaluator<>(new Random(seed), numSamples, se, -1, timeoutForNodeEvaluationInMs); - } - - public RandomCompletionBasedNodeEvaluator getSeededNodeEvaluator(final int seed, final int numSamples) { - return this.getNodeEvaluator(n -> Math.random(), seed, numSamples, -1); - } - - @Override - public RandomCompletionBasedNodeEvaluator getNodeEvaluator() { - return this.getSeededNodeEvaluator(0, 3); - } - - @Override - public RandomCompletionBasedNodeEvaluator getBusyNodeEvaluator() { - return this.getTimedNodeEvaluator(-1); - } - - @Override - public RandomCompletionBasedNodeEvaluator getTimedNodeEvaluator(final int timeoutInMS) { - return this.getNodeEvaluator(new BusyObjectEvaluator<>(), 0, 3, timeoutInMS); - } - - @Override - public Collection> getNodesToTest(final RandomCompletionBasedNodeEvaluator ne) { - StandardBestFirst bf = this.getBF(new AlternativeNodeEvaluator<>(n -> 0.0, ne)); // the n -> 0.0 is not really used except for efficient initialization - bf.setLoggerName("testedalgorithm"); - bf.next(); - bf.next(); - Collection> nodes = new ArrayList<>(); - nodes.addAll(bf.getOpen()); - return nodes; - } -} +package ai.libs.jaicore.search.algorithms.standard.bestfirst; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Random; +import java.util.Set; + +import org.junit.Test; + +import com.google.common.eventbus.Subscribe; + +import ai.libs.jaicore.basic.BusyObjectEvaluator; +import ai.libs.jaicore.basic.IObjectEvaluator; +import ai.libs.jaicore.basic.PartiallyFailingObjectEvaluator; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; +import ai.libs.jaicore.basic.algorithm.exceptions.ObjectEvaluationFailedException; +import ai.libs.jaicore.basic.sets.SetUtil; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.testproblems.nqueens.QueenNode; + +public class RandomCompletionNodeEvaluatorTester extends TimeAwareNodeEvaluatorTester> { + + @Test + public void testThatEvaluationDependsOnSeed() throws NodeEvaluationException, InterruptedException { + + Set seenScores = new HashSet<>(); + for (int seed = 0; seed < 5; seed++) { + RandomCompletionBasedNodeEvaluator ne = this.getSeededNodeEvaluator(seed, 10); + for (Node node : this.getNodesToTest(ne)) { + Double score = ne.f(node); + assertTrue("Score " + score + " has already been seen.", !seenScores.contains(score)); + seenScores.add(score); + } + } + } + + @Test + /** + * This tests over several invocations that all solutions are produced exactly + * once. + * + * This includes, as a special case, that a single call will not produce and + * evaluation any solution more than once + * + * @throws NodeEvaluationException + * @throws InterruptedException + */ + public void testDuplicateFreeEnumeration() throws NodeEvaluationException, InterruptedException { + + /* this is cheap, test it several times */ + for (int seed = 0; seed < 5; seed++) { + List> seenSolutions = new ArrayList<>(); + RandomCompletionBasedNodeEvaluator ne = this.getSeededNodeEvaluator(seed, 20); // draw (up to 20 examples), but only 10 solutions exist + ne.setLoggerName("testednodeevaluator"); + ne.registerSolutionListener(new Object() { + @Subscribe + public void receiveSolution(final EvaluatedSearchSolutionCandidateFoundEvent e) { + List solution = e.getSolutionCandidate().getNodes(); + seenSolutions.add(solution); + } + }); + Collection> openNodes = this.getNodesToTest(ne); + assert openNodes.size() == 5 : "open size should be 2 but is " + openNodes.size(); + + /* now collect solutions */ + for (Node node : openNodes) { + ne.f(node); + } + + /* check that all solutions have been enumerated exactly once */ + Set> solutionSet = new HashSet<>(seenSolutions); + assertEquals("The number of found solutions deviates from the sample size!", 10, seenSolutions.size()); + assertEquals("The items " + SetUtil.intersection(solutionSet, seenSolutions) + " solutions found by the completer.", solutionSet.size(), seenSolutions.size()); + } + } + + @Test + public void testThatAScoreIsReturnedIfExactlyOneSampleSucceeds() throws NodeEvaluationException, InterruptedException { + int numSamples = 1; + for (int seed = 0; seed < 1; seed++) { + for (int successfulInvocation = 1; successfulInvocation <= numSamples; successfulInvocation++) { + Set> seenSolutions = new HashSet<>(); + List seenScores = new ArrayList<>(); + List successfulInvocations = new ArrayList<>(); + successfulInvocations.add(successfulInvocation); + RandomCompletionBasedNodeEvaluator ne = this.getNodeEvaluator(new PartiallyFailingObjectEvaluator<>(successfulInvocations, 0.0), seed, numSamples, -1); + ne.setLoggerName("testednodeevaluator"); + ne.registerSolutionListener(new Object() { + @Subscribe + public void receiveSolution(final EvaluatedSearchSolutionCandidateFoundEvent e) { + List solution = e.getSolutionCandidate().getNodes(); + seenSolutions.add(solution); + } + }); + for (Node node : this.getNodesToTest(ne)) { + try { + Double score = ne.f(node); + seenScores.add(score); + } catch (NodeEvaluationException e) { + + /* we expect this to happen for some cases */ + if (!(e.getCause() instanceof NoSuchElementException)) + throw e; + } + } + assertEquals("There should be exactly one solution.", 1, seenSolutions.size()); + assertEquals(1, seenScores.size()); + } + } + } + + public RandomCompletionBasedNodeEvaluator getNodeEvaluator(final IObjectEvaluator, Double> oe, final int seed, final int numSamples, final int timeoutForNodeEvaluationInMs) { + IObjectEvaluator, Double> se = new IObjectEvaluator, Double>() { + + @Override + public Double evaluate(final SearchGraphPath solutionPath) throws InterruptedException, ObjectEvaluationFailedException { + return oe.evaluate(solutionPath); + } + }; + return new RandomCompletionBasedNodeEvaluator<>(new Random(seed), numSamples, se, -1, timeoutForNodeEvaluationInMs); + } + + public RandomCompletionBasedNodeEvaluator getSeededNodeEvaluator(final int seed, final int numSamples) { + return this.getNodeEvaluator(n -> Math.random(), seed, numSamples, -1); + } + + @Override + public RandomCompletionBasedNodeEvaluator getNodeEvaluator() { + return this.getSeededNodeEvaluator(0, 3); + } + + @Override + public RandomCompletionBasedNodeEvaluator getBusyNodeEvaluator() { + return this.getTimedNodeEvaluator(-1); + } + + @Override + public RandomCompletionBasedNodeEvaluator getTimedNodeEvaluator(final int timeoutInMS) { + return this.getNodeEvaluator(new BusyObjectEvaluator<>(), 0, 3, timeoutInMS); + } + + @Override + public Collection> getNodesToTest(final RandomCompletionBasedNodeEvaluator ne) { + StandardBestFirst bf = this.getBF(new AlternativeNodeEvaluator<>(n -> 0.0, ne)); // the n -> 0.0 is not really used except for efficient initialization + bf.setLoggerName("testedalgorithm"); + bf.next(); + bf.next(); + Collection> nodes = new ArrayList<>(); + nodes.addAll(bf.getOpen()); + return nodes; + } +} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/RolloutBasedBestFirstTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/RolloutBasedBestFirstTester.java index ce2b499c97..aacb598ae7 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/RolloutBasedBestFirstTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/RolloutBasedBestFirstTester.java @@ -3,13 +3,13 @@ import java.util.Random; import ai.libs.jaicore.search.algorithms.GraphSearchSolutionIteratorTester; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.model.other.AgnosticPathEvaluator; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.model.other.AgnosticPathEvaluator; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class RolloutBasedBestFirstTester extends GraphSearchSolutionIteratorTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/TimeAwareNodeEvaluatorTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/TimeAwareNodeEvaluatorTester.java index e98ef9611c..961cc57ee5 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/TimeAwareNodeEvaluatorTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/TimeAwareNodeEvaluatorTester.java @@ -1,35 +1,35 @@ -package ai.libs.jaicore.search.algorithms.standard.bestfirst; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import ai.libs.jaicore.search.testproblems.nqueens.QueenNode; -import ai.libs.jaicore.timing.TimedComputation; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.TimeAwareNodeEvaluator; -import jaicore.search.model.travesaltree.Node; - -public abstract class TimeAwareNodeEvaluatorTester> extends NodeEvaluatorTester { - - private static final Logger logger = LoggerFactory.getLogger(TimeAwareNodeEvaluatorTester.class); - - private static final int TIMEOUT = 3000; - private static final int TOLERANCE = 50; - - public abstract T getTimedNodeEvaluator(int timeoutInMS); - - @Test - public void testTimeoutAdherence() throws InterruptedException, ExecutionException, TimeoutException { - T ne = this.getTimedNodeEvaluator(TIMEOUT); - ne.setLoggerName("testednodeevaluator"); - for (Node node : this.getNodesToTest(ne)) { - long start = System.currentTimeMillis(); - logger.info("Starting computation of score for node with hash code {} with timeout {}", node.hashCode(), TIMEOUT); - TimedComputation.compute(() -> ne.f(node), (long) TIMEOUT + TOLERANCE, "Timeout Test"); - logger.info("Finished computation. Runtime was {}ms", System.currentTimeMillis() - start); - } - } -} +package ai.libs.jaicore.search.algorithms.standard.bestfirst; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.TimeAwareNodeEvaluator; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.testproblems.nqueens.QueenNode; +import ai.libs.jaicore.timing.TimedComputation; + +public abstract class TimeAwareNodeEvaluatorTester> extends NodeEvaluatorTester { + + private static final Logger logger = LoggerFactory.getLogger(TimeAwareNodeEvaluatorTester.class); + + private static final int TIMEOUT = 3000; + private static final int TOLERANCE = 50; + + public abstract T getTimedNodeEvaluator(int timeoutInMS); + + @Test + public void testTimeoutAdherence() throws InterruptedException, ExecutionException, TimeoutException { + T ne = this.getTimedNodeEvaluator(TIMEOUT); + ne.setLoggerName("testednodeevaluator"); + for (Node node : this.getNodesToTest(ne)) { + long start = System.currentTimeMillis(); + logger.info("Starting computation of score for node with hash code {} with timeout {}", node.hashCode(), TIMEOUT); + TimedComputation.compute(() -> ne.f(node), (long) TIMEOUT + TOLERANCE, "Timeout Test"); + logger.info("Finished computation. Runtime was {}ms", System.currentTimeMillis() - start); + } + } +} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/UninformedBestFirstTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/UninformedBestFirstTester.java index 12f917f7a0..190d56d097 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/UninformedBestFirstTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/bestfirst/UninformedBestFirstTester.java @@ -1,9 +1,9 @@ package ai.libs.jaicore.search.algorithms.standard.bestfirst; import ai.libs.jaicore.search.algorithms.GraphSearchWithSubPathEvaluationUninformedTester; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class UninformedBestFirstTester extends GraphSearchWithSubPathEvaluationUninformedTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/dfs/DepthFirstSearchTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/dfs/DepthFirstSearchTester.java index f399796213..86ce65fec2 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/dfs/DepthFirstSearchTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/dfs/DepthFirstSearchTester.java @@ -1,9 +1,9 @@ package ai.libs.jaicore.search.algorithms.standard.dfs; import ai.libs.jaicore.search.algorithms.GraphSearchSolutionIteratorTester; -import jaicore.search.algorithms.standard.dfs.DepthFirstSearch; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.algorithms.standard.dfs.DepthFirstSearch; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; public class DepthFirstSearchTester extends GraphSearchSolutionIteratorTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearchTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearchTester.java index cb35526ef0..368f38af5b 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearchTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/lds/BestFirstLimitedDiscrepancySearchTester.java @@ -1,10 +1,10 @@ package ai.libs.jaicore.search.algorithms.standard.lds; import ai.libs.jaicore.search.algorithms.GraphSearchSolutionIteratorTester; -import jaicore.search.algorithms.standard.lds.BestFirstLimitedDiscrepancySearch; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; +import ai.libs.jaicore.search.algorithms.standard.lds.BestFirstLimitedDiscrepancySearch; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; public class BestFirstLimitedDiscrepancySearchTester extends GraphSearchSolutionIteratorTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/lds/LDSTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/lds/LDSTester.java index 4a341bb265..fb4e4156ff 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/lds/LDSTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/lds/LDSTester.java @@ -1,10 +1,10 @@ package ai.libs.jaicore.search.algorithms.standard.lds; import ai.libs.jaicore.search.algorithms.GeneralGraphSearchAlgorithmTester; -import jaicore.search.algorithms.standard.lds.LimitedDiscrepancySearch; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; +import ai.libs.jaicore.search.algorithms.standard.lds.LimitedDiscrepancySearch; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; public class LDSTester extends GeneralGraphSearchAlgorithmTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/mcts/MCTSTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/mcts/MCTSTester.java index e5c56c559b..0cad799dea 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/mcts/MCTSTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/mcts/MCTSTester.java @@ -1,11 +1,11 @@ package ai.libs.jaicore.search.algorithms.standard.mcts; import ai.libs.jaicore.search.algorithms.GraphSearchSolutionIteratorTester; -import jaicore.search.algorithms.standard.mcts.UCTFactory; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.model.other.AgnosticPathEvaluator; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.mcts.UCTFactory; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.model.other.AgnosticPathEvaluator; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; public class MCTSTester extends GraphSearchSolutionIteratorTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/random/RandomSearchTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/random/RandomSearchTester.java index bb68f61b57..411f15684f 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/random/RandomSearchTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/random/RandomSearchTester.java @@ -1,9 +1,9 @@ package ai.libs.jaicore.search.algorithms.standard.random; import ai.libs.jaicore.search.algorithms.GraphSearchSolutionIteratorTester; -import jaicore.search.algorithms.standard.random.RandomSearch; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.algorithms.standard.random.RandomSearch; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; public class RandomSearchTester extends GraphSearchSolutionIteratorTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStarTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStarTester.java index 38858ab779..7b53d13b41 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStarTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/rstar/RStarTester.java @@ -7,11 +7,11 @@ import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; import ai.libs.jaicore.search.algorithms.GraphSearchSolutionIteratorTester; -import jaicore.search.algorithms.standard.rstar.GraphBasedDistantSuccessorGenerator; -import jaicore.search.algorithms.standard.rstar.RStarFactory; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic; +import ai.libs.jaicore.search.algorithms.standard.rstar.GraphBasedDistantSuccessorGenerator; +import ai.libs.jaicore.search.algorithms.standard.rstar.RStarFactory; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluationAndSubPathHeuristic; /** * This test deactivates the solution enumerators, because RStar is not a complete algorithm diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/ParetoSearchTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/ParetoSearchTester.java index d29ce78f53..6c00574ba8 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/ParetoSearchTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/ParetoSearchTester.java @@ -1,29 +1,29 @@ -package ai.libs.jaicore.search.algorithms.standard.uncertainty; - -import java.util.Random; - -import ai.libs.jaicore.search.algorithms.GraphSearchSolutionIteratorTester; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; -import jaicore.search.algorithms.standard.uncertainty.BasicUncertaintySource; -import jaicore.search.algorithms.standard.uncertainty.OversearchAvoidanceConfig; -import jaicore.search.algorithms.standard.uncertainty.UncertaintyORGraphSearchFactory; -import jaicore.search.algorithms.standard.uncertainty.OversearchAvoidanceConfig.OversearchAvoidanceMode; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.model.other.AgnosticPathEvaluator; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithUncertaintyBasedSubpathEvaluationInput; - -public class ParetoSearchTester extends GraphSearchSolutionIteratorTester { - - @Override - public IGraphSearch getSearchAlgorithm(final GraphSearchInput problem) { - OversearchAvoidanceConfig config = new OversearchAvoidanceConfig<>(OversearchAvoidanceMode.PARETO_FRONT_SELECTION, 0); - UncertaintyORGraphSearchFactory searchFactory = new UncertaintyORGraphSearchFactory<>(); - searchFactory.setConfig(config); - RandomCompletionBasedNodeEvaluator rcne = new RandomCompletionBasedNodeEvaluator<>(new Random(0), 3, new AgnosticPathEvaluator<>()); - rcne.setUncertaintySource(new BasicUncertaintySource<>()); - GraphSearchWithUncertaintyBasedSubpathEvaluationInput transformedProblem = new GraphSearchWithUncertaintyBasedSubpathEvaluationInput<>(problem.getGraphGenerator(), rcne); - searchFactory.setProblemInput(transformedProblem); - return searchFactory.getAlgorithm(); - } -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty; + +import java.util.Random; + +import ai.libs.jaicore.search.algorithms.GraphSearchSolutionIteratorTester; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.BasicUncertaintySource; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.OversearchAvoidanceConfig; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.UncertaintyORGraphSearchFactory; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.OversearchAvoidanceConfig.OversearchAvoidanceMode; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.model.other.AgnosticPathEvaluator; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithUncertaintyBasedSubpathEvaluationInput; + +public class ParetoSearchTester extends GraphSearchSolutionIteratorTester { + + @Override + public IGraphSearch getSearchAlgorithm(final GraphSearchInput problem) { + OversearchAvoidanceConfig config = new OversearchAvoidanceConfig<>(OversearchAvoidanceMode.PARETO_FRONT_SELECTION, 0); + UncertaintyORGraphSearchFactory searchFactory = new UncertaintyORGraphSearchFactory<>(); + searchFactory.setConfig(config); + RandomCompletionBasedNodeEvaluator rcne = new RandomCompletionBasedNodeEvaluator<>(new Random(0), 3, new AgnosticPathEvaluator<>()); + rcne.setUncertaintySource(new BasicUncertaintySource<>()); + GraphSearchWithUncertaintyBasedSubpathEvaluationInput transformedProblem = new GraphSearchWithUncertaintyBasedSubpathEvaluationInput<>(problem.getGraphGenerator(), rcne); + searchFactory.setProblemInput(transformedProblem); + return searchFactory.getAlgorithm(); + } +} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/TwoPhaseTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/TwoPhaseTester.java index 30a6aab1b2..6eb056ae5a 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/TwoPhaseTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/algorithms/standard/uncertainty/TwoPhaseTester.java @@ -1,29 +1,29 @@ -package ai.libs.jaicore.search.algorithms.standard.uncertainty; - -import java.util.Random; - -import ai.libs.jaicore.search.algorithms.GraphSearchSolutionIteratorTester; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; -import jaicore.search.algorithms.standard.uncertainty.BasicUncertaintySource; -import jaicore.search.algorithms.standard.uncertainty.OversearchAvoidanceConfig; -import jaicore.search.algorithms.standard.uncertainty.UncertaintyORGraphSearchFactory; -import jaicore.search.algorithms.standard.uncertainty.OversearchAvoidanceConfig.OversearchAvoidanceMode; -import jaicore.search.core.interfaces.IGraphSearch; -import jaicore.search.model.other.AgnosticPathEvaluator; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithUncertaintyBasedSubpathEvaluationInput; - -public class TwoPhaseTester extends GraphSearchSolutionIteratorTester { - - @Override - public IGraphSearch getSearchAlgorithm(final GraphSearchInput problem) { - OversearchAvoidanceConfig config = new OversearchAvoidanceConfig<>(OversearchAvoidanceMode.TWO_PHASE_SELECTION, 0); - UncertaintyORGraphSearchFactory searchFactory = new UncertaintyORGraphSearchFactory<>(); - searchFactory.setConfig(config); - RandomCompletionBasedNodeEvaluator rcne = new RandomCompletionBasedNodeEvaluator<>(new Random(0), 3, new AgnosticPathEvaluator<>()); - rcne.setUncertaintySource(new BasicUncertaintySource<>()); - GraphSearchWithUncertaintyBasedSubpathEvaluationInput transformedProblem = new GraphSearchWithUncertaintyBasedSubpathEvaluationInput<>(problem.getGraphGenerator(), rcne); - searchFactory.setProblemInput(transformedProblem); - return searchFactory.getAlgorithm(); - } -} +package ai.libs.jaicore.search.algorithms.standard.uncertainty; + +import java.util.Random; + +import ai.libs.jaicore.search.algorithms.GraphSearchSolutionIteratorTester; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.BasicUncertaintySource; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.OversearchAvoidanceConfig; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.UncertaintyORGraphSearchFactory; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.OversearchAvoidanceConfig.OversearchAvoidanceMode; +import ai.libs.jaicore.search.core.interfaces.IGraphSearch; +import ai.libs.jaicore.search.model.other.AgnosticPathEvaluator; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithUncertaintyBasedSubpathEvaluationInput; + +public class TwoPhaseTester extends GraphSearchSolutionIteratorTester { + + @Override + public IGraphSearch getSearchAlgorithm(final GraphSearchInput problem) { + OversearchAvoidanceConfig config = new OversearchAvoidanceConfig<>(OversearchAvoidanceMode.TWO_PHASE_SELECTION, 0); + UncertaintyORGraphSearchFactory searchFactory = new UncertaintyORGraphSearchFactory<>(); + searchFactory.setConfig(config); + RandomCompletionBasedNodeEvaluator rcne = new RandomCompletionBasedNodeEvaluator<>(new Random(0), 3, new AgnosticPathEvaluator<>()); + rcne.setUncertaintySource(new BasicUncertaintySource<>()); + GraphSearchWithUncertaintyBasedSubpathEvaluationInput transformedProblem = new GraphSearchWithUncertaintyBasedSubpathEvaluationInput<>(problem.getGraphGenerator(), rcne); + searchFactory.setProblemInput(transformedProblem); + return searchFactory.getAlgorithm(); + } +} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalGraphGenerator.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalGraphGenerator.java index 602f70e530..f5d8455cba 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalGraphGenerator.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalGraphGenerator.java @@ -1,157 +1,157 @@ -package ai.libs.jaicore.search.testproblems.cannibals; - -import java.util.ArrayList; -import java.util.List; - -import ai.libs.jaicore.testproblems.cannibals.CannibalProblem; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.GoalTester; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.RootGenerator; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; - -public class CannibalGraphGenerator implements GraphGenerator { - - private final CannibalProblem initState; - - public CannibalGraphGenerator(final CannibalProblem initState) { - super(); - this.initState = initState; - } - - @Override - public RootGenerator getRootGenerator() { - return new SingleRootGenerator() { - - @Override - public CannibalProblem getRoot() { - return initState; - } - }; - } - - @Override - public SuccessorGenerator getSuccessorGenerator() { - return new SuccessorGenerator() { - - @Override - public List> generateSuccessors(final CannibalProblem node) throws InterruptedException { - List> successors = new ArrayList<>(); - int ml = node.getMissionariesOnLeft(); - int mr = node.getMissionariesOnRight(); - int cl = node.getCannibalsOnLeft(); - int cr = node.getCannibalsOnRight(); - - /* first consider the case that the boat is on the left */ - if (node.isBoatOnLeft()) { - if (ml >= 2) { - CannibalProblem candidate = new CannibalProblem(false, ml - 2, cl, mr + 2, cr); - checkThatNumberOfPeopleHasNotChanged(node, candidate); - if (!candidate.isLost()) { - successors.add(new NodeExpansionDescription(node, candidate, "2m->", NodeType.OR)); - } - } - if (ml >= 1) { - CannibalProblem candidate = new CannibalProblem(false, ml - 1, cl, mr + 1, cr); - checkThatNumberOfPeopleHasNotChanged(node, candidate); - if (!candidate.isLost()) { - successors.add(new NodeExpansionDescription(node, candidate, "1m->", NodeType.OR)); - } - } - if (cl >= 1) { - CannibalProblem candidate = new CannibalProblem(false, ml, cl - 1, mr, cr + 1); - checkThatNumberOfPeopleHasNotChanged(node, candidate); - if (!candidate.isLost()) { - successors.add(new NodeExpansionDescription(node, candidate, "1c->", NodeType.OR)); - } - } - if (ml >= 1 && cl >= 1) { - CannibalProblem candidate = new CannibalProblem(false, ml - 1, cl - 1, mr + 1, cr + 1); - checkThatNumberOfPeopleHasNotChanged(node, candidate); - if (!candidate.isLost()) { - successors.add(new NodeExpansionDescription(node, candidate, "1m1c->", NodeType.OR)); - } - } - if (cl >= 2) { - CannibalProblem candidate = new CannibalProblem(false, ml, cl - 2, mr, cr + 2); - checkThatNumberOfPeopleHasNotChanged(node, candidate); - if (!candidate.isLost()) { - successors.add(new NodeExpansionDescription(node, candidate, "2c->", NodeType.OR)); - } - } - } - - /* now consider the cases that the boat is on the right */ - else { - if (mr >= 2) { - CannibalProblem candidate = new CannibalProblem(true, ml + 2, cl, mr - 2, cr); - checkThatNumberOfPeopleHasNotChanged(node, candidate); - if (!candidate.isLost()) { - successors.add(new NodeExpansionDescription(node, candidate, "2m<-", NodeType.OR)); - } - } - if (mr >= 1) { - CannibalProblem candidate = new CannibalProblem(true, ml + 1, cl, mr - 1, cr); - checkThatNumberOfPeopleHasNotChanged(node, candidate); - if (!candidate.isLost()) { - successors.add(new NodeExpansionDescription(node, candidate, "1m<-", NodeType.OR)); - } - } - if (cr >= 1) { - CannibalProblem candidate = new CannibalProblem(true, ml, cl + 1, mr, cr - 1); - checkThatNumberOfPeopleHasNotChanged(node, candidate); - if (!candidate.isLost()) { - successors.add(new NodeExpansionDescription(node, candidate, "1c<-", NodeType.OR)); - } - } - if (mr >= 1 && cr >= 1) { - CannibalProblem candidate = new CannibalProblem(true, ml + 1, cl + 1, mr - 1, cr - 1); - checkThatNumberOfPeopleHasNotChanged(node, candidate); - if (!candidate.isLost()) { - successors.add(new NodeExpansionDescription(node, candidate, "1m1c<-", NodeType.OR)); - } - } - if (cr >= 2) { - CannibalProblem candidate = new CannibalProblem(true, ml, cl + 2, mr, cr - 2); - checkThatNumberOfPeopleHasNotChanged(node, candidate); - if (!candidate.isLost()) { - successors.add(new NodeExpansionDescription(node, candidate, "2c<-", NodeType.OR)); - } - } - } - return successors; - } - }; - } - - private void checkThatNumberOfPeopleHasNotChanged(final CannibalProblem a, final CannibalProblem b) { - if (a.getTotalNumberOfPeople() != b.getTotalNumberOfPeople()) { - throw new IllegalStateException("Number of people has changed from " + a.getTotalNumberOfPeople() + " to " + b.getTotalNumberOfPeople()); - } - } - - @Override - public GoalTester getGoalTester() { - return new NodeGoalTester() { - - @Override - public boolean isGoal(final CannibalProblem node) { - return node.isWon(); - } - }; - } - - @Override - public boolean isSelfContained() { - return false; - } - - @Override - public void setNodeNumbering(final boolean nodenumbering) { - - } - -} +package ai.libs.jaicore.search.testproblems.cannibals; + +import java.util.ArrayList; +import java.util.List; + +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.GoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.RootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.testproblems.cannibals.CannibalProblem; + +public class CannibalGraphGenerator implements GraphGenerator { + + private final CannibalProblem initState; + + public CannibalGraphGenerator(final CannibalProblem initState) { + super(); + this.initState = initState; + } + + @Override + public RootGenerator getRootGenerator() { + return new SingleRootGenerator() { + + @Override + public CannibalProblem getRoot() { + return initState; + } + }; + } + + @Override + public SuccessorGenerator getSuccessorGenerator() { + return new SuccessorGenerator() { + + @Override + public List> generateSuccessors(final CannibalProblem node) throws InterruptedException { + List> successors = new ArrayList<>(); + int ml = node.getMissionariesOnLeft(); + int mr = node.getMissionariesOnRight(); + int cl = node.getCannibalsOnLeft(); + int cr = node.getCannibalsOnRight(); + + /* first consider the case that the boat is on the left */ + if (node.isBoatOnLeft()) { + if (ml >= 2) { + CannibalProblem candidate = new CannibalProblem(false, ml - 2, cl, mr + 2, cr); + checkThatNumberOfPeopleHasNotChanged(node, candidate); + if (!candidate.isLost()) { + successors.add(new NodeExpansionDescription(node, candidate, "2m->", NodeType.OR)); + } + } + if (ml >= 1) { + CannibalProblem candidate = new CannibalProblem(false, ml - 1, cl, mr + 1, cr); + checkThatNumberOfPeopleHasNotChanged(node, candidate); + if (!candidate.isLost()) { + successors.add(new NodeExpansionDescription(node, candidate, "1m->", NodeType.OR)); + } + } + if (cl >= 1) { + CannibalProblem candidate = new CannibalProblem(false, ml, cl - 1, mr, cr + 1); + checkThatNumberOfPeopleHasNotChanged(node, candidate); + if (!candidate.isLost()) { + successors.add(new NodeExpansionDescription(node, candidate, "1c->", NodeType.OR)); + } + } + if (ml >= 1 && cl >= 1) { + CannibalProblem candidate = new CannibalProblem(false, ml - 1, cl - 1, mr + 1, cr + 1); + checkThatNumberOfPeopleHasNotChanged(node, candidate); + if (!candidate.isLost()) { + successors.add(new NodeExpansionDescription(node, candidate, "1m1c->", NodeType.OR)); + } + } + if (cl >= 2) { + CannibalProblem candidate = new CannibalProblem(false, ml, cl - 2, mr, cr + 2); + checkThatNumberOfPeopleHasNotChanged(node, candidate); + if (!candidate.isLost()) { + successors.add(new NodeExpansionDescription(node, candidate, "2c->", NodeType.OR)); + } + } + } + + /* now consider the cases that the boat is on the right */ + else { + if (mr >= 2) { + CannibalProblem candidate = new CannibalProblem(true, ml + 2, cl, mr - 2, cr); + checkThatNumberOfPeopleHasNotChanged(node, candidate); + if (!candidate.isLost()) { + successors.add(new NodeExpansionDescription(node, candidate, "2m<-", NodeType.OR)); + } + } + if (mr >= 1) { + CannibalProblem candidate = new CannibalProblem(true, ml + 1, cl, mr - 1, cr); + checkThatNumberOfPeopleHasNotChanged(node, candidate); + if (!candidate.isLost()) { + successors.add(new NodeExpansionDescription(node, candidate, "1m<-", NodeType.OR)); + } + } + if (cr >= 1) { + CannibalProblem candidate = new CannibalProblem(true, ml, cl + 1, mr, cr - 1); + checkThatNumberOfPeopleHasNotChanged(node, candidate); + if (!candidate.isLost()) { + successors.add(new NodeExpansionDescription(node, candidate, "1c<-", NodeType.OR)); + } + } + if (mr >= 1 && cr >= 1) { + CannibalProblem candidate = new CannibalProblem(true, ml + 1, cl + 1, mr - 1, cr - 1); + checkThatNumberOfPeopleHasNotChanged(node, candidate); + if (!candidate.isLost()) { + successors.add(new NodeExpansionDescription(node, candidate, "1m1c<-", NodeType.OR)); + } + } + if (cr >= 2) { + CannibalProblem candidate = new CannibalProblem(true, ml, cl + 2, mr, cr - 2); + checkThatNumberOfPeopleHasNotChanged(node, candidate); + if (!candidate.isLost()) { + successors.add(new NodeExpansionDescription(node, candidate, "2c<-", NodeType.OR)); + } + } + } + return successors; + } + }; + } + + private void checkThatNumberOfPeopleHasNotChanged(final CannibalProblem a, final CannibalProblem b) { + if (a.getTotalNumberOfPeople() != b.getTotalNumberOfPeople()) { + throw new IllegalStateException("Number of people has changed from " + a.getTotalNumberOfPeople() + " to " + b.getTotalNumberOfPeople()); + } + } + + @Override + public GoalTester getGoalTester() { + return new NodeGoalTester() { + + @Override + public boolean isGoal(final CannibalProblem node) { + return node.isWon(); + } + }; + } + + @Override + public boolean isSelfContained() { + return false; + } + + @Override + public void setNodeNumbering(final boolean nodenumbering) { + + } + +} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalProblemAsGraphSearchSet.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalProblemAsGraphSearchSet.java index e42b64e7d1..a3e6648bbb 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalProblemAsGraphSearchSet.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalProblemAsGraphSearchSet.java @@ -1,16 +1,16 @@ -package ai.libs.jaicore.search.testproblems.cannibals; - -import java.util.List; - -import ai.libs.jaicore.basic.algorithm.ReductionBasedAlgorithmTestProblemSet; -import ai.libs.jaicore.testproblems.cannibals.CannibalProblem; -import ai.libs.jaicore.testproblems.cannibals.CannibalProblemSet; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; - -public class CannibalProblemAsGraphSearchSet extends ReductionBasedAlgorithmTestProblemSet, SearchGraphPath, CannibalProblem, List> { - - public CannibalProblemAsGraphSearchSet() { - super("Cannibal problem as graph search", new CannibalProblemSet(), new CannibalProblemToGraphSearchReducer()); - } -} +package ai.libs.jaicore.search.testproblems.cannibals; + +import java.util.List; + +import ai.libs.jaicore.basic.algorithm.ReductionBasedAlgorithmTestProblemSet; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.testproblems.cannibals.CannibalProblem; +import ai.libs.jaicore.testproblems.cannibals.CannibalProblemSet; + +public class CannibalProblemAsGraphSearchSet extends ReductionBasedAlgorithmTestProblemSet, SearchGraphPath, CannibalProblem, List> { + + public CannibalProblemAsGraphSearchSet() { + super("Cannibal problem as graph search", new CannibalProblemSet(), new CannibalProblemToGraphSearchReducer()); + } +} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalProblemToGraphSearchReducer.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalProblemToGraphSearchReducer.java index d22d944fa3..d144676df8 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalProblemToGraphSearchReducer.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalProblemToGraphSearchReducer.java @@ -3,9 +3,9 @@ import java.util.List; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; import ai.libs.jaicore.testproblems.cannibals.CannibalProblem; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; public class CannibalProblemToGraphSearchReducer implements AlgorithmicProblemReduction, GraphSearchWithPathEvaluationsInput, SearchGraphPath> { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalTester.java index e2e37c17bb..e083ca16a5 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/cannibals/CannibalTester.java @@ -1,40 +1,40 @@ -package ai.libs.jaicore.search.testproblems.cannibals; - -import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; -import ai.libs.jaicore.graphvisualizer.plugin.graphview.GraphViewPlugin; -import ai.libs.jaicore.graphvisualizer.plugin.nodeinfo.NodeInfoGUIPlugin; -import ai.libs.jaicore.graphvisualizer.window.AlgorithmVisualizationWindow; -import ai.libs.jaicore.testproblems.cannibals.CannibalProblem; -import jaicore.search.algorithms.standard.astar.AStar; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; -import jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; -import javafx.application.Platform; -import javafx.embed.swing.JFXPanel; - -public class CannibalTester { - - - public static void main(final String[] args) throws AlgorithmTimeoutedException, InterruptedException, AlgorithmExecutionCanceledException, AlgorithmException { - CannibalProblem p = new CannibalProblem(true, 3, 3, 0, 0); - - - - GraphSearchWithSubpathEvaluationsInput prob = new GraphSearchWithSubpathEvaluationsInput<>(new CannibalGraphGenerator(p), n -> n.externalPath().size()); - StandardBestFirst rs = new StandardBestFirst<>(prob); - - AStar astar = new AStar<>(new GraphSearchWithNumberBasedAdditivePathEvaluation<>(prob.getGraphGenerator(), (n1,n2) -> 1, n -> 1.0 * n.getPoint().getCannibalsOnLeft() + n.getPoint().getMissionariesOnLeft())); - new JFXPanel(); - Platform.runLater(new AlgorithmVisualizationWindow(astar, new GraphViewPlugin(), new NodeInfoGUIPlugin<>(n -> n.toString()))); - - System.out.println(astar.nextSolutionCandidate().getNodes().size() - 1); - // rs.cancel(); - // for (int i = 0; i < 20 && rs.hasNext(); i++) { - // System.out.println(rs.next()); - // } - - System.out.println("ready"); - } -} +package ai.libs.jaicore.search.testproblems.cannibals; + +import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; +import ai.libs.jaicore.graphvisualizer.plugin.graphview.GraphViewPlugin; +import ai.libs.jaicore.graphvisualizer.plugin.nodeinfo.NodeInfoGUIPlugin; +import ai.libs.jaicore.graphvisualizer.window.AlgorithmVisualizationWindow; +import ai.libs.jaicore.search.algorithms.standard.astar.AStar; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirst; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.testproblems.cannibals.CannibalProblem; +import javafx.application.Platform; +import javafx.embed.swing.JFXPanel; + +public class CannibalTester { + + + public static void main(final String[] args) throws AlgorithmTimeoutedException, InterruptedException, AlgorithmExecutionCanceledException, AlgorithmException { + CannibalProblem p = new CannibalProblem(true, 3, 3, 0, 0); + + + + GraphSearchWithSubpathEvaluationsInput prob = new GraphSearchWithSubpathEvaluationsInput<>(new CannibalGraphGenerator(p), n -> n.externalPath().size()); + StandardBestFirst rs = new StandardBestFirst<>(prob); + + AStar astar = new AStar<>(new GraphSearchWithNumberBasedAdditivePathEvaluation<>(prob.getGraphGenerator(), (n1,n2) -> 1, n -> 1.0 * n.getPoint().getCannibalsOnLeft() + n.getPoint().getMissionariesOnLeft())); + new JFXPanel(); + Platform.runLater(new AlgorithmVisualizationWindow(astar, new GraphViewPlugin(), new NodeInfoGUIPlugin<>(n -> n.toString()))); + + System.out.println(astar.nextSolutionCandidate().getNodes().size() - 1); + // rs.cancel(); + // for (int i = 0; i < 20 && rs.hasNext(); i++) { + // System.out.println(rs.next()); + // } + + System.out.println("ready"); + } +} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPAsGraphSearchSet.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPAsGraphSearchSet.java index 773556c7d3..a70906722d 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPAsGraphSearchSet.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPAsGraphSearchSet.java @@ -1,17 +1,17 @@ -package ai.libs.jaicore.search.testproblems.enhancedttsp; - -import ai.libs.jaicore.basic.algorithm.ReductionBasedAlgorithmTestProblemSet; -import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSP; -import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSPNode; -import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSPProblemSet; -import it.unimi.dsi.fastutil.shorts.ShortList; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; - -public class EnhancedTTSPAsGraphSearchSet -extends ReductionBasedAlgorithmTestProblemSet, SearchGraphPath, EnhancedTTSP, ShortList> { - - public EnhancedTTSPAsGraphSearchSet() { - super("Enhanced TTSP as graph search", new EnhancedTTSPProblemSet(), new EnhancedTTSPToGraphSearchReducer()); - } -} +package ai.libs.jaicore.search.testproblems.enhancedttsp; + +import ai.libs.jaicore.basic.algorithm.ReductionBasedAlgorithmTestProblemSet; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSP; +import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSPNode; +import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSPProblemSet; +import it.unimi.dsi.fastutil.shorts.ShortList; + +public class EnhancedTTSPAsGraphSearchSet +extends ReductionBasedAlgorithmTestProblemSet, SearchGraphPath, EnhancedTTSP, ShortList> { + + public EnhancedTTSPAsGraphSearchSet() { + super("Enhanced TTSP as graph search", new EnhancedTTSPProblemSet(), new EnhancedTTSPToGraphSearchReducer()); + } +} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphGenerator.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphGenerator.java index 966eafaaed..d062d0f48c 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphGenerator.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphGenerator.java @@ -7,17 +7,17 @@ import org.slf4j.LoggerFactory; import ai.libs.jaicore.basic.ILoggingCustomizable; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SingleSuccessorGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSP; import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSPNode; import it.unimi.dsi.fastutil.shorts.ShortArrayList; import it.unimi.dsi.fastutil.shorts.ShortList; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SingleSuccessorGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; public class EnhancedTTSPGraphGenerator implements GraphGenerator, ILoggingCustomizable { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphSearchToAdditiveGraphSearchReducer.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphSearchToAdditiveGraphSearchReducer.java index 2a096279fe..2776816b67 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphSearchToAdditiveGraphSearchReducer.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphSearchToAdditiveGraphSearchReducer.java @@ -1,10 +1,10 @@ package ai.libs.jaicore.search.testproblems.enhancedttsp; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSPNode; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithNumberBasedAdditivePathEvaluation; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class EnhancedTTSPGraphSearchToAdditiveGraphSearchReducer implements AlgorithmicProblemReduction, EvaluatedSearchGraphPath, GraphSearchWithNumberBasedAdditivePathEvaluation, EvaluatedSearchGraphPath> { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphSearchToUncertaintyBasedGraphSearchReducer.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphSearchToUncertaintyBasedGraphSearchReducer.java index 2a423fa50e..3b3739a575 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphSearchToUncertaintyBasedGraphSearchReducer.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPGraphSearchToUncertaintyBasedGraphSearchReducer.java @@ -4,15 +4,15 @@ import ai.libs.jaicore.basic.IObjectEvaluator; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallyUncertaintyAnnotatingNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.uncertainty.IUncertaintySource; +import ai.libs.jaicore.search.model.other.AgnosticPathEvaluator; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithUncertaintyBasedSubpathEvaluationInput; import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSPNode; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.IPotentiallyUncertaintyAnnotatingNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; -import jaicore.search.algorithms.standard.uncertainty.IUncertaintySource; -import jaicore.search.model.other.AgnosticPathEvaluator; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; -import jaicore.search.probleminputs.GraphSearchWithUncertaintyBasedSubpathEvaluationInput; public class EnhancedTTSPGraphSearchToUncertaintyBasedGraphSearchReducer implements AlgorithmicProblemReduction, EvaluatedSearchGraphPath, GraphSearchWithUncertaintyBasedSubpathEvaluationInput, EvaluatedSearchGraphPath> { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPToGraphSearchReducer.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPToGraphSearchReducer.java index 1b8abb0216..8295f127a9 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPToGraphSearchReducer.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/enhancedttsp/EnhancedTTSPToGraphSearchReducer.java @@ -1,11 +1,11 @@ package ai.libs.jaicore.search.testproblems.enhancedttsp; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSP; import ai.libs.jaicore.testproblems.enhancedttsp.EnhancedTTSPNode; import it.unimi.dsi.fastutil.shorts.ShortList; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class EnhancedTTSPToGraphSearchReducer implements AlgorithmicProblemReduction, SearchGraphPath> { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/gridworld/GridWorldBasicGraphGenerator.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/gridworld/GridWorldBasicGraphGenerator.java index ff89c9c14f..5bcffa97d1 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/gridworld/GridWorldBasicGraphGenerator.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/gridworld/GridWorldBasicGraphGenerator.java @@ -3,16 +3,16 @@ import java.util.ArrayList; import java.util.List; +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.GoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.RootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; import ai.libs.jaicore.testproblems.gridworld.GridWorldNode; import ai.libs.jaicore.testproblems.gridworld.GridWorldProblem; -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.GoalTester; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.RootGenerator; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; @SuppressWarnings("serial") public class GridWorldBasicGraphGenerator implements SerializableGraphGenerator { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/gridworld/GridWorldHeuristic.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/gridworld/GridWorldHeuristic.java index 4c77e53bdf..58a858508f 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/gridworld/GridWorldHeuristic.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/gridworld/GridWorldHeuristic.java @@ -1,8 +1,8 @@ package ai.libs.jaicore.search.testproblems.gridworld; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.model.travesaltree.Node; import ai.libs.jaicore.testproblems.gridworld.GridWorldNode; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.model.travesaltree.Node; public class GridWorldHeuristic implements INodeEvaluator { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackProblemAsGraphSearchSet.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackProblemAsGraphSearchSet.java index 549c3455d6..4b00fe4106 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackProblemAsGraphSearchSet.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackProblemAsGraphSearchSet.java @@ -1,17 +1,17 @@ -package ai.libs.jaicore.search.testproblems.knapsack; - -import java.util.Set; - -import ai.libs.jaicore.basic.algorithm.ReductionBasedAlgorithmTestProblemSet; -import ai.libs.jaicore.testproblems.knapsack.KnapsackConfiguration; -import ai.libs.jaicore.testproblems.knapsack.KnapsackProblem; -import ai.libs.jaicore.testproblems.knapsack.KnapsackProblemSet; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; - -public class KnapsackProblemAsGraphSearchSet extends ReductionBasedAlgorithmTestProblemSet, SearchGraphPath, KnapsackProblem, Set> { - - public KnapsackProblemAsGraphSearchSet() { - super("Knapsack problem as graph search", new KnapsackProblemSet(), new KnapsackToGraphSearchReducer()); - } -} +package ai.libs.jaicore.search.testproblems.knapsack; + +import java.util.Set; + +import ai.libs.jaicore.basic.algorithm.ReductionBasedAlgorithmTestProblemSet; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.testproblems.knapsack.KnapsackConfiguration; +import ai.libs.jaicore.testproblems.knapsack.KnapsackProblem; +import ai.libs.jaicore.testproblems.knapsack.KnapsackProblemSet; + +public class KnapsackProblemAsGraphSearchSet extends ReductionBasedAlgorithmTestProblemSet, SearchGraphPath, KnapsackProblem, Set> { + + public KnapsackProblemAsGraphSearchSet() { + super("Knapsack problem as graph search", new KnapsackProblemSet(), new KnapsackToGraphSearchReducer()); + } +} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackProblemGraphGenerator.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackProblemGraphGenerator.java index cdf3d259f3..2b9a50d172 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackProblemGraphGenerator.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackProblemGraphGenerator.java @@ -12,15 +12,15 @@ import org.slf4j.LoggerFactory; import ai.libs.jaicore.basic.ILoggingCustomizable; +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SingleSuccessorGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; import ai.libs.jaicore.testproblems.knapsack.KnapsackConfiguration; import ai.libs.jaicore.testproblems.knapsack.KnapsackProblem; -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SingleSuccessorGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; public class KnapsackProblemGraphGenerator implements SerializableGraphGenerator, ILoggingCustomizable { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackToGraphSearchReducer.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackToGraphSearchReducer.java index 5e0aec9b44..565511383f 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackToGraphSearchReducer.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/knapsack/KnapsackToGraphSearchReducer.java @@ -5,13 +5,13 @@ import ai.libs.jaicore.basic.algorithm.exceptions.ObjectEvaluationFailedException; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; import ai.libs.jaicore.testproblems.knapsack.KnapsackConfiguration; import ai.libs.jaicore.testproblems.knapsack.KnapsackProblem; -import jaicore.search.algorithms.standard.bestfirst.exceptions.NodeEvaluationException; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.model.travesaltree.Node; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class KnapsackToGraphSearchReducer implements AlgorithmicProblemReduction, GraphSearchWithSubpathEvaluationsInput, SearchGraphPath> { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/parentdiscarding/PDPuzzleGenerator.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/parentdiscarding/PDPuzzleGenerator.java index b117fd2e68..d7a3207f3b 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/parentdiscarding/PDPuzzleGenerator.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/parentdiscarding/PDPuzzleGenerator.java @@ -3,12 +3,12 @@ import java.util.ArrayList; import java.util.List; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; public class PDPuzzleGenerator implements GraphGenerator { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/standard/NPuzzleGraphGenerator.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/standard/NPuzzleGraphGenerator.java index bb94392a58..66824029b8 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/standard/NPuzzleGraphGenerator.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/standard/NPuzzleGraphGenerator.java @@ -3,13 +3,13 @@ import java.util.ArrayList; import java.util.List; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; import ai.libs.jaicore.testproblems.npuzzle.NPuzzleState; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; /** * A simple generator for the normal NPuzzleProblem. diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/standard/NPuzzleToGraphSearchReducer.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/standard/NPuzzleToGraphSearchReducer.java index b1cacadc59..f737def2bf 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/standard/NPuzzleToGraphSearchReducer.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/npuzzle/standard/NPuzzleToGraphSearchReducer.java @@ -3,12 +3,12 @@ import java.util.List; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; +import ai.libs.jaicore.search.core.interfaces.EdgeCountingSolutionEvaluator; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; import ai.libs.jaicore.testproblems.npuzzle.NPuzzleProblem; import ai.libs.jaicore.testproblems.npuzzle.NPuzzleState; -import jaicore.search.core.interfaces.EdgeCountingSolutionEvaluator; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class NPuzzleToGraphSearchReducer implements AlgorithmicProblemReduction, GraphSearchWithSubpathEvaluationsInput, EvaluatedSearchGraphPath> { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphGenerator.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphGenerator.java index 151903d3b5..0a15d888b8 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphGenerator.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphGenerator.java @@ -1,62 +1,62 @@ -package ai.libs.jaicore.search.testproblems.nqueens; - -import java.util.ArrayList; -import java.util.List; - -import jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; -import jaicore.search.model.travesaltree.NodeExpansionDescription; -import jaicore.search.model.travesaltree.NodeType; -import jaicore.search.structure.graphgenerator.NodeGoalTester; -import jaicore.search.structure.graphgenerator.SingleRootGenerator; -import jaicore.search.structure.graphgenerator.SuccessorGenerator; - -@SuppressWarnings("serial") -public class NQueensGraphGenerator implements SerializableGraphGenerator { - - private final int dimension; - private int countSinceLastSleep = 0; - - public NQueensGraphGenerator(final int dimension) { - this.dimension = dimension; - } - - @Override - public SingleRootGenerator getRootGenerator() { - return () -> new QueenNode(this.dimension); - } - - @Override - public SuccessorGenerator getSuccessorGenerator() { - return n -> { - List> l = new ArrayList<>(); - int currentRow = n.getPositions().size(); - for (int i = 0; i < this.dimension; i++, countSinceLastSleep ++) { - if (countSinceLastSleep % 100 == 0) - Thread.sleep(5); - if (Thread.interrupted()) { - throw new InterruptedException("Successor generation has been interrupted."); - } - if (!n.attack(currentRow, i)) { - l.add(new NodeExpansionDescription<>(n, new QueenNode(n, i), "" + i, NodeType.OR)); - } - } - return l; - }; - } - - @Override - public NodeGoalTester getGoalTester() { - return n -> n.getNumberOfQueens() == this.dimension; - } - - @Override - public boolean isSelfContained() { - return true; - } - - @Override - public void setNodeNumbering(final boolean nodenumbering) { - - /* not applicable */ - } -} +package ai.libs.jaicore.search.testproblems.nqueens; + +import java.util.ArrayList; +import java.util.List; + +import ai.libs.jaicore.search.algorithms.parallel.parallelexploration.distributed.interfaces.SerializableGraphGenerator; +import ai.libs.jaicore.search.model.travesaltree.NodeExpansionDescription; +import ai.libs.jaicore.search.model.travesaltree.NodeType; +import ai.libs.jaicore.search.structure.graphgenerator.NodeGoalTester; +import ai.libs.jaicore.search.structure.graphgenerator.SingleRootGenerator; +import ai.libs.jaicore.search.structure.graphgenerator.SuccessorGenerator; + +@SuppressWarnings("serial") +public class NQueensGraphGenerator implements SerializableGraphGenerator { + + private final int dimension; + private int countSinceLastSleep = 0; + + public NQueensGraphGenerator(final int dimension) { + this.dimension = dimension; + } + + @Override + public SingleRootGenerator getRootGenerator() { + return () -> new QueenNode(this.dimension); + } + + @Override + public SuccessorGenerator getSuccessorGenerator() { + return n -> { + List> l = new ArrayList<>(); + int currentRow = n.getPositions().size(); + for (int i = 0; i < this.dimension; i++, countSinceLastSleep ++) { + if (countSinceLastSleep % 100 == 0) + Thread.sleep(5); + if (Thread.interrupted()) { + throw new InterruptedException("Successor generation has been interrupted."); + } + if (!n.attack(currentRow, i)) { + l.add(new NodeExpansionDescription<>(n, new QueenNode(n, i), "" + i, NodeType.OR)); + } + } + return l; + }; + } + + @Override + public NodeGoalTester getGoalTester() { + return n -> n.getNumberOfQueens() == this.dimension; + } + + @Override + public boolean isSelfContained() { + return true; + } + + @Override + public void setNodeNumbering(final boolean nodenumbering) { + + /* not applicable */ + } +} diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphGeneratorTester.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphGeneratorTester.java index fafb19c414..8e9f52b8bf 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphGeneratorTester.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphGeneratorTester.java @@ -5,7 +5,7 @@ import ai.libs.jaicore.basic.sets.SetUtil.Pair; import ai.libs.jaicore.search.GraphGeneratorTester; -import jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; public class NQueensGraphGeneratorTester extends GraphGeneratorTester { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphSearchToGraphSearchWithSubPathEvaluationReducer.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphSearchToGraphSearchWithSubPathEvaluationReducer.java index a76b8bbc6f..56f55f7066 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphSearchToGraphSearchWithSubPathEvaluationReducer.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphSearchToGraphSearchWithSubPathEvaluationReducer.java @@ -1,10 +1,10 @@ package ai.libs.jaicore.search.testproblems.nqueens; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class NQueensGraphSearchToGraphSearchWithSubPathEvaluationReducer implements AlgorithmicProblemReduction, SearchGraphPath, GraphSearchWithSubpathEvaluationsInput, SearchGraphPath> { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphSearchToNodeRecommendedTreeReducer.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphSearchToNodeRecommendedTreeReducer.java index 573428aa9d..5aa2ec7308 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphSearchToNodeRecommendedTreeReducer.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensGraphSearchToNodeRecommendedTreeReducer.java @@ -1,9 +1,9 @@ package ai.libs.jaicore.search.testproblems.nqueens; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithNodeRecommenderInput; public class NQueensGraphSearchToNodeRecommendedTreeReducer implements AlgorithmicProblemReduction, SearchGraphPath, GraphSearchWithNodeRecommenderInput, SearchGraphPath> { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensProblemAsGraphSearchSet.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensProblemAsGraphSearchSet.java index 868000cd50..d519f4a52d 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensProblemAsGraphSearchSet.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensProblemAsGraphSearchSet.java @@ -3,10 +3,10 @@ import java.util.List; import ai.libs.jaicore.basic.algorithm.ReductionBasedAlgorithmTestProblemSet; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; import ai.libs.jaicore.testproblems.nqueens.NQueenProblemSet; import ai.libs.jaicore.testproblems.nqueens.NQueensProblem; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; public class NQueensProblemAsGraphSearchSet extends ReductionBasedAlgorithmTestProblemSet, SearchGraphPath, NQueensProblem, List> { diff --git a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensToGraphSearchReducer.java b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensToGraphSearchReducer.java index 5956073465..b75c2a11fd 100644 --- a/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensToGraphSearchReducer.java +++ b/JAICore/jaicore-search/src/test/java/ai/libs/jaicore/search/testproblems/nqueens/NQueensToGraphSearchReducer.java @@ -3,12 +3,12 @@ import java.util.List; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.model.other.AgnosticPathEvaluator; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; import ai.libs.jaicore.testproblems.nqueens.NQueensProblem; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.model.other.AgnosticPathEvaluator; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; public class NQueensToGraphSearchReducer implements AlgorithmicProblemReduction, GraphSearchInput, SearchGraphPath> { diff --git a/README.md b/README.md index 097d6786ca..ef9ad00696 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ [![Build Status](https://travis-ci.org/fmohr/AILibs.svg?branch=dev)](https://travis-ci.org/fmohr/AILibs) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=starlibs.ailibs&metric=alert_status)](https://sonarcloud.io/dashboard/index/starlibs.ailibs) +[![Javadocs](https://javadoc.io/badge/ai.libs/jaicore-basic.svg)](https://javadoc.io/doc/ai.libs/jaicore-basic) # AILibs @@ -9,25 +10,20 @@ AILibs is a collection of Java libraries related to automated decision making. I * **softwareconfiguration** is a collection of projects related to automatically configuring software systems. Here we also maintain the code for our AutoML flagship **[ML-Plan](https://github.com/fmohr/AILibs/tree/master/softwareconfiguration/mlplan)** ## Using AILibs in your project -You can resolve snapshots of this projects via a maven-dependency. -### Gradle -First register our departements nexus as a maven repository: -``` -repositories { - mavenCentral() - maven { url "https://nexus.cs.upb.de/repository/sfb901-snapshots/" } -} +You can resolve each of our projects via a Maven dependency (using Maven central as repository). +### Maven ``` -Then, you can either import the bundeled library via: -``` -dependencies { - compile group: "de.upb.isys", name: "AILibs", version:"0.0.1-SNAPSHOT" -} -``` -Or, the different artifacts individually e.g. + + ai.libs + jaicore-ml + 0.1.2 + ``` + +### Gradle +```gradle dependencies { - compile group: "de.upb.isys", name: "jaicore-ml", version:"0.0.1-SNAPSHOT" + implementation 'ai.libs:jaicore-ml:0.1.2' } ``` @@ -45,21 +41,18 @@ Then open Eclipse and go to the import menu, e.g., in the package manager. Choos ### JAICore -* [JAICore:jaicore-basic](JAICore/jaicore-basic/docs/javadoc/) -* [JAICore:jaicore-concurrent](JAICore/jaicore-concurrent/docs/javadoc/) -* [JAICore:jaicore-ea](JAICore/jaicore-ea/docs/javadoc/) -* [JAICore:jaicore-experiments](JAICore/jaicore-experiments/docs/javadoc/) -* [JAICore:jaicore-graph](JAICore/jaicore-graph/docs/javadoc/) -* [JAICore:jaicore-graphvisualizer](JAICore/jaicore-graphvisualizer/docs/javadoc/) -* [JAICore:jaicore-logic](JAICore/jaicore-logic/docs/javadoc/) -* [JAICore:jaicore-math](JAICore/jaicore-math/docs/javadoc/) -* [JAICore:jaicore-ml](JAICore/jaicore-ml/docs/javadoc/) -* [JAICore:jaicore-planning](JAICore/jaicore-planning/docs/javadoc/) -* [JAICore:jaicore-processes](JAICore/jaicore-processes/docs/javadoc/) -* [JAICore:jaicore-search](JAICore/jaicore-search/docs/javadoc/) -* [JAICore:jaicore-services](JAICore/jaicore-services/docs/javadoc/) +* [JAICore:jaicore-basic](https://javadoc.io/doc/ai.libs/jaicore-basic/) +* [JAICore:jaicore-ea](https://javadoc.io/doc/ai.libs/jaicore-ea/) +* [JAICore:jaicore-experiments](https://javadoc.io/doc/ai.libs/jaicore-experiments/) +* [JAICore:jaicore-graphvisualizer](https://javadoc.io/doc/ai.libs/jaicore-graphvisualizer/) +* [JAICore:jaicore-logic](https://javadoc.io/doc/ai.libs/jaicore-logic/) +* [JAICore:jaicore-math](https://javadoc.io/doc/ai.libs/jaicore-math/) +* [JAICore:jaicore-ml](https://javadoc.io/doc/ai.libs/jaicore-ml/) +* [JAICore:jaicore-planning](https://javadoc.io/doc/ai.libs/jaicore-planning/) +* [JAICore:jaicore-processes](https://javadoc.io/doc/ai.libs/jaicore-processes/) +* [JAICore:jaicore-search](https://javadoc.io/doc/ai.libs/jaicore-search/) ### Software Configuration -* [HASCO](softwareconfiguration/hasco/docs/javadoc/) -* [ML-Plan](softwareconfiguration/mlplan/docs/javadoc/) +* [HASCO](https://javadoc.io/doc/ai.libs/hasco/) +* [ML-Plan](https://javadoc.io/doc/ai.libs/mlplan/) diff --git a/build.gradle b/build.gradle index 67eef6766f..ea0ed7def8 100644 --- a/build.gradle +++ b/build.gradle @@ -1,204 +1,197 @@ -buildscript { - repositories { - mavenLocal() - mavenCentral() - maven { url "https://plugins.gradle.org/m2/" } - } - dependencies { - classpath "com.github.jengelman.gradle.plugins:shadow:2.0.4" - } -} - -// Artifact publishing and versoning -plugins { - id 'nebula.release' version '6.0.2' - id "nebula.project" version "3.4.0" - id "nebula.maven-base-publish" version "5.1.4" - id "org.sonarqube" version "2.6.2" -} - -allprojects { - //Shadow for fat-jars - apply plugin: "com.github.johnrengelman.shadow" - - //IDE - apply plugin: "java" - apply plugin: "eclipse" - apply plugin: "idea" - - //Other - apply plugin: "maven" - apply plugin: "jacoco" - //apply plugin: "signing" - - //Nebula - apply plugin: 'nebula.project' - apply plugin: 'nebula.nebula-release' - apply plugin: 'nebula.maven-base-publish' - - //Java version - sourceCompatibility = 1.8 - targetCompatibility = 1.8 - - //Project properties - project.group = 'ai.libs' - project.version = '0.0.8' - - ext { - ossrhUsername = hasProperty('ossrhUsername') ? ossrhUsername : System.getenv("ossrhUsername") - ossrhPassword = hasProperty('ossrhPassword') ? ossrhPassword : System.getenv("ossrhPassword") - } - - - sourceSets { - main { - java { - srcDir 'src/main/java' - } - resources { - srcDir 'conf' - srcDir 'resources' - } - } - test { - java { - srcDir 'src/test/java' - srcDir 'src/example/java' - } - } - } - - //Repositories - repositories { - mavenCentral() - mavenLocal() - maven { url "https://jitpack.io" } - maven { url "http://clojars.org/repo/" } - maven { url "https://plugins.gradle.org/m2/" } - maven { url "https://nexus.cs.upb.de/repository/maven-releases/" } - flatDir { - dirs 'lib' - } - } - //Dependencies for all(!) projects - dependencies { - - // configuration - compile group: 'org.aeonbits.owner', name: 'owner-java8', version:'1.0.10' - - // event bus - compile group: 'com.google.guava', name: 'guava', version: '27.0-jre' - - //Logger - compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' - runtimeOnly group: 'org.slf4j', name:'slf4j-log4j12', version:'1.7.25' - - //Testing - testCompile group: 'junit', name: 'junit', version: '4.12' - //testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.4.0-M1' - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3' - testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19' - } - - //Always check for updates in SNAPSHOT versions, do not cache - configurations.all { - // check for updates every build - resolutionStrategy.cacheChangingModulesFor 0, 'seconds' - exclude module: 'all' - } - - //Nebula releases - nebulaRelease { addReleaseBranchPattern('/dev/') } - - //Sonarqube config - sonarqube { - properties { - properties["sonar.projectKey"] = "starlibs.ailibs" - properties["sonar.projectName"] = project.name - properties["sonar.projectDescription"] = project.description - properties["sonar.projectVersion"] = project.version - properties["sonar.projectBaseDir"] = project.projectDir - properties["sonar.working.directory"] = "$project.buildDir/sonar" - properties["sonar.sourceEncoding"] = project.compileJava.options.encoding - properties["sonar.java.source"] = project.sourceCompatibility - properties["sonar.java.target"] = project.targetCompatibility - properties["sonar.java.binaries"] = sourceSets.main.output.classesDir - properties["sonar.java.test.binaries"] = sourceSets.test.output.classesDir - } - } - - publishing { - publications { - shadow(MavenPublication) { publication -> - project.shadow.component(publication) - } - } - repositories { - maven { - url "${nexusBaseUrl}/repository/${nexusUpRepo}-${'snapshots'}" - credentials { - username "${nexusUser}" - password "${nexusPassword}" - } - } - } - } - // This task creates a jar with test classes. - task testClassesJar(type: Jar) { - classifier = 'tests' - from sourceSets.test.output - } - - task sourcesJar(type: Jar, dependsOn: classes) { - classifier = 'sources' - from sourceSets.main.allSource - } - // Add a new configuration named testArtifacts - configurations { - testArtifacts - } - // testArtifacts contains the jar with test classes. - // Other projects can declare the dependency: - // testCompile project(path: ':JAICore:jaicore-basic', configuration: 'testArtifacts') - artifacts { - testArtifacts testClassesJar - archives sourcesJar, javadocJar - } - - // generate JavaDoc for each project - task generateJavadoc(type: Javadoc) { - source = sourceSets.main.allJava - classpath = files(sourceSets.main.compileClasspath) - destinationDir = file("docs/javadoc") -// failOnError = true - } - -} - -//signing { -// sign configurations.archives -//} - - -dependencies{ - compile project(":hasco") - compile project(":mlplan") - compile project(":JAICore:jaicore-basic") - compile (project(":JAICore:jaicore-ea")) { - exclude group: 'commons-cli' - } - compile project(":JAICore:jaicore-experiments") - compile project(":JAICore:jaicore-graphvisualizer") - compile project(":JAICore:jaicore-logic") - compile project(":JAICore:jaicore-math") - compile project(":JAICore:jaicore-ml") - compile project(":JAICore:jaicore-planning") - compile project(":JAICore:jaicore-processes") - compile project(":JAICore:jaicore-search") -} - -test{ - maxHeapSize = "4g" -} - -publish.dependsOn shadowJar +buildscript { + repositories { + mavenLocal() + mavenCentral() + maven { url "https://plugins.gradle.org/m2/" } + } + dependencies { + classpath "com.github.jengelman.gradle.plugins:shadow:2.0.4" + } +} + +// Artifact publishing and versoning +plugins { + id 'nebula.release' version '6.0.2' + id "nebula.project" version "3.4.0" + id "nebula.maven-base-publish" version "5.1.4" + id "org.sonarqube" version "2.6.2" +} + +allprojects { + //Shadow for fat-jars + apply plugin: "com.github.johnrengelman.shadow" + + //IDE + apply plugin: "java" + apply plugin: "eclipse" + apply plugin: "idea" + + //Other + apply plugin: "maven" + apply plugin: "jacoco" + apply plugin: "signing" + + //Nebula + apply plugin: 'nebula.project' + apply plugin: 'nebula.nebula-release' + apply plugin: 'nebula.maven-base-publish' + + //Java version + sourceCompatibility = 1.8 + targetCompatibility = 1.8 + + //Project properties + project.group = 'ai.libs' + project.version = '0.1.2' + + sourceSets { + main { + java { + srcDir 'src/main/java' + } + resources { + srcDir 'conf' + srcDir 'resources' + } + } + test { + java { + srcDir 'src/test/java' + srcDir 'src/example/java' + } + } + } + + //Repositories + repositories { + mavenCentral() + mavenLocal() + maven { url "https://jitpack.io" } + maven { url "http://clojars.org/repo/" } + maven { url "https://plugins.gradle.org/m2/" } + maven { url "https://nexus.cs.upb.de/repository/maven-releases/" } + flatDir { + dirs 'lib' + } + } + //Dependencies for all(!) projects + dependencies { + + // configuration + compile group: 'org.aeonbits.owner', name: 'owner-java8', version:'1.0.10' + + // event bus + compile group: 'com.google.guava', name: 'guava', version: '27.0-jre' + + //Logger + compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' + runtimeOnly group: 'org.slf4j', name:'slf4j-log4j12', version:'1.7.25' + + //Testing + testCompile group: 'junit', name: 'junit', version: '4.12' + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3' + testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19' + } + + //Always check for updates in SNAPSHOT versions, do not cache + configurations.all { + // check for updates every build + resolutionStrategy.cacheChangingModulesFor 0, 'seconds' + exclude module: 'all' + } + + //Nebula releases + nebulaRelease { addReleaseBranchPattern('/dev/') } + + //Sonarqube config + sonarqube { + properties { + properties["sonar.projectKey"] = "starlibs.ailibs" + properties["sonar.projectName"] = project.name + properties["sonar.projectDescription"] = project.description + properties["sonar.projectVersion"] = project.version + properties["sonar.projectBaseDir"] = project.projectDir + properties["sonar.working.directory"] = "$project.buildDir/sonar" + properties["sonar.sourceEncoding"] = project.compileJava.options.encoding + properties["sonar.java.source"] = project.sourceCompatibility + properties["sonar.java.target"] = project.targetCompatibility + properties["sonar.java.binaries"] = sourceSets.main.output.classesDir + properties["sonar.java.test.binaries"] = sourceSets.test.output.classesDir + } + } + + publishing { + publications { + shadow(MavenPublication) { publication -> + project.shadow.component(publication) + } + } + repositories { + maven { + url "${nexusBaseUrl}/repository/${nexusUpRepo}-${'snapshots'}" + credentials { + username "${nexusUser}" + password "${nexusPassword}" + } + } + } + } + // This task creates a jar with test classes. + task testClassesJar(type: Jar) { + classifier = 'tests' + from sourceSets.test.output + } + + task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from sourceSets.main.allSource + } + // Add a new configuration named testArtifacts + configurations { + testArtifacts + } + // testArtifacts contains the jar with test classes. + // Other projects can declare the dependency: + // testCompile project(path: ':JAICore:jaicore-basic', configuration: 'testArtifacts') + artifacts { + testArtifacts testClassesJar + archives sourcesJar, javadocJar + } + + // generate JavaDoc for each project + task generateJavadoc(type: Javadoc) { + source = sourceSets.main.allJava + classpath = files(sourceSets.main.compileClasspath) + destinationDir = file("docs/javadoc") +// failOnError = true + } + + signing { + sign configurations.archives + } + +} + + +dependencies{ + compile project(":hasco") + compile project(":mlplan") + compile project(":JAICore:jaicore-basic") + compile (project(":JAICore:jaicore-ea")) { + exclude group: 'commons-cli' + } + compile project(":JAICore:jaicore-experiments") + compile project(":JAICore:jaicore-graphvisualizer") + compile project(":JAICore:jaicore-logic") + compile project(":JAICore:jaicore-math") + compile project(":JAICore:jaicore-ml") + compile project(":JAICore:jaicore-planning") + compile project(":JAICore:jaicore-processes") + compile project(":JAICore:jaicore-search") +} + +test{ + maxHeapSize = "4g" +} + +publish.dependsOn shadowJar diff --git a/softwareconfiguration/hasco/build.gradle b/softwareconfiguration/hasco/build.gradle index 457c2e8707..529a702064 100644 --- a/softwareconfiguration/hasco/build.gradle +++ b/softwareconfiguration/hasco/build.gradle @@ -12,15 +12,19 @@ dependencies { testCompile project(path: ':JAICore:jaicore-basic', configuration: 'testArtifacts') } + uploadArchives { repositories { mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") + authentication(userName: ossrhUsername, password: ossrhPassword) } pom.project { @@ -56,8 +60,8 @@ uploadArchives { } developer { id 'ahetzer' - name 'Alexander Hetzer' - email 'alexander.hetzer@upb.de' + name 'Alexander Tornede' + email 'alexander.tornede@upb.de' } } } diff --git a/softwareconfiguration/hasco/conf/ai/libs/hasco/testrsc/weka-all-autoweka.json b/softwareconfiguration/hasco/conf/ai/libs/hasco/testrsc/weka-all-autoweka.json new file mode 100644 index 0000000000..123388297d --- /dev/null +++ b/softwareconfiguration/hasco/conf/ai/libs/hasco/testrsc/weka-all-autoweka.json @@ -0,0 +1,18 @@ +{ + "repository" : "WEKA - Auto-WEKA Searchspace", + "include": ["./weka-classifiers-autoweka.json", "./weka-preprocessors-autoweka.json"], + "components" : [ { + "name" : "pipeline", + "providedInterface" : [ "MLPipeline", "AbstractClassifier" ], + "requiredInterface" : [ + { + "id": "preprocessor", + "name": "AbstractPreprocessor" + }, { + "id": "classifier", + "name": "BaseClassifier" + } + ], + "parameter" : [ ] + }] +} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/weka/autoweka-for-mlc.json b/softwareconfiguration/hasco/conf/ai/libs/hasco/testrsc/weka-classifiers-autoweka.json similarity index 80% rename from softwareconfiguration/mlplan/resources/automl/searchmodels/weka/autoweka-for-mlc.json rename to softwareconfiguration/hasco/conf/ai/libs/hasco/testrsc/weka-classifiers-autoweka.json index b3e88768d7..e085df66e9 100644 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/weka/autoweka-for-mlc.json +++ b/softwareconfiguration/hasco/conf/ai/libs/hasco/testrsc/weka-classifiers-autoweka.json @@ -1,6 +1,6 @@ { "repository" : "Auto-WEKA", - "components" : [ { + "components" : [ { "name" : "weka.classifiers.bayes.BayesNet", "requiredInterface" : [ ], "providedInterface" : [ "AbstractClassifier", "WekaBaseClassifier", "BaseClassifier", "Test" ], @@ -32,7 +32,13 @@ "pre" : "D in {true}", "post" : "K in {false}" } ] - }, { + }, { + "name" : "weka.classifiers.bayes.NaiveBayesMultinomial", + "requiredInterface" : [ ], + "providedInterface" : [ "AbstractClassifier", "WekaBaseClassifier", "BaseClassifier" ], + "parameter" : [ ], + "dependencies" : [ ] + }, { "name" : "weka.classifiers.functions.Logistic", "requiredInterface" : [ ], "providedInterface" : [ "AbstractClassifier", "WekaBaseClassifier", "BaseClassifier" ], @@ -94,7 +100,47 @@ "values" : [ "1" ] } ], "dependencies" : [ ] - }, { + }, { + "name" : "weka.classifiers.functions.SimpleLinearRegression", + "requiredInterface" : [ ], + "providedInterface" : [ "AbstractClassifier", "WekaBaseClassifier", "Regressor", "BaseClassifier" ], + "parameter" : [ ], + "dependencies" : [ ] + }, { + "name" : "weka.classifiers.functions.SimpleLogistic", + "requiredInterface" : [ ], + "providedInterface" : [ "AbstractClassifier", "WekaBaseClassifier", "BaseClassifier" ], + "parameter" : [ { + "name" : "S", + "type" : "boolean", + "default" : "true" + }, { + "name" : "WActivator", + "type" : "cat", + "default" : "0", + "values" : [ "0", "1" ] + }, { + "name" : "W", + "type" : "double", + "default" : "0", + "values" : [ "0" ], + "min" : 0.0, + "max" : 0.0, + "refineSplits" : 8, + "minInterval" : 10 + }, { + "name" : "A", + "type" : "boolean", + "default" : "true" + } ], + "dependencies" : [ { + "pre" : "WActivator in {0}", + "post" : "W in {0}" + }, { + "pre" : "WActivator in {1}", + "post" : "W in [0.0,1.0]" + } ] + }, { "name" : "weka.classifiers.functions.supportVector.NormalizedPolyKernel", "requiredInterface" : [ ], "providedInterface" : [ "K" ], @@ -137,7 +183,37 @@ "requiredInterface" : [ ], "providedInterface" : [ "K" ], "parameter" : [ ] - }, { + }, { + "name" : "weka.classifiers.functions.VotedPerceptron", + "requiredInterface" : [ ], + "providedInterface" : [ "AbstractClassifier", "WekaBaseClassifier", "BaseClassifier" ], + "parameter" : [ { + "name" : "I", + "type" : "int", + "default" : 1.0, + "min" : 1.0, + "max" : 10.0, + "refineSplits" : 8, + "minInterval" : 10 + }, { + "name" : "M", + "type" : "int", + "default" : 10000.0, + "min" : 5000.0, + "max" : 50000.0, + "refineSplits" : 8, + "minInterval" : 10 + }, { + "name" : "E", + "type" : "double", + "default" : 1.0, + "min" : 0.2, + "max" : 5.0, + "refineSplits" : 8, + "minInterval" : 10 + } ], + "dependencies" : [ ] + }, { "name" : "weka.classifiers.lazy.IBk", "requiredInterface" : [ ], "providedInterface" : [ "AbstractClassifier", "WekaBaseClassifier", "BaseClassifier" ], @@ -157,12 +233,19 @@ "name" : "X", "type" : "boolean", "default" : "true" + }, { + "name" : "F", + "type" : "boolean", + "default" : "true" }, { "name" : "I", "type" : "boolean", "default" : "true" } ], - "dependencies" : [ ] + "dependencies" : [ { + "pre" : "I in {true}", + "post" : "F in {false, true}" + } ] }, { "name" : "weka.classifiers.lazy.KStar", "requiredInterface" : [ ], @@ -216,7 +299,33 @@ "minInterval" : 10 } ], "dependencies" : [ ] - },{ + }, { + "name" : "weka.classifiers.rules.M5Rules", + "requiredInterface" : [ ], + "providedInterface" : [ "AbstractClassifier", "WekaBaseClassifier", "BaseClassifier" ], + "parameter" : [ { + "name" : "N", + "type" : "boolean", + "default" : "true" + }, { + "name" : "M", + "type" : "int", + "default" : 4.0, + "min" : 1.0, + "max" : 64.0, + "refineSplits" : 8, + "minInterval" : 10 + }, { + "name" : "U", + "type" : "boolean", + "default" : "true" + }, { + "name" : "R", + "type" : "boolean", + "default" : "true" + } ], + "dependencies" : [ ] + }, { "name" : "weka.classifiers.rules.OneR", "requiredInterface" : [ ], "providedInterface" : [ "AbstractClassifier", "WekaBaseClassifier", "BaseClassifier" ], @@ -261,7 +370,7 @@ } ], "dependencies" : [ { "pre" : "R in {false}", - "post" : "N in [3.0,3.0]" + "post" : "N in [2.0,5.0]" } ] }, { "name" : "weka.classifiers.rules.ZeroR", @@ -308,7 +417,7 @@ "refineSplits" : 8, "minInterval" : 10 } ], - "dependencies" : [ ] + "dependencies" : [ ] }, { "name" : "weka.classifiers.trees.LMT", "requiredInterface" : [ ], @@ -363,6 +472,32 @@ "pre" : "WActivator in {1}", "post" : "W in [0.0,1.0]" } ] + }, { + "name" : "weka.classifiers.trees.M5P", + "requiredInterface" : [ ], + "providedInterface" : [ "AbstractClassifier", "WekaBaseClassifier", "Regressor", "BaseClassifier" ], + "parameter" : [ { + "name" : "N", + "type" : "boolean", + "default" : "true" + }, { + "name" : "M", + "type" : "int", + "default" : 4.0, + "min" : 1.0, + "max" : 64.0, + "refineSplits" : 8, + "minInterval" : 10 + }, { + "name" : "U", + "type" : "boolean", + "default" : "true" + }, { + "name" : "R", + "type" : "boolean", + "default" : "true" + } ], + "dependencies" : [ ] }, { "name" : "weka.classifiers.trees.RandomForest", "requiredInterface" : [ ], @@ -648,8 +783,8 @@ "default" : "true" } ], "dependencies" : [ { - "pre" : "O in {true}", - "post" : "P in {100}" + "pre" : "P in {100}", + "post" : "O in {false}" } ] }, { "name" : "weka.classifiers.meta.ClassificationViaRegression", @@ -747,5 +882,6 @@ "values" : [ "1" ] } ], "dependencies" : [ ] - } ] + } + ] } \ No newline at end of file diff --git a/softwareconfiguration/hasco/conf/ai/libs/hasco/testrsc/weka-preprocessors-autoweka.json b/softwareconfiguration/hasco/conf/ai/libs/hasco/testrsc/weka-preprocessors-autoweka.json new file mode 100644 index 0000000000..c54d08a3ee --- /dev/null +++ b/softwareconfiguration/hasco/conf/ai/libs/hasco/testrsc/weka-preprocessors-autoweka.json @@ -0,0 +1,209 @@ +{ + "repository" : "WEKA Preprocessors Auto-WEKA", + "components" : [ { + "name" : "weka.attributeSelection.CfsSubsetEval", + "requiredInterface" : [ ], + "providedInterface" : [ "evaluator" ], + "parameter" : [ { + "name" : "M", + "type" : "boolean", + "default" : "true" + }, { + "name" : "L", + "type" : "boolean", + "default" : "true" + } ], + "dependencies" : [ ] + }, { + "name" : "weka.attributeSelection.CorrelationAttributeEval", + "requiredInterface" : [ ], + "providedInterface" : [ "evaluator" ], + "parameter" : [ ], + "dependencies" : [ ] + }, { + "name" : "weka.attributeSelection.GainRatioAttributeEval", + "requiredInterface" : [ ], + "providedInterface" : [ "evaluator" ], + "parameter" : [ ], + "dependencies" : [ ] + }, { + "name" : "weka.attributeSelection.InfoGainAttributeEval", + "requiredInterface" : [ ], + "providedInterface" : [ "evaluator" ], + "parameter" : [ { + "name" : "M", + "type" : "boolean", + "default" : "true" + }, { + "name" : "B", + "type" : "boolean", + "default" : "true" + } ], + "dependencies" : [ ] + }, { + "name" : "weka.attributeSelection.OneRAttributeEval", + "requiredInterface" : [ ], + "providedInterface" : [ "evaluator" ], + "parameter" : [ { + "name" : "S", + "type" : "cat", + "default" : "0", + "values" : [ "0" ] + }, { + "name" : "F", + "type" : "int", + "default" : 10.0, + "min" : 2.0, + "max" : 15.0, + "refineSplits" : 8, + "minInterval" : 10 + }, { + "name" : "D", + "type" : "boolean", + "default" : "true" + }, { + "name" : "B", + "type" : "int", + "default" : 6.0, + "min" : 1.0, + "max" : 64.0, + "refineSplits" : 8, + "minInterval" : 10 + } ], + "dependencies" : [ ] + }, { + "name" : "weka.attributeSelection.PrincipalComponents", + "requiredInterface" : [ ], + "providedInterface" : [ "evaluator" ], + "parameter" : [ { + "name" : "numActivator", + "type" : "cat", + "default" : "0", + "values" : [ "0", "1" ] + }, { + "name" : "A", + "type" : "int", + "default" : "-1", + "values" : [ "-1" ], + "min" : -1.0, + "max" : -1.0, + "refineSplits" : 8, + "minInterval" : 10 + }, { + "name" : "C", + "type" : "boolean", + "default" : "true" + }, { + "name" : "R", + "type" : "double", + "default" : 0.95, + "min" : 0.5, + "max" : 1.0, + "refineSplits" : 8, + "minInterval" : 10 + }, { + "name" : "O", + "type" : "boolean", + "default" : "true" + } ], + "dependencies" : [ { + "pre" : "numActivator in {0}", + "post" : "A in {-1}" + }, { + "pre" : "numActivator in {1}", + "post" : "A in [1.0,1024.0]" + } ] + }, { + "name" : "weka.attributeSelection.ReliefFAttributeEval", + "requiredInterface" : [ ], + "providedInterface" : [ "evaluator" ], + "parameter" : [ { + "name" : "K", + "type" : "int", + "default" : 10.0, + "min" : 2.0, + "max" : 64.0, + "refineSplits" : 8, + "minInterval" : 10 + }, { + "name" : "WActivator", + "type" : "cat", + "default" : "0", + "values" : [ "0", "1" ] + }, { + "name" : "W", + "type" : "cat", + "default" : "REMOVED", + "values" : [ "REMOVED" ] + }, { + "name" : "A", + "type" : "int", + "default" : 2.0, + "min" : 1.0, + "max" : 8.0, + "refineSplits" : 8, + "minInterval" : 10 + } ], + "dependencies" : [ { + "pre" : "WActivator in {1}", + "post" : "W in {false}" + }, { + "pre" : "WActivator in {1}", + "post" : "A in [1.0,8.0]" + } ] + }, { + "name" : "weka.attributeSelection.SymmetricalUncertAttributeEval", + "requiredInterface" : [ ], + "providedInterface" : [ "evaluator" ], + "parameter" : [ { + "name" : "M", + "type" : "boolean", + "default" : "true" + } ], + "dependencies" : [ ] + }, { + "name" : "weka.attributeSelection.BestFirst", + "requiredInterface" : [ ], + "providedInterface" : [ "searcher" ], + "parameter" : [ { + "name" : "D", + "type" : "cat", + "default" : "1", + "values": ["0","1","2"] + } ], + "dependencies" : [ ] + }, { + "name" : "weka.attributeSelection.GreedyStepwise", + "requiredInterface" : [ ], + "providedInterface" : [ "searcher" ], + "parameter" : [ { + "name" : "C", + "type" : "boolean", + "default" : "true" + }, { + "name" : "B", + "type" : "boolean", + "default" : "false" + } ], + "dependencies" : [ ] + },{ + "name" : "weka.attributeSelection.Ranker", + "requiredInterface" : [ ], + "providedInterface" : [ "searcher" ], + "parameter" : [ ], + "dependencies" : [ ] + }, { + "name" : "weka.attributeSelection.AttributeSelection", + "providedInterface" : [ "AbstractPreprocessor" ], + "requiredInterface" : [ {"id": "eval", "name": "evaluator" }, {"id": "search", "name": "searcher" } ], + "parameter" : [ { + "name" : "M", + "type" : "boolean", + "default" : "true" + } ], + "dependencies" : [ ] + } + + + ] +} \ No newline at end of file diff --git a/softwareconfiguration/hasco/conf/log4j.xml b/softwareconfiguration/hasco/conf/log4j.xml index 992cdc1dfa..366b2860be 100644 --- a/softwareconfiguration/hasco/conf/log4j.xml +++ b/softwareconfiguration/hasco/conf/log4j.xml @@ -46,7 +46,7 @@ - + @@ -55,11 +55,11 @@ - + - + @@ -68,19 +68,19 @@ - + - + - + - + @@ -94,11 +94,11 @@ - + - + diff --git a/softwareconfiguration/hasco/conf/searchgraph.css b/softwareconfiguration/hasco/conf/searchgraph.css deleted file mode 100644 index c2ab39965b..0000000000 --- a/softwareconfiguration/hasco/conf/searchgraph.css +++ /dev/null @@ -1,69 +0,0 @@ -edge { - padding: 100px; -} - -node { - size-mode: fit; - fill-mode: plain; - fill-color: grey; - padding: 5px; -} - -node.root { - padding: 10px; - fill-color: black; -} - -node.expanding { - fill-color: blue; -} - - -node.or_pruned { - fill-color: red; -} - -node.or_distributed { - fill-color: orange; -} - -node.or_prioritized { - fill-color: brown; -} - -node.and_closed { - shape: box; - padding: 6px; - fill-color: brown; -} - -node.and_open { - shape: box; - padding: 6px; - stroke-color: brown; - stroke-mode: plain; - fill-mode: none; -} - -node.or_closed { - shape: circle; - fill-color: purple; -} - -node.or_open { - shape: circle; - stroke-mode: plain; - fill-mode: none; - stroke-color: purple; -} - -node.and_solution { - shape: box; - padding: 6px; - fill-color: green; -} - -node.or_solution { - shape: circle; - fill-color: green; -} \ No newline at end of file diff --git a/softwareconfiguration/hasco/src/example/java/ai/libs/hasco/examples/HASCOModelStatisticsObserverPluginExample.java b/softwareconfiguration/hasco/src/example/java/ai/libs/hasco/examples/HASCOModelStatisticsObserverPluginExample.java index c7baa5cc1d..9b2e539478 100644 --- a/softwareconfiguration/hasco/src/example/java/ai/libs/hasco/examples/HASCOModelStatisticsObserverPluginExample.java +++ b/softwareconfiguration/hasco/src/example/java/ai/libs/hasco/examples/HASCOModelStatisticsObserverPluginExample.java @@ -1,50 +1,49 @@ -package ai.libs.hasco.examples; - -import java.io.File; -import java.io.IOException; -import java.util.Random; -import java.util.concurrent.TimeoutException; - -import com.google.common.eventbus.Subscribe; - -import ai.libs.hasco.core.RefinementConfiguredSoftwareConfigurationProblem; -import ai.libs.hasco.events.HASCOSolutionEvent; -import ai.libs.hasco.gui.civiewplugin.TFDNodeAsCIViewInfoGenerator; -import ai.libs.hasco.gui.statsplugin.HASCOModelStatisticsPlugin; -import ai.libs.hasco.serialization.CompositionSerializer; -import ai.libs.hasco.serialization.UnresolvableRequiredInterfaceException; -import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDAndBestFirst; -import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDAndBestFirstFactory; -import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; -import ai.libs.jaicore.graphvisualizer.plugin.graphview.GraphViewPlugin; -import ai.libs.jaicore.graphvisualizer.plugin.nodeinfo.NodeInfoGUIPlugin; -import ai.libs.jaicore.graphvisualizer.window.AlgorithmVisualizationWindow; -import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNodeInfoGenerator; -import jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; - -import javafx.application.Platform; -import javafx.embed.swing.JFXPanel; -public class HASCOModelStatisticsObserverPluginExample { - public static void main(final String[] args) throws UnresolvableRequiredInterfaceException, IOException, InterruptedException, AlgorithmExecutionCanceledException, TimeoutException, AlgorithmException { - HASCOViaFDAndBestFirstFactory hascoFactory = new HASCOViaFDAndBestFirstFactory<>(n -> 0.0); - Random r = new Random(); - RefinementConfiguredSoftwareConfigurationProblem problem = new RefinementConfiguredSoftwareConfigurationProblem<>(new File("testrsc/simpleproblemwithtwocomponents.json"), "IFace", n -> System.currentTimeMillis() * 1.0); - hascoFactory.setProblemInput(problem); - // RefinementConfiguredSoftwareConfigurationProblem problem = new RefinementConfiguredSoftwareConfigurationProblem<>(new File("testrsc/tinylogparamproblem.json"), "IFace", n -> r.nextDouble()); -// hascoFactory.setProblemInput(problem); - HASCOViaFDAndBestFirst hasco = hascoFactory.getAlgorithm(); - hasco.setNumCPUs(1); - hasco.registerListener(new Object() { - - @Subscribe - public void receiveSolution(final HASCOSolutionEvent solutionEvent) { - System.out.println(CompositionSerializer.serializeComponentInstance(solutionEvent.getSolutionCandidate().getComponentInstance())); - - } - }); - new JFXPanel(); - Platform.runLater(new AlgorithmVisualizationWindow(hasco, new GraphViewPlugin(), new NodeInfoGUIPlugin<>(new TFDNodeAsCIViewInfoGenerator(problem.getComponents())), new HASCOModelStatisticsPlugin())); - hasco.call(); - } -} +package ai.libs.hasco.examples; + +import java.io.File; +import java.io.IOException; +import java.util.Random; +import java.util.concurrent.TimeoutException; + +import com.google.common.eventbus.Subscribe; + +import ai.libs.hasco.core.RefinementConfiguredSoftwareConfigurationProblem; +import ai.libs.hasco.events.HASCOSolutionEvent; +import ai.libs.hasco.gui.civiewplugin.TFDNodeAsCIViewInfoGenerator; +import ai.libs.hasco.gui.statsplugin.HASCOModelStatisticsPlugin; +import ai.libs.hasco.serialization.CompositionSerializer; +import ai.libs.hasco.serialization.UnresolvableRequiredInterfaceException; +import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDAndBestFirst; +import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDAndBestFirstFactory; +import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; +import ai.libs.jaicore.graphvisualizer.plugin.graphview.GraphViewPlugin; +import ai.libs.jaicore.graphvisualizer.plugin.nodeinfo.NodeInfoGUIPlugin; +import ai.libs.jaicore.graphvisualizer.window.AlgorithmVisualizationWindow; +import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNodeInfoGenerator; +import ai.libs.jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; +import javafx.application.Platform; +import javafx.embed.swing.JFXPanel; +public class HASCOModelStatisticsObserverPluginExample { + public static void main(final String[] args) throws UnresolvableRequiredInterfaceException, IOException, InterruptedException, AlgorithmExecutionCanceledException, TimeoutException, AlgorithmException { + HASCOViaFDAndBestFirstFactory hascoFactory = new HASCOViaFDAndBestFirstFactory<>(n -> 0.0); + Random r = new Random(); + RefinementConfiguredSoftwareConfigurationProblem problem = new RefinementConfiguredSoftwareConfigurationProblem<>(new File("testrsc/simpleproblemwithtwocomponents.json"), "IFace", n -> System.currentTimeMillis() * 1.0); + hascoFactory.setProblemInput(problem); + // RefinementConfiguredSoftwareConfigurationProblem problem = new RefinementConfiguredSoftwareConfigurationProblem<>(new File("testrsc/tinylogparamproblem.json"), "IFace", n -> r.nextDouble()); +// hascoFactory.setProblemInput(problem); + HASCOViaFDAndBestFirst hasco = hascoFactory.getAlgorithm(); + hasco.setNumCPUs(1); + hasco.registerListener(new Object() { + + @Subscribe + public void receiveSolution(final HASCOSolutionEvent solutionEvent) { + System.out.println(CompositionSerializer.serializeComponentInstance(solutionEvent.getSolutionCandidate().getComponentInstance())); + + } + }); + new JFXPanel(); + Platform.runLater(new AlgorithmVisualizationWindow(hasco, new GraphViewPlugin(), new NodeInfoGUIPlugin<>(new TFDNodeAsCIViewInfoGenerator(problem.getComponents())), new HASCOModelStatisticsPlugin())); + hasco.call(); + } +} diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/DefaultHASCOPlanningGraphGeneratorDeriver.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/DefaultHASCOPlanningGraphGeneratorDeriver.java index 8b80a1e02f..48763bbc5c 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/DefaultHASCOPlanningGraphGeneratorDeriver.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/DefaultHASCOPlanningGraphGeneratorDeriver.java @@ -7,8 +7,8 @@ import ai.libs.jaicore.planning.core.Plan; import ai.libs.jaicore.planning.hierarchical.problems.ceocipstn.CEOCIPSTNPlanningProblem; import ai.libs.jaicore.planning.hierarchical.problems.htn.IHierarchicalPlanningGraphGeneratorDeriver; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; /** * This class only serves to facilitate the usage of HASCO when passing a IPlanningGraphGeneratorDeriver. diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/HASCO.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/HASCO.java index 01eadf2bb2..bebe38fd21 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/HASCO.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/HASCO.java @@ -40,13 +40,13 @@ import ai.libs.jaicore.planning.hierarchical.problems.ceocipstn.CEOCIPSTNPlanningProblem; import ai.libs.jaicore.planning.hierarchical.problems.htn.CostSensitiveHTNPlanningProblem; import ai.libs.jaicore.planning.hierarchical.problems.htn.CostSensitivePlanningToSearchProblemTransformer; -import jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearch; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.events.EvaluatedSearchSolutionCandidateFoundEvent; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearch; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; /** * Hierarchically create an object of type T diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/HASCOFactory.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/HASCOFactory.java index a9d1594e40..03d7cb271c 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/HASCOFactory.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/HASCOFactory.java @@ -7,10 +7,10 @@ import ai.libs.hasco.optimizingfactory.SoftwareConfigurationAlgorithmFactory; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; public class HASCOFactory, N, A, V extends Comparable> implements SoftwareConfigurationAlgorithmFactory, HASCOSolutionCandidate, V> { diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/Util.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/Util.java index 92b633e390..2a6ee42f8e 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/Util.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/core/Util.java @@ -1,610 +1,610 @@ -package ai.libs.hasco.core; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Deque; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import org.apache.commons.math3.geometry.euclidean.oned.Interval; -import org.apache.commons.math3.geometry.partitioning.Region.Location; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import ai.libs.hasco.model.CategoricalParameterDomain; -import ai.libs.hasco.model.Component; -import ai.libs.hasco.model.ComponentInstance; -import ai.libs.hasco.model.Dependency; -import ai.libs.hasco.model.IParameterDomain; -import ai.libs.hasco.model.NumericParameterDomain; -import ai.libs.hasco.model.Parameter; -import ai.libs.hasco.model.ParameterRefinementConfiguration; -import ai.libs.jaicore.basic.sets.SetUtil; -import ai.libs.jaicore.basic.sets.SetUtil.Pair; -import ai.libs.jaicore.logic.fol.structure.Literal; -import ai.libs.jaicore.logic.fol.structure.LiteralParam; -import ai.libs.jaicore.logic.fol.structure.Monom; -import ai.libs.jaicore.planning.classical.algorithms.strips.forward.StripsUtil; -import ai.libs.jaicore.planning.core.Action; -import ai.libs.jaicore.planning.core.Plan; -import ai.libs.jaicore.planning.hierarchical.problems.ceocipstn.CEOCIPSTNPlanningProblem; -import ai.libs.jaicore.planning.hierarchical.problems.htn.IHierarchicalPlanningGraphGeneratorDeriver; -import jaicore.search.model.other.SearchGraphPath; -import jaicore.search.model.travesaltree.Node; - -public class Util { - - private static final String LITERAL_RESOLVES = "resolves"; - private static final String LITERAL_PARAMCONTAINER = "parameterContainer"; - private static final String LITERAL_VAL = "val"; - private static final String LITERAL_INTERFACEIDENTIFIER = "interfaceIdentifier"; - - private static final Logger logger = LoggerFactory.getLogger(Util.class); - - private Util() { - - } - - static Map getParameterContainerMap(final Monom state, final String objectName) { - Map parameterContainerMap = new HashMap<>(); - List containerLiterals = state.stream().filter(l -> l.getPropertyName().equals(LITERAL_PARAMCONTAINER) && l.getParameters().get(2).getName().equals(objectName)).collect(Collectors.toList()); - containerLiterals.forEach(l -> parameterContainerMap.put(l.getParameters().get(1).getName(), l.getParameters().get(3).getName())); - return parameterContainerMap; - } - - public static Map> getParametrizations(final Monom state, final Collection components, final boolean resolveIntervals) { - Map objectMap = new HashMap<>(); - Map> parameterContainerMap = new HashMap<>(); // stores for each object the name of the container of each parameter - Map parameterValues = new HashMap<>(); - - Map> parameterValuesPerComponentInstance = new HashMap<>(); - - Collection overwrittenDataContainers = getOverwrittenDatacontainersInState(state); - - /* - * create (empty) component instances, detect containers for parameter values, and register the - * values of the data containers - */ - for (Literal l : state) { - String[] params = l.getParameters().stream().map(LiteralParam::getName).collect(Collectors.toList()).toArray(new String[] {}); - switch (l.getPropertyName()) { - case LITERAL_RESOLVES: // field 0 and 1 (parent object name and interface name) are ignored here - String componentName = params[2]; - String objectName = params[3]; - Optional component = components.stream().filter(c -> c.getName().equals(componentName)).findAny(); - assert component.isPresent() : "Could not find component with name " + componentName; - ComponentInstance object = new ComponentInstance(component.get(), new HashMap<>(), new HashMap<>()); - objectMap.put(objectName, object); - break; - case LITERAL_PARAMCONTAINER: - if (!parameterContainerMap.containsKey(params[2])) { - parameterContainerMap.put(params[2], new HashMap<>()); - } - parameterContainerMap.get(params[2]).put(params[1], params[3]); - break; - case LITERAL_VAL: - if (overwrittenDataContainers.contains(params[0])) { - parameterValues.put(params[0], params[1]); - } - break; - - default: - - /* simply ignore other literals */ - break; - } - } - - /* update the configurations of the objects */ - for (Entry entry : objectMap.entrySet()) { - Map paramValuesForThisComponent = new HashMap<>(); - String objectName = entry.getKey(); - ComponentInstance object = entry.getValue(); - parameterValuesPerComponentInstance.put(object, paramValuesForThisComponent); - for (Parameter p : object.getComponent().getParameters()) { - - assert parameterContainerMap.containsKey(objectName) : "No parameter container map has been defined for object " + objectName + " of component " + object.getComponent().getName() + "!"; - assert parameterContainerMap.get(objectName).containsKey(p.getName()) : "The data container for parameter " + p.getName() + " of " + object.getComponent().getName() + " is not defined!"; - - String assignedValue = parameterValues.get(parameterContainerMap.get(objectName).get(p.getName())); - String interpretedValue = ""; - if (assignedValue != null) { - if (p.getDefaultDomain() instanceof NumericParameterDomain) { - if (resolveIntervals) { - NumericParameterDomain np = (NumericParameterDomain) p.getDefaultDomain(); - List vals = SetUtil.unserializeList(assignedValue); - Interval interval = new Interval(Double.valueOf(vals.get(0)), Double.valueOf(vals.get(1))); - if (np.isInteger()) { - interpretedValue = String.valueOf((int) Math.round(interval.getBarycenter())); - } else { - interpretedValue = String.valueOf(interval.getBarycenter()); - } - } else { - interpretedValue = assignedValue; - } - } else if (p.getDefaultDomain() instanceof CategoricalParameterDomain) { - interpretedValue = assignedValue; - } else { - throw new UnsupportedOperationException("No support for parameters of type " + p.getClass().getName()); - } - paramValuesForThisComponent.put(p, interpretedValue); - } - } - } - return parameterValuesPerComponentInstance; - } - - public static Collection getOverwrittenDatacontainersInState(final Monom state) { - return state.stream().filter(l -> l.getPropertyName().equals("overwritten")).map(l -> l.getParameters().get(0).getName()).collect(Collectors.toSet()); - } - - public static Collection getClosedDatacontainersInState(final Monom state) { - return state.stream().filter(l -> l.getPropertyName().equals("closed")).map(l -> l.getParameters().get(0).getName()).collect(Collectors.toSet()); - } - - static Map getGroundComponentsFromState(final Monom state, final Collection components, final boolean resolveIntervals) { - Map objectMap = new HashMap<>(); - Map> parameterContainerMap = new HashMap<>(); // stores for each object the name of the container of each parameter - Map parameterValues = new HashMap<>(); - Map interfaceContainerMap = new HashMap<>(); - Collection overwrittenDatacontainers = getOverwrittenDatacontainersInState(state); - - /* create (empty) component instances, detect containers for parameter values, and register the values of the data containers */ - for (Literal l : state) { - String[] params = l.getParameters().stream().map(LiteralParam::getName).collect(Collectors.toList()).toArray(new String[] {}); - switch (l.getPropertyName()) { - case LITERAL_RESOLVES: // field 0 and 1 (parent object name and interface name) are ignored here - String componentName = params[2]; - String objectName = params[3]; - - Optional component = components.stream().filter(c -> c.getName().equals(componentName)).findAny(); - assert component.isPresent() : "Could not find component with name " + componentName; - ComponentInstance object = new ComponentInstance(component.get(), new HashMap<>(), new HashMap<>()); - objectMap.put(objectName, object); - break; - case LITERAL_PARAMCONTAINER: - if (!parameterContainerMap.containsKey(params[2])) { - parameterContainerMap.put(params[2], new HashMap<>()); - } - parameterContainerMap.get(params[2]).put(params[1], params[3]); - break; - case LITERAL_VAL: - parameterValues.put(params[0], params[1]); - break; - case LITERAL_INTERFACEIDENTIFIER: - interfaceContainerMap.put(params[3], params[1]); - break; - default: - /* simply ignore other cases */ - break; - } - } - - /* now establish the binding of the required interfaces of the component instances */ - state.stream().filter(l -> l.getPropertyName().equals(LITERAL_RESOLVES)).forEach(l -> { - String[] params = l.getParameters().stream().map(LiteralParam::getName).collect(Collectors.toList()).toArray(new String[] {}); - String parentObjectName = params[0]; - String objectName = params[3]; - ComponentInstance object = objectMap.get(objectName); - if (!parentObjectName.equals("request")) { - assert interfaceContainerMap.containsKey(objectName) : "Object name " + objectName + " for requried interface must have a defined identifier "; - objectMap.get(parentObjectName).getSatisfactionOfRequiredInterfaces().put(interfaceContainerMap.get(objectName), object); - } - }); - - /* set the explicitly defined parameters (e.g. overwritten containers) in the component instances */ - for (Entry entry : objectMap.entrySet()) { - String objectName = entry.getKey(); - ComponentInstance object = entry.getValue(); - for (Parameter p : object.getComponent().getParameters()) { - - assert parameterContainerMap.containsKey(objectName) : "No parameter container map has been defined for object " + objectName + " of component " + object.getComponent().getName() + "!"; - assert parameterContainerMap.get(objectName).containsKey(p.getName()) : "The data container for parameter " + p.getName() + " of " + object.getComponent().getName() + " is not defined! State: " + state.stream().sorted().map(l -> "\n\t" + l).collect(Collectors.joining()); - String paramContainerName = parameterContainerMap.get(objectName).get(p.getName()); - if (overwrittenDatacontainers.contains(paramContainerName)) { - String assignedValue = parameterValues.get(paramContainerName); - assert assignedValue != null : "parameter containers must always have a value!"; - object.getParameterValues().put(p.getName(), getParamValue(p, assignedValue, resolveIntervals)); - } - } - } - return objectMap; - } - - public static > ComponentInstance getSolutionCompositionForNode(final IHierarchicalPlanningGraphGeneratorDeriver planningGraphDeriver, final Collection components, - final Monom initState, final Node path, final boolean resolveIntervals) { - return getSolutionCompositionForPlan(components, initState, planningGraphDeriver.decodeSolution(new SearchGraphPath<>(path.externalPath())), resolveIntervals); - } - - public static > ComponentInstance getComponentInstanceForNode(final IHierarchicalPlanningGraphGeneratorDeriver planningGraphDeriver, final Collection components, - final Monom initState, final Node path, final String name, final boolean resolveIntervals) { - return getComponentInstanceForPlan(components, initState, planningGraphDeriver.decodeSolution(new SearchGraphPath<>(path.externalPath())), name, resolveIntervals); - } - - public static Monom getFinalStateOfPlan(final Monom initState, final Plan plan) { - Monom state = new Monom(initState); - for (Action a : plan.getActions()) { - StripsUtil.updateState(state, a); - } - return state; - } - - public static ComponentInstance getSolutionCompositionForPlan(final Collection components, final Monom initState, final Plan plan, final boolean resolveIntervals) { - return getSolutionCompositionFromState(components, getFinalStateOfPlan(initState, plan), resolveIntervals); - } - - public static ComponentInstance getComponentInstanceForPlan(final Collection components, final Monom initState, final Plan plan, final String name, final boolean resolveIntervals) { - return getComponentInstanceFromState(components, getFinalStateOfPlan(initState, plan), name, resolveIntervals); - } - - public static ComponentInstance getSolutionCompositionFromState(final Collection components, final Monom state, final boolean resolveIntervals) { - return getComponentInstanceFromState(components, state, "solution", resolveIntervals); - } - - public static ComponentInstance getComponentInstanceFromState(final Collection components, final Monom state, final String name, final boolean resolveIntervals) { - return Util.getGroundComponentsFromState(state, components, resolveIntervals).get(name); - } - - /** - * Computes a String of component names that appear in the composition which can be used as an identifier for the composition - * - * @param composition - * @return String of all component names in right to left depth-first order - */ - public static String getComponentNamesOfComposition(final ComponentInstance composition) { - StringBuilder builder = new StringBuilder(); - Deque componentInstances = new ArrayDeque<>(); - componentInstances.push(composition); - ComponentInstance curInstance; - while (!componentInstances.isEmpty()) { - curInstance = componentInstances.pop(); - builder.append(curInstance.getComponent().getName()); - Map requiredInterfaces = curInstance.getComponent().getRequiredInterfaces(); - // This set should be ordered - Set requiredInterfaceNames = requiredInterfaces.keySet(); - for (String requiredInterfaceName : requiredInterfaceNames) { - ComponentInstance instance = curInstance.getSatisfactionOfRequiredInterfaces().get(requiredInterfaceName); - componentInstances.push(instance); - } - } - return builder.toString(); - } - - /** - * Computes a list of all components of the given composition. - * - * @param composition - * @return List of components in right to left depth-first order - */ - public static List getComponentsOfComposition(final ComponentInstance composition) { - List components = new LinkedList<>(); - Deque componentInstances = new ArrayDeque<>(); - componentInstances.push(composition); - ComponentInstance curInstance; - while (!componentInstances.isEmpty()) { - curInstance = componentInstances.pop(); - components.add(curInstance.getComponent()); - Map requiredInterfaces = curInstance.getComponent().getRequiredInterfaces(); - // This set should be ordered - Set requiredInterfaceNames = requiredInterfaces.keySet(); - for (String requiredInterfaceName : requiredInterfaceNames) { - ComponentInstance instance = curInstance.getSatisfactionOfRequiredInterfaces().get(requiredInterfaceName); - componentInstances.push(instance); - } - } - return components; - } - - public static Map getUpdatedDomainsOfComponentParameters(final Monom state, final Component component, final String objectIdentifierInState) { - Map parameterContainerMap = new HashMap<>(); - Map parameterContainerMapInv = new HashMap<>(); - Map parameterValues = new HashMap<>(); - - /* detect containers for parameter values, and register the values of the data containers */ - for (Literal l : state) { - String[] params = l.getParameters().stream().map(LiteralParam::getName).collect(Collectors.toList()).toArray(new String[] {}); - switch (l.getPropertyName()) { - case LITERAL_PARAMCONTAINER: - if (!params[2].equals(objectIdentifierInState)) { - continue; - } - parameterContainerMap.put(params[1], params[3]); - parameterContainerMapInv.put(params[3], params[1]); - break; - case LITERAL_VAL: - parameterValues.put(params[0], params[1]); - break; - default: // ignore other literals - break; - } - } - - /* determine current values of the parameters of this component instance */ - Map paramValuesForThisComponentInstance = new HashMap<>(); - for (Parameter p : component.getParameters()) { - if (!parameterContainerMap.containsKey(p.getName())) { - throw new IllegalStateException("The data container for parameter " + p.getName() + " of " + objectIdentifierInState + " is not defined!"); - } - String assignedValue = parameterValues.get(parameterContainerMap.get(p.getName())); - if (assignedValue == null) { - throw new IllegalStateException("No value has been assigned to parameter " + p.getName() + " stored in container " + parameterContainerMap.get(p.getName()) + " in state " + state); - } - String value = getParamValue(p, assignedValue, false); - assert value != null : "Determined value NULL for parameter " + p.getName() + ", which is not plausible."; - paramValuesForThisComponentInstance.put(p, value); - } - - /* extract instance */ - Collection components = new ArrayList<>(); - components.add(component); - ComponentInstance instance = getComponentInstanceFromState(components, state, objectIdentifierInState, false); - - /* now compute the new domains based on the current values */ - return getUpdatedDomainsOfComponentParameters(instance); - } - - private static String getParamValue(final Parameter p, final String assignedValue, final boolean resolveIntervals) { - String interpretedValue = ""; - if (assignedValue == null) { - throw new IllegalArgumentException("Cannot determine true value for assigned param value " + assignedValue + " for parameter " + p.getName()); - } - if (p.isNumeric()) { - if (resolveIntervals) { - NumericParameterDomain np = (NumericParameterDomain) p.getDefaultDomain(); - List vals = SetUtil.unserializeList(assignedValue); - Interval interval = new Interval(Double.valueOf(vals.get(0)), Double.valueOf(vals.get(1))); - if (np.isInteger()) { - interpretedValue = String.valueOf((int) Math.round(interval.getBarycenter())); - } else { - interpretedValue = String.valueOf(interval.checkPoint((double)p.getDefaultValue(), 0.001) == Location.INSIDE ? (double)p.getDefaultValue() : interval.getBarycenter()); - } - } else { - interpretedValue = assignedValue; - } - } else if (p.getDefaultDomain() instanceof CategoricalParameterDomain) { - interpretedValue = assignedValue; - } else { - throw new UnsupportedOperationException("No support for parameters of type " + p.getClass().getName()); - } - return interpretedValue; - } - - public static Map getUpdatedDomainsOfComponentParameters(final ComponentInstance componentInstance) { - Component component = componentInstance.getComponent(); - - /* initialize all params for which a decision has been made already with their respective value */ - Map domains = new HashMap<>(); - for (Parameter p : componentInstance.getParametersThatHaveBeenSetExplicitly()) { - if (p.isNumeric()) { - NumericParameterDomain defaultDomain = (NumericParameterDomain) p.getDefaultDomain(); - Interval interval = SetUtil.unserializeInterval(componentInstance.getParameterValue(p)); - domains.put(p, new NumericParameterDomain(defaultDomain.isInteger(), interval.getInf(), interval.getSup())); - } else if (p.isCategorical()) { - domains.put(p, new CategoricalParameterDomain(new String[] { componentInstance.getParameterValue(p) })); - } - } - - /* initialize all others with the default domain */ - for (Parameter p : componentInstance.getParametersThatHaveNotBeenSetExplicitly()) { - domains.put(p, p.getDefaultDomain()); - } - assert (domains.keySet().equals(component.getParameters())) : "There are parameters for which no current domain was derived."; - - /* update domains based on the dependencies defined for this component */ - for (Dependency dependency : component.getDependencies()) { - if (isDependencyPremiseSatisfied(dependency, domains)) { - logger.info("Premise of dependency {} is satisfied, applying its conclusions ...", dependency); - for (Pair newDomain : dependency.getConclusion()) { - /* - * directly use the concluded domain if the current value is NOT subsumed by it. Otherwise, just - * stick to the current domain - */ - Parameter param = newDomain.getX(); - IParameterDomain concludedDomain = newDomain.getY(); - if (!componentInstance.getParametersThatHaveBeenSetExplicitly().contains(param)) { - domains.put(param, concludedDomain); - logger.debug("Changing domain of {} from {} to {}", param, domains.get(param), concludedDomain); - } else { - logger.debug("Not changing domain of {} since it has already been set explicitly in the past.", param); - } - } - } else { - logger.debug("Ignoring unsatisfied dependency {}.", dependency); - } - } - return domains; - } - - public static boolean isDependencyPremiseSatisfied(final Dependency dependency, final Map values) { - logger.debug("Checking satisfcation of dependency {} with values {}", dependency, values); - for (Collection> condition : dependency.getPremise()) { - boolean check = isDependencyConditionSatisfied(condition, values); - logger.trace("Result of check for condition {}: {}", condition, check); - if (!check) { - return false; - } - } - return true; - } - - public static boolean isDependencyConditionSatisfied(final Collection> condition, final Map values) { - for (Pair conditionItem : condition) { - IParameterDomain requiredDomain = conditionItem.getY(); - Parameter param = conditionItem.getX(); - IParameterDomain actualDomain = values.get(param); - if (!values.containsKey(param)) { - throw new IllegalArgumentException("Cannot check condition " + condition + " as the value for parameter " + param.getName() + " is not defined in " + values); - } - if (values.get(param) == null) { - throw new IllegalArgumentException("Cannot check condition " + condition + " as the value for parameter " + param.getName() + " is NULL in " + values); - } - if (!requiredDomain.subsumes(actualDomain)) { - return false; - } - } - return true; - } - - public static List getNumericParameterRefinement(final Interval interval, final double focus, final boolean integer, final ParameterRefinementConfiguration refinementConfig) { - - double inf = interval.getInf(); - double sup = interval.getSup(); - - /* if there is nothing to refine anymore */ - if (inf == sup) { - return new ArrayList<>(); - } - - /* - * if this is an integer and the number of comprised integers are at most as - * many as the branching factor, enumerate them - */ - if (integer && (Math.floor(sup) - Math.ceil(inf) + 1 <= refinementConfig.getRefinementsPerStep())) { - List proposedRefinements = new ArrayList<>(); - for (int i = (int) Math.ceil(inf); i <= (int) Math.floor(sup); i++) { - proposedRefinements.add(new Interval(i, i)); - } - return proposedRefinements; - } - - /* - * if the interval is already below the threshold for this parameter, no more - * refinements will be allowed - */ - if (sup - inf < refinementConfig.getIntervalLength()) { - return new ArrayList<>(); - } - - if (!refinementConfig.isInitRefinementOnLogScale()) { - List proposedRefinements = refineOnLinearScale(interval, refinementConfig.getRefinementsPerStep(), refinementConfig.getIntervalLength()); - for (Interval proposedRefinement : proposedRefinements) { - assert proposedRefinement.getInf() >= inf && proposedRefinement.getSup() <= sup : "The proposed refinement [" + proposedRefinement.getInf() + ", " + proposedRefinement.getSup() + "] is not a sub-interval of [" + inf + ", " - + sup + "]."; - if (proposedRefinement.equals(interval)) { - throw new IllegalStateException("No real refinement! Intervals are identical."); - } - } - return proposedRefinements; - } - - List proposedRefinements = refineOnLogScale(interval, refinementConfig.getRefinementsPerStep(), 2, focus); - for (Interval proposedRefinement : proposedRefinements) { - double epsilon = 1E-7; - assert proposedRefinement.getInf() + epsilon >= inf && proposedRefinement.getSup() <= sup + epsilon : "The proposed refinement [" + proposedRefinement.getInf() + ", " + proposedRefinement.getSup() - + "] is not a sub-interval of [" + inf + ", " + sup + "]."; - if (proposedRefinement.equals(interval)) { - throw new IllegalStateException("No real refinement! Intervals are identical."); - } - } - return proposedRefinements; - } - - public static List refineOnLinearScale(final Interval interval, final int maxNumberOfSubIntervals, final double minimumLengthOfIntervals) { - double min = interval.getInf(); - double max = interval.getSup(); - double length = max - min; - List intervals = new ArrayList<>(); - - /* if no refinement is possible, return just the interval itself */ - if (length <= minimumLengthOfIntervals) { - intervals.add(interval); - return intervals; - } - - /* otherwise compute the sub-intervals */ - int numberOfIntervals = Math.min((int) Math.ceil(length / minimumLengthOfIntervals), maxNumberOfSubIntervals); - double stepSize = length / numberOfIntervals; - for (int i = 0; i < numberOfIntervals; i++) { - intervals.add(new Interval(min + i * stepSize, min + ((i + 1) * stepSize))); - } - return intervals; - } - - public static List refineOnLogScale(final Interval interval, final int n, final double basis, final double pointOfConcentration) { - List list = new ArrayList<>(); - double min = interval.getInf(); - double max = interval.getSup(); - double length = max - min; - - /* - * if the point of concentration is exactly on the left or the right of the - * interval, conduct the standard technique - */ - if (pointOfConcentration <= min || pointOfConcentration >= max) { - double lengthOfShortestInterval = length * (1 - basis) / (1 - Math.pow(basis, n)); - if (pointOfConcentration <= min) { - double endOfLast = min; - for (int i = 0; i < n; i++) { - double start = endOfLast; - endOfLast = start + Math.pow(basis, i) * lengthOfShortestInterval; - list.add(new Interval(start, endOfLast)); - } - } else { - double endOfLast = max; - for (int i = 0; i < n; i++) { - double start = endOfLast; - endOfLast = start - Math.pow(basis, i) * lengthOfShortestInterval; - list.add(new Interval(endOfLast, start)); - } - Collections.reverse(list); - } - return list; - } - - /* - * if the point of concentration is in the inner of the interval, split the - * interval correspondingly and recursively solve the problem - */ - double distanceFromMinToFocus = Math.abs(interval.getInf() - pointOfConcentration); - int segmentsForLeft = (int) Math.max(1, Math.floor(n * distanceFromMinToFocus / length)); - int segmentsForRight = n - segmentsForLeft; - list.addAll(refineOnLogScale(new Interval(min, pointOfConcentration), segmentsForLeft, basis, pointOfConcentration)); - list.addAll(refineOnLogScale(new Interval(pointOfConcentration, max), segmentsForRight, basis, pointOfConcentration)); - return list; - } - - public static void refineRecursively(final Interval interval, final int maxNumberOfSubIntervalsPerRefinement, final double basis, final double pointOfConcentration, final double factorForMaximumLengthOfFinestIntervals) { - - /* first, do a logarithmic refinement */ - List initRefinement = refineOnLogScale(interval, maxNumberOfSubIntervalsPerRefinement, basis, pointOfConcentration); - Collections.reverse(initRefinement); - - Deque openRefinements = new LinkedList<>(); - openRefinements.addAll(initRefinement); - int depth = 0; - do { - Interval intervalToRefine = openRefinements.pop(); - if (logger.isInfoEnabled()) { - StringBuilder offsetSB = new StringBuilder(); - for (int i = 0; i < depth; i++) { - offsetSB.append("\t"); - } - logger.info("{}[{}, {}]", offsetSB, intervalToRefine.getInf(), intervalToRefine.getSup()); - } - - /* compute desired granularity for this specific interval */ - double distanceToPointOfContentration = Math.min(Math.abs(intervalToRefine.getInf() - pointOfConcentration), Math.abs(intervalToRefine.getSup() - pointOfConcentration)); - double maximumLengthOfFinestIntervals = Math.pow(distanceToPointOfContentration + 1, 2) * factorForMaximumLengthOfFinestIntervals; - logger.info("{} * {} = {}", Math.pow(distanceToPointOfContentration + 1, 2), factorForMaximumLengthOfFinestIntervals, maximumLengthOfFinestIntervals); - List refinements = refineOnLinearScale(intervalToRefine, maxNumberOfSubIntervalsPerRefinement, maximumLengthOfFinestIntervals); - - depth++; - if (refinements.size() == 1 && refinements.get(0).equals(intervalToRefine)) { - depth--; - } else { - Collections.reverse(refinements); - openRefinements.addAll(refinements); - } - - } while (!openRefinements.isEmpty()); - } - -} +package ai.libs.hasco.core; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Deque; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.math3.geometry.euclidean.oned.Interval; +import org.apache.commons.math3.geometry.partitioning.Region.Location; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ai.libs.hasco.model.CategoricalParameterDomain; +import ai.libs.hasco.model.Component; +import ai.libs.hasco.model.ComponentInstance; +import ai.libs.hasco.model.Dependency; +import ai.libs.hasco.model.IParameterDomain; +import ai.libs.hasco.model.NumericParameterDomain; +import ai.libs.hasco.model.Parameter; +import ai.libs.hasco.model.ParameterRefinementConfiguration; +import ai.libs.jaicore.basic.sets.SetUtil; +import ai.libs.jaicore.basic.sets.SetUtil.Pair; +import ai.libs.jaicore.logic.fol.structure.Literal; +import ai.libs.jaicore.logic.fol.structure.LiteralParam; +import ai.libs.jaicore.logic.fol.structure.Monom; +import ai.libs.jaicore.planning.classical.algorithms.strips.forward.StripsUtil; +import ai.libs.jaicore.planning.core.Action; +import ai.libs.jaicore.planning.core.Plan; +import ai.libs.jaicore.planning.hierarchical.problems.ceocipstn.CEOCIPSTNPlanningProblem; +import ai.libs.jaicore.planning.hierarchical.problems.htn.IHierarchicalPlanningGraphGeneratorDeriver; +import ai.libs.jaicore.search.model.other.SearchGraphPath; +import ai.libs.jaicore.search.model.travesaltree.Node; + +public class Util { + + private static final String LITERAL_RESOLVES = "resolves"; + private static final String LITERAL_PARAMCONTAINER = "parameterContainer"; + private static final String LITERAL_VAL = "val"; + private static final String LITERAL_INTERFACEIDENTIFIER = "interfaceIdentifier"; + + private static final Logger logger = LoggerFactory.getLogger(Util.class); + + private Util() { + + } + + static Map getParameterContainerMap(final Monom state, final String objectName) { + Map parameterContainerMap = new HashMap<>(); + List containerLiterals = state.stream().filter(l -> l.getPropertyName().equals(LITERAL_PARAMCONTAINER) && l.getParameters().get(2).getName().equals(objectName)).collect(Collectors.toList()); + containerLiterals.forEach(l -> parameterContainerMap.put(l.getParameters().get(1).getName(), l.getParameters().get(3).getName())); + return parameterContainerMap; + } + + public static Map> getParametrizations(final Monom state, final Collection components, final boolean resolveIntervals) { + Map objectMap = new HashMap<>(); + Map> parameterContainerMap = new HashMap<>(); // stores for each object the name of the container of each parameter + Map parameterValues = new HashMap<>(); + + Map> parameterValuesPerComponentInstance = new HashMap<>(); + + Collection overwrittenDataContainers = getOverwrittenDatacontainersInState(state); + + /* + * create (empty) component instances, detect containers for parameter values, and register the + * values of the data containers + */ + for (Literal l : state) { + String[] params = l.getParameters().stream().map(LiteralParam::getName).collect(Collectors.toList()).toArray(new String[] {}); + switch (l.getPropertyName()) { + case LITERAL_RESOLVES: // field 0 and 1 (parent object name and interface name) are ignored here + String componentName = params[2]; + String objectName = params[3]; + Optional component = components.stream().filter(c -> c.getName().equals(componentName)).findAny(); + assert component.isPresent() : "Could not find component with name " + componentName; + ComponentInstance object = new ComponentInstance(component.get(), new HashMap<>(), new HashMap<>()); + objectMap.put(objectName, object); + break; + case LITERAL_PARAMCONTAINER: + if (!parameterContainerMap.containsKey(params[2])) { + parameterContainerMap.put(params[2], new HashMap<>()); + } + parameterContainerMap.get(params[2]).put(params[1], params[3]); + break; + case LITERAL_VAL: + if (overwrittenDataContainers.contains(params[0])) { + parameterValues.put(params[0], params[1]); + } + break; + + default: + + /* simply ignore other literals */ + break; + } + } + + /* update the configurations of the objects */ + for (Entry entry : objectMap.entrySet()) { + Map paramValuesForThisComponent = new HashMap<>(); + String objectName = entry.getKey(); + ComponentInstance object = entry.getValue(); + parameterValuesPerComponentInstance.put(object, paramValuesForThisComponent); + for (Parameter p : object.getComponent().getParameters()) { + + assert parameterContainerMap.containsKey(objectName) : "No parameter container map has been defined for object " + objectName + " of component " + object.getComponent().getName() + "!"; + assert parameterContainerMap.get(objectName).containsKey(p.getName()) : "The data container for parameter " + p.getName() + " of " + object.getComponent().getName() + " is not defined!"; + + String assignedValue = parameterValues.get(parameterContainerMap.get(objectName).get(p.getName())); + String interpretedValue = ""; + if (assignedValue != null) { + if (p.getDefaultDomain() instanceof NumericParameterDomain) { + if (resolveIntervals) { + NumericParameterDomain np = (NumericParameterDomain) p.getDefaultDomain(); + List vals = SetUtil.unserializeList(assignedValue); + Interval interval = new Interval(Double.valueOf(vals.get(0)), Double.valueOf(vals.get(1))); + if (np.isInteger()) { + interpretedValue = String.valueOf((int) Math.round(interval.getBarycenter())); + } else { + interpretedValue = String.valueOf(interval.getBarycenter()); + } + } else { + interpretedValue = assignedValue; + } + } else if (p.getDefaultDomain() instanceof CategoricalParameterDomain) { + interpretedValue = assignedValue; + } else { + throw new UnsupportedOperationException("No support for parameters of type " + p.getClass().getName()); + } + paramValuesForThisComponent.put(p, interpretedValue); + } + } + } + return parameterValuesPerComponentInstance; + } + + public static Collection getOverwrittenDatacontainersInState(final Monom state) { + return state.stream().filter(l -> l.getPropertyName().equals("overwritten")).map(l -> l.getParameters().get(0).getName()).collect(Collectors.toSet()); + } + + public static Collection getClosedDatacontainersInState(final Monom state) { + return state.stream().filter(l -> l.getPropertyName().equals("closed")).map(l -> l.getParameters().get(0).getName()).collect(Collectors.toSet()); + } + + static Map getGroundComponentsFromState(final Monom state, final Collection components, final boolean resolveIntervals) { + Map objectMap = new HashMap<>(); + Map> parameterContainerMap = new HashMap<>(); // stores for each object the name of the container of each parameter + Map parameterValues = new HashMap<>(); + Map interfaceContainerMap = new HashMap<>(); + Collection overwrittenDatacontainers = getOverwrittenDatacontainersInState(state); + + /* create (empty) component instances, detect containers for parameter values, and register the values of the data containers */ + for (Literal l : state) { + String[] params = l.getParameters().stream().map(LiteralParam::getName).collect(Collectors.toList()).toArray(new String[] {}); + switch (l.getPropertyName()) { + case LITERAL_RESOLVES: // field 0 and 1 (parent object name and interface name) are ignored here + String componentName = params[2]; + String objectName = params[3]; + + Optional component = components.stream().filter(c -> c.getName().equals(componentName)).findAny(); + assert component.isPresent() : "Could not find component with name " + componentName; + ComponentInstance object = new ComponentInstance(component.get(), new HashMap<>(), new HashMap<>()); + objectMap.put(objectName, object); + break; + case LITERAL_PARAMCONTAINER: + if (!parameterContainerMap.containsKey(params[2])) { + parameterContainerMap.put(params[2], new HashMap<>()); + } + parameterContainerMap.get(params[2]).put(params[1], params[3]); + break; + case LITERAL_VAL: + parameterValues.put(params[0], params[1]); + break; + case LITERAL_INTERFACEIDENTIFIER: + interfaceContainerMap.put(params[3], params[1]); + break; + default: + /* simply ignore other cases */ + break; + } + } + + /* now establish the binding of the required interfaces of the component instances */ + state.stream().filter(l -> l.getPropertyName().equals(LITERAL_RESOLVES)).forEach(l -> { + String[] params = l.getParameters().stream().map(LiteralParam::getName).collect(Collectors.toList()).toArray(new String[] {}); + String parentObjectName = params[0]; + String objectName = params[3]; + ComponentInstance object = objectMap.get(objectName); + if (!parentObjectName.equals("request")) { + assert interfaceContainerMap.containsKey(objectName) : "Object name " + objectName + " for requried interface must have a defined identifier "; + objectMap.get(parentObjectName).getSatisfactionOfRequiredInterfaces().put(interfaceContainerMap.get(objectName), object); + } + }); + + /* set the explicitly defined parameters (e.g. overwritten containers) in the component instances */ + for (Entry entry : objectMap.entrySet()) { + String objectName = entry.getKey(); + ComponentInstance object = entry.getValue(); + for (Parameter p : object.getComponent().getParameters()) { + + assert parameterContainerMap.containsKey(objectName) : "No parameter container map has been defined for object " + objectName + " of component " + object.getComponent().getName() + "!"; + assert parameterContainerMap.get(objectName).containsKey(p.getName()) : "The data container for parameter " + p.getName() + " of " + object.getComponent().getName() + " is not defined! State: " + state.stream().sorted().map(l -> "\n\t" + l).collect(Collectors.joining()); + String paramContainerName = parameterContainerMap.get(objectName).get(p.getName()); + if (overwrittenDatacontainers.contains(paramContainerName)) { + String assignedValue = parameterValues.get(paramContainerName); + assert assignedValue != null : "parameter containers must always have a value!"; + object.getParameterValues().put(p.getName(), getParamValue(p, assignedValue, resolveIntervals)); + } + } + } + return objectMap; + } + + public static > ComponentInstance getSolutionCompositionForNode(final IHierarchicalPlanningGraphGeneratorDeriver planningGraphDeriver, final Collection components, + final Monom initState, final Node path, final boolean resolveIntervals) { + return getSolutionCompositionForPlan(components, initState, planningGraphDeriver.decodeSolution(new SearchGraphPath<>(path.externalPath())), resolveIntervals); + } + + public static > ComponentInstance getComponentInstanceForNode(final IHierarchicalPlanningGraphGeneratorDeriver planningGraphDeriver, final Collection components, + final Monom initState, final Node path, final String name, final boolean resolveIntervals) { + return getComponentInstanceForPlan(components, initState, planningGraphDeriver.decodeSolution(new SearchGraphPath<>(path.externalPath())), name, resolveIntervals); + } + + public static Monom getFinalStateOfPlan(final Monom initState, final Plan plan) { + Monom state = new Monom(initState); + for (Action a : plan.getActions()) { + StripsUtil.updateState(state, a); + } + return state; + } + + public static ComponentInstance getSolutionCompositionForPlan(final Collection components, final Monom initState, final Plan plan, final boolean resolveIntervals) { + return getSolutionCompositionFromState(components, getFinalStateOfPlan(initState, plan), resolveIntervals); + } + + public static ComponentInstance getComponentInstanceForPlan(final Collection components, final Monom initState, final Plan plan, final String name, final boolean resolveIntervals) { + return getComponentInstanceFromState(components, getFinalStateOfPlan(initState, plan), name, resolveIntervals); + } + + public static ComponentInstance getSolutionCompositionFromState(final Collection components, final Monom state, final boolean resolveIntervals) { + return getComponentInstanceFromState(components, state, "solution", resolveIntervals); + } + + public static ComponentInstance getComponentInstanceFromState(final Collection components, final Monom state, final String name, final boolean resolveIntervals) { + return Util.getGroundComponentsFromState(state, components, resolveIntervals).get(name); + } + + /** + * Computes a String of component names that appear in the composition which can be used as an identifier for the composition + * + * @param composition + * @return String of all component names in right to left depth-first order + */ + public static String getComponentNamesOfComposition(final ComponentInstance composition) { + StringBuilder builder = new StringBuilder(); + Deque componentInstances = new ArrayDeque<>(); + componentInstances.push(composition); + ComponentInstance curInstance; + while (!componentInstances.isEmpty()) { + curInstance = componentInstances.pop(); + builder.append(curInstance.getComponent().getName()); + Map requiredInterfaces = curInstance.getComponent().getRequiredInterfaces(); + // This set should be ordered + Set requiredInterfaceNames = requiredInterfaces.keySet(); + for (String requiredInterfaceName : requiredInterfaceNames) { + ComponentInstance instance = curInstance.getSatisfactionOfRequiredInterfaces().get(requiredInterfaceName); + componentInstances.push(instance); + } + } + return builder.toString(); + } + + /** + * Computes a list of all components of the given composition. + * + * @param composition + * @return List of components in right to left depth-first order + */ + public static List getComponentsOfComposition(final ComponentInstance composition) { + List components = new LinkedList<>(); + Deque componentInstances = new ArrayDeque<>(); + componentInstances.push(composition); + ComponentInstance curInstance; + while (!componentInstances.isEmpty()) { + curInstance = componentInstances.pop(); + components.add(curInstance.getComponent()); + Map requiredInterfaces = curInstance.getComponent().getRequiredInterfaces(); + // This set should be ordered + Set requiredInterfaceNames = requiredInterfaces.keySet(); + for (String requiredInterfaceName : requiredInterfaceNames) { + ComponentInstance instance = curInstance.getSatisfactionOfRequiredInterfaces().get(requiredInterfaceName); + componentInstances.push(instance); + } + } + return components; + } + + public static Map getUpdatedDomainsOfComponentParameters(final Monom state, final Component component, final String objectIdentifierInState) { + Map parameterContainerMap = new HashMap<>(); + Map parameterContainerMapInv = new HashMap<>(); + Map parameterValues = new HashMap<>(); + + /* detect containers for parameter values, and register the values of the data containers */ + for (Literal l : state) { + String[] params = l.getParameters().stream().map(LiteralParam::getName).collect(Collectors.toList()).toArray(new String[] {}); + switch (l.getPropertyName()) { + case LITERAL_PARAMCONTAINER: + if (!params[2].equals(objectIdentifierInState)) { + continue; + } + parameterContainerMap.put(params[1], params[3]); + parameterContainerMapInv.put(params[3], params[1]); + break; + case LITERAL_VAL: + parameterValues.put(params[0], params[1]); + break; + default: // ignore other literals + break; + } + } + + /* determine current values of the parameters of this component instance */ + Map paramValuesForThisComponentInstance = new HashMap<>(); + for (Parameter p : component.getParameters()) { + if (!parameterContainerMap.containsKey(p.getName())) { + throw new IllegalStateException("The data container for parameter " + p.getName() + " of " + objectIdentifierInState + " is not defined!"); + } + String assignedValue = parameterValues.get(parameterContainerMap.get(p.getName())); + if (assignedValue == null) { + throw new IllegalStateException("No value has been assigned to parameter " + p.getName() + " stored in container " + parameterContainerMap.get(p.getName()) + " in state " + state); + } + String value = getParamValue(p, assignedValue, false); + assert value != null : "Determined value NULL for parameter " + p.getName() + ", which is not plausible."; + paramValuesForThisComponentInstance.put(p, value); + } + + /* extract instance */ + Collection components = new ArrayList<>(); + components.add(component); + ComponentInstance instance = getComponentInstanceFromState(components, state, objectIdentifierInState, false); + + /* now compute the new domains based on the current values */ + return getUpdatedDomainsOfComponentParameters(instance); + } + + private static String getParamValue(final Parameter p, final String assignedValue, final boolean resolveIntervals) { + String interpretedValue = ""; + if (assignedValue == null) { + throw new IllegalArgumentException("Cannot determine true value for assigned param value " + assignedValue + " for parameter " + p.getName()); + } + if (p.isNumeric()) { + if (resolveIntervals) { + NumericParameterDomain np = (NumericParameterDomain) p.getDefaultDomain(); + List vals = SetUtil.unserializeList(assignedValue); + Interval interval = new Interval(Double.valueOf(vals.get(0)), Double.valueOf(vals.get(1))); + if (np.isInteger()) { + interpretedValue = String.valueOf((int) Math.round(interval.getBarycenter())); + } else { + interpretedValue = String.valueOf(interval.checkPoint((double)p.getDefaultValue(), 0.001) == Location.INSIDE ? (double)p.getDefaultValue() : interval.getBarycenter()); + } + } else { + interpretedValue = assignedValue; + } + } else if (p.getDefaultDomain() instanceof CategoricalParameterDomain) { + interpretedValue = assignedValue; + } else { + throw new UnsupportedOperationException("No support for parameters of type " + p.getClass().getName()); + } + return interpretedValue; + } + + public static Map getUpdatedDomainsOfComponentParameters(final ComponentInstance componentInstance) { + Component component = componentInstance.getComponent(); + + /* initialize all params for which a decision has been made already with their respective value */ + Map domains = new HashMap<>(); + for (Parameter p : componentInstance.getParametersThatHaveBeenSetExplicitly()) { + if (p.isNumeric()) { + NumericParameterDomain defaultDomain = (NumericParameterDomain) p.getDefaultDomain(); + Interval interval = SetUtil.unserializeInterval(componentInstance.getParameterValue(p)); + domains.put(p, new NumericParameterDomain(defaultDomain.isInteger(), interval.getInf(), interval.getSup())); + } else if (p.isCategorical()) { + domains.put(p, new CategoricalParameterDomain(new String[] { componentInstance.getParameterValue(p) })); + } + } + + /* initialize all others with the default domain */ + for (Parameter p : componentInstance.getParametersThatHaveNotBeenSetExplicitly()) { + domains.put(p, p.getDefaultDomain()); + } + assert (domains.keySet().equals(component.getParameters())) : "There are parameters for which no current domain was derived."; + + /* update domains based on the dependencies defined for this component */ + for (Dependency dependency : component.getDependencies()) { + if (isDependencyPremiseSatisfied(dependency, domains)) { + logger.info("Premise of dependency {} is satisfied, applying its conclusions ...", dependency); + for (Pair newDomain : dependency.getConclusion()) { + /* + * directly use the concluded domain if the current value is NOT subsumed by it. Otherwise, just + * stick to the current domain + */ + Parameter param = newDomain.getX(); + IParameterDomain concludedDomain = newDomain.getY(); + if (!componentInstance.getParametersThatHaveBeenSetExplicitly().contains(param)) { + domains.put(param, concludedDomain); + logger.debug("Changing domain of {} from {} to {}", param, domains.get(param), concludedDomain); + } else { + logger.debug("Not changing domain of {} since it has already been set explicitly in the past.", param); + } + } + } else { + logger.debug("Ignoring unsatisfied dependency {}.", dependency); + } + } + return domains; + } + + public static boolean isDependencyPremiseSatisfied(final Dependency dependency, final Map values) { + logger.debug("Checking satisfcation of dependency {} with values {}", dependency, values); + for (Collection> condition : dependency.getPremise()) { + boolean check = isDependencyConditionSatisfied(condition, values); + logger.trace("Result of check for condition {}: {}", condition, check); + if (!check) { + return false; + } + } + return true; + } + + public static boolean isDependencyConditionSatisfied(final Collection> condition, final Map values) { + for (Pair conditionItem : condition) { + IParameterDomain requiredDomain = conditionItem.getY(); + Parameter param = conditionItem.getX(); + IParameterDomain actualDomain = values.get(param); + if (!values.containsKey(param)) { + throw new IllegalArgumentException("Cannot check condition " + condition + " as the value for parameter " + param.getName() + " is not defined in " + values); + } + if (values.get(param) == null) { + throw new IllegalArgumentException("Cannot check condition " + condition + " as the value for parameter " + param.getName() + " is NULL in " + values); + } + if (!requiredDomain.subsumes(actualDomain)) { + return false; + } + } + return true; + } + + public static List getNumericParameterRefinement(final Interval interval, final double focus, final boolean integer, final ParameterRefinementConfiguration refinementConfig) { + + double inf = interval.getInf(); + double sup = interval.getSup(); + + /* if there is nothing to refine anymore */ + if (inf == sup) { + return new ArrayList<>(); + } + + /* + * if this is an integer and the number of comprised integers are at most as + * many as the branching factor, enumerate them + */ + if (integer && (Math.floor(sup) - Math.ceil(inf) + 1 <= refinementConfig.getRefinementsPerStep())) { + List proposedRefinements = new ArrayList<>(); + for (int i = (int) Math.ceil(inf); i <= (int) Math.floor(sup); i++) { + proposedRefinements.add(new Interval(i, i)); + } + return proposedRefinements; + } + + /* + * if the interval is already below the threshold for this parameter, no more + * refinements will be allowed + */ + if (sup - inf < refinementConfig.getIntervalLength()) { + return new ArrayList<>(); + } + + if (!refinementConfig.isInitRefinementOnLogScale()) { + List proposedRefinements = refineOnLinearScale(interval, refinementConfig.getRefinementsPerStep(), refinementConfig.getIntervalLength()); + for (Interval proposedRefinement : proposedRefinements) { + assert proposedRefinement.getInf() >= inf && proposedRefinement.getSup() <= sup : "The proposed refinement [" + proposedRefinement.getInf() + ", " + proposedRefinement.getSup() + "] is not a sub-interval of [" + inf + ", " + + sup + "]."; + if (proposedRefinement.equals(interval)) { + throw new IllegalStateException("No real refinement! Intervals are identical."); + } + } + return proposedRefinements; + } + + List proposedRefinements = refineOnLogScale(interval, refinementConfig.getRefinementsPerStep(), 2, focus); + for (Interval proposedRefinement : proposedRefinements) { + double epsilon = 1E-7; + assert proposedRefinement.getInf() + epsilon >= inf && proposedRefinement.getSup() <= sup + epsilon : "The proposed refinement [" + proposedRefinement.getInf() + ", " + proposedRefinement.getSup() + + "] is not a sub-interval of [" + inf + ", " + sup + "]."; + if (proposedRefinement.equals(interval)) { + throw new IllegalStateException("No real refinement! Intervals are identical."); + } + } + return proposedRefinements; + } + + public static List refineOnLinearScale(final Interval interval, final int maxNumberOfSubIntervals, final double minimumLengthOfIntervals) { + double min = interval.getInf(); + double max = interval.getSup(); + double length = max - min; + List intervals = new ArrayList<>(); + + /* if no refinement is possible, return just the interval itself */ + if (length <= minimumLengthOfIntervals) { + intervals.add(interval); + return intervals; + } + + /* otherwise compute the sub-intervals */ + int numberOfIntervals = Math.min((int) Math.ceil(length / minimumLengthOfIntervals), maxNumberOfSubIntervals); + double stepSize = length / numberOfIntervals; + for (int i = 0; i < numberOfIntervals; i++) { + intervals.add(new Interval(min + i * stepSize, min + ((i + 1) * stepSize))); + } + return intervals; + } + + public static List refineOnLogScale(final Interval interval, final int n, final double basis, final double pointOfConcentration) { + List list = new ArrayList<>(); + double min = interval.getInf(); + double max = interval.getSup(); + double length = max - min; + + /* + * if the point of concentration is exactly on the left or the right of the + * interval, conduct the standard technique + */ + if (pointOfConcentration <= min || pointOfConcentration >= max) { + double lengthOfShortestInterval = length * (1 - basis) / (1 - Math.pow(basis, n)); + if (pointOfConcentration <= min) { + double endOfLast = min; + for (int i = 0; i < n; i++) { + double start = endOfLast; + endOfLast = start + Math.pow(basis, i) * lengthOfShortestInterval; + list.add(new Interval(start, endOfLast)); + } + } else { + double endOfLast = max; + for (int i = 0; i < n; i++) { + double start = endOfLast; + endOfLast = start - Math.pow(basis, i) * lengthOfShortestInterval; + list.add(new Interval(endOfLast, start)); + } + Collections.reverse(list); + } + return list; + } + + /* + * if the point of concentration is in the inner of the interval, split the + * interval correspondingly and recursively solve the problem + */ + double distanceFromMinToFocus = Math.abs(interval.getInf() - pointOfConcentration); + int segmentsForLeft = (int) Math.max(1, Math.floor(n * distanceFromMinToFocus / length)); + int segmentsForRight = n - segmentsForLeft; + list.addAll(refineOnLogScale(new Interval(min, pointOfConcentration), segmentsForLeft, basis, pointOfConcentration)); + list.addAll(refineOnLogScale(new Interval(pointOfConcentration, max), segmentsForRight, basis, pointOfConcentration)); + return list; + } + + public static void refineRecursively(final Interval interval, final int maxNumberOfSubIntervalsPerRefinement, final double basis, final double pointOfConcentration, final double factorForMaximumLengthOfFinestIntervals) { + + /* first, do a logarithmic refinement */ + List initRefinement = refineOnLogScale(interval, maxNumberOfSubIntervalsPerRefinement, basis, pointOfConcentration); + Collections.reverse(initRefinement); + + Deque openRefinements = new LinkedList<>(); + openRefinements.addAll(initRefinement); + int depth = 0; + do { + Interval intervalToRefine = openRefinements.pop(); + if (logger.isInfoEnabled()) { + StringBuilder offsetSB = new StringBuilder(); + for (int i = 0; i < depth; i++) { + offsetSB.append("\t"); + } + logger.info("{}[{}, {}]", offsetSB, intervalToRefine.getInf(), intervalToRefine.getSup()); + } + + /* compute desired granularity for this specific interval */ + double distanceToPointOfContentration = Math.min(Math.abs(intervalToRefine.getInf() - pointOfConcentration), Math.abs(intervalToRefine.getSup() - pointOfConcentration)); + double maximumLengthOfFinestIntervals = Math.pow(distanceToPointOfContentration + 1, 2) * factorForMaximumLengthOfFinestIntervals; + logger.info("{} * {} = {}", Math.pow(distanceToPointOfContentration + 1, 2), factorForMaximumLengthOfFinestIntervals, maximumLengthOfFinestIntervals); + List refinements = refineOnLinearScale(intervalToRefine, maxNumberOfSubIntervalsPerRefinement, maximumLengthOfFinestIntervals); + + depth++; + if (refinements.size() == 1 && refinements.get(0).equals(intervalToRefine)) { + depth--; + } else { + Collections.reverse(refinements); + openRefinements.addAll(refinements); + } + + } while (!openRefinements.isEmpty()); + } + +} diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/gui/civiewplugin/TFDNodeAsCIViewInfoGenerator.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/gui/civiewplugin/TFDNodeAsCIViewInfoGenerator.java index b36594ce1a..4b559ce63f 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/gui/civiewplugin/TFDNodeAsCIViewInfoGenerator.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/gui/civiewplugin/TFDNodeAsCIViewInfoGenerator.java @@ -9,7 +9,7 @@ import ai.libs.hasco.model.Parameter; import ai.libs.jaicore.graphvisualizer.plugin.nodeinfo.NodeInfoGenerator; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.model.travesaltree.Node; /** * This info generator is meant to be used in combination with the node info plug-in. diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/reduction/HASCOReduction.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/reduction/HASCOReduction.java index ae0bdbe7d7..8a5bfa4909 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/reduction/HASCOReduction.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/reduction/HASCOReduction.java @@ -42,7 +42,7 @@ import ai.libs.jaicore.planning.hierarchical.problems.htn.CostSensitiveHTNPlanningProblem; import ai.libs.jaicore.planning.hierarchical.problems.htn.IHierarchicalPlanningGraphGeneratorDeriver; import ai.libs.jaicore.planning.hierarchical.problems.stn.TaskNetwork; -import jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; /** * This is the class that conducts the actual problem reduction of software configuration to HTN Planning diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/serialization/ComponentLoader.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/serialization/ComponentLoader.java index ef77d0a197..3fa579e9af 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/serialization/ComponentLoader.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/serialization/ComponentLoader.java @@ -1,8 +1,6 @@ package ai.libs.hasco.serialization; -import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -31,6 +29,9 @@ import ai.libs.hasco.model.NumericParameterDomain; import ai.libs.hasco.model.Parameter; import ai.libs.hasco.model.ParameterRefinementConfiguration; +import ai.libs.jaicore.basic.FileUtil; +import ai.libs.jaicore.basic.ResourceFile; +import ai.libs.jaicore.basic.ResourceUtil; import ai.libs.jaicore.basic.sets.SetUtil; import ai.libs.jaicore.basic.sets.SetUtil.Pair; @@ -62,65 +63,53 @@ public ComponentLoader(final boolean checkRequiredInterfacesResolvable) { public ComponentLoader(final File jsonFile) throws IOException { this(); - loadComponents(jsonFile); + this.loadComponents(jsonFile); } public ComponentLoader(final File jsonFile, final boolean checkRequiredInterfacesResolvable) throws IOException { this(checkRequiredInterfacesResolvable); - loadComponents(jsonFile); + this.loadComponents(jsonFile); } private void parseFile(final File jsonFile) throws IOException { L.debug("Parse file {}...", jsonFile.getAbsolutePath()); - StringBuilder stringDescriptionSB = new StringBuilder(); - String line; - try (BufferedReader br = new BufferedReader(new FileReader(jsonFile))) { - while ((line = br.readLine()) != null) { - stringDescriptionSB.append(line + "\n"); - } + + String jsonDescription; + if (jsonFile instanceof ResourceFile) { + jsonDescription = ResourceUtil.readResourceFileToString(((ResourceFile) jsonFile).getPathName()); + } else { + jsonDescription = FileUtil.readFileAsString(jsonFile); } - String jsonDescription = stringDescriptionSB.toString(); jsonDescription = jsonDescription.replaceAll("/\\*(.*)\\*/", ""); - JsonNode rootNode = objectMapper.readTree(jsonDescription); + JsonNode rootNode = this.objectMapper.readTree(jsonDescription); for (JsonNode elem : rootNode.path("parameters")) { - parameterMap.put(elem.get("name").asText(), elem); + this.parameterMap.put(elem.get("name").asText(), elem); } JsonNode includes = rootNode.path("include"); - File baseFolder = new File(jsonFile.getCanonicalPath()); - if (jsonFile.isFile()) { - baseFolder = new File(jsonFile.getCanonicalFile().getParentFile().getCanonicalPath()); - } - + File baseFolder = jsonFile.getParentFile(); for (JsonNode includePathNode : includes) { String path = includePathNode.asText(); - File subFile = new File(baseFolder.getAbsolutePath() + File.separator + path); - if (!parsedFiles.contains(subFile.getCanonicalPath())) { - if (!subFile.exists()) { - throw new IllegalArgumentException("Cannot load " + subFile.getName() + " as this file or folder does not exist in " + subFile.getParent()); - } - if (subFile.isFile()) { - parsedFiles.add(subFile.getCanonicalPath()); - parseFile(subFile.getCanonicalFile()); - } else { - for (File subsubFile : subFile.listFiles()) { - if (!parsedFiles.contains(subsubFile.getCanonicalPath()) && subsubFile.isFile() && subsubFile.getName().endsWith(".json")) { - parsedFiles.add(subsubFile.getCanonicalPath()); - parseFile(subsubFile.getCanonicalFile()); - } - } - parsedFiles.add(subFile.getCanonicalPath()); - } + File subFile; + if (baseFolder instanceof ResourceFile) { + subFile = new ResourceFile((ResourceFile) baseFolder, path); + } else { + subFile = new File(baseFolder, path); + } + + if (!this.parsedFiles.contains(subFile.getCanonicalPath())) { + this.parsedFiles.add(subFile.getCanonicalPath()); + this.parseFile(subFile); } } - readFromJson(rootNode); + this.readFromJson(rootNode); } public void readFromString(final String json) throws IOException { ObjectMapper mapper = new ObjectMapper(); - readFromJson(mapper.readTree(json)); + this.readFromJson(mapper.readTree(json)); } private void readFromJson(final JsonNode rootNode) throws IOException { @@ -130,9 +119,9 @@ private void readFromJson(final JsonNode rootNode) throws IOException { Component c; for (JsonNode component : components) { c = new Component(component.get("name").asText()); - componentMap.put(c.getName(), component); + this.componentMap.put(c.getName(), component); - if (!uniqueComponentNames.add(c.getName())) { + if (!this.uniqueComponentNames.add(c.getName())) { throw new IllegalArgumentException("Noticed a component with duplicative component name: " + c.getName()); } @@ -168,8 +157,8 @@ private void readFromJson(final JsonNode rootNode) throws IOException { String[] doubleParams = new String[] { "default", "min", "max", "refineSplits", "minInterval" }; double[] doubleParamValues = new double[doubleParams.length]; - if (parameterMap.containsKey(name)) { - JsonNode commonParameter = parameterMap.get(name); + if (this.parameterMap.containsKey(name)) { + JsonNode commonParameter = this.parameterMap.get(name); // get string parameter values from common parameter for (int i = 0; i < stringParams.length; i++) { if (commonParameter.get(stringParams[i]) != null) { @@ -226,8 +215,7 @@ private void readFromJson(final JsonNode rootNode) throws IOException { if (type.endsWith("-log")) { paramConfig.put(p, new ParameterRefinementConfiguration(parameter.get("focus").asDouble(), parameter.get("basis").asDouble(), boolParamValues[1], (int) doubleParamValues[3], doubleParamValues[4])); - } - else { + } else { paramConfig.put(p, new ParameterRefinementConfiguration(boolParamValues[1], (int) doubleParamValues[3], doubleParamValues[4])); } break; @@ -245,8 +233,8 @@ private void readFromJson(final JsonNode rootNode) throws IOException { for (JsonNode value : parameter.get("values")) { values.add(value.asText()); } - } else if (parameterMap.containsKey(name)) { - for (JsonNode value : parameterMap.get(name).get("values")) { + } else if (this.parameterMap.containsKey(name)) { + for (JsonNode value : this.parameterMap.get(name).get("values")) { values.add(value.asText()); } } else { @@ -377,25 +365,25 @@ private void readFromJson(final JsonNode rootNode) throws IOException { c.addDependency(new Dependency(premise, conclusion)); } - paramConfigs.put(c, paramConfig); + this.paramConfigs.put(c, paramConfig); this.components.add(c); - requiredInterfaces.addAll(c.getRequiredInterfaces().values()); - providedInterfaces.addAll(c.getProvidedInterfaces()); + this.requiredInterfaces.addAll(c.getRequiredInterfaces().values()); + this.providedInterfaces.addAll(c.getProvidedInterfaces()); } } } public ComponentLoader loadComponents(final File componentDescriptionFile) throws IOException, UnresolvableRequiredInterfaceException { - paramConfigs.clear(); - components.clear(); - uniqueComponentNames.clear(); - requiredInterfaces.clear(); - providedInterfaces.clear(); + this.paramConfigs.clear(); + this.components.clear(); + this.uniqueComponentNames.clear(); + this.requiredInterfaces.clear(); + this.providedInterfaces.clear(); - parseFile(componentDescriptionFile); + this.parseFile(componentDescriptionFile); - if (checkRequiredInterfacesResolvable && !getUnresolvableRequiredInterfaces().isEmpty()) { + if (this.checkRequiredInterfacesResolvable && !this.getUnresolvableRequiredInterfaces().isEmpty()) { throw new UnresolvableRequiredInterfaceException(); } @@ -406,7 +394,7 @@ public ComponentLoader loadComponents(final File componentDescriptionFile) throw * @return Returns the collection of required interfaces that cannot be resolved by a provided interface. */ public Collection getUnresolvableRequiredInterfaces() { - return SetUtil.difference(requiredInterfaces, providedInterfaces); + return SetUtil.difference(this.requiredInterfaces, this.providedInterfaces); } /** @@ -415,21 +403,21 @@ public Collection getUnresolvableRequiredInterfaces() { * @return Returns the collection of required interfaces that cannot be resolved by a provided interface. */ public JsonNode getComponentAsJsonNode(final String componentName) { - return componentMap.get(componentName); + return this.componentMap.get(componentName); } /** * @return The map describing for each component individually how its parameters may be refined. */ public Map> getParamConfigs() { - return paramConfigs; + return this.paramConfigs; } /** * @return The collection of parsed components. */ public Collection getComponents() { - return components; + return this.components; } /** @@ -438,7 +426,7 @@ public Collection getComponents() { * @return The component for the given name. */ public Component getComponentWithName(final String name) { - for (Component component : getComponents()) { + for (Component component : this.getComponents()) { if (component.getName().equals(name)) { return component; } @@ -452,7 +440,7 @@ public static void main(final String[] args) throws IOException, UnresolvableReq } public Map getJsonNodeComponents() { - return componentMap; + return this.componentMap; } } diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFD.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFD.java index 00c60f4a28..a73418a932 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFD.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFD.java @@ -6,10 +6,10 @@ import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.ForwardDecompositionReducer; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; public class HASCOViaFD, V extends Comparable> extends HASCO { diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirst.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirst.java index 413e372755..be93c8545a 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirst.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirst.java @@ -5,10 +5,10 @@ import ai.libs.hasco.core.RefinementConfiguredSoftwareConfigurationProblem; import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.model.other.EvaluatedSearchGraphPath; -import jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.model.other.EvaluatedSearchGraphPath; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithPathEvaluationsInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class HASCOViaFDAndBestFirst> extends HASCOViaFD, V> { diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstFactory.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstFactory.java index c7772ada19..86307d7748 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstFactory.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstFactory.java @@ -1,10 +1,10 @@ package ai.libs.hasco.variants.forwarddecomposition; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirstFactory; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; -import jaicore.search.problemtransformers.GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformer; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirstFactory; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.problemtransformers.GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformer; /** * This factory makes it easier to create HASCO objects. diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstWithRandomCompletions.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstWithRandomCompletions.java index 2ed0376ec2..9cf6fd53b1 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstWithRandomCompletions.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstWithRandomCompletions.java @@ -4,9 +4,9 @@ import ai.libs.hasco.core.RefinementConfiguredSoftwareConfigurationProblem; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirstFactory; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.problemtransformers.GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirstFactory; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.problemtransformers.GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS; public class HASCOViaFDAndBestFirstWithRandomCompletions> extends HASCOViaFDAndBestFirst { diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstWithRandomCompletionsFactory.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstWithRandomCompletionsFactory.java index 95da38e53a..d6eab7233a 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstWithRandomCompletionsFactory.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDAndBestFirstWithRandomCompletionsFactory.java @@ -4,9 +4,9 @@ import ai.libs.hasco.core.RefinementConfiguredSoftwareConfigurationProblem; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirstFactory; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.problemtransformers.GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirstFactory; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.problemtransformers.GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS; public class HASCOViaFDAndBestFirstWithRandomCompletionsFactory extends HASCOViaFDAndBestFirstFactory { diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDFactory.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDFactory.java index f9e85f763c..1b5053ba9f 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDFactory.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/HASCOViaFDFactory.java @@ -4,8 +4,8 @@ import ai.libs.hasco.core.HASCOFactory; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.ForwardDecompositionReducer; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; public class HASCOViaFDFactory, V extends Comparable> extends HASCOFactory { diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/twophase/TwoPhaseHASCO.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/twophase/TwoPhaseHASCO.java index a964b48bcb..3f2417145d 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/twophase/TwoPhaseHASCO.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/twophase/TwoPhaseHASCO.java @@ -1,6 +1,7 @@ package ai.libs.hasco.variants.forwarddecomposition.twophase; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -43,9 +44,9 @@ import ai.libs.jaicore.concurrent.NamedTimerTask; import ai.libs.jaicore.logging.LoggerUtil; import ai.libs.jaicore.logging.ToJSONStringUtil; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; import ai.libs.jaicore.timing.TimedComputation; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.probleminputs.GraphSearchInput; public class TwoPhaseHASCO, N, A> extends SoftwareConfigurationAlgorithm, Double> { @@ -119,17 +120,17 @@ public void receiveHASCOEvent(final AlgorithmEvent event) { @Override public AlgorithmEvent nextWithException() throws InterruptedException, AlgorithmTimeoutedException, AlgorithmException, AlgorithmExecutionCanceledException { - this.logger.info("Stepping 2phase HASCO. Current state: {}", this.getState()); - switch (this.getState()) { + this.logger.info("Stepping 2phase HASCO. Current state: {}", getState()); + switch (getState()) { case created: if (this.hasco == null) { throw new IllegalStateException("Cannot start algorithm before HASCO has been set. Please set HASCO either in constructor or via the setter."); } this.timeOfStart = System.currentTimeMillis(); - AlgorithmInitializedEvent event = this.activate(); + AlgorithmInitializedEvent event = activate(); this.logger.info( "Starting 2-Phase HASCO with the following setup:\n\tCPUs:{},\n\tTimeout: {}s\n\tTimeout per node evaluation: {}ms\n\tTimeout per candidate: {}ms\n\tNumber of Random Completions: {}\n\tExpected blow-ups are {} (selection) and {} (post-processing).\nThe search factory is: {}", - this.getNumCPUs(), this.getTimeout().seconds(), this.getConfig().timeoutForNodeEvaluation(), this.getConfig().timeoutForCandidateEvaluation(), this.getConfig().numberOfRandomCompletions(), + getNumCPUs(), getTimeout().seconds(), this.getConfig().timeoutForNodeEvaluation(), this.getConfig().timeoutForCandidateEvaluation(), this.getConfig().numberOfRandomCompletions(), this.getConfig().expectedBlowupInSelection(), this.getConfig().expectedBlowupInPostprocessing(), this.hasco.getSearchFactory()); DefaultPathPriorizingPredicate prioritizingPredicate = new DefaultPathPriorizingPredicate<>(); @@ -150,20 +151,25 @@ public AlgorithmEvent nextWithException() throws InterruptedException, Algorithm @Override public void run() { - /* check whether the algorithm has been shutdown, then also cancel this task */ - if (TwoPhaseHASCO.this.isShutdownInitialized()) { - this.cancel(); - return; + try { + /* check whether the algorithm has been shutdown, then also cancel this task */ + if (TwoPhaseHASCO.this.isShutdownInitialized()) { + cancel(); + return; + } + + /* check termination of phase 1 */ + int timeElapsed = (int) (System.currentTimeMillis() - TwoPhaseHASCO.this.timeOfStart); + int timeRemaining = (int) TwoPhaseHASCO.this.hasco.getTimeout().milliseconds() - timeElapsed; + if (timeRemaining < 2000 || TwoPhaseHASCO.this.shouldSearchTerminate(timeRemaining)) { + TwoPhaseHASCO.this.logger.info("Canceling HASCO (first phase). {}ms remaining.", timeRemaining); + TwoPhaseHASCO.this.hasco.cancel(); + TwoPhaseHASCO.this.logger.info("HASCO canceled successfully after {}ms", (System.currentTimeMillis() - TwoPhaseHASCO.this.timeOfStart) - timeElapsed); + cancel(); + } } - - /* check termination of phase 1 */ - int timeElapsed = (int) (System.currentTimeMillis() - TwoPhaseHASCO.this.timeOfStart); - int timeRemaining = (int) TwoPhaseHASCO.this.hasco.getTimeout().milliseconds() - timeElapsed; - if (timeRemaining < 2000 || TwoPhaseHASCO.this.shouldSearchTerminate(timeRemaining)) { - TwoPhaseHASCO.this.logger.info("Canceling HASCO (first phase). {}ms remaining.", timeRemaining); - TwoPhaseHASCO.this.hasco.cancel(); - TwoPhaseHASCO.this.logger.info("HASCO canceled successfully after {}ms", (System.currentTimeMillis() - TwoPhaseHASCO.this.timeOfStart) - timeElapsed); - this.cancel(); + catch (Throwable e) { + logger.error("Observed {} while checking termination of phase 1. Stack trace is: {}", e.getClass().getName(), Arrays.stream(e.getStackTrace()).map(se -> "\n\t" + se.toString()).collect(Collectors.joining())); } } }; @@ -175,11 +181,11 @@ public void run() { this.hasco.call(); } catch (AlgorithmExecutionCanceledException e) { this.logger.info("HASCO has terminated due to a cancel."); - if (this.isCanceled()) { + if (isCanceled()) { throw new AlgorithmExecutionCanceledException(e.getDelay()); } } catch (AlgorithmTimeoutedException e) { - this.logger.warn("HASCO has timeouted. In fact, time to deadline is {}ms", this.getTimeout().milliseconds() - (System.currentTimeMillis() - this.timeOfStart)); + this.logger.warn("HASCO has timeouted. In fact, time to deadline is {}ms", getTimeout().milliseconds() - (System.currentTimeMillis() - this.timeOfStart)); } finally { this.phase1CancellationTask.cancel(); } @@ -187,14 +193,14 @@ public void run() { /* if there is no candidate, and the remaining time is very small, throw an AlgorithmTimeoutedException */ this.logger.info("HASCO has finished. {} solutions were found.", this.phase1ResultQueue.size()); - if (this.phase1ResultQueue.isEmpty() && this.getRemainingTimeToDeadline().seconds() < 10) { + if (this.phase1ResultQueue.isEmpty() && getRemainingTimeToDeadline().seconds() < 10) { this.logger.info("No solution found within phase 1. Throwing an AlgorithmTimeoutedException (This is conventional behavior for when an algorithm has not identified its solution when the timeout bound is hit.)"); - this.terminate(); // this sends the AlgorithmFinishedEvent - throw new AlgorithmTimeoutedException(this.getRemainingTimeToDeadline().milliseconds() * -1); + terminate(); // this sends the AlgorithmFinishedEvent + throw new AlgorithmTimeoutedException(getRemainingTimeToDeadline().milliseconds() * -1); } /* phase 2: select model */ - IObjectEvaluator selectionBenchmark = this.getInput().getSelectionBenchmark(); + IObjectEvaluator selectionBenchmark = getInput().getSelectionBenchmark(); if (this.logger.isInfoEnabled()) { this.logger.info("Entering phase 2. Solutions seen so far had an (internal) error of {}", this.phase1ResultQueue.stream().map(e -> "\n\t" + e.getScore() + "(" + e.getComponentInstance() + ")").collect(Collectors.joining())); } @@ -202,14 +208,14 @@ public void run() { this.logger.debug("Setting best score for selection phase node evaluator to {}", this.phase1ResultQueue.peek().getScore()); ((IInformedObjectEvaluatorExtension) selectionBenchmark).updateBestScore(this.phase1ResultQueue.peek().getScore()); } - this.checkAndConductTermination(); + checkAndConductTermination(); this.selectedHASCOSolution = this.selectModel(); - this.setBestSeenSolution(this.selectedHASCOSolution); - assert this.getBestSeenSolution().equals(this.selectedHASCOSolution); - return this.terminate(); + setBestSeenSolution(this.selectedHASCOSolution); + assert getBestSeenSolution().equals(this.selectedHASCOSolution); + return terminate(); default: - throw new IllegalStateException("Cannot do anything in state " + this.getState()); + throw new IllegalStateException("Cannot do anything in state " + getState()); } } @@ -236,7 +242,7 @@ private synchronized List> getSelectionForPhase2( if (remainingTime < 0) { throw new IllegalArgumentException("Cannot do anything in negative time (" + remainingTime + "ms)"); } - HASCOSolutionCandidate internallyOptimalSolution = this.getBestSeenSolution(); + HASCOSolutionCandidate internallyOptimalSolution = getBestSeenSolution(); if (internallyOptimalSolution == null) { return new ArrayList<>(); } @@ -248,12 +254,12 @@ private synchronized List> getSelectionForPhase2( Collection> potentialCandidates = new ArrayList<>(this.phase1ResultQueue).stream().filter(solution -> solution.getScore() <= optimalInternalScore + MAX_MARGIN_FROM_BEST).collect(Collectors.toList()); this.logger.debug("Computing {} best and {} random solutions for a max runtime of {}. Number of candidates that are at most {} worse than optimum {} is: {}/{}", bestK, randomK, remainingTime, MAX_MARGIN_FROM_BEST, optimalInternalScore, potentialCandidates.size(), this.phase1ResultQueue.size()); - assert potentialCandidates.contains(internallyOptimalSolution); + // assert potentialCandidates.contains(internallyOptimalSolution); List> selectionCandidates = potentialCandidates.stream().limit(bestK).collect(Collectors.toList()); List> remainingCandidates = new ArrayList<>(SetUtil.difference(potentialCandidates, selectionCandidates)); Collections.shuffle(remainingCandidates, new Random(this.getConfig().randomSeed())); selectionCandidates.addAll(remainingCandidates.stream().limit(randomK).collect(Collectors.toList())); - assert selectionCandidates.contains(internallyOptimalSolution); + // assert selectionCandidates.contains(internallyOptimalSolution); if (this.logger.isTraceEnabled()) { this.logger.trace("Determined the following candidates for selection phase (in this order): {}", selectionCandidates.stream().map(c -> "\n\t" + c.getScore() + ": " + c.getComponentInstance()).collect(Collectors.joining())); } @@ -285,7 +291,7 @@ private int getInSearchEvaluationTimeOfSolutionSet(final Collection> solutions, final boolean assumeCurrentlyBestCandidateToBeSelected) { int timeForPhase2 = this.getExpectedRuntimeForPhase2ForAGivenPool(solutions); int timeForPostprocessing = 0; - if (assumeCurrentlyBestCandidateToBeSelected && this.getBestSeenSolution() != null) { + if (assumeCurrentlyBestCandidateToBeSelected && getBestSeenSolution() != null) { timeForPostprocessing = this.getPostprocessingTimeOfCurrentlyBest(); } else { timeForPostprocessing = this.getMaximumPostprocessingTimeOfAnyPoolMember(solutions); @@ -294,7 +300,7 @@ public int getExpectedTotalRemainingRuntimeForAGivenPool(final Collection> solutions) { @@ -316,7 +322,7 @@ public int getExpectedRuntimeForPhase2ForAGivenPool(final Collection selectModel() throws InterruptedException { - final IObjectEvaluator evaluator = this.getInput().getSelectionBenchmark(); + final IObjectEvaluator evaluator = getInput().getSelectionBenchmark(); final Optional> bestSolutionOptional = this.phase1ResultQueue.stream().min((s1, s2) -> s1.getScore().compareTo(s2.getScore())); if (!bestSolutionOptional.isPresent()) { throw new IllegalStateException("Cannot select a model since phase 1 has not returned any result."); @@ -328,8 +334,8 @@ protected HASCOSolutionCandidate selectModel() throws InterruptedExcepti this.logger.info("Starting with phase 2: Selection of final model among the {} solutions that were identified.", this.phase1ResultQueue.size()); long startOfPhase2 = System.currentTimeMillis(); List> ensembleToSelectFrom; - if (this.getTimeout().seconds() > 0) { - int remainingTime = (int) (this.getTimeout().milliseconds() - (System.currentTimeMillis() - this.timeOfStart)); + if (getTimeout().seconds() > 0) { + int remainingTime = (int) (getTimeout().milliseconds() - (System.currentTimeMillis() - this.timeOfStart)); /* * check remaining time, otherwise just return the solution with best F-Value. */ @@ -344,7 +350,7 @@ protected HASCOSolutionCandidate selectModel() throws InterruptedExcepti int expectedTimeForPhase2 = this.getExpectedRuntimeForPhase2ForAGivenPool(ensembleToSelectFrom); int expectedPostprocessingTime = this.getPostprocessingTimeOfCurrentlyBest(); int expectedMaximumRemainingRuntime = expectedTimeForPhase2 + expectedPostprocessingTime; - remainingTime = (int) (this.getTimeout().milliseconds() - (System.currentTimeMillis() - this.timeOfStart)); + remainingTime = (int) (getTimeout().milliseconds() - (System.currentTimeMillis() - this.timeOfStart)); if (expectedMaximumRemainingRuntime > remainingTime) { this.logger.warn("Only {}ms remaining. We probably cannot make it in time.", remainingTime); @@ -367,7 +373,7 @@ protected HASCOSolutionCandidate selectModel() throws InterruptedExcepti }); HASCOSolutionCandidate selectedModel = bestSolution; // backup solution final Semaphore sem = new Semaphore(0); - long timestampOfDeadline = this.timeOfStart + this.getTimeout().milliseconds() - 2000; + long timestampOfDeadline = this.timeOfStart + getTimeout().milliseconds() - 2000; /* evaluate each candiate */ List stats = new ArrayList<>(); @@ -509,7 +515,7 @@ public void cancel() { if (this.hasco != null) { this.hasco.cancel(); } - assert this.isCanceled() : "Cancel-flag is not true at the end of the cancel procedure!"; + assert isCanceled() : "Cancel-flag is not true at the end of the cancel procedure!"; } /** diff --git a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/twophase/TwoPhaseHASCOFactory.java b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/twophase/TwoPhaseHASCOFactory.java index baca0e04a6..86ca95bd4d 100644 --- a/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/twophase/TwoPhaseHASCOFactory.java +++ b/softwareconfiguration/hasco/src/main/java/ai/libs/hasco/variants/forwarddecomposition/twophase/TwoPhaseHASCOFactory.java @@ -4,7 +4,7 @@ import ai.libs.hasco.core.HASCOFactory; import ai.libs.hasco.core.HASCOSolutionCandidate; import ai.libs.hasco.optimizingfactory.SoftwareConfigurationAlgorithmFactory; -import jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; public class TwoPhaseHASCOFactory, N, A> implements SoftwareConfigurationAlgorithmFactory, Double> { diff --git a/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/serialization/ComponentLoaderTest.java b/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/serialization/ComponentLoaderTest.java new file mode 100644 index 0000000000..6851333e4c --- /dev/null +++ b/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/serialization/ComponentLoaderTest.java @@ -0,0 +1,28 @@ +package ai.libs.hasco.serialization; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; + +import org.junit.Test; + +import ai.libs.hasco.model.Component; +import ai.libs.jaicore.basic.ResourceFile; + +public class ComponentLoaderTest { + + @Test + public void testLoadFromFile() throws IOException { + Collection components = new ComponentLoader(new File("testrsc/weka/weka-all-autoweka.json")).getComponents(); + assertTrue(!components.isEmpty()); + } + + @Test + public void testLoadFromResource() throws IOException { + Collection components = new ComponentLoader(new ResourceFile("ai/libs/hasco/testrsc/weka-all-autoweka.json")).getComponents(); + assertTrue(!components.isEmpty()); + } + +} diff --git a/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOTester.java b/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOTester.java index 12fb3b4dbb..0f41389c25 100644 --- a/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOTester.java +++ b/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOTester.java @@ -27,12 +27,12 @@ import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; import ai.libs.jaicore.basic.sets.SetUtil.Pair; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.util.CycleDetectedResult; -import jaicore.search.util.DeadEndDetectedResult; -import jaicore.search.util.GraphSanityChecker; -import jaicore.search.util.SanityCheckResult; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.util.CycleDetectedResult; +import ai.libs.jaicore.search.util.DeadEndDetectedResult; +import ai.libs.jaicore.search.util.GraphSanityChecker; +import ai.libs.jaicore.search.util.SanityCheckResult; public abstract class HASCOTester, N, A> extends SoftwareConfigurationAlgorithmTester { diff --git a/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOViaFDAndBestFirstWithRandomCompletionsTester.java b/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOViaFDAndBestFirstWithRandomCompletionsTester.java index 9d31d15ba6..248e3a6ead 100644 --- a/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOViaFDAndBestFirstWithRandomCompletionsTester.java +++ b/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOViaFDAndBestFirstWithRandomCompletionsTester.java @@ -4,7 +4,7 @@ import ai.libs.hasco.core.RefinementConfiguredSoftwareConfigurationProblem; import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDAndBestFirstWithRandomCompletionsFactory; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class HASCOViaFDAndBestFirstWithRandomCompletionsTester extends HASCOTester, TFDNode, String> { diff --git a/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOViaFDAndBlindBestFirstTester.java b/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOViaFDAndBlindBestFirstTester.java index 3445671748..8877489ce7 100644 --- a/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOViaFDAndBlindBestFirstTester.java +++ b/softwareconfiguration/hasco/src/test/java/ai/libs/hasco/test/HASCOViaFDAndBlindBestFirstTester.java @@ -4,7 +4,7 @@ import ai.libs.hasco.core.RefinementConfiguredSoftwareConfigurationProblem; import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDAndBestFirstFactory; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; +import ai.libs.jaicore.search.probleminputs.GraphSearchWithSubpathEvaluationsInput; public class HASCOViaFDAndBlindBestFirstTester extends HASCOTester, TFDNode, String> { diff --git a/softwareconfiguration/mlplan/build.gradle b/softwareconfiguration/mlplan/build.gradle index 4a77d3255f..0a6376eba6 100644 --- a/softwareconfiguration/mlplan/build.gradle +++ b/softwareconfiguration/mlplan/build.gradle @@ -1,118 +1,122 @@ -sourceSets { - main { - resources { - srcDir 'resources' - } - } -} - -dependencies { - // basic dependencies - compile project(':hasco') - - // JAICore dependencies - compile project(':JAICore:jaicore-basic') - compile project(':JAICore:jaicore-experiments') - compile project(':JAICore:jaicore-logic') - compile project(':JAICore:jaicore-planning') - compile project(':JAICore:jaicore-search') - compile project(':JAICore:jaicore-ml') - - - // OWL API - compile 'net.sourceforge.owlapi:owlapi-distribution:5.1.0' - // TreeMiner - compile 'com.github.helegraf:TreeMiner:df764c7b13' - // linear algebra - compile group: 'org.nd4j', name: 'nd4j-native-platform', version: '0.9.1' - compile group: 'org.nd4j', name: 'nd4j-api', version: '0.9.1' - - // gradient descent (but forbid that the guy uses his log4j-stuff, which we will bride to slf4j) - compile ('de.jungblut.common:thomasjungblut-common:1.1') { - exclude group: 'log4j' - exclude group: 'org.slf4j' - exclude group: 'org.apache.logging.log4j', module: 'log4j-core' - exclude group: 'org.apache.logging.log4j', module: 'log4j-api' - exclude group: 'commons-cli' - } - - // https://mvnrepository.com/artifact/commons-cli/commons-cli - compile group: 'commons-cli', name: 'commons-cli', version: '1.4' - - testCompile project(path: ':JAICore:jaicore-basic', configuration: 'testArtifacts') - testCompile project(path: ':JAICore:jaicore-search', configuration: 'testArtifacts') - -} - - -configurations.all { - exclude module: 'weka-dev' -} - -uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") - } - snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: "${ossrhUsername}", password: "${ossrhPassword}") - } - - pom.project { - name 'MLPlan' - packaging 'jar' - // optionally artifactId can be defined here - description 'This project provides an implementation of the AutoML tool ML-Plan.' - url 'https://libs.ai' - - scm { - connection 'scm:git:https://github.com/fmohr/AILibs.git' - developerConnection 'scm:git:https://github.com/fmohr/AILibs.git' - url 'https://github.com/fmohr/AILibs' - } - - licenses { - license { - name 'GPLv3' - url 'https://www.gnu.org/licenses/gpl-3.0.en.html' - } - } - - developers { - developer { - id 'fmohr' - name 'Felix Mohr' - email 'felix.mohr@upb.de' - } - developer { - id 'mwever' - name 'Marcel Wever' - email 'marcel.wever@upb.de' - } - developer { - id 'ahetzer' - name 'Alexander Hetzer' - email 'alexander.hetzer@upb.de' - } - } - } - } - } -} - -task mlplanCLIjar(type: Jar) { - zip64 = true - manifest { - attributes 'Main-Class': 'de.upb.crc901.mlplan.cli.MLPlanCLI' - } - destinationDir = file("${projectDir}/cli") - archivesBaseName="mlplancli" - exclude ('META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA') - from sourceSets.main.allSource - from { (configurations.compile) - .collect { it.isDirectory() ? it : zipTree(it) } } - with jar -} - +sourceSets { + main { + resources { + srcDir 'resources' + } + } +} + +dependencies { + // basic dependencies + compile project(':hasco') + + // JAICore dependencies + compile project(':JAICore:jaicore-basic') + compile project(':JAICore:jaicore-experiments') + compile project(':JAICore:jaicore-logic') + compile project(':JAICore:jaicore-planning') + compile project(':JAICore:jaicore-search') + compile project(':JAICore:jaicore-ml') + + + // OWL API + compile 'net.sourceforge.owlapi:owlapi-distribution:5.1.0' + // TreeMiner + compile 'com.github.helegraf:TreeMiner:df764c7b13' + // linear algebra + compile group: 'org.nd4j', name: 'nd4j-native-platform', version: '0.9.1' + compile group: 'org.nd4j', name: 'nd4j-api', version: '0.9.1' + + // gradient descent (but forbid that the guy uses his log4j-stuff, which we will bride to slf4j) + compile ('de.jungblut.common:thomasjungblut-common:1.1') { + exclude group: 'log4j' + exclude group: 'org.slf4j' + exclude group: 'org.apache.logging.log4j', module: 'log4j-core' + exclude group: 'org.apache.logging.log4j', module: 'log4j-api' + exclude group: 'commons-cli' + } + + // https://mvnrepository.com/artifact/commons-cli/commons-cli + compile group: 'commons-cli', name: 'commons-cli', version: '1.4' + + testCompile project(path: ':JAICore:jaicore-basic', configuration: 'testArtifacts') + testCompile project(path: ':JAICore:jaicore-search', configuration: 'testArtifacts') + +} + + +configurations.all { + exclude module: 'weka-dev' +} + +uploadArchives { + repositories { + mavenDeployer { + def ossrhUsername = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : "" + def ossrhPassword = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : "" + + + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + + pom.project { + name 'MLPlan' + packaging 'jar' + // optionally artifactId can be defined here + description 'This project provides an implementation of the AutoML tool ML-Plan.' + url 'https://libs.ai' + + scm { + connection 'scm:git:https://github.com/fmohr/AILibs.git' + developerConnection 'scm:git:https://github.com/fmohr/AILibs.git' + url 'https://github.com/fmohr/AILibs' + } + + licenses { + license { + name 'GPLv3' + url 'https://www.gnu.org/licenses/gpl-3.0.en.html' + } + } + + developers { + developer { + id 'fmohr' + name 'Felix Mohr' + email 'felix.mohr@upb.de' + } + developer { + id 'mwever' + name 'Marcel Wever' + email 'marcel.wever@upb.de' + } + developer { + id 'ahetzer' + name 'Alexander Hetzer' + email 'alexander.hetzer@upb.de' + } + } + } + } + } +} + +//task mlplanCLIjar(type: Jar) { +// zip64 = true +// manifest { +// attributes 'Main-Class': 'de.upb.crc901.mlplan.cli.MLPlanCLI' +// } +// destinationDir = file("${projectDir}/cli") +// archivesBaseName="mlplancli" +// exclude ('META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA') +// from sourceSets.main.allSource +// from { (configurations.compile) +// .collect { it.isDirectory() ? it : zipTree(it) } } +// with jar +//} + diff --git a/softwareconfiguration/mlplan/conf/log4j.xml b/softwareconfiguration/mlplan/conf/log4j.xml index 2a7f2ae27d..164ecab5ab 100644 --- a/softwareconfiguration/mlplan/conf/log4j.xml +++ b/softwareconfiguration/mlplan/conf/log4j.xml @@ -1,248 +1,248 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/softwareconfiguration/mlplan/conf/ml2planAutoExperimenter.properties b/softwareconfiguration/mlplan/conf/ml2planAutoExperimenter.properties deleted file mode 100644 index 730bca7a5d..0000000000 --- a/softwareconfiguration/mlplan/conf/ml2planAutoExperimenter.properties +++ /dev/null @@ -1,17 +0,0 @@ -mem.max = 4096 -cpu.max = 8 - -datasets = arts1, bibtex, birds, birds-fixed, business1, emotions, enron-f, flags, genbase, health1, llog-f, medical, scene, science1, yeast -datasets = genbase -test_folds = 1 -test_split_techs = mccv:0.7/0.3 -seeds = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 -seeds = 10 -timeouts = 5 -node_timeouts = 2 -metric_ids = 73,1,8,62 - -keyfields = datasets, test_split_techs, test_folds, seeds, timeouts, node_timeouts, metric_ids -resultfields = completed, classifier_string, value - -datasetfolder = ../../../datasets/classification/multi-label \ No newline at end of file diff --git a/softwareconfiguration/mlplan/conf/mlplan-weka-eval.properties b/softwareconfiguration/mlplan/conf/mlplan-weka-eval.properties deleted file mode 100644 index 77aca9ed23..0000000000 --- a/softwareconfiguration/mlplan/conf/mlplan-weka-eval.properties +++ /dev/null @@ -1,34 +0,0 @@ -cpu.max = 1 -mem.max = 4096 - -hasco.seed = 0 -hasco.timeout = 60 -hasco.visualize = false - -# database settings -db.host = isys-db.cs.upb.de -db.username = results -db.password = Hallo333! -db.database = results_mlplan -db.table = mlplan_dev2 -db.ssl = true -db.evalTable = dev_eval - -# ML-Plan specific parameters -mlplan.selection.data_portion = 0.3 -mlplan.selection.num_considered_solutions = 100 -mlplan.selection.num_mc_iterations = 5 -mlplan.search.num_mc_iterations = 5 -mlplan.search.precedence_list = model/weka/precedenceList.txt - -datasetfolder = ../../../datasets/classification/multi-class - -# experiment specific settings -keyfields = timeouts, evaluationTimeouts, datasets, seeds - -datasets = car -evaluationTimeouts = 15 -timeouts = 60 -seeds = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 - -resultfields = loss, classifier, preprocessor \ No newline at end of file diff --git a/softwareconfiguration/mlplan/conf/mlplanwekacli.properties b/softwareconfiguration/mlplan/conf/mlplanwekacli.properties deleted file mode 100644 index 41f7beecb2..0000000000 --- a/softwareconfiguration/mlplan/conf/mlplanwekacli.properties +++ /dev/null @@ -1,8 +0,0 @@ -mem.max = 8192 -cpu.max = 8 - -mlplanwekacli.globaltimeout = 300 -mlplanwekacli.evaltimeout = 10 -mlplanwekacli.datasetfile=../../../datasets/classification/multi-class/ecoli.arff -mlplanwekacli.outputfile=out.txt -mlplanwekacli.weka.cli.showgrpah=true \ No newline at end of file diff --git a/softwareconfiguration/mlplan/gradlew b/softwareconfiguration/mlplan/gradlew deleted file mode 100644 index 27309d9231..0000000000 --- a/softwareconfiguration/mlplan/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/softwareconfiguration/mlplan/gradlew.bat b/softwareconfiguration/mlplan/gradlew.bat deleted file mode 100644 index f6d5974e72..0000000000 --- a/softwareconfiguration/mlplan/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/softwareconfiguration/mlplan/mlplan-30.csv b/softwareconfiguration/mlplan/mlplan-30.csv deleted file mode 100644 index 74c19d1d82..0000000000 --- a/softwareconfiguration/mlplan/mlplan-30.csv +++ /dev/null @@ -1,27 +0,0 @@ -dataset,time_1,accuracy_1,precision_1,recall_1,f1score_1,error_1,time_2,accuracy_2,precision_2,recall_2,f1score_2,error_2,time_3,accuracy_3,precision_3,recall_3,f1score_3,error_3,accuracy_mean,accuracy_std,precision_mean,precision_std,recall_mean,recall_std,f1score_mean,f1score_std,model_1,model_2,model_3 -AP_Breast_Lung,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 175050ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 177324ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 176421ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -AP_Omentum_Ovary,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 177995ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 177645ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 177867ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -AP_Prostate_Ovary,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 177478ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 177647ms.,,,,,,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -AirlinesCodrnaAdult,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 165098ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 163397ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 163436ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -Amazon,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 175314ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 174649ms.,1981.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 176836ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -CovPokElec,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 143739ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 144695ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 141716ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -KDDCup99,1919.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 111935ms.,1942.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 135946ms.,1933.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 124777ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -cifar-10,45.0,0.0,0.0,0.0,0.0,,42.0,0.0,0.0,0.0,0.0,,45.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -connect-4,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 178791ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179028ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 178449ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -dataset_60_waveform-5000,1799.0,0.8672,0.8672088585941022,0.8672,0.8671814905869325,,1799.0,0.8632,0.8634012599874957,0.8632,0.8632478620221807,,1798.0,0.8656,0.8658212497980948,0.8656,0.8656672077368303,,0.8653333333333334,0.0016438437341250653,0.865477122793231,0.0015733762707132724,0.8653333333333334,0.0016438437341250653,0.8653655201153145,0.0016200041125646644,"[SupervisedFilterSelector [searcher=weka.attributeSelection.Ranker, evaluator=weka.attributeSelection.PrincipalComponents]] (preprocessors), weka.classifiers.functions.SimpleLogistic- [-I, 0, -M, 500, -H, 50, -W, 0.0, -A] (classifier)","[SupervisedFilterSelector [searcher=weka.attributeSelection.Ranker, evaluator=weka.attributeSelection.PrincipalComponents]] (preprocessors), weka.classifiers.functions.Logistic- [-R, 1.0E-8, -M, -1, -num-decimal-places, 4] (classifier)","[SupervisedFilterSelector [searcher=weka.attributeSelection.Ranker, evaluator=weka.attributeSelection.PrincipalComponents]] (preprocessors), weka.classifiers.functions.SimpleLogistic- [-I, 0, -S, -M, 500, -H, 50, -W, 0.0, -A] (classifier)" -dataset_61_iris,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179980ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179977ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179976ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -dataset_9_autos,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179975ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179977ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179964ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -devnagari,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 158519ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 159564ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 155861ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -electricity-normalized,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179296ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179317ms.,1906.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 104200ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -eye_movements,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179727ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179739ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179697ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -hiva_agnostic,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 176519ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 176795ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 177838ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -ipums_la_99-small,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179583ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179606ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179627ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -leukemia,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179474ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179455ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179467ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -lymphoma_2classes,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179746ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179736ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179745ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -mfeat-pixel,1798.0,0.994,0.9940395604395604,0.9940000000000001,0.9939131486289432,,1797.0,0.994,0.9940395604395604,0.9940000000000001,0.9939131486289432,,,,,,,,0.994,0.0,0.9940395604395604,0.0,0.9940000000000001,0.0,0.9939131486289432,0.0,"[SupervisedFilterSelector [searcher=weka.attributeSelection.Ranker, evaluator=weka.attributeSelection.PrincipalComponents]] (preprocessors), weka.classifiers.functions.SMO- [-C, 1.0, -L, 0.001, -P, 1.0E-12, -N, 0, -V, -1, -W, 1, -K, weka.classifiers.functions.supportVector.Puk -O 1.0 -S 1.0 -C 250007, -calibrator, weka.classifiers.functions.Logistic -R 1.0E-8 -M -1 -num-decimal-places 4] (classifier)","[SupervisedFilterSelector [searcher=weka.attributeSelection.BestFirst, evaluator=weka.attributeSelection.CfsSubsetEval]] (preprocessors), weka.classifiers.trees.RandomForest- [-P, 100, -I, 20, -num-slots, 1, -K, 7, -M, 1.0, -V, 0.001, -S, 1] (classifier)", -phpB0xrNj,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 174560ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 177424ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 177327ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -phpGReJjU,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179724ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179703ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179762ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -phpWfYmlu,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179813ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179794ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179812ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -phpfLuQE4,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 179107ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 178627ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 178622ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -phprAeXmK,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 168591ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 170891ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 171196ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, -pokerhand-normalized,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 177071ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 175794ms.,1980.0,0.0,0.0,0.0,0.0,Timeout was triggered with a delay of 174692ms.,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,, diff --git a/softwareconfiguration/mlplan/readme.md b/softwareconfiguration/mlplan/readme.md index 7b4fea6b6b..c61eceb201 100644 --- a/softwareconfiguration/mlplan/readme.md +++ b/softwareconfiguration/mlplan/readme.md @@ -1,3 +1,90 @@ ## ML-Plan ### Installation +You can bind in ML-Plan via a Maven dependency (using Maven central as repository). +### Maven +``` + + ai.libs + mlplan + 0.1.2 + +``` + +### Gradle +```gradle +dependencies { + implementation 'ai.libs:mlplan:0.1.2' +} +``` + ### Usage +The shortest way to obtain an optimized WEKA classifier via ML-Plan for your data object `data` is to run +```java +Classifier optimizedClassifier = AbstractMLPlanBuilder.forWeka().withDataset(data).build().call(); +``` +An analogous call exists for scikit-learn pipelines. +Here, several default parameters apply that you may usually want to customize. + +### Customizing ML-Plan +This is just a quick overview of the most important configurations of ML-Plan. + +#### Creating an ML-Plan builder for your learning framework +Depending on the library you want to work with, you then can construct a WEKA or scikit-learn related builder for ML-Plan. +Both builders have the same basic capacities (and only these are needed for the simple example below). +For library-specific aspects, there may be additional methods for the respective builders. + + +Note that ML-Plan for scikit-learn is also Java-based, i.e. we do not have a Python version of ML-Plan only for being able to cope with scikit-learn. Instead, ML-Plan can be configured to work with scikit-learn as the library to be used. + +##### ML-Plan for WEKA +```java +MLPlanWekaBuilder builder = AbstractMLPlanBuilder.forWeka(); +``` + +##### ML-Plan for scikit-learn +```java +MLPlanSKLearnBuilder builder = AbstractMLPlanBuilder.forSKLearn(); +``` + +**Note**: If you want to use ML-Plan for scikit-learn, then ML-Plan assumes Python 3.5 or higher to be active (invoked when calling `python` on the command line), and the following packages must be installed: +`liac-arff`, +`numpy`, +`json`, +`pickle`, +`os`, +`sys`, +`warnings`, +`scipy`, +`scikit-learn`. +Please make sure that you really have `liac-arff` installed, and **not** the `arff` package. + +#### Configuring timeouts +With the `builder` variable being configured as above, you can specify timeouts for ML-Plan as a whole, as well as timeouts for the evaluation of a single solution candidate or nodes in the search. +By default, all these timeouts are set to 60 seconds. +```java +/* set the global timeout of ML-Plan to 1 hour: */ +builder.withTimeOut(new TimeOut(3600, TimeUnit.SECONDS)); + +/* set the timeout of a node in the search graph (evaluation of all random completions of a node): */ +builder.withNodeEvaluationTimeOut(new TimeOut(300, TimeUnit.SECONDS)); + +/* set the timeout of a single solution candidate */ +builder.withCandidateEvaluationTimeOut(new TimeOut(300, TimeUnit.SECONDS)); +``` + +#### Running ML-Plan with your data +We currently work with the Instances data format of the WEKA library: +```java +/* Load your training dataset with WEKA's instances */ +Instances trainDataset = new Instances(new FileReader("myDataset.arff")); + +/* configure the builder to use the given data */ +builder.withDataset(trainDataset); + +/* build and call ML-Plan */ +MLPlan mlplan = builder.build(); +Classifier chosenClassifier = mlplan.call(); +``` + +### JavaDoc +JavaDoc is available here: https://javadoc.io/doc/ai.libs/mlplan/ diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-mulanbridge.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-mulanbridge.json deleted file mode 100644 index 6469b5adff..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-mulanbridge.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "repository": "MEKA Mulan Bridge", - "include": [ - ], - "parameters": [ - ], - "components": [ - { - "name": "meka.classifiers.multilabel.MULAN", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "baselearner", - "name": "Classifier" - } - ], - "parameter": [ - { - "name": "_S", - "comment": "Method Name default: RAkEL1; HOMER is discarded in the set of values", - "type": "cat", - "default": "RAkEL1", - "values": [ - "RAkEL1", - "BR", - "LP", - "CLR", - "RAkELn", - "MLkNN", - "IBLR_ML", - "BPMLL" - ] - } - ] - } - ] -} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-base.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-base.json index 2299d8d619..322f50fa5b 100644 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-base.json +++ b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-base.json @@ -1,552 +1,206 @@ { "repository": "MEKA", - "include": [ - ], - "parameters": [ - ], + "include": [], + "parameters": [], "components": [ - { - "name": "meka.classifiers.multilabel.BCC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "name": "X", - "comment": "The way to measure dependencies. default: lbf (frequencies only)", - "type": "cat", - "default": "lbf", - "values": [ - "lbf" - ] - } - ] - }, - { - "name": "meka.classifiers.multilabel.BPNN", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "name": "H", - "comment": "Sets the number of hidden units default: 10", - "type": "int", - "default": "10", - "min": "1", - "max": "100", - "refineSplits": 4, - "minInterval": 2 - }, - { - "name": "E", - "comment": "Sets the maximum number of epochs default: 1000 (auto_cut_out)", - "type": "int", - "default": 1000, - "min": 100, - "max": 10000, - "refineSplits": 2, - "minInterval": 100 - }, - { - "name": "r", - "comment": "Sets the learning rate (typically somewhere between 'very small' and 0.1) default: 0.1", - "type": "double", - "default": 0.1, - "min": 1E-5, - "max": 0.1, - "refineSplits": 2, - "minInterval": 1E-5 - }, - { - "name": "m", - "comment": "Sets the momentum (typically somewhere between 0.1 and 0.9) default: 0.1", - "type": "double", - "default": 0.1, - "min": 0.1, - "max": 0.9, - "refineSplits": 2, - "minInterval": 0.05 - } - ] - }, { "name": "meka.classifiers.multilabel.BR", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - ] + "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], + "parameter": [] }, { "name": "meka.classifiers.multilabel.BRq", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], + "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], "parameter": [ { - "comment": "Sets the downsampling ratio default: 0.75 (of original)", "name": "P", "type": "double", - "default": 0.75, - "min": 0.1, - "max": 0.99, - "refineSplits": 2, - "minInterval": 0.05 + "min": 0.2, + "max": 0.8, + "default": 0.8, + "minInterval": 0.01, + "refineSplits": 8 } ] }, { "name": "meka.classifiers.multilabel.CC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - ] + "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], + "parameter": [] }, { "name": "meka.classifiers.multilabel.CCq", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], + "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], "parameter": [ { - "comment": "Sets the downsampling ratio default: 0.75 (of original)", "name": "P", "type": "double", - "default": 0.75, - "min": 0.1, - "max": 0.99, - "refineSplits": 2, - "minInterval": 0.05 + "min": 0.2, + "max": 0.8, + "default": 0.8, + "minInterval": 0.01, + "refineSplits": 8 } ] }, { - "name": "meka.classifiers.multilabel.CDN", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], + "name": "meka.classifiers.multilabel.BCC", + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], "parameter": [ { - "comment": "The total number of iterations. default: 1000 ", - "name": "I", - "type": "cat", - "default": 1000, - "values": [ - 100, - 1000, - 10000, - 20000 - ] - }, - { - "comment": "The number of collection iterations. default: 100 ", - "name": "Ic", + "name": "X", + "comment": "The way to measure dependencies. default: lbf (frequencies only) | TODO: No label dependence still missing as an option", "type": "cat", - "default": 100, - "values": [ - 50, - 100, - 200, - 500, - 1000 - ] + "default": "lbf", + "values": ["lbf","C","I","Ib","H","Hbf","X","F","L","None"] } ] }, { - "name": "meka.classifiers.multilabel.CDT", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "comment": "Determines the width of the trellis (use 0 for chain; use _1 for a square trellis, i.e., width of sqrt(number of labels)). ", - "name": "H", - "type": "cat", - "default": 0, - "values": [ - 0, - -1 - ] - }, - { - "comment": "Determines the neighbourhood density (the number of neighbours for each node in the trellis). CAUTION: default obtained from source code. No idea about good other values ", - "name": "L", - "type": "int", - "default": 1, - "min": 1, - "max": 5, - "minInterval": 1, - "refineSplits": 2 - }, - { - "comment": "The dependency heuristic to use in rearranging the trellis (None by default). ", - "name": "X", - "type": "cat", - "default": "None", - "values": [ - "None" - ] - }, - { - "comment": "The total number of iterations. default: 1000 ", - "name": "I", - "type": "cat", - "default": 1000, - "values": [ - 100, - 1000, - 10000, - 20000 - ] - }, - { - "comment": "The number of collection iterations. default: 100 ", - "name": "Ic", - "type": "cat", - "default": 100, - "values": [ - 50, - 100, - 200, - 500, - 1000 - ] - } - ] + "name": "meka.classifiers.multilabel.PCC", + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], + "parameter": [] }, { - "name": "meka.classifiers.multilabel.CT", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], + "name": "meka.classifiers.multilabel.MCC", + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], "parameter": [ { - "comment": "Determines the width of the trellis (use 0 for chain; use _1 for a square trellis, i.e., width of sqrt(number of labels)). ", - "name": "H", - "type": "cat", + "name": "Is", + "comment": "The number of iterations to search the chain space at train time. default: 0", + "type": "int", "default": 0, - "values": [ - 0, - -1 - ] + "min": 0, + "max": 1500, + "minInterval": 5, + "refineSplits": 8 }, { - "comment": "Determines the neighbourhood density (the number of neighbours for each node in the trellis). CAUTION: default obtained from source code. No idea about good other values ", - "name": "L", + "name": "Iy", + "comment": "The number of iterations to search the output space at test time. default: 10", "type": "int", - "default": 1, - "min": 1, - "max": 5, + "default": 10, + "min": 0, + "max": 100, "minInterval": 1, - "refineSplits": 2 - }, - { - "comment": "The dependency heuristic to use in rearranging the trellis (None by default). ", - "name": "X", - "type": "cat", - "default": "None", - "values": [ - "None" - ] - }, - { - "comment": "The total number of iterations. default: 1000 ", - "name": "I", - "type": "cat", - "default": 1000, - "values": [ - 100, - 1000, - 10000, - 20000 - ] - }, - { - "comment": "The number of collection iterations. default: 100 ", - "name": "Ic", - "type": "cat", - "default": 100, - "values": [ - 50, - 100, - 200, - 500, - 1000 - ] + "refineSplits": 8 }, { "name": "P", "comment": "Sets the payoff function. Any of those listed in regular evaluation output will do (e.g., 'Exact match'). default: Exact match", "type": "cat", "default": "Exact match", - "values": [ - "Exact match" - ] + "values": ["Accuracy","Jaccard index","Hamming score","Exact match","Jaccard distance","Hamming loss","ZeroOne loss","Harmonic score","One error","Rank loss","Avg precision","Log Loss (lim. L)","Log Loss (lim. D)","Micro Precision","Micro Recall","Macro Precision","Macro Recall","F1 (micro averaged)","F1 (macro averaged by example)","F1 (macro averaged by label)","AUPRC (macro averaged)","AUROC (macro averaged)","Levenshtein distance"] } ] }, { - "name": "meka.classifiers.multilabel.DBPNN", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], + "name": "meka.classifiers.multilabel.PMCC", + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], "parameter": [ { - "name": "N", + "name": "M", + "comment": "The population size (of chains) __ should be smaller than the total number of chains evaluated (Is) default: 10", "type": "int", - "default": 2, + "default": 10, "min": 1, - "max": 10, + "max": 50, "minInterval": 1, - "refineSplits": 2 + "refineSplits": 8 }, { - "name": "H", - "comment": "Sets the number of hidden units default: 10", + "name": "O", + "comment": "Use temperature: cool the chain down over time (from the beginning of the chain) __ can be faster default: 0 (no temperature)", "type": "cat", - "default": 10, - "values": [ - 5, - 10, - 20, - 50 - ] - }, - { - "name": "E", - "comment": "Sets the maximum number of epochs default: 1000 (auto_cut_out)", - "type": "int", - "default": 1000, - "min": 100, - "max": 10000, - "refineSplits": 2, - "minInterval": 100 + "default": "0", + "values": ["0","1"] }, { - "name": "r", - "comment": "Sets the learning rate (tyically somewhere between 'very small' and 0.1) default: 0.1", + "name": "B", + "comment": "If using O = 1 for temperature, this sets the Beta constant default: 0.03", "type": "double", - "default": 0.1, - "min": 1E-5, - "max": 0.1, - "refineSplits": 2, - "minInterval": 1E-5 + "default": 0.03, + "min": 0.01, + "max": 0.99, + "minInterval": 1E-3, + "refineSplits": 8 }, { - "name": "m", - "comment": "Sets the momentum (typically somewhere between 0.1 and 0.9) default: 0.1", - "type": "double", - "default": 0.1, - "min": 0.1, - "max": 0.9, - "refineSplits": 2, - "minInterval": 0.05 - } - ] - }, - { - "name": "meka.classifiers.multilabel.FW", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.HASEL", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "comment": "LEFT OUT: _k The number of labels in each partition __ should be 1 <= k < (L/2) where L is the total number of labels. LEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", - "parameter": [ - { - "name": "P", - "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", + "name": "Is", + "comment": "The number of iterations to search the chain space at train time. default: 0", "type": "int", "default": 0, "min": 0, - "max": 10, + "max": 1500, + "minInterval": 5, + "refineSplits": 8 + }, + { + "name": "Iy", + "comment": "The number of iterations to search the output space at test time. default: 10", + "type": "int", + "default": 10, + "min": 0, + "max": 100, "minInterval": 1, - "refineSplits": 2 - } - ] - }, - { - "name": "meka.classifiers.multilabel.LC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ + "refineSplits": 8 + }, { - "id": "W", - "name": "AbstractClassifier" + "name": "P", + "comment": "Sets the payoff function. Any of those listed in regular evaluation output will do (e.g., 'Exact match'). default: Exact match", + "type": "cat", + "default": "Exact match", + "values": ["Accuracy","Jaccard index","Hamming score","Exact match","Jaccard distance","Hamming loss","ZeroOne loss","Harmonic score","One error","Rank loss","Avg precision","Log Loss (lim. L)","Log Loss (lim. D)","Micro Precision","Micro Recall","Macro Precision","Macro Recall","F1 (micro averaged)","F1 (macro averaged by example)","F1 (macro averaged by label)","AUPRC (macro averaged)","AUROC (macro averaged)","Levenshtein distance"] } ], - "parameter": [ - ] + "dependencies": [{"pre": "O in {1}","post": "B in [0.03,0.03]"}] }, { - "name": "meka.classifiers.multilabel.MajorityLabelset", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - ], + "name": "meka.classifiers.multilabel.CT", + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.Maniac", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ + "name": "H", + "comment": "Determines the width of the trellis (use 0 for chain; use _1 for a square trellis, i.e., width of sqrt(number of labels)).", + "type": "cat", + "default": "0", + "values": ["0","-1"] + }, { - "name": "compression", - "comment": "Compression factor of the autoencoders, each level of autoencoders will compress the labels to factor times previous layer size. (default: 0.85)", - "type": "double", - "default": 0.85, - "min": 0.01, - "max": 0.99, - "minInterval": 0.05, - "refineSplits": 2 + "name": "X", + "comment": "The way to measure dependencies. default: lbf (frequencies only) | TODO: No label dependence still missing as an option", + "type": "cat", + "default": "lbf", + "values": ["lbf","C","I","Ib","H","Hbf","X","F","L","None"] }, { - "name": "numberAutoencoders", - "comment": "Number of autoencoders, i.e. number of hidden layers +1. Note that this can be also used as the number of autoencoders to use in the optimization search, autoencoders will be added until this number is reached and then the best configuration in terms of number of layers is selects. (default: 4)", + "comment": "Determines the neighbourhood density (the number of neighbours for each node in the trellis). CAUTION: default obtained from source code. No idea about good other values ", + "name": "L", "type": "int", - "default": 4, + "default": 1, "min": 1, - "max": 10, + "max": 4, "minInterval": 1, - "refineSplits": 2 + "refineSplits": 4 }, - { - "name": "optimizeAE", - "comment": "Number of autoencoders, i.e. number of hidden layers +1. Note that this can be also used as the number of autoencoders to use in the optimization search, autoencoders will be added until this number is reached and then the best configuration in terms of number of layers is selects. (default: 4)", - "type": "boolean", - "default": "false" - } - ] - }, - { - "name": "meka.classifiers.multilabel.MCC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ { "name": "Is", "comment": "The number of iterations to search the chain space at train time. default: 0", "type": "int", "default": 0, "min": 0, - "max": 10, - "minInterval": 1, - "refineSplits": 2 + "max": 1500, + "minInterval": 5, + "refineSplits": 8 }, { "name": "Iy", @@ -554,123 +208,123 @@ "type": "int", "default": 10, "min": 0, - "max": 20, + "max": 100, "minInterval": 1, - "refineSplits": 2 + "refineSplits": 8 }, { "name": "P", "comment": "Sets the payoff function. Any of those listed in regular evaluation output will do (e.g., 'Exact match'). default: Exact match", "type": "cat", "default": "Exact match", - "values": [ - "Exact match" - ] + "values": ["Accuracy","Jaccard index","Hamming score","Exact match","Jaccard distance","Hamming loss","ZeroOne loss","Harmonic score","One error","Rank loss","Avg precision","Log Loss (lim. L)","Log Loss (lim. D)","Micro Precision","Micro Recall","Macro Precision","Macro Recall","F1 (micro averaged)","F1 (macro averaged by example)","F1 (macro averaged by label)","AUPRC (macro averaged)","AUROC (macro averaged)","Levenshtein distance"] } ] }, { - "name": "meka.classifiers.multilabel.PCC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ + "name": "meka.classifiers.multilabel.CDN", + "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], + "parameter": [ + { + "name": "I", + "comment": "The total number of iterations. default: 1000 ", + "type": "int", + "default": 1000, + "min": 100, + "max": 1000, + "refineSplits": 8, + "minInterval": 10 + }, { - "id": "W", - "name": "AbstractClassifier" + "name": "Ic", + "comment": "The number of collection iterations. default: 100 ", + "type": "int", + "default": 100, + "min": 1, + "max": 100, + "refineSplits": 8, + "minInterval": 1 } - ], - "parameter": [ ] }, + { - "name": "meka.classifiers.multilabel.PMCC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], + "name": "meka.classifiers.multilabel.CDT", + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], "parameter": [ { - "name": "M", - "comment": "The population size (of chains) __ should be smaller than the total number of chains evaluated (Is) default: 10", - "type": "int", - "default": 10, - "min": 1, - "max": 20, - "minInterval": 1, - "refineSplits": 2 + "name": "H", + "comment": "Determines the width of the trellis (use 0 for chain; use _1 for a square trellis, i.e., width of sqrt(number of labels)). ", + "type": "cat", + "default": "0", + "values": ["0","-1"] }, { - "name": "O", - "comment": "Use temperature: cool the chain down over time (from the beginning of the chain) __ can be faster default: 0 (no temperature)", + "name": "L", + "comment": "Determines the neighbourhood density (the number of neighbours for each node in the trellis). CAUTION: default obtained from source code. No idea about good other values ", "type": "int", - "default": 0, - "min": 0, - "max": 10, + "default": 1, + "min": 1, + "max": 5, "minInterval": 1, - "refineSplits": 2 + "refineSplits": 5 }, { - "name": "B", - "comment": "If using O = 1 for temperature, this sets the Beta constant default: 0.03", - "type": "double", - "default": 0.03, - "min": 0, - "max": 0.1, - "minInterval": 1E-3, - "refineSplits": 2 + "comment": "The dependency heuristic to use in rearranging the trellis (None by default). ", + "name": "X", + "type": "cat", + "default": "None", + "values": ["lbf","C","I","Ib","H","Hbf","X","F","L","None"] }, { - "name": "Is", - "comment": "The number of iterations to search the chain space at train time. default: 0", + "name": "I", + "comment": "The total number of iterations. default: 1000 ", "type": "int", - "default": 50, - "min": 20, - "max": 100, - "minInterval": 5, - "refineSplits": 2 + "default": 1000, + "min": 100, + "max": 1000, + "refineSplits": 8, + "minInterval": 10 }, { - "name": "Iy", - "comment": "The number of iterations to search the output space at test time. default: 10", + "name": "Ic", + "comment": "The number of collection iterations. default: 100 ", "type": "int", - "default": 10, - "min": 0, - "max": 20, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "P", - "comment": "Sets the payoff function. Any of those listed in regular evaluation output will do (e.g., 'Exact match'). default: Exact match", - "type": "cat", - "default": "Exact match", - "values": [ - "Exact match" - ] + "default": 100, + "min": 1, + "max": 100, + "refineSplits": 8, + "minInterval": 1 } ] }, + { + "name": "meka.classifiers.multilabel.FW", + "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], + "parameter": [ + ] + }, + { + "name": "meka.classifiers.multilabel.RT", + "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], + "parameter": [ + ] + }, + { + "name": "meka.classifiers.multilabel.LC", + "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], + "parameter": [ + ] + }, { "name": "meka.classifiers.multilabel.PS", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "comment": "LEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m).", + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], "parameter": [ { "name": "P", @@ -678,25 +332,26 @@ "type": "int", "default": 0, "min": 0, - "max": 10, + "max": 5, + "minInterval": 1, + "refineSplits": 6 + }, + { + "name": "N", + "comment": "Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m).", + "type": "int", + "default": 0, + "min": 0, + "max": 5, "minInterval": 1, - "refineSplits": 2 + "refineSplits": 6 } ] }, { "name": "meka.classifiers.multilabel.PSt", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "comment": "LEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], "parameter": [ { "name": "P", @@ -704,24 +359,26 @@ "type": "int", "default": 0, "min": 0, - "max": 10, + "max": 5, + "minInterval": 1, + "refineSplits": 6 + }, + { + "name": "N", + "comment": "Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", + "type": "int", + "default": 0, + "min": 0, + "max": 5, "minInterval": 1, - "refineSplits": 2 + "refineSplits": 6 } ] }, { "name": "meka.classifiers.multilabel.RAkEL", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], "comment": "LEFT OUT: _k The number of labels in each partition __ should be 1 <= k < (L/2) where L is the total number of labels\nLEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m).", "parameter": [ { @@ -740,24 +397,26 @@ "type": "int", "default": 0, "min": 0, - "max": 10, + "max": 5, + "minInterval": 1, + "refineSplits": 6 + }, + { + "name": "N", + "comment": "Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", + "type": "int", + "default": 0, + "min": 0, + "max": 5, "minInterval": 1, - "refineSplits": 2 + "refineSplits": 6 } ] }, { "name": "meka.classifiers.multilabel.RAkELd", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], "comment": "LEFT OUT: _k The number of labels in each partition __ should be 1 <= k < (L/2) where L is the total number of labels.\nLEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m).", "parameter": [ { @@ -766,26 +425,162 @@ "type": "int", "default": 0, "min": 0, - "max": 10, + "max": 5, + "minInterval": 1, + "refineSplits": 6 + }, + { + "name": "N", + "comment": "Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", + "type": "int", + "default": 0, + "min": 0, + "max": 5, "minInterval": 1, - "refineSplits": 2 + "refineSplits": 6 } ] }, { - "name": "meka.classifiers.multilabel.RT", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ + "name": "meka.classifiers.multilabel.BPNN", + "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [], + "parameter": [ + { + "name": "H", + "comment": "Sets the number of hidden units default: 10", + "type": "int", + "default": "10", + "min": "1", + "max": "100", + "refineSplits": 8, + "minInterval": 5 + }, + { + "name": "E", + "comment": "Sets the maximum number of epochs default: 1000 (auto_cut_out)", + "type": "int", + "default": 1000, + "min": 10, + "max": 10000, + "refineSplits": 8, + "minInterval": 100 + }, + { + "name": "r", + "comment": "Sets the learning rate (tyically somewhere between 'very small' and 0.1) default: 0.1", + "type": "double", + "default": 0.1, + "min": 1E-3, + "max": 0.1, + "refineSplits": 8, + "minInterval": 1E-4 + }, { - "id": "W", - "name": "AbstractClassifier" + "name": "m", + "comment": "Sets the momentum (typically somewhere between 0.1 and 0.9) default: 0.1", + "type": "double", + "default": 0.1, + "min": 0.1, + "max": 0.9, + "refineSplits": 8, + "minInterval": 0.05 } - ], + ] + }, + { + "name": "meka.classifiers.multilabel.DBPNN", + "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "meka.classifiers.multilabel.BPNN"}], + "parameter": [ + { + "name": "H", + "comment": "Sets the number of hidden units default: 10", + "type": "int", + "default": "10", + "min": "1", + "max": "100", + "refineSplits": 8, + "minInterval": 5 + }, + { + "name": "E", + "comment": "Sets the maximum number of epochs default: 1000 (auto_cut_out)", + "type": "int", + "default": 1000, + "min": 10, + "max": 10000, + "refineSplits": 8, + "minInterval": 100 + }, + { + "name": "r", + "comment": "Sets the learning rate (tyically somewhere between 'very small' and 0.1) default: 0.1", + "type": "double", + "default": 0.1, + "min": 1E-3, + "max": 0.1, + "refineSplits": 8, + "minInterval": 1E-4 + }, + { + "name": "m", + "comment": "Sets the momentum (typically somewhere between 0.1 and 0.9) default: 0.1", + "type": "double", + "default": 0.1, + "min": 0.1, + "max": 0.9, + "refineSplits": 8, + "minInterval": 0.05 + }, + + { + "name": "N", + "type": "int", + "default": 1, + "min": 1, + "max": 5, + "minInterval": 1, + "refineSplits": 6 + } + ] + }, + + + + { + "name": "meka.classifiers.multilabel.HASEL", + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], + "comment": "LEFT OUT: _k The number of labels in each partition __ should be 1 <= k < (L/2) where L is the total number of labels. LEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", "parameter": [ + { + "name": "P", + "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", + "type": "int", + "default": 0, + "min": 0, + "max": 5, + "minInterval": 1, + "refineSplits": 6 + }, + { + "name": "N", + "comment": "Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", + "type": "int", + "default": 0, + "min": 0, + "max": 5, + "minInterval": 1, + "refineSplits": 6 + } ] + }, + { + "name": "meka.classifiers.multilabel.MajorityLabelset", + "providedInterface": ["MLClassifier","BasicMLClassifier"], + "requiredInterface": [], + "parameter": [] } ] } diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-gecco.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-gecco.json deleted file mode 100644 index af58c6b0d4..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-gecco.json +++ /dev/null @@ -1,468 +0,0 @@ -{ - "repository": "MEKA", - "include": ["../mlplan/autoweka.json"], - "parameters": [ - { - "name": "_P", - "type": "double", - "default": 0.75, - "min": 0.1, - "max": 0.99, - "refineSplits": 2, - "minInterval": 0.05 - }, - { - "name": "_H", - "type": "cat", - "default": 0, - "values": [0, -1] - }, - { - "name": "_L", - "type": "int", - "default": 1, - "min": 1, - "max": 5, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "_X", - "type": "cat", - "default": "None", - "values": ["None"] - }, - { - "name": "_I", - "type": "cat", - "default": 1000, - "values": [100, 1000, 10000, 20000] - }, - { - "name": "_Ic", - "type": "cat", - "default": 100, - "values": [50, 100, 200, 500, 1000] - } - ], - "components": [ - { - "name": "meka.classifiers.multilabel.BCC", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_X", - "type": "cat", - "default": "lbf", - "values": [ "lbf" ] - } - ] - }, - { - "name": "meka.classifiers.multilabel.BPNN", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_H", - "type": "int", - "default": "10", - "min": "1", - "max": "100", - "refineSplits": 4, - "minInterval": 2 - }, - { - "name": "_E", - "type": "int", - "default": 1000, - "min": 100, - "max": 10000, - "refineSplits": 2, - "minInterval": 100 - }, - { - "name": "_r", - "type": "double", - "default": 0.1, - "min": 1E-5, - "max": 0.1, - "refineSplits": 2, - "minInterval": 1E-5 - }, - { - "name": "_m", - "type": "double", - "default": 0.1, - "min": 0.1, - "max": 0.9, - "refineSplits": 2, - "minInterval": 0.05 - } - ] - }, - { - "name": "meka.classifiers.multilabel.BR", - "providedInterface": ["MLClassifier", "BasicMLClassifier", "meka.classifiers.multilabel.BR"], - "requiredInterface": ["Classifier"], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.BRq", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_P" - } - ] - }, - { - "name": "meka.classifiers.multilabel.CC", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.CCq", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_P" - } - ] - }, - { - "name": "meka.classifiers.multilabel.CDN", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_I" - }, - { - "name": "_Ic" - } - ] - }, - { - "name": "meka.classifiers.multilabel.CDT", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_H" - }, - { - "name": "_L" - }, - { - "name": "_X" - }, - { - "name": "_I" - }, - { - "name": "_Ic" - } - ] - }, - { - "name": "meka.classifiers.multilabel.CT", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_H" - }, - { - "name": "_L" - }, - { - "name": "_X" - }, - { - "name": "_I" - }, - { - "name": "_Ic" - }, - { - "name": "_P", - "type": "cat", - "default": "Exact match", - "values": ["Exact match"] - } - ] - }, - { - "name": "meka.classifiers.multilabel.DBPNN", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_N", - "type": "int", - "default": 2, - "min": 1, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "_H", - "type": "cat", - "default": 10, - "values": [ 5, 10, 20, 50 ] - }, - { - "name": "_E", - "type": "int", - "default": 1000, - "min": 100, - "max": 10000, - "refineSplits": 2, - "minInterval": 100 - }, - { - "name": "_r", - "type": "double", - "default": 0.1, - "min": 1E-5, - "max": 0.1, - "refineSplits": 2, - "minInterval": 1E-5 - }, - { - "name": "_m", - "type": "double", - "default": 0.1, - "min": 0.1, - "max": 0.9, - "refineSplits": 2, - "minInterval": 0.05 - } - ] - }, - { - "name": "meka.classifiers.multilabel.FW", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - - ] - }, - { - "name": "meka.classifiers.multilabel.HASEL", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_P", - "type": "int", - "default": 0, - "min": 0, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - } - ] - }, - { - "name": "meka.classifiers.multilabel.LC", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.MajorityLabelset", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": [], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.MCC", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_Is", - "type": "int", - "default": 0, - "min": 0, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "_Iy", - "type": "int", - "default": 10, - "min": 0, - "max": 20, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "_P", - "type": "cat", - "default": "Exact match", - "values": ["Exact match"] - } - ] - }, - { - "name": "meka.classifiers.multilabel.PCC", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - - ] - }, - { - "name": "meka.classifiers.multilabel.PMCC", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_M", - "type": "int", - "default": 10, - "min": 1, - "max": 20, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "_O", - "type": "int", - "default": 0, - "min": 0, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "_B", - "type": "double", - "default": 0.03, - "min": 0, - "max": 0.1, - "minInterval": 1E-3, - "refineSplits": 2 - }, - { - "name": "_Is", - "type": "int", - "default": 50, - "min": 20, - "max": 100, - "minInterval": 5, - "refineSplits": 2 - }, - { - "name": "_Iy", - "type": "int", - "default": 10, - "min": 0, - "max": 20, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "_P", - "type": "cat", - "default": "Exact match", - "values": ["Exact match"] - } - ] - }, - { - "name": "meka.classifiers.multilabel.PS", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_P", - "type": "int", - "default": 0, - "min": 0, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - } - ] - }, - { - "name": "meka.classifiers.multilabel.PSt", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_P", - "type": "int", - "default": 0, - "min": 0, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - } - ] - }, - { - "name": "meka.classifiers.multilabel.RAkEL", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_M", - "type": "int", - "min": 2, - "max": 20, - "default": 10, - "refineSplits": 2, - "minInterval": 1 - }, - { - "name": "_P", - "type": "int", - "default": 0, - "min": 0, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - } - ] - }, - { - "name": "meka.classifiers.multilabel.RAkELd", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - { - "name": "_P", - "type": "int", - "default": 0, - "min": 0, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - } - ] - }, - { - "name": "meka.classifiers.multilabel.RT", - "providedInterface": ["MLClassifier", "BasicMLClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - - ] - } - ] -} \ No newline at end of file diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-meta-gecco.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-meta-gecco.json deleted file mode 100644 index a56bd099d8..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-meta-gecco.json +++ /dev/null @@ -1,175 +0,0 @@ -{ - "repository": "MEKA_META", - "include": [ - ], - "parameters": [ - ], - "components": [ - { - "name": "meka.classifiers.multilabel.meta.BaggingML", - "providedInterface": ["MLClassifier", "MetaMLClassifier"], - "requiredInterface": ["BasicMLClassifier"], - "parameter": [ - { - "name": "_I", - "comment": "Sets the number of models (default 10)", - "type": "int", - "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, - "minInterval": 1 - }, - { - "name": "_P", - "comment": "Size of each bag, as a percentage of total training size (default 67)", - "type": "int", - "default": 67, - "min": 40, - "max": 90, - "refineSplits": 2, - "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.BaggingMLdup", - "providedInterface": ["MLClassifier", "MetaMLClassifier"], - "requiredInterface": ["BasicMLClassifier"], - "parameter": [ - { - "name": "_I", - "type": "int", - "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, - "minInterval": 1 - }, - { - "name": "_P", - "type": "int", - "default": 67, - "min": 40, - "max": 90, - "refineSplits": 2, - "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.CM", - "providedInterface": ["MLClassifier", "MetaMLClassifier"], - "requiredInterface": ["BasicMLClassifier"], - "parameter": [ - { - "name": "_I", - "type": "int", - "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, - "minInterval": 1 - }, - { - "name": "_P", - "type": "int", - "default": 67, - "min": 40, - "max": 90, - "refineSplits": 2, - "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.EM", - "providedInterface": ["MLClassifier", "MetaMLClassifier"], - "requiredInterface": ["BasicMLClassifier"], - "parameter": [ - { - "name": "_I", - "type": "int", - "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, - "minInterval": 1 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.EnsembleML", - "providedInterface": ["MLClassifier", "MetaMLClassifier"], - "requiredInterface": ["BasicMLClassifier"], - "parameter": [ - { - "name": "_I", - "type": "int", - "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, - "minInterval": 1 - }, - { - "name": "_P", - "type": "int", - "default": 67, - "min": 40, - "max": 90, - "refineSplits": 2, - "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.MBR", - "providedInterface": ["MLClassifier", "MetaMLClassifier"], - "requiredInterface": ["meka.classifiers.multilabel.BR"], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.meta.RandomSubspaceML", - "providedInterface": ["MLClassifier", "MetaMLClassifier"], - "requiredInterface": ["BasicMLClassifier"], - "parameter": [ - { - "name": "_A", - "type": "int", - "default": 50, - "min": 1, - "max": 100, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "_I", - "type": "int", - "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, - "minInterval": 1 - }, - { - "name": "_P", - "type": "int", - "default": 67, - "min": 40, - "max": 90, - "refineSplits": 2, - "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.SubsetMapper", - "providedInterface": ["MLClassifier", "MetaMLClassifier"], - "requiredInterface": ["BasicMLClassifier"], - "parameter": [ - ] - } - ] -} \ No newline at end of file diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-meta.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-meta.json index 0551fa6941..1f29f58d40 100644 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-meta.json +++ b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-meta.json @@ -5,328 +5,148 @@ ], "components": [ { - "name": "meka.classifiers.multilabel.meta.BaggingML", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], + "name": "meka.classifiers.multilabel.meta.MBR", + "providedInterface": ["MLClassifier","MetaMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "meka.classifiers.multilabel.BR"}], + "parameter": [] + }, + { + "name": "meka.classifiers.multilabel.meta.SubsetMapper", + "providedInterface": ["MLClassifier","MetaMLClassifier"], + "requiredInterface": [{"id": "W","name": "ProblemTransformationMethod"}], + "parameter": [] + }, + { + "name": "meka.classifiers.multilabel.meta.RandomSubspaceML", + "providedInterface": ["MLClassifier","MetaMLClassifier"], + "requiredInterface": [{"id": "W","name": "ProblemTransformationMethod"}], "parameter": [ { - "comment": "Sets the number of models (default 10)", - "name": "I", - "type": "int", - "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, - "minInterval": 1 - }, - { - "comment": "Size of each bag, as a percentage of total training size (default 67)", "name": "P", + "comment": "Size of each bag, as a percentage of total training size (default 67)", "type": "int", "default": 67, - "min": 40, - "max": 90, - "refineSplits": 2, + "min": 10, + "max": 100, + "refineSplits": 8, "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multilabel.DBPNN", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "meka.classifiers.multilabel.BPNN" - } - ], - "parameter": [ - { - "name": "N", - "type": "int", - "default": 2, - "min": 1, - "max": 10, - "minInterval": 1, - "refineSplits": 2 }, { - "name": "H", - "comment": "Sets the number of hidden units default: 10", - "type": "cat", + "name": "I", + "comment": "The number of models (default: 10)", + "type": "int", "default": 10, - "values": [ - 5, - 10, - 20, - 50 - ] + "min": 10, + "max": 50, + "refineSplits": 8, + "minInterval": 1 }, { - "name": "E", - "comment": "Sets the maximum number of epochs default: 1000 (auto_cut_out)", + "name": "A", + "comment": "Size of attribute space, as a percentage of total attribute space size (must be between 1 and 100, default: 50)", "type": "int", - "default": 1000, - "min": 100, - "max": 10000, - "refineSplits": 2, - "minInterval": 100 - }, - { - "name": "r", - "comment": "Sets the learning rate (tyically somewhere between 'very small' and 0.1) default: 0.1", - "type": "double", - "default": 0.1, - "min": 1E-5, - "max": 0.1, - "refineSplits": 2, - "minInterval": 1E-5 - }, - { - "name": "m", - "comment": "Sets the momentum (typically somewhere between 0.1 and 0.9) default: 0.1", - "type": "double", - "default": 0.1, - "min": 0.1, - "max": 0.9, - "refineSplits": 2, - "minInterval": 0.05 + "default": 50, + "min": 10, + "max": 100, + "minInterval": 5, + "refineSplits": 8 } ] }, { - "name": "meka.classifiers.multilabel.Maniac", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], + "name": "meka.classifiers.multilabel.MLCBMaD", + "providedInterface": ["MLClassifier","MetaMLClassifier"], + "requiredInterface": [{"id": "W","name": "BasicMLClassifier"}], "parameter": [ { - "name": "compression", - "comment": "Compression factor of the autoencoders, each level of autoencoders will compress the labels to factor times previous layer size. (default: 0.85)", - "type": "double", - "default": 0.85, - "min": 0.01, - "max": 0.99, - "minInterval": 0.05, - "refineSplits": 2 - }, - { - "name": "numberAutoencoders", - "comment": "Number of autoencoders, i.e. number of hidden layers +1. Note that this can be also used as the number of autoencoders to use in the optimization search, autoencoders will be added until this number is reached and then the best configuration in terms of number of layers is selects. (default: 4)", + "name": "size", + "comment": "Size of the compressed matrix. Should be less than the number of labels and more than 1. (default: 20)", "type": "int", - "default": 4, "min": 1, - "max": 10, + "max": 20, + "default": 20, "minInterval": 1, "refineSplits": 2 }, { - "name": "optimizeAE", - "comment": "Number of autoencoders, i.e. number of hidden layers +1. Note that this can be also used as the number of autoencoders to use in the optimization search, autoencoders will be added until this number is reached and then the best configuration in terms of number of layers is selects. (default: 4)", - "type": "boolean", - "default": "false" + "name": "threshold", + "comment": "Threshold for the matrix decompositon, what is considered frequent. Between 0 and 1. (default: 0.5)", + "type": "double", + "min": 0.0, + "max": 1.0, + "default": 0.5, + "minInterval": 0.05, + "refineSplits": 8 } ] }, { - "name": "meka.classifiers.multilabel.meta.BaggingMLdup", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], + "name": "meka.classifiers.multilabel.meta.BaggingML", + "providedInterface": ["MLClassifier","MetaMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "BasicMLClassifier"}], "parameter": [ { - "comment": "Sets the number of models (default 10)", "name": "I", + "comment": "Sets the number of models (default 10)", "type": "int", "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, + "min": 10, + "max": 50, + "refineSplits": 8, "minInterval": 1 }, { - "comment": "Size of each bag, as a percentage of total training size (default 67)", "name": "P", + "comment": "Size of each bag, as a percentage of total training size (default 67)", "type": "int", "default": 67, - "min": 40, - "max": 90, - "refineSplits": 2, + "min": 10, + "max": 100, + "refineSplits": 8, "minInterval": 5 } ] }, { - "name": "meka.classifiers.multilabel.meta.CM", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], + "name": "meka.classifiers.multilabel.meta.BaggingMLdup", + "providedInterface": ["MLClassifier","MetaMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "BasicMLClassifier"}], "parameter": [ { - "comment": "The number of iterations of EM to carry out (default: 10)", + "comment": "Sets the number of models (default 10)", "name": "I", "type": "int", "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, + "min": 10, + "max": 50, + "refineSplits": 4, "minInterval": 1 }, { - "comment": "Size of each bag, as a percentage of total training size (default 67)", "name": "P", + "comment": "Size of each bag, as a percentage of total training size (default 67)", "type": "int", "default": 67, - "min": 40, - "max": 90, - "refineSplits": 2, - "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.DeepML", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], - "parameter": [ - { - "comment": "Sets the number of RBMs default: 2", - "name": "N", - "type": "int", - "default": 2, - "min": 2, - "max": 5, - "refineSplits": 2, - "minInterval": 1 - }, - { - "comment": "Sets the number of hidden units default: 10", - "name": "H", - "type": "int", - "default": 10, - "min": 5, + "min": 10, "max": 100, - "refineSplits": 2, + "refineSplits": 8, "minInterval": 5 - }, - { - "comment": "Sets the maximum number of epochs default: 1000 (auto_cut_out)", - "name": "E", - "type": "int", - "default": 1000, - "min": 100, - "max": 10000, - "refineSplits": 2, - "minInterval": 100 - }, - { - "comment": "Sets the learning rate (tyically somewhere between 'very small' and 0.1) default: 0.1", - "name": "r", - "type": "double", - "default": 0.1, - "min": 1E-5, - "max": 0.1, - "refineSplits": 2, - "minInterval": 1E-5 - }, - { - "name": "m", - "comment": "Sets the momentum (typically somewhere between 0.1 and 0.9) default: 0.1", - "type": "double", - "default": 0.1, - "min": 0.1, - "max": 0.9, - "refineSplits": 2, - "minInterval": 0.05 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.EM", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], - "parameter": [ - { - "name": "I", - "comment": "The number of iterations of EM to carry out (default: 10)", - "type": "int", - "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, - "minInterval": 1 } ] }, { "name": "meka.classifiers.multilabel.meta.EnsembleML", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], + "providedInterface": ["MLClassifier","MetaMLClassifier","ProblemTransformationMethod"], + "requiredInterface": [{"id": "W","name": "BasicMLClassifier"}], "parameter": [ { + "comment": "Sets the number of models (default 10)", "name": "I", - "comment": "The number of iterations of EM to carry out (default: 10)", "type": "int", "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, + "min": 10, + "max": 50, + "refineSplits": 4, "minInterval": 1 }, { @@ -334,144 +154,44 @@ "comment": "Size of each bag, as a percentage of total training size (default 67)", "type": "int", "default": 67, - "min": 40, - "max": 90, - "refineSplits": 2, + "min": 10, + "max": 100, + "refineSplits": 8, "minInterval": 5 } ] }, { - "name": "meka.classifiers.multilabel.meta.FilteredClassifier", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], - "parameter": [ - { - "name": "F", - "comment": "The number of iterations of EM to carry out (default: 10). REMARK: Here we could also use a subcomponent for filters!", - "type": "cat", - "default": "weka.filters.supervised.attribute.Discretize -R first_last -precision 6", - "values": [ - "weka.filters.supervised.attribute.Discretize -R first_last -precision 6" - ] - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.MBR", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.meta.RandomSubspaceML", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], + "name": "meka.classifiers.multilabel.meta.EM", + "providedInterface": ["MLClassifier","MetaMLClassifier"], + "requiredInterface": [{"id": "W","name": "ProblemTransformationMethod"}], "parameter": [ { - "name": "A", - "comment": "Size of attribute space, as a percentage of total attribute space size (must be between 1 and 100, default: 50)", - "type": "int", - "default": 50, - "min": 1, - "max": 100, - "minInterval": 1, - "refineSplits": 2 - }, - { + "comment": "Sets the number of models (default 10)", "name": "I", - "comment": "The number of models (default: 10)", "type": "int", "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, + "min": 10, + "max": 50, + "refineSplits": 4, "minInterval": 1 - }, - { - "name": "P", - "comment": "Size of each bag, as a percentage of total training size (default 67)", - "type": "int", - "default": 67, - "min": 40, - "max": 90, - "refineSplits": 2, - "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.SubsetMapper", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" } - ], - "parameter": [ ] }, { - "name": "meka.classifiers.multilabel.MLCBMaD", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], + "name": "meka.classifiers.multilabel.meta.CM", + "providedInterface": ["MLClassifier","MetaMLClassifier"], + "requiredInterface": [{"id": "W","name": "BasicMLClassifier"}], "parameter": [ { - "name": "size", - "comment": "Size of the compressed matrix. Should be less than the number of labels and more than 1. (default: 20)", + "comment": "Sets the number of models (default 10)", + "name": "I", "type": "int", - "min": 1, - "max": 20, - "default": 20, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "threshold", - "comment": "Threshold for the matrix decompositon, what is considered frequent. Between 0 and 1. (default: 0.5)", - "type": "double", - "min": 0, - "max": 1, - "default": 0.5, - "minInterval": 0.1, - "refineSplits": 2 + "default": 10, + "min": 10, + "max": 50, + "refineSplits": 4, + "minInterval": 1 } ] } diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-meta2.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-meta2.json index 64f0811d29..57e2ddb3c2 100644 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-meta2.json +++ b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel-meta2.json @@ -1,14 +1,14 @@ { - "repository": "MEKA-MultiTarget-Meta", - "include": ["./mlplan-multitarget.json"], + "repository": "MEKA_META", + "include": [], "parameters": [ ], "components": [ { - "name": "meka.classifiers.multilabel.meta.MultiSearch", + "name": "meka.classifiers.multilabel.Maniac", "providedInterface": [ "MLClassifier", - "MetaMLClassifier" + "BasicMLClassifier" ], "requiredInterface": [ { @@ -16,54 +16,123 @@ "name": "BasicMLClassifier" } ], - "comment": "LEFT OUT: _search, _algorithm", "parameter": [ { - "name": "F", - "comment": "Determines the parameter used for evaluation: ACC = Accuracy JIDX = Jaccard index HSCORE = Hamming score EM = Exact match JDIST = Jaccard distance HLOSS = Hamming loss ZOLOSS = ZeroOne loss HARSCORE = Harmonic score OE = One error RLOSS = Rank loss AVGPREC = Avg precision LOGLOSSL = Log Loss (lim. L) LOGLOSSD = Log Loss (lim. D) F1MICRO = F1 (micro averaged) F1MACROEX = F1 (macro averaged by example) F1MACROLBL = F1 (macro averaged by label) AUPRC = AUPRC (macro averaged) AUROC = AUROC (macro averaged) LCARD = Label cardinality (predicted) LDIST = Levenshtein distance (default: ACC)", - "type": "cat", - "default": "ACC", - "values": [ - "ACC", - "JIDX", - "HSCORE", - "EM", - "JDIST", - "HLOSS", - "ZOLOSS", - "HARSCORE", - "OE", - "RLOSS", - "AVGPREC", - "LOGLOSSL", - "LOGLOSSD", - "F1MICRO", - "F1MACROEX", - "F1MACROLBL", - "AUPRC", - "AUROC", - "LCARD", - "LDIST" - ] + "name": "compression", + "comment": "Compression factor of the autoencoders, each level of autoencoders will compress the labels to factor times previous layer size. (default: 0.85)", + "type": "double", + "default": 0.85, + "min": 0.01, + "max": 0.99, + "minInterval": 0.05, + "refineSplits": 2 + }, + { + "name": "numberAutoencoders", + "comment": "Number of autoencoders, i.e. number of hidden layers +1. Note that this can be also used as the number of autoencoders to use in the optimization search, autoencoders will be added until this number is reached and then the best configuration in terms of number of layers is selects. (default: 4)", + "type": "int", + "default": 4, + "min": 1, + "max": 10, + "minInterval": 1, + "refineSplits": 2 + }, + { + "name": "optimizeAE", + "comment": "Number of autoencoders, i.e. number of hidden layers +1. Note that this can be also used as the number of autoencoders to use in the optimization search, autoencoders will be added until this number is reached and then the best configuration in terms of number of layers is selects. (default: 4)", + "type": "boolean", + "default": "false" } ] }, { - "name": "meka.classifiers.multilabel.PLST", - "providedInterface": ["MLClassifier", "MetaMLClassifier"], - "requiredInterface": ["BasicMTClassifier"], + "name": "meka.classifiers.multilabel.meta.DeepML", + "providedInterface": [ + "MLClassifier", + "MetaMLClassifier","ProblemTransformationMethod" + ], + "requiredInterface": [ + { + "id": "W", + "name": "BasicMLClassifier" + } + ], "parameter": [ { - "name": "_size", - "comment": "Size of the compressed matrix. Should be less than the number of labels and more than 1. (default: 3)", + "comment": "Sets the number of RBMs default: 2", + "name": "N", "type": "int", + "default": 2, "min": 2, - "max": 20, - "default": 3, - "minInterval": 1, - "refineSplits": 2 + "max": 5, + "refineSplits": 2, + "minInterval": 1 + }, + { + "comment": "Sets the number of hidden units default: 10", + "name": "H", + "type": "int", + "default": 10, + "min": 5, + "max": 100, + "refineSplits": 2, + "minInterval": 5 + }, + { + "comment": "Sets the maximum number of epochs default: 1000 (auto_cut_out)", + "name": "E", + "type": "int", + "default": 1000, + "min": 100, + "max": 10000, + "refineSplits": 2, + "minInterval": 100 + }, + { + "comment": "Sets the learning rate (tyically somewhere between 'very small' and 0.1) default: 0.1", + "name": "r", + "type": "double", + "default": 0.1, + "min": 1E-5, + "max": 0.1, + "refineSplits": 2, + "minInterval": 1E-5 + }, + { + "name": "m", + "comment": "Sets the momentum (typically somewhere between 0.1 and 0.9) default: 0.1", + "type": "double", + "default": 0.1, + "min": 0.1, + "max": 0.9, + "refineSplits": 2, + "minInterval": 0.05 + } + ] + }, + { + "name": "meka.classifiers.multilabel.meta.FilteredClassifier", + "providedInterface": [ + "MLClassifier", + "MetaMLClassifier" + ], + "requiredInterface": [ + { + "id": "W", + "name": "BasicMLClassifier" + } + ], + "parameter": [ + { + "name": "F", + "comment": "The number of iterations of EM to carry out (default: 10). REMARK: Here we could also use a subcomponent for filters!", + "type": "cat", + "default": "weka.filters.supervised.attribute.Discretize -R first_last -precision 6", + "values": [ + "weka.filters.supervised.attribute.Discretize -R first_last -precision 6" + ] } ] } ] -} \ No newline at end of file +} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel.json deleted file mode 100644 index d74e7bdaa1..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multilabel.json +++ /dev/null @@ -1,821 +0,0 @@ -{ - "repository": "MEKA", - "include": [ - ], - "parameters": [ - { - "name": "P", - "comment": "Sets the downsampling ratio default: 0.75 (of original)", - "type": "double", - "default": 0.75, - "min": 0.1, - "max": 0.99, - "refineSplits": 2, - "minInterval": 0.05 - }, - { - "name": "H", - "comment": "Determines the width of the trellis (use 0 for chain; use _1 for a square trellis, i.e., width of sqrt(number of labels)).", - "type": "cat", - "default": 0, - "values": [ - 0, - -1 - ] - }, - { - "name": "L", - "comment": "Determines the neighbourhood density (the number of neighbours for each node in the trellis). CAUTION: default obtained from source code. No idea about good other values", - "type": "int", - "default": 1, - "min": 1, - "max": 5, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "X", - "comment": "The dependency heuristic to use in rearranging the trellis (None by default).", - "type": "cat", - "default": "None", - "values": [ - "None" - ] - }, - { - "name": "I", - "comment": "The total number of iterations. default: 1000", - "type": "cat", - "default": 1000, - "values": [ - 100, - 1000, - 10000, - 20000 - ] - }, - { - "name": "Ic", - "comment": "The number of collection iterations. default: 100", - "type": "cat", - "default": 100, - "values": [ - 50, - 100, - 200, - 500, - 1000 - ] - } - ], - "components": [ - { - "name": "meka.classifiers.multilabel.BCC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "name": "X", - "comment": "The way to measure dependencies. default: lbf (frequencies only)", - "type": "cat", - "default": "lbf", - "values": [ - "lbf", - "C", - "I", - "Ib", - "H", - "Hbf", - "X", - "F", - "L" - ] - } - ] - }, - { - "name": "meka.classifiers.multilabel.BPNN", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "name": "H", - "comment": "Sets the number of hidden units default: 10", - "type": "int", - "default": "10", - "min": "1", - "max": "100", - "refineSplits": 4, - "minInterval": 2 - }, - { - "name": "E", - "comment": "Sets the maximum number of epochs default: 1000 (auto_cut_out)", - "type": "int", - "default": 1000, - "min": 100, - "max": 10000, - "refineSplits": 2, - "minInterval": 100 - }, - { - "name": "r", - "comment": "Sets the learning rate (tyically somewhere between 'very small' and 0.1) default: 0.1", - "type": "double", - "default": 0.1, - "min": 1E-5, - "max": 0.1, - "refineSplits": 2, - "minInterval": 1E-5 - }, - { - "name": "m", - "comment": "Sets the momentum (typically somewhere between 0.1 and 0.9) default: 0.1", - "type": "double", - "default": 0.1, - "min": 0.1, - "max": 0.9, - "refineSplits": 2, - "minInterval": 0.05 - } - ] - }, - { - "name": "meka.classifiers.multilabel.BR", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.BRq", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "name": "P", - "type": "double", - "min": 0.2, - "max": 0.8, - "default": 0.8, - "minInterval": 0.01, - "refineSplits": 8 - } - ] - }, - { - "name": "meka.classifiers.multilabel.CC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.CCq", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "name": "P", - "type": "double", - "min": 0.2, - "max": 0.8, - "default": 0.8, - "minInterval": 0.01, - "refineSplits": 8 - } - ] - }, - { - "name": "meka.classifiers.multilabel.CDN", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "comment": "The total number of iterations. default: 1000 ", - "name": "I", - "type": "cat", - "default": 1000, - "values": [ - 100, - 1000, - 10000, - 20000 - ] - }, - { - "comment": "The number of collection iterations. default: 100 ", - "name": "Ic", - "type": "cat", - "default": 100, - "values": [ - 50, - 100, - 200, - 500, - 1000 - ] - } - ] - }, - { - "name": "meka.classifiers.multilabel.CDT", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "comment": "Determines the width of the trellis (use 0 for chain; use _1 for a square trellis, i.e., width of sqrt(number of labels)). ", - "name": "H", - "type": "cat", - "default": 0, - "values": [ - 0, - -1 - ] - }, - { - "comment": "Determines the neighbourhood density (the number of neighbours for each node in the trellis). CAUTION: default obtained from source code. No idea about good other values ", - "name": "L", - "type": "int", - "default": 1, - "min": 1, - "max": 5, - "minInterval": 1, - "refineSplits": 2 - }, - { - "comment": "The dependency heuristic to use in rearranging the trellis (None by default). ", - "name": "X", - "type": "cat", - "default": "None", - "values": [ - "None" - ] - }, - { - "comment": "The total number of iterations. default: 1000 ", - "name": "I", - "type": "cat", - "default": 1000, - "values": [ - 100, - 1000, - 10000, - 20000 - ] - }, - { - "comment": "The number of collection iterations. default: 100 ", - "name": "Ic", - "type": "cat", - "default": 100, - "values": [ - 50, - 100, - 200, - 500, - 1000 - ] - } - ] - }, - { - "name": "meka.classifiers.multilabel.CT", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "name": "H", - "comment": "Determines the width of the trellis (use 0 for chain; use _1 for a square trellis, i.e., width of sqrt(number of labels)).", - "type": "cat", - "default": 0, - "values": [ - 0, - -1 - ] - }, - { - "comment": "Determines the neighbourhood density (the number of neighbours for each node in the trellis). CAUTION: default obtained from source code. No idea about good other values ", - "name": "L", - "type": "int", - "default": 1, - "min": 1, - "max": 5, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "X", - "comment": "The way to measure dependencies. default: lbf (frequencies only)", - "type": "cat", - "default": "lbf", - "values": [ - "lbf", - "C", - "I", - "Ib", - "H", - "Hbf", - "X", - "F", - "L" - ] - }, - { - "comment": "The total number of iterations. default: 1000 ", - "name": "I", - "type": "cat", - "default": 1000, - "values": [ - 100, - 1000, - 10000, - 20000 - ] - }, - { - "comment": "The number of collection iterations. default: 100 ", - "name": "Ic", - "type": "cat", - "default": 100, - "values": [ - 50, - 100, - 200, - 500, - 1000 - ] - }, - { - "name": "P", - "comment": "Sets the payoff function. Any of those listed in regular evaluation output will do (e.g., 'Exact match'). default: Exact match", - "type": "cat", - "default": "Exact match", - "values": [ - "Exact match" - ] - } - ] - }, - { - "name": "meka.classifiers.multilabel.FW", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.HASEL", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "comment": "LEFT OUT: _k The number of labels in each partition __ should be 1 <= k < (L/2) where L is the total number of labels. LEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", - "parameter": [ - { - "name": "P", - "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", - "type": "int", - "default": 0, - "min": 0, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - } - ] - }, - { - "name": "meka.classifiers.multilabel.LC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.MajorityLabelset", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - ], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.MCC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "name": "Is", - "comment": "The number of iterations to search the chain space at train time. default: 0", - "type": "int", - "default": 0, - "min": 0, - "max": 1500, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "Iy", - "comment": "The number of iterations to search the output space at test time. default: 10", - "type": "int", - "default": 10, - "min": 0, - "max": 100, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "P", - "comment": "Sets the payoff function. Any of those listed in regular evaluation output will do (e.g., 'Exact match'). default: Exact match", - "type": "cat", - "default": "Exact match", - "values": [ - "Accuracy", - "Jaccard index", - "Hamming score", - "Exact match", - "Jaccard distance", - "Hamming loss", - "ZeroOne loss", - "Harmonic score", - "One error", - "Rank loss", - "Avg precision", - "Log Loss (lim. L)", - "Log Loss (lim. D)", - "Micro Precision", - "Micro Recall", - "Macro Precision", - "Macro Recall", - "F1 (micro averaged)", - "F1 (macro averaged by example)", - "F1 (macro averaged by label)", - "AUPRC (macro averaged)", - "AUROC (macro averaged)", - "Levenshtein distance" - ] - } - ] - }, - { - "name": "meka.classifiers.multilabel.PCC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.PMCC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "name": "M", - "comment": "The population size (of chains) __ should be smaller than the total number of chains evaluated (Is) default: 10", - "type": "int", - "default": 10, - "min": 1, - "max": 50, - "minInterval": 1, - "refineSplits": 8 - }, - { - "name": "O", - "comment": "Use temperature: cool the chain down over time (from the beginning of the chain) __ can be faster default: 0 (no temperature)", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "B", - "comment": "If using O = 1 for temperature, this sets the Beta constant default: 0.03", - "type": "double", - "default": 0.03, - "min": 0.01, - "max": 0.99, - "minInterval": 1E-3, - "refineSplits": 8 - }, - { - "name": "Is", - "comment": "The number of iterations to search the chain space at train time. default: 0", - "type": "int", - "default": 50, - "min": 50, - "max": 1500, - "minInterval": 5, - "refineSplits": 8 - }, - { - "name": "Iy", - "comment": "The number of iterations to search the output space at test time. default: 10", - "type": "int", - "default": 10, - "min": 1, - "max": 100, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "P", - "comment": "Sets the payoff function. Any of those listed in regular evaluation output will do (e.g., 'Exact match'). default: Exact match", - "type": "cat", - "default": "Exact match", - "values": [ - "Accuracy", - "Jaccard index", - "Hamming score", - "Exact match", - "Jaccard distance", - "Hamming loss", - "ZeroOne loss", - "Harmonic score", - "One error", - "Rank loss", - "Avg precision", - "Log Loss (lim. L)", - "Log Loss (lim. D)", - "Micro Precision", - "Micro Recall", - "Macro Precision", - "Macro Recall", - "F1 (micro averaged)", - "F1 (macro averaged by example)", - "F1 (macro averaged by label)", - "AUPRC (macro averaged)", - "AUROC (macro averaged)", - "Levenshtein distance" - ] - } - ], - "dependencies": [ - { - "pre": "O in {1}", - "post": "B in [0.03,0.03]" - } - ] - }, - { - "name": "meka.classifiers.multilabel.PS", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "comment": "LEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m).", - "parameter": [ - { - "name": "P", - "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", - "type": "int", - "default": 0, - "min": 0, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - } - ] - }, - { - "name": "meka.classifiers.multilabel.PSt", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "name": "P", - "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - }, - { - "name": "N", - "comment": "Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - } - ] - }, - { - "name": "meka.classifiers.multilabel.RAkEL", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "comment": "LEFT OUT: _k The number of labels in each partition __ should be 1 <= k < (L/2) where L is the total number of labels\nLEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m).", - "parameter": [ - { - "name": "M", - "comment": "Sets M (default 10): the number of subsets", - "type": "int", - "min": 2, - "max": 20, - "default": 10, - "refineSplits": 2, - "minInterval": 1 - }, - { - "name": "P", - "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", - "type": "int", - "default": 0, - "min": 0, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - } - ] - }, - { - "name": "meka.classifiers.multilabel.RAkELd", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "comment": "LEFT OUT: _k The number of labels in each partition __ should be 1 <= k < (L/2) where L is the total number of labels.\nLEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m).", - "parameter": [ - { - "name": "P", - "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", - "type": "int", - "default": 0, - "min": 0, - "max": 0, - "minInterval": 0.05, - "refineSplits": 1 - } - ] - }, - { - "name": "meka.classifiers.multilabel.RT", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - ] - } - ] -} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multitarget-meta.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multitarget-meta.json deleted file mode 100644 index f60e5f8bb4..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multitarget-meta.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "repository": "MEKA-MultiTarget-META", - "include": [], - "parameters": [], - "components": [ - { - "name": "meka.classifiers.multitarget.meta.BaggingMT", - "providedInterface": ["MTClassifier", "MetaMTClassifier"], - "requiredInterface": ["BasicMTClassifier"], - "parameter": [ - { - "name": "_I", - "type": "int", - "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, - "minInterval": 1 - }, - { - "name": "_P", - "type": "int", - "default": 67, - "min": 40, - "max": 90, - "refineSplits": 2, - "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multitarget.meta.EnsembleMT", - "providedInterface": ["MTClassifier", "MetaMTClassifier"], - "requiredInterface": ["BasicMTClassifier"], - "parameter": [ ] - }, - { - "name": "meka.classifiers.multitarget.meta.FilteredClassifier", - "providedInterface": ["MTClassifier", "MetaMTClassifier"], - "requiredInterface": ["BasicMTClassifier"], - "parameter": [ ] - }, - { - "name": "meka.classifiers.multitarget.meta.MultiSearch", - "providedInterface": ["MTClassifier", "MetaMTClassifier"], - "requiredInterface": ["BasicMTClassifier"], - "parameter": [ ] - } - ] -} \ No newline at end of file diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multitarget.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multitarget.json deleted file mode 100644 index 27043fbcf8..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/meka-multitarget.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "repository": "MEKA-MultiTarget", - "include": [ "../mlplan" ], - "parameters": [ - ], - "components": [ - { - "name": "meka.classifiers.multitarget.BCC", - "providedInterface": ["MTClassifier", "BasicMTClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multitarget.CC", - "providedInterface": ["MTClassifier", "BasicMTClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multitarget.CCp", - "providedInterface": ["MTClassifier", "BasicMTClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multitarget.CR", - "providedInterface": ["MTClassifier", "BasicMTClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multitarget.NSR", - "providedInterface": ["MTClassifier", "BasicMTClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multitarget.RAkELd", - "providedInterface": ["MTClassifier", "BasicMTClassifier"], - "requiredInterface": ["Classifier"], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multitarget.SCC", - "providedInterface": ["MTClassifier", "WrappingMTClassifier"], - "requiredInterface": ["BasicMTClassifier"], - "parameter": [ - ] - } - ] -} \ No newline at end of file diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/mlplan-meka.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/mlplan-meka.json similarity index 100% rename from softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/mlplan-meka.json rename to softwareconfiguration/mlplan/resources/automl/searchmodels/meka/mlplan-meka.json diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/mlplan-multilabel-small.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/mlplan-multilabel-small.json deleted file mode 100644 index 6c5bba9745..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/mlplan-multilabel-small.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "repository": "MLPlan-Multilabel", - "include": ["./small/meka-multilabel-small.json","./small/meka-multilabel-meta-small.json", "../weka/weka-classifiers-autoweka.json"], - "parameters": [ ], - "components": [ ] -} \ No newline at end of file diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/mlplan-multilabel.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/mlplan-multilabel.json deleted file mode 100644 index 38da870ab6..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/mlplan-multilabel.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "repository": "MLPlan-Multilabel", - "include": [ - "./meka-multilabel-meta.json", - "./meka-multilabel-base.json", - "./weka-classifiers-base.json", - "./weka-classifiers-meta.json" - ], - "parameters": [ - ], - "components": [ - ] -} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/mlplan-multitarget.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/mlplan-multitarget.json deleted file mode 100644 index 11c51fff45..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/mlplan-multitarget.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "repository": "MLPlan-MultiTarget", - "include": ["./meka-multitarget.json","./meka-multitarget-meta.json"], - "parameters": [ ], - "components": [ ] -} \ No newline at end of file diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/small/meka-multilabel-meta-small.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/small/meka-multilabel-meta-small.json deleted file mode 100644 index 73a0820cd6..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/small/meka-multilabel-meta-small.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "repository": "MEKA_META", - "include": [], - "parameters": [ - ], - "components": [ - { - "name": "meka.classifiers.multilabel.meta.BaggingML", - "providedInterface": ["MLClassifier", "MetaMLClassifier"], - "requiredInterface": [ { "id": "W", "name": "BasicMLClassifier" } ], - "parameter": [ - { - "name": "I", - "comment": "Sets the number of models (default 10)", - "type": "int", - "default": 10, - "min": 2, - "max": 20, - "refineSplits": 2, - "minInterval": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/small/meka-multilabel-small.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/small/meka-multilabel-small.json deleted file mode 100644 index cbf6ad06dc..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/small/meka-multilabel-small.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "repository": "MEKA", - "parameters": [ - { - "name": "P", - "comment": "Sets the downsampling ratio default: 0.75 (of original)", - "type": "double", - "default": 0.75, - "min": 0.1, - "max": 0.99, - "refineSplits": 2, - "minInterval": 0.05 - }, - { - "name": "H", - "comment": "Determines the width of the trellis (use 0 for chain; use _1 for a square trellis, i.e., width of sqrt(number of labels)).", - "type": "cat", - "default": 0, - "values": [ - 0, - -1 - ] - }, - { - "name": "L", - "comment": "Determines the neighbourhood density (the number of neighbours for each node in the trellis). CAUTION: no default found", - "type": "double", - "default": 0.5, - "min": 0.1, - "max": 1.0, - "minInterval": 0.05, - "refineSplits": 2 - }, - { - "name": "X", - "comment": "The dependency heuristic to use in rearranging the trellis (None by default).", - "type": "cat", - "default": "None", - "values": [ - "None" - ] - }, - { - "name": "I", - "comment": "The total number of iterations. default: 1000", - "type": "cat", - "default": 1000, - "values": [ - 100, - 1000, - 10000, - 20000 - ] - }, - { - "name": "Ic", - "comment": "The number of collection iterations. default: 100", - "type": "cat", - "default": 100, - "values": [ - 50, - 100, - 200, - 500, - 1000 - ] - } - ], - "components": [ - { - "name": "meka.classifiers.multilabel.BCC", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - { - "name": "X", - "comment": "The way to measure dependencies. default: lbf (frequencies only)", - "type": "cat", - "default": "lbf", - "values": [ - "lbf" - ] - } - ] - }, - { - "name": "meka.classifiers.multilabel.BR", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "AbstractClassifier" - } - ], - "parameter": [ - ] - } - ] -} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/weka-all.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-all.json similarity index 100% rename from softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/weka-all.json rename to softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-all.json diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-classifiers-base.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-classifiers-base.json deleted file mode 100644 index 7a79f3fd06..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-classifiers-base.json +++ /dev/null @@ -1,957 +0,0 @@ -{ - "repository": "Auto-WEKA", - "components": [ - { - "name": "weka.classifiers.bayes.BayesNet", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "D", - "type": "boolean", - "default": "true" - }, - { - "name": "Q", - "type": "cat", - "default": "weka.classifiers.bayes.net.search.local.K2", - "values": [ - "weka.classifiers.bayes.net.search.local.K2", - "weka.classifiers.bayes.net.search.local.HillClimber", - "weka.classifiers.bayes.net.search.local.LAGDHillClimber", - "weka.classifiers.bayes.net.search.local.SimulatedAnnealing", - "weka.classifiers.bayes.net.search.local.TabuSearch", - "weka.classifiers.bayes.net.search.local.TAN" - ] - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.bayes.NaiveBayes", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "K", - "type": "boolean", - "default": "false" - }, - { - "name": "D", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "D in {true}", - "post": "K in {false}" - } - ] - }, - { - "name": "weka.classifiers.bayes.NaiveBayesMultinomial", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.functions.Logistic", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "R", - "type": "double", - "default": 1.0E-7, - "min": 1.0E-12, - "max": 10.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.functions.MultilayerPerceptron", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier", - "RandomizableBaseClassifier" - ], - "parameter": [ - { - "name": "L", - "type": "double", - "default": 0.3, - "min": 0.1, - "max": 1.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "M", - "type": "double", - "default": 0.2, - "min": 0.1, - "max": 1.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "B", - "type": "boolean", - "default": "true" - }, - { - "name": "H", - "type": "cat", - "default": "a", - "values": [ - "a", - "i", - "o", - "t" - ] - }, - { - "name": "C", - "type": "boolean", - "default": "true" - }, - { - "name": "R", - "type": "boolean", - "default": "true" - }, - { - "name": "D", - "type": "boolean", - "default": "false" - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.functions.SimpleLogistic", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "S", - "type": "boolean", - "default": "true" - }, - { - "name": "WActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "W", - "type": "double", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "A", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "WActivator in {0}", - "post": "W in {0}" - }, - { - "pre": "WActivator in {1}", - "post": "W in [0.0,1.0]" - } - ] - }, - { - "name": "weka.classifiers.functions.supportVector.NormalizedPolyKernel", - "requiredInterface": [ - ], - "providedInterface": [ - "K" - ], - "parameter": [ - ] - }, - { - "name": "weka.classifiers.functions.supportVector.PolyKernel", - "requiredInterface": [ - ], - "providedInterface": [ - "K" - ], - "parameter": [ - ] - }, - { - "name": "weka.classifiers.functions.supportVector.RBFKernel", - "requiredInterface": [ - ], - "providedInterface": [ - "K" - ], - "parameter": [ - ] - }, - { - "name": "weka.classifiers.functions.SMO", - "requiredInterface": [ - { - "id": "K", - "name": "K" - } - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "C", - "type": "double", - "default": 1.0, - "min": 0.5, - "max": 1.5, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "N", - "type": "cat", - "default": "0", - "values": [ - "0", - "1", - "2" - ] - }, - { - "name": "M", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.functions.supportVector.Puk", - "requiredInterface": [ - ], - "providedInterface": [ - "K" - ], - "parameter": [ - ] - }, - { - "name": "weka.classifiers.functions.VotedPerceptron", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "I", - "type": "int", - "default": 1.0, - "min": 1.0, - "max": 10.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "M", - "type": "int", - "default": 10000.0, - "min": 5000.0, - "max": 50000.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "E", - "type": "double", - "default": 1.0, - "min": 0.2, - "max": 5.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.lazy.IBk", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "E", - "type": "boolean", - "default": "true" - }, - { - "name": "K", - "type": "int", - "default": 1.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "X", - "type": "boolean", - "default": "true" - }, - { - "name": "I", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.lazy.KStar", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "B", - "type": "int", - "default": 20.0, - "min": 1.0, - "max": 100.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "E", - "type": "boolean", - "default": "true" - }, - { - "name": "M", - "type": "cat", - "default": "a", - "values": [ - "a", - "d", - "m", - "n" - ] - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.rules.JRip", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "N", - "type": "double", - "default": 2.0, - "min": 1.0, - "max": 5.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "E", - "type": "boolean", - "default": "true" - }, - { - "name": "P", - "type": "boolean", - "default": "true" - }, - { - "name": "O", - "type": "int", - "default": 2.0, - "min": 1.0, - "max": 5.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.rules.OneR", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "B", - "type": "int", - "default": 6.0, - "min": 1.0, - "max": 32.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.rules.PART", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "N", - "type": "int", - "default": 3.0, - "min": 2.0, - "max": 5.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "M", - "type": "int", - "default": 2.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "R", - "type": "boolean", - "default": "true" - }, - { - "name": "B", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "R in {false}", - "post": "N in [3.0,3.0]" - } - ] - }, - { - "name": "weka.classifiers.rules.ZeroR", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.trees.DecisionStump", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier", - "BaseRegressor" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.trees.J48", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "O", - "type": "boolean", - "default": "true" - }, - { - "name": "U", - "type": "boolean", - "default": "true" - }, - { - "name": "B", - "type": "boolean", - "default": "true" - }, - { - "name": "J", - "type": "boolean", - "default": "true" - }, - { - "name": "A", - "type": "boolean", - "default": "true" - }, - { - "name": "M", - "type": "int", - "default": 2.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.trees.LMT", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "B", - "type": "boolean", - "default": "true" - }, - { - "name": "R", - "type": "boolean", - "default": "true" - }, - { - "name": "C", - "type": "boolean", - "default": "true" - }, - { - "name": "P", - "type": "boolean", - "default": "true" - }, - { - "name": "M", - "type": "int", - "default": 15.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "WActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "W", - "type": "double", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "A", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "WActivator in {0}", - "post": "W in {0}" - }, - { - "pre": "WActivator in {1}", - "post": "W in [0.0,1.0]" - } - ] - }, - { - "name": "weka.classifiers.trees.RandomForest", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier", - "RandomizableBaseClassifier", - "BaseRegressor" - ], - "parameter": [ - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 256.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "featuresActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "K", - "type": "int", - "default": "0", - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "depthActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "depth", - "type": "int", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - { - "pre": "featuresActivator in {0}", - "post": "K in {0}" - }, - { - "pre": "featuresActivator in {1}", - "post": "K in [1.0,32.0]" - }, - { - "pre": "depthActivator in {0}", - "post": "depth in {0}" - }, - { - "pre": "depthActivator in {1}", - "post": "depth in [1.0,20.0]" - } - ] - }, - { - "name": "weka.classifiers.trees.RandomTree", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier", - "RandomizableBaseClassifier", - "BaseRegressor" - ], - "parameter": [ - { - "name": "M", - "type": "int", - "default": 1.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "featuresActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "K", - "type": "int", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "depthActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "depth", - "type": "int", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "backActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "N", - "type": "int", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "U", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "featuresActivator in {0}", - "post": "K in {0}" - }, - { - "pre": "featuresActivator in {1}", - "post": "K in [2.0,32.0]" - }, - { - "pre": "depthActivator in {0}", - "post": "depth in {0}" - }, - { - "pre": "depthActivator in {1}", - "post": "depth in [2.0,20.0]" - }, - { - "pre": "backActivator in {0}", - "post": "N in {0}" - }, - { - "pre": "backActivator in {1}", - "post": "N in [2.0,5.0]" - } - ] - }, - { - "name": "weka.classifiers.trees.REPTree", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier", - "RandomizableBaseClassifier", - "BaseRegressor" - ], - "parameter": [ - { - "name": "M", - "type": "int", - "default": 2.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "V", - "type": "double", - "default": 0.001, - "min": 1.0E-5, - "max": 0.1, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "depthActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "L", - "type": "int", - "default": "-1", - "values": [ - "-1" - ], - "min": -1.0, - "max": -1.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "P", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "depthActivator in {0}", - "post": "L in {-1}" - }, - { - "pre": "depthActivator in {1}", - "post": "L in [2.0,20.0]" - } - ] - } - ] -} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-classifiers-meta.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-classifiers-meta.json deleted file mode 100644 index 88ef0ee88c..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-classifiers-meta.json +++ /dev/null @@ -1,391 +0,0 @@ -{ - "repository": "WEKA Meta Classifiers", - "components": [ - { - "name": "weka.classifiers.meta.AdaBoostM1", - "requiredInterface": [ - { - "id": "W", - "name": "BaseClassifier" - } - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier" - ], - "parameter": [ - { - "name": "pActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "P", - "type": "int", - "default": "100", - "values": [ - "100" - ], - "min": 100.0, - "max": 100.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 128.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "Q", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "pActivator in {0}", - "post": "P in {100}" - }, - { - "pre": "pActivator in {1}", - "post": "P in [50.0,100.0]" - } - ] - }, - { - "name": "weka.classifiers.meta.Bagging", - "requiredInterface": [ - { - "id": "W", - "name": "BaseClassifier" - } - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier" - ], - "parameter": [ - { - "name": "P", - "type": "int", - "default": 100.0, - "min": 10.0, - "max": 100.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 128.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - }, - { - "name": "O", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "O in {true}", - "post": "P in {100}" - } - ] - }, - { - "name": "weka.classifiers.meta.ClassificationViaRegression", - "requiredInterface": [ - { - "id": "W", - "name": "AbstractRegressor" - } - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.meta.LogitBoost", - "requiredInterface": [ - { - "id": "W", - "name": "BaseRegressor" - } - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier" - ], - "parameter": [ - { - "comment": "Use resampling instead of reweighting for boosting.", - "name": "Q", - "type": "cat", - "default": "false", - "values": [ - "true", - "false" - ] - }, - { - "comment": "Sets the multiplier when using random codes. (default 2.0).", - "name": "I", - "type": "int", - "default": "10", - "min": 2, - "max": 100, - "minInterval": 1, - "refineSplits": 8 - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.meta.MultiClassClassifier", - "requiredInterface": [ - { - "id": "W", - "name": "BaseClassifier" - } - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier" - ], - "parameter": [ - { - "comment": "Sets the method to use. Valid values are 0 (1-against-all), 1 (random codes), 2 (exhaustive code), and 3 (1-against-1). (default 0)", - "name": "M", - "type": "cat", - "default": "0", - "values": [ - "0", - "1", - "2", - "3" - ] - }, - { - "comment": "Use log loss decoding for random and exhaustive codes.", - "name": "L", - "type": "cat", - "default": "false", - "values": [ - "true", - "false" - ] - }, - { - "comment": "Sets the multiplier when using random codes. (default 2.0).", - "name": "R", - "type": "double", - "default": "2.0", - "min": 1.0, - "max": 10.0, - "minInterval": 0.1, - "refineSplits": 8 - }, - { - "comment": "Use pairwise coupling (only has an effect for 1-against1)", - "name": "P", - "type": "cat", - "default": "false", - "values": [ - "true", - "false" - ] - } - ], - "dependencies": [ - { - "pre": "M in {0,3}", - "post": "L in {false}" - }, - { - "pre": "M in {0,1,2}", - "post": "P in {false}" - }, - { - "pre": "M in {0,2,3}", - "post": "R in [2.0,2.0]" - } - ] - }, - { - "name": "weka.classifiers.meta.RandomCommittee", - "requiredInterface": [ - { - "id": "W", - "name": "RandomizableBaseClassifier" - } - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier" - ], - "parameter": [ - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.meta.RandomSubSpace", - "requiredInterface": [ - { - "id": "W", - "name": "BaseClassifier" - } - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier" - ], - "parameter": [ - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "P", - "type": "double", - "default": 0.5, - "min": 0.1, - "max": 1.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.meta.Stacking", - "requiredInterface": [ - { - "id": "B", - "name": "BaseClassifier" - } - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier" - ], - "parameter": [ - { - "name": "X", - "type": "cat", - "default": "10", - "values": [ - "5", - "10" - ] - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.meta.Vote", - "requiredInterface": [ - { - "id": "B", - "name": "BaseClassifier" - } - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier" - ], - "parameter": [ - { - "name": "R", - "type": "cat", - "default": "AVG", - "values": [ - "AVG", - "PROD", - "MAJ", - "MIN", - "MAX", - "MED" - ] - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - } - ], - "dependencies": [ - ] - } - ] -} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-regressors-base.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-regressors-base.json deleted file mode 100644 index 79eca4466e..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-regressors-base.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "repository": "Auto-WEKA", - "components": [ - { - "name": "weka.classifiers.trees.M5P", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractRegressor", - "BaseRegressor", - "Regressor" - ], - "parameter": [ - { - "name": "N", - "type": "boolean", - "default": "true" - }, - { - "name": "M", - "type": "int", - "default": 4.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "U", - "type": "boolean", - "default": "true" - }, - { - "name": "R", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.functions.SimpleLinearRegression", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractRegressor", - "BaseRegressor", - "Regressor" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.rules.M5Rules", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractRegressor", - "BaseRegressor", - "Regressor" - ], - "parameter": [ - { - "name": "N", - "type": "boolean", - "default": "true" - }, - { - "name": "M", - "type": "int", - "default": 4.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "U", - "type": "boolean", - "default": "true" - }, - { - "name": "R", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - ] - } - ] -} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-regressors-meta.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-regressors-meta.json deleted file mode 100644 index 1f993f637f..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-regressors-meta.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "repository": "WEKA Regressors Meta", - "include": [ - ], - "parameters": [ - ], - "components": [ - { - "name": "weka.classifiers.meta.AdditiveRegression", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractRegressor", - "MetaRegressor", - "Regressor", - "BaseClassifier" - ], - "parameter": [ - { - "name": "sActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "S", - "type": "double", - "default": "1", - "values": [ - "1" - ], - "min": 1.0, - "max": 1.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 128.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - { - "pre": "sActivator in {0}", - "post": "S in {1}" - }, - { - "pre": "sActivator in {1}", - "post": "S in [0.0,1.0]" - } - ] - } - ] -} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/weka-singlelabel-base.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-singlelabel-base.json similarity index 100% rename from softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/weka-singlelabel-base.json rename to softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-singlelabel-base.json diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/weka-singlelabel-meta.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-singlelabel-meta.json similarity index 100% rename from softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/weka-singlelabel-meta.json rename to softwareconfiguration/mlplan/resources/automl/searchmodels/meka/weka-singlelabel-meta.json diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/meka-multilabel-base.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/meka-multilabel-base.json deleted file mode 100644 index 322f50fa5b..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/meka-multilabel-base.json +++ /dev/null @@ -1,586 +0,0 @@ -{ - "repository": "MEKA", - "include": [], - "parameters": [], - "components": [ - { - "name": "meka.classifiers.multilabel.BR", - "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [] - }, - { - "name": "meka.classifiers.multilabel.BRq", - "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - { - "name": "P", - "type": "double", - "min": 0.2, - "max": 0.8, - "default": 0.8, - "minInterval": 0.01, - "refineSplits": 8 - } - ] - }, - { - "name": "meka.classifiers.multilabel.CC", - "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [] - }, - { - "name": "meka.classifiers.multilabel.CCq", - "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - { - "name": "P", - "type": "double", - "min": 0.2, - "max": 0.8, - "default": 0.8, - "minInterval": 0.01, - "refineSplits": 8 - } - ] - }, - { - "name": "meka.classifiers.multilabel.BCC", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - { - "name": "X", - "comment": "The way to measure dependencies. default: lbf (frequencies only) | TODO: No label dependence still missing as an option", - "type": "cat", - "default": "lbf", - "values": ["lbf","C","I","Ib","H","Hbf","X","F","L","None"] - } - ] - }, - { - "name": "meka.classifiers.multilabel.PCC", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [] - }, - { - "name": "meka.classifiers.multilabel.MCC", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - { - "name": "Is", - "comment": "The number of iterations to search the chain space at train time. default: 0", - "type": "int", - "default": 0, - "min": 0, - "max": 1500, - "minInterval": 5, - "refineSplits": 8 - }, - { - "name": "Iy", - "comment": "The number of iterations to search the output space at test time. default: 10", - "type": "int", - "default": 10, - "min": 0, - "max": 100, - "minInterval": 1, - "refineSplits": 8 - }, - { - "name": "P", - "comment": "Sets the payoff function. Any of those listed in regular evaluation output will do (e.g., 'Exact match'). default: Exact match", - "type": "cat", - "default": "Exact match", - "values": ["Accuracy","Jaccard index","Hamming score","Exact match","Jaccard distance","Hamming loss","ZeroOne loss","Harmonic score","One error","Rank loss","Avg precision","Log Loss (lim. L)","Log Loss (lim. D)","Micro Precision","Micro Recall","Macro Precision","Macro Recall","F1 (micro averaged)","F1 (macro averaged by example)","F1 (macro averaged by label)","AUPRC (macro averaged)","AUROC (macro averaged)","Levenshtein distance"] - } - ] - }, - { - "name": "meka.classifiers.multilabel.PMCC", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - { - "name": "M", - "comment": "The population size (of chains) __ should be smaller than the total number of chains evaluated (Is) default: 10", - "type": "int", - "default": 10, - "min": 1, - "max": 50, - "minInterval": 1, - "refineSplits": 8 - }, - { - "name": "O", - "comment": "Use temperature: cool the chain down over time (from the beginning of the chain) __ can be faster default: 0 (no temperature)", - "type": "cat", - "default": "0", - "values": ["0","1"] - }, - { - "name": "B", - "comment": "If using O = 1 for temperature, this sets the Beta constant default: 0.03", - "type": "double", - "default": 0.03, - "min": 0.01, - "max": 0.99, - "minInterval": 1E-3, - "refineSplits": 8 - }, - { - "name": "Is", - "comment": "The number of iterations to search the chain space at train time. default: 0", - "type": "int", - "default": 0, - "min": 0, - "max": 1500, - "minInterval": 5, - "refineSplits": 8 - }, - { - "name": "Iy", - "comment": "The number of iterations to search the output space at test time. default: 10", - "type": "int", - "default": 10, - "min": 0, - "max": 100, - "minInterval": 1, - "refineSplits": 8 - }, - { - "name": "P", - "comment": "Sets the payoff function. Any of those listed in regular evaluation output will do (e.g., 'Exact match'). default: Exact match", - "type": "cat", - "default": "Exact match", - "values": ["Accuracy","Jaccard index","Hamming score","Exact match","Jaccard distance","Hamming loss","ZeroOne loss","Harmonic score","One error","Rank loss","Avg precision","Log Loss (lim. L)","Log Loss (lim. D)","Micro Precision","Micro Recall","Macro Precision","Macro Recall","F1 (micro averaged)","F1 (macro averaged by example)","F1 (macro averaged by label)","AUPRC (macro averaged)","AUROC (macro averaged)","Levenshtein distance"] - } - ], - "dependencies": [{"pre": "O in {1}","post": "B in [0.03,0.03]"}] - }, - { - "name": "meka.classifiers.multilabel.CT", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - { - "name": "H", - "comment": "Determines the width of the trellis (use 0 for chain; use _1 for a square trellis, i.e., width of sqrt(number of labels)).", - "type": "cat", - "default": "0", - "values": ["0","-1"] - }, - { - "name": "X", - "comment": "The way to measure dependencies. default: lbf (frequencies only) | TODO: No label dependence still missing as an option", - "type": "cat", - "default": "lbf", - "values": ["lbf","C","I","Ib","H","Hbf","X","F","L","None"] - }, - { - "comment": "Determines the neighbourhood density (the number of neighbours for each node in the trellis). CAUTION: default obtained from source code. No idea about good other values ", - "name": "L", - "type": "int", - "default": 1, - "min": 1, - "max": 4, - "minInterval": 1, - "refineSplits": 4 - }, - { - "name": "Is", - "comment": "The number of iterations to search the chain space at train time. default: 0", - "type": "int", - "default": 0, - "min": 0, - "max": 1500, - "minInterval": 5, - "refineSplits": 8 - }, - { - "name": "Iy", - "comment": "The number of iterations to search the output space at test time. default: 10", - "type": "int", - "default": 10, - "min": 0, - "max": 100, - "minInterval": 1, - "refineSplits": 8 - }, - { - "name": "P", - "comment": "Sets the payoff function. Any of those listed in regular evaluation output will do (e.g., 'Exact match'). default: Exact match", - "type": "cat", - "default": "Exact match", - "values": ["Accuracy","Jaccard index","Hamming score","Exact match","Jaccard distance","Hamming loss","ZeroOne loss","Harmonic score","One error","Rank loss","Avg precision","Log Loss (lim. L)","Log Loss (lim. D)","Micro Precision","Micro Recall","Macro Precision","Macro Recall","F1 (micro averaged)","F1 (macro averaged by example)","F1 (macro averaged by label)","AUPRC (macro averaged)","AUROC (macro averaged)","Levenshtein distance"] - } - ] - }, - { - "name": "meka.classifiers.multilabel.CDN", - "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - { - "name": "I", - "comment": "The total number of iterations. default: 1000 ", - "type": "int", - "default": 1000, - "min": 100, - "max": 1000, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "Ic", - "comment": "The number of collection iterations. default: 100 ", - "type": "int", - "default": 100, - "min": 1, - "max": 100, - "refineSplits": 8, - "minInterval": 1 - } - ] - }, - - { - "name": "meka.classifiers.multilabel.CDT", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - { - "name": "H", - "comment": "Determines the width of the trellis (use 0 for chain; use _1 for a square trellis, i.e., width of sqrt(number of labels)). ", - "type": "cat", - "default": "0", - "values": ["0","-1"] - }, - { - "name": "L", - "comment": "Determines the neighbourhood density (the number of neighbours for each node in the trellis). CAUTION: default obtained from source code. No idea about good other values ", - "type": "int", - "default": 1, - "min": 1, - "max": 5, - "minInterval": 1, - "refineSplits": 5 - }, - { - "comment": "The dependency heuristic to use in rearranging the trellis (None by default). ", - "name": "X", - "type": "cat", - "default": "None", - "values": ["lbf","C","I","Ib","H","Hbf","X","F","L","None"] - }, - { - "name": "I", - "comment": "The total number of iterations. default: 1000 ", - "type": "int", - "default": 1000, - "min": 100, - "max": 1000, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "Ic", - "comment": "The number of collection iterations. default: 100 ", - "type": "int", - "default": 100, - "min": 1, - "max": 100, - "refineSplits": 8, - "minInterval": 1 - } - ] - }, - { - "name": "meka.classifiers.multilabel.FW", - "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.RT", - "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.LC", - "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - ] - }, - { - "name": "meka.classifiers.multilabel.PS", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - { - "name": "P", - "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - }, - { - "name": "N", - "comment": "Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m).", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - } - ] - }, - { - "name": "meka.classifiers.multilabel.PSt", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "parameter": [ - { - "name": "P", - "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - }, - { - "name": "N", - "comment": "Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - } - ] - }, - { - "name": "meka.classifiers.multilabel.RAkEL", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "comment": "LEFT OUT: _k The number of labels in each partition __ should be 1 <= k < (L/2) where L is the total number of labels\nLEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m).", - "parameter": [ - { - "name": "M", - "comment": "Sets M (default 10): the number of subsets", - "type": "int", - "min": 2, - "max": 20, - "default": 10, - "refineSplits": 2, - "minInterval": 1 - }, - { - "name": "P", - "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - }, - { - "name": "N", - "comment": "Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - } - ] - }, - { - "name": "meka.classifiers.multilabel.RAkELd", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "comment": "LEFT OUT: _k The number of labels in each partition __ should be 1 <= k < (L/2) where L is the total number of labels.\nLEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m).", - "parameter": [ - { - "name": "P", - "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - }, - { - "name": "N", - "comment": "Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - } - ] - }, - { - "name": "meka.classifiers.multilabel.BPNN", - "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [], - "parameter": [ - { - "name": "H", - "comment": "Sets the number of hidden units default: 10", - "type": "int", - "default": "10", - "min": "1", - "max": "100", - "refineSplits": 8, - "minInterval": 5 - }, - { - "name": "E", - "comment": "Sets the maximum number of epochs default: 1000 (auto_cut_out)", - "type": "int", - "default": 1000, - "min": 10, - "max": 10000, - "refineSplits": 8, - "minInterval": 100 - }, - { - "name": "r", - "comment": "Sets the learning rate (tyically somewhere between 'very small' and 0.1) default: 0.1", - "type": "double", - "default": 0.1, - "min": 1E-3, - "max": 0.1, - "refineSplits": 8, - "minInterval": 1E-4 - }, - { - "name": "m", - "comment": "Sets the momentum (typically somewhere between 0.1 and 0.9) default: 0.1", - "type": "double", - "default": 0.1, - "min": 0.1, - "max": 0.9, - "refineSplits": 8, - "minInterval": 0.05 - } - ] - }, - { - "name": "meka.classifiers.multilabel.DBPNN", - "providedInterface": ["MLClassifier","BasicMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "meka.classifiers.multilabel.BPNN"}], - "parameter": [ - { - "name": "H", - "comment": "Sets the number of hidden units default: 10", - "type": "int", - "default": "10", - "min": "1", - "max": "100", - "refineSplits": 8, - "minInterval": 5 - }, - { - "name": "E", - "comment": "Sets the maximum number of epochs default: 1000 (auto_cut_out)", - "type": "int", - "default": 1000, - "min": 10, - "max": 10000, - "refineSplits": 8, - "minInterval": 100 - }, - { - "name": "r", - "comment": "Sets the learning rate (tyically somewhere between 'very small' and 0.1) default: 0.1", - "type": "double", - "default": 0.1, - "min": 1E-3, - "max": 0.1, - "refineSplits": 8, - "minInterval": 1E-4 - }, - { - "name": "m", - "comment": "Sets the momentum (typically somewhere between 0.1 and 0.9) default: 0.1", - "type": "double", - "default": 0.1, - "min": 0.1, - "max": 0.9, - "refineSplits": 8, - "minInterval": 0.05 - }, - - { - "name": "N", - "type": "int", - "default": 1, - "min": 1, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - } - ] - }, - - - - { - "name": "meka.classifiers.multilabel.HASEL", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [{"id": "W","name": "AbstractClassifier"}], - "comment": "LEFT OUT: _k The number of labels in each partition __ should be 1 <= k < (L/2) where L is the total number of labels. LEFT OUT: _N Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", - "parameter": [ - { - "name": "P", - "comment": "Sets the pruning value, defining an infrequent labelset as one which occurs <= P times in the data (P = 0 defaults to LC). default: 0 (LC)", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - }, - { - "name": "N", - "comment": "Sets the (maximum) number of frequent labelsets to subsample from the infrequent labelsets. default: 0 (none) n N = n _n N = n, or 0 if LCard(D) >= 2 n_m N = random(n,m)", - "type": "int", - "default": 0, - "min": 0, - "max": 5, - "minInterval": 1, - "refineSplits": 6 - } - ] - }, - { - "name": "meka.classifiers.multilabel.MajorityLabelset", - "providedInterface": ["MLClassifier","BasicMLClassifier"], - "requiredInterface": [], - "parameter": [] - } - ] -} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/meka-multilabel-meta.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/meka-multilabel-meta.json deleted file mode 100644 index 1f29f58d40..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/meka-multilabel-meta.json +++ /dev/null @@ -1,199 +0,0 @@ -{ - "repository": "MEKA_META", - "include": [], - "parameters": [ - ], - "components": [ - { - "name": "meka.classifiers.multilabel.meta.MBR", - "providedInterface": ["MLClassifier","MetaMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "meka.classifiers.multilabel.BR"}], - "parameter": [] - }, - { - "name": "meka.classifiers.multilabel.meta.SubsetMapper", - "providedInterface": ["MLClassifier","MetaMLClassifier"], - "requiredInterface": [{"id": "W","name": "ProblemTransformationMethod"}], - "parameter": [] - }, - { - "name": "meka.classifiers.multilabel.meta.RandomSubspaceML", - "providedInterface": ["MLClassifier","MetaMLClassifier"], - "requiredInterface": [{"id": "W","name": "ProblemTransformationMethod"}], - "parameter": [ - { - "name": "P", - "comment": "Size of each bag, as a percentage of total training size (default 67)", - "type": "int", - "default": 67, - "min": 10, - "max": 100, - "refineSplits": 8, - "minInterval": 5 - }, - { - "name": "I", - "comment": "The number of models (default: 10)", - "type": "int", - "default": 10, - "min": 10, - "max": 50, - "refineSplits": 8, - "minInterval": 1 - }, - { - "name": "A", - "comment": "Size of attribute space, as a percentage of total attribute space size (must be between 1 and 100, default: 50)", - "type": "int", - "default": 50, - "min": 10, - "max": 100, - "minInterval": 5, - "refineSplits": 8 - } - ] - }, - { - "name": "meka.classifiers.multilabel.MLCBMaD", - "providedInterface": ["MLClassifier","MetaMLClassifier"], - "requiredInterface": [{"id": "W","name": "BasicMLClassifier"}], - "parameter": [ - { - "name": "size", - "comment": "Size of the compressed matrix. Should be less than the number of labels and more than 1. (default: 20)", - "type": "int", - "min": 1, - "max": 20, - "default": 20, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "threshold", - "comment": "Threshold for the matrix decompositon, what is considered frequent. Between 0 and 1. (default: 0.5)", - "type": "double", - "min": 0.0, - "max": 1.0, - "default": 0.5, - "minInterval": 0.05, - "refineSplits": 8 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.BaggingML", - "providedInterface": ["MLClassifier","MetaMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "BasicMLClassifier"}], - "parameter": [ - { - "name": "I", - "comment": "Sets the number of models (default 10)", - "type": "int", - "default": 10, - "min": 10, - "max": 50, - "refineSplits": 8, - "minInterval": 1 - }, - { - "name": "P", - "comment": "Size of each bag, as a percentage of total training size (default 67)", - "type": "int", - "default": 67, - "min": 10, - "max": 100, - "refineSplits": 8, - "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.BaggingMLdup", - "providedInterface": ["MLClassifier","MetaMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "BasicMLClassifier"}], - "parameter": [ - { - "comment": "Sets the number of models (default 10)", - "name": "I", - "type": "int", - "default": 10, - "min": 10, - "max": 50, - "refineSplits": 4, - "minInterval": 1 - }, - { - "name": "P", - "comment": "Size of each bag, as a percentage of total training size (default 67)", - "type": "int", - "default": 67, - "min": 10, - "max": 100, - "refineSplits": 8, - "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.EnsembleML", - "providedInterface": ["MLClassifier","MetaMLClassifier","ProblemTransformationMethod"], - "requiredInterface": [{"id": "W","name": "BasicMLClassifier"}], - "parameter": [ - { - "comment": "Sets the number of models (default 10)", - "name": "I", - "type": "int", - "default": 10, - "min": 10, - "max": 50, - "refineSplits": 4, - "minInterval": 1 - }, - { - "name": "P", - "comment": "Size of each bag, as a percentage of total training size (default 67)", - "type": "int", - "default": 67, - "min": 10, - "max": 100, - "refineSplits": 8, - "minInterval": 5 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.EM", - "providedInterface": ["MLClassifier","MetaMLClassifier"], - "requiredInterface": [{"id": "W","name": "ProblemTransformationMethod"}], - "parameter": [ - { - "comment": "Sets the number of models (default 10)", - "name": "I", - "type": "int", - "default": 10, - "min": 10, - "max": 50, - "refineSplits": 4, - "minInterval": 1 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.CM", - "providedInterface": ["MLClassifier","MetaMLClassifier"], - "requiredInterface": [{"id": "W","name": "BasicMLClassifier"}], - "parameter": [ - { - "comment": "Sets the number of models (default 10)", - "name": "I", - "type": "int", - "default": 10, - "min": 10, - "max": 50, - "refineSplits": 4, - "minInterval": 1 - } - ] - } - ] -} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/meka-multilabel-meta2.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/meka-multilabel-meta2.json deleted file mode 100644 index 57e2ddb3c2..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/mekanew/meka-multilabel-meta2.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "repository": "MEKA_META", - "include": [], - "parameters": [ - ], - "components": [ - { - "name": "meka.classifiers.multilabel.Maniac", - "providedInterface": [ - "MLClassifier", - "BasicMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], - "parameter": [ - { - "name": "compression", - "comment": "Compression factor of the autoencoders, each level of autoencoders will compress the labels to factor times previous layer size. (default: 0.85)", - "type": "double", - "default": 0.85, - "min": 0.01, - "max": 0.99, - "minInterval": 0.05, - "refineSplits": 2 - }, - { - "name": "numberAutoencoders", - "comment": "Number of autoencoders, i.e. number of hidden layers +1. Note that this can be also used as the number of autoencoders to use in the optimization search, autoencoders will be added until this number is reached and then the best configuration in terms of number of layers is selects. (default: 4)", - "type": "int", - "default": 4, - "min": 1, - "max": 10, - "minInterval": 1, - "refineSplits": 2 - }, - { - "name": "optimizeAE", - "comment": "Number of autoencoders, i.e. number of hidden layers +1. Note that this can be also used as the number of autoencoders to use in the optimization search, autoencoders will be added until this number is reached and then the best configuration in terms of number of layers is selects. (default: 4)", - "type": "boolean", - "default": "false" - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.DeepML", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier","ProblemTransformationMethod" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], - "parameter": [ - { - "comment": "Sets the number of RBMs default: 2", - "name": "N", - "type": "int", - "default": 2, - "min": 2, - "max": 5, - "refineSplits": 2, - "minInterval": 1 - }, - { - "comment": "Sets the number of hidden units default: 10", - "name": "H", - "type": "int", - "default": 10, - "min": 5, - "max": 100, - "refineSplits": 2, - "minInterval": 5 - }, - { - "comment": "Sets the maximum number of epochs default: 1000 (auto_cut_out)", - "name": "E", - "type": "int", - "default": 1000, - "min": 100, - "max": 10000, - "refineSplits": 2, - "minInterval": 100 - }, - { - "comment": "Sets the learning rate (tyically somewhere between 'very small' and 0.1) default: 0.1", - "name": "r", - "type": "double", - "default": 0.1, - "min": 1E-5, - "max": 0.1, - "refineSplits": 2, - "minInterval": 1E-5 - }, - { - "name": "m", - "comment": "Sets the momentum (typically somewhere between 0.1 and 0.9) default: 0.1", - "type": "double", - "default": 0.1, - "min": 0.1, - "max": 0.9, - "refineSplits": 2, - "minInterval": 0.05 - } - ] - }, - { - "name": "meka.classifiers.multilabel.meta.FilteredClassifier", - "providedInterface": [ - "MLClassifier", - "MetaMLClassifier" - ], - "requiredInterface": [ - { - "id": "W", - "name": "BasicMLClassifier" - } - ], - "parameter": [ - { - "name": "F", - "comment": "The number of iterations of EM to carry out (default: 10). REMARK: Here we could also use a subcomponent for filters!", - "type": "cat", - "default": "weka.filters.supervised.attribute.Discretize -R first_last -precision 6", - "values": [ - "weka.filters.supervised.attribute.Discretize -R first_last -precision 6" - ] - } - ] - } - ] -} diff --git a/softwareconfiguration/mlplan/resources/automl/searchmodels/weka/weka-classifiers-autoweka.json b/softwareconfiguration/mlplan/resources/automl/searchmodels/weka/weka-classifiers-autoweka.json deleted file mode 100644 index 5cdb27bb3e..0000000000 --- a/softwareconfiguration/mlplan/resources/automl/searchmodels/weka/weka-classifiers-autoweka.json +++ /dev/null @@ -1,1379 +0,0 @@ -{ - "repository": "Auto-WEKA", - "components": [ - { - "name": "weka.classifiers.bayes.BayesNet", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier", - "Test" - ], - "parameter": [ - { - "name": "D", - "type": "boolean", - "default": "true" - }, - { - "name": "Q", - "type": "cat", - "default": "weka.classifiers.bayes.net.search.local.K2", - "values": [ - "weka.classifiers.bayes.net.search.local.K2", - "weka.classifiers.bayes.net.search.local.HillClimber", - "weka.classifiers.bayes.net.search.local.LAGDHillClimber", - "weka.classifiers.bayes.net.search.local.SimulatedAnnealing", - "weka.classifiers.bayes.net.search.local.TabuSearch", - "weka.classifiers.bayes.net.search.local.TAN" - ] - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.bayes.NaiveBayes", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "K", - "type": "boolean", - "default": "true" - }, - { - "name": "D", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "D in {true}", - "post": "K in {false}" - } - ] - }, - { - "name": "weka.classifiers.bayes.NaiveBayesMultinomial", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.functions.Logistic", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "R", - "type": "double", - "default": 1.0E-7, - "min": 1.0E-12, - "max": 10.0, - "refineSplits": 8, - "minInterval": 5.0E-12 - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.functions.MultilayerPerceptron", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "L", - "type": "double", - "default": 0.3, - "min": 0.1, - "max": 1.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "M", - "type": "double", - "default": 0.2, - "min": 0.1, - "max": 1.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "B", - "type": "boolean", - "default": "true" - }, - { - "name": "H", - "type": "cat", - "default": "a", - "values": [ - "a", - "i", - "o", - "t" - ] - }, - { - "name": "C", - "type": "boolean", - "default": "true" - }, - { - "name": "R", - "type": "boolean", - "default": "true" - }, - { - "name": "D", - "type": "boolean", - "default": "false" - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.functions.SimpleLinearRegression", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "Regressor", - "BaseClassifier" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.functions.SimpleLogistic", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "S", - "type": "boolean", - "default": "true" - }, - { - "name": "WActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "W", - "type": "double", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "A", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "WActivator in {0}", - "post": "W in {0}" - }, - { - "pre": "WActivator in {1}", - "post": "W in [0.0,1.0]" - } - ] - }, - { - "name": "weka.classifiers.functions.supportVector.NormalizedPolyKernel", - "requiredInterface": [ - ], - "providedInterface": [ - "K" - ], - "parameter": [ - ] - }, - { - "name": "weka.classifiers.functions.supportVector.PolyKernel", - "requiredInterface": [ - ], - "providedInterface": [ - "K" - ], - "parameter": [ - ] - }, - { - "name": "weka.classifiers.functions.supportVector.RBFKernel", - "requiredInterface": [ - ], - "providedInterface": [ - "K" - ], - "parameter": [ - ] - }, - { - "name": "weka.classifiers.functions.SMO", - "requiredInterface": [ - { - "id": "K", - "name": "K" - } - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "C", - "type": "double", - "default": 1.0, - "min": 0.5, - "max": 1.5, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "N", - "type": "cat", - "default": "0", - "values": [ - "0", - "1", - "2" - ] - }, - { - "name": "M", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.functions.supportVector.Puk", - "requiredInterface": [ - ], - "providedInterface": [ - "K" - ], - "parameter": [ - ] - }, - { - "name": "weka.classifiers.functions.VotedPerceptron", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "I", - "type": "int", - "default": 1.0, - "min": 1.0, - "max": 10.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "M", - "type": "int", - "default": 10000.0, - "min": 5000.0, - "max": 50000.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "E", - "type": "double", - "default": 1.0, - "min": 0.2, - "max": 5.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.lazy.IBk", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "E", - "type": "boolean", - "default": "true" - }, - { - "name": "K", - "type": "int", - "default": 1.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "X", - "type": "boolean", - "default": "true" - }, - { - "name": "I", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.lazy.KStar", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "B", - "type": "int", - "default": 20.0, - "min": 1.0, - "max": 100.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "E", - "type": "boolean", - "default": "true" - }, - { - "name": "M", - "type": "cat", - "default": "a", - "values": [ - "a", - "d", - "m", - "n" - ] - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.rules.JRip", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "N", - "type": "double", - "default": 2.0, - "min": 1.0, - "max": 5.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "E", - "type": "boolean", - "default": "true" - }, - { - "name": "P", - "type": "boolean", - "default": "true" - }, - { - "name": "O", - "type": "int", - "default": 2.0, - "min": 1.0, - "max": 5.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.rules.M5Rules", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "N", - "type": "boolean", - "default": "true" - }, - { - "name": "M", - "type": "int", - "default": 4.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "U", - "type": "boolean", - "default": "true" - }, - { - "name": "R", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.rules.OneR", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "B", - "type": "int", - "default": 6.0, - "min": 1.0, - "max": 32.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.rules.PART", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "N", - "type": "int", - "default": 3.0, - "min": 2.0, - "max": 5.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "M", - "type": "int", - "default": 2.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "R", - "type": "boolean", - "default": "true" - }, - { - "name": "B", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "R in {false}", - "post": "N in [3.0,3.0]" - } - ] - }, - { - "name": "weka.classifiers.rules.ZeroR", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.trees.DecisionStump", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.trees.J48", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier", - "Test" - ], - "parameter": [ - { - "name": "O", - "type": "boolean", - "default": "true" - }, - { - "name": "U", - "type": "boolean", - "default": "true" - }, - { - "name": "B", - "type": "boolean", - "default": "true" - }, - { - "name": "J", - "type": "boolean", - "default": "true" - }, - { - "name": "A", - "type": "boolean", - "default": "true" - }, - { - "name": "M", - "type": "int", - "default": 2.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.trees.LMT", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "B", - "type": "boolean", - "default": "true" - }, - { - "name": "R", - "type": "boolean", - "default": "true" - }, - { - "name": "C", - "type": "boolean", - "default": "true" - }, - { - "name": "P", - "type": "boolean", - "default": "true" - }, - { - "name": "M", - "type": "int", - "default": 15.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "WActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "W", - "type": "double", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "A", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "WActivator in {0}", - "post": "W in {0}" - }, - { - "pre": "WActivator in {1}", - "post": "W in [0.0,1.0]" - } - ] - }, - { - "name": "weka.classifiers.trees.M5P", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "Regressor", - "BaseClassifier" - ], - "parameter": [ - { - "name": "N", - "type": "boolean", - "default": "true" - }, - { - "name": "M", - "type": "int", - "default": 4.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "U", - "type": "boolean", - "default": "true" - }, - { - "name": "R", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.trees.RandomForest", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 256.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "featuresActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "K", - "type": "int", - "default": "0", - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "depthActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "depth", - "type": "int", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - { - "pre": "featuresActivator in {0}", - "post": "K in {0}" - }, - { - "pre": "featuresActivator in {1}", - "post": "K in [1.0,32.0]" - }, - { - "pre": "depthActivator in {0}", - "post": "depth in {0}" - }, - { - "pre": "depthActivator in {1}", - "post": "depth in [1.0,20.0]" - } - ] - }, - { - "name": "weka.classifiers.trees.RandomTree", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "M", - "type": "int", - "default": 1.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "featuresActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "K", - "type": "int", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "depthActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "depth", - "type": "int", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "backActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "N", - "type": "int", - "default": "0", - "values": [ - "0" - ], - "min": 0.0, - "max": 0.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "U", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "featuresActivator in {0}", - "post": "K in {0}" - }, - { - "pre": "featuresActivator in {1}", - "post": "K in [2.0,32.0]" - }, - { - "pre": "depthActivator in {0}", - "post": "depth in {0}" - }, - { - "pre": "depthActivator in {1}", - "post": "depth in [2.0,20.0]" - }, - { - "pre": "backActivator in {0}", - "post": "N in {0}" - }, - { - "pre": "backActivator in {1}", - "post": "N in [2.0,5.0]" - } - ] - }, - { - "name": "weka.classifiers.trees.REPTree", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "WekaBaseClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "M", - "type": "int", - "default": 2.0, - "min": 1.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "V", - "type": "double", - "default": 0.001, - "min": 1.0E-5, - "max": 0.1, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "depthActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "L", - "type": "int", - "default": "-1", - "values": [ - "-1" - ], - "min": -1.0, - "max": -1.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "P", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "depthActivator in {0}", - "post": "L in {-1}" - }, - { - "pre": "depthActivator in {1}", - "post": "L in [2.0,20.0]" - } - ] - }, - { - "name": "weka.classifiers.meta.AdaBoostM1", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "pActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "P", - "type": "int", - "default": "100", - "values": [ - "100" - ], - "min": 100.0, - "max": 100.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 128.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "Q", - "type": "boolean", - "default": "true" - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - } - ], - "dependencies": [ - { - "pre": "pActivator in {0}", - "post": "P in {100}" - }, - { - "pre": "pActivator in {1}", - "post": "P in [50.0,100.0]" - } - ] - }, - { - "name": "weka.classifiers.meta.AdditiveRegression", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier", - "Regressor", - "BaseClassifier" - ], - "parameter": [ - { - "name": "sActivator", - "type": "cat", - "default": "0", - "values": [ - "0", - "1" - ] - }, - { - "name": "S", - "type": "double", - "default": "1", - "values": [ - "1" - ], - "min": 1.0, - "max": 1.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 128.0, - "refineSplits": 8, - "minInterval": 10 - } - ], - "dependencies": [ - { - "pre": "sActivator in {0}", - "post": "S in {1}" - }, - { - "pre": "sActivator in {1}", - "post": "S in [0.0,1.0]" - } - ] - }, - { - "name": "weka.classifiers.meta.Bagging", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "P", - "type": "int", - "default": 100.0, - "min": 10.0, - "max": 100.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 128.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - }, - { - "name": "O", - "type": "boolean", - "default": "true" - } - ], - "dependencies": [ - { - "pre": "O in {true}", - "post": "P in {100}" - } - ] - }, - { - "name": "weka.classifiers.meta.ClassificationViaRegression", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier", - "BaseClassifier" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.meta.LogitBoost", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier", - "BaseClassifier" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.meta.MultiClassClassifier", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier", - "BaseClassifier" - ], - "parameter": [ - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.meta.RandomCommittee", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 10 - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.meta.RandomSubSpace", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "I", - "type": "int", - "default": 10.0, - "min": 2.0, - "max": 64.0, - "refineSplits": 8, - "minInterval": 1 - }, - { - "name": "P", - "type": "double", - "default": 0.5, - "min": 0.1, - "max": 1.0, - "refineSplits": 8, - "minInterval": 0.01 - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.meta.Stacking", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "X", - "type": "cat", - "default": "10", - "values": [ - "10" - ] - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - } - ], - "dependencies": [ - ] - }, - { - "name": "weka.classifiers.meta.Vote", - "requiredInterface": [ - ], - "providedInterface": [ - "AbstractClassifier", - "MetaClassifier", - "BaseClassifier" - ], - "parameter": [ - { - "name": "R", - "type": "cat", - "default": "AVG", - "values": [ - "AVG", - "PROD", - "MAJ", - "MIN", - "MAX" - ] - }, - { - "name": "S", - "type": "cat", - "default": "1", - "values": [ - "1" - ] - } - ], - "dependencies": [ - ] - } - ] -} diff --git a/softwareconfiguration/mlplan/conf/ml2plan.properties b/softwareconfiguration/mlplan/resources/mlplan/ml2plan.properties similarity index 100% rename from softwareconfiguration/mlplan/conf/ml2plan.properties rename to softwareconfiguration/mlplan/resources/mlplan/ml2plan.properties diff --git a/softwareconfiguration/mlplan/conf/mlplan.properties b/softwareconfiguration/mlplan/resources/mlplan/mlplan.properties similarity index 54% rename from softwareconfiguration/mlplan/conf/mlplan.properties rename to softwareconfiguration/mlplan/resources/mlplan/mlplan.properties index 96f48ff52a..bf5d363cc5 100644 --- a/softwareconfiguration/mlplan/conf/mlplan.properties +++ b/softwareconfiguration/mlplan/resources/mlplan/mlplan.properties @@ -1,10 +1,10 @@ cpus = 8 memory = 8192 -timeout = 3600 +timeout = 60000 hasco.seed = 0 -hasco.random_completions.timeout_path = 300 -hasco.random_completions.timeout_node = 300 +hasco.random_completions.timeout_path = 60000 +hasco.random_completions.timeout_node = 60000 #hasco.blowup.selection = 1.3 #hasco.blowup.postprocess = 1.3 diff --git a/softwareconfiguration/mlplan/settings.gradle b/softwareconfiguration/mlplan/settings.gradle deleted file mode 100644 index 55c612a769..0000000000 --- a/softwareconfiguration/mlplan/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'ML-Plan' \ No newline at end of file diff --git a/softwareconfiguration/mlplan/src/example/java/ai/libs/automl/mlplan/examples/MLPlanARFFExample.java b/softwareconfiguration/mlplan/src/example/java/ai/libs/automl/mlplan/examples/MLPlanARFFExample.java index 2c0b2dbe83..80ea198e0b 100644 --- a/softwareconfiguration/mlplan/src/example/java/ai/libs/automl/mlplan/examples/MLPlanARFFExample.java +++ b/softwareconfiguration/mlplan/src/example/java/ai/libs/automl/mlplan/examples/MLPlanARFFExample.java @@ -17,11 +17,11 @@ import ai.libs.jaicore.graphvisualizer.window.AlgorithmVisualizationWindow; import ai.libs.jaicore.ml.WekaUtil; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNodeInfoGenerator; +import ai.libs.jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; +import ai.libs.jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; import ai.libs.mlplan.core.AbstractMLPlanBuilder; import ai.libs.mlplan.core.MLPlan; import ai.libs.mlplan.gui.outofsampleplots.OutOfSampleErrorPlotPlugin; -import jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; -import jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import weka.classifiers.Classifier; diff --git a/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/MLPlanSubsamplingExample.java b/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/MLPlanSubsamplingExample.java index aa2a226e14..c297c2ea76 100644 --- a/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/MLPlanSubsamplingExample.java +++ b/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/MLPlanSubsamplingExample.java @@ -1,84 +1,84 @@ -package ai.libs.mlplan.examples; - -import java.io.File; -import java.io.FileReader; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Random; -import java.util.concurrent.TimeUnit; - -import ai.libs.hasco.gui.statsplugin.HASCOModelStatisticsPlugin; -import ai.libs.jaicore.basic.TimeOut; -import ai.libs.jaicore.graphvisualizer.plugin.graphview.GraphViewPlugin; -import ai.libs.jaicore.graphvisualizer.plugin.nodeinfo.NodeInfoGUIPlugin; -import ai.libs.jaicore.graphvisualizer.plugin.solutionperformanceplotter.SolutionPerformanceTimelinePlugin; -import ai.libs.jaicore.graphvisualizer.window.AlgorithmVisualizationWindow; -import ai.libs.jaicore.ml.WekaUtil; -import ai.libs.jaicore.ml.core.dataset.sampling.infiles.AFileSamplingAlgorithm; -import ai.libs.jaicore.ml.core.dataset.sampling.infiles.stratified.sampling.ClassStratiFileAssigner; -import ai.libs.jaicore.ml.core.dataset.sampling.infiles.stratified.sampling.StratifiedFileSampling; -import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNodeInfoGenerator; -import ai.libs.mlplan.core.AbstractMLPlanBuilder; -import ai.libs.mlplan.core.MLPlan; -import ai.libs.mlplan.core.MLPlanWekaBuilder; -import ai.libs.mlplan.gui.outofsampleplots.OutOfSampleErrorPlotPlugin; -import ai.libs.mlplan.multiclass.wekamlplan.weka.model.MLPipeline; -import jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; -import jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; -import javafx.application.Platform; -import javafx.embed.swing.JFXPanel; -import weka.classifiers.Classifier; -import weka.classifiers.evaluation.Evaluation; -import weka.core.Instances; - -public class MLPlanSubsamplingExample { - - public static void main(final String[] args) throws Exception { - - /* create a subsample of the input with 1000 datapoints */ - File file = new File("testrsc/car.arff"); - File sampleFile = new File("testrsc/car_sample.arff"); - sampleFile.deleteOnExit(); - AFileSamplingAlgorithm samplingAlgorithm = new StratifiedFileSampling(new Random(1l), new ClassStratiFileAssigner(), file); - samplingAlgorithm.setSampleSize(1000); - samplingAlgorithm.setOutputFileName(sampleFile.getAbsolutePath()); - samplingAlgorithm.call(); - - /* create a train-test-split */ - Instances data = new Instances(new FileReader(sampleFile)); - data.setClassIndex(data.numAttributes() - 1); - List split = WekaUtil.getStratifiedSplit(data, 0, .7f); - - /* initialize mlplan with a tiny search space, and let it run for 30 seconds */ - MLPlanWekaBuilder builder = AbstractMLPlanBuilder.forWeka(); - builder.withNodeEvaluationTimeOut(new TimeOut(30, TimeUnit.SECONDS)); - builder.withCandidateEvaluationTimeOut(new TimeOut(10, TimeUnit.SECONDS)); - builder.withTimeOut(new TimeOut(300, TimeUnit.SECONDS)); - builder.withNumCpus(1); - MLPlan mlplan = new MLPlan(builder, split.get(0)); - mlplan.setPortionOfDataForPhase2(0f); - mlplan.setLoggerName("mlplan"); - - new JFXPanel(); - AlgorithmVisualizationWindow window = new AlgorithmVisualizationWindow(mlplan, new GraphViewPlugin(), new NodeInfoGUIPlugin<>(new JaicoreNodeInfoGenerator<>(new TFDNodeInfoGenerator())), new SearchRolloutHistogramPlugin<>(), - new SolutionPerformanceTimelinePlugin(), new HASCOModelStatisticsPlugin(), new OutOfSampleErrorPlotPlugin(split.get(0), split.get(1))); - Platform.runLater(window); - - try { - long start = System.currentTimeMillis(); - Classifier optimizedClassifier = mlplan.call(); - long trainTime = (int) (System.currentTimeMillis() - start) / 1000; - System.out.println("Finished build of the classifier."); - System.out.println("Chosen model is: " + ((MLPipeline) mlplan.getSelectedClassifier()).toString()); - System.out.println("Training time was " + trainTime + "s."); - - /* evaluate solution produced by mlplan */ - Evaluation eval = new Evaluation(split.get(0)); - eval.evaluateModel(optimizedClassifier, split.get(1)); - System.out.println("Error Rate of the solution produced by ML-Plan: " + ((100 - eval.pctCorrect()) / 100f) + ". Internally believed error was " + mlplan.getInternalValidationErrorOfSelectedClassifier()); - } catch (NoSuchElementException e) { - System.out.println("Building the classifier failed: " + e.getMessage()); - } - } - -} +package ai.libs.mlplan.examples; + +import java.io.File; +import java.io.FileReader; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +import ai.libs.hasco.gui.statsplugin.HASCOModelStatisticsPlugin; +import ai.libs.jaicore.basic.TimeOut; +import ai.libs.jaicore.graphvisualizer.plugin.graphview.GraphViewPlugin; +import ai.libs.jaicore.graphvisualizer.plugin.nodeinfo.NodeInfoGUIPlugin; +import ai.libs.jaicore.graphvisualizer.plugin.solutionperformanceplotter.SolutionPerformanceTimelinePlugin; +import ai.libs.jaicore.graphvisualizer.window.AlgorithmVisualizationWindow; +import ai.libs.jaicore.ml.WekaUtil; +import ai.libs.jaicore.ml.core.dataset.sampling.infiles.AFileSamplingAlgorithm; +import ai.libs.jaicore.ml.core.dataset.sampling.infiles.stratified.sampling.ClassStratiFileAssigner; +import ai.libs.jaicore.ml.core.dataset.sampling.infiles.stratified.sampling.StratifiedFileSampling; +import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNodeInfoGenerator; +import ai.libs.jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; +import ai.libs.jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; +import ai.libs.mlplan.core.AbstractMLPlanBuilder; +import ai.libs.mlplan.core.MLPlan; +import ai.libs.mlplan.core.MLPlanWekaBuilder; +import ai.libs.mlplan.gui.outofsampleplots.OutOfSampleErrorPlotPlugin; +import ai.libs.mlplan.multiclass.wekamlplan.weka.model.MLPipeline; +import javafx.application.Platform; +import javafx.embed.swing.JFXPanel; +import weka.classifiers.Classifier; +import weka.classifiers.evaluation.Evaluation; +import weka.core.Instances; + +public class MLPlanSubsamplingExample { + + public static void main(final String[] args) throws Exception { + + /* create a subsample of the input with 1000 datapoints */ + File file = new File("testrsc/car.arff"); + File sampleFile = new File("testrsc/car_sample.arff"); + sampleFile.deleteOnExit(); + AFileSamplingAlgorithm samplingAlgorithm = new StratifiedFileSampling(new Random(1l), new ClassStratiFileAssigner(), file); + samplingAlgorithm.setSampleSize(1000); + samplingAlgorithm.setOutputFileName(sampleFile.getAbsolutePath()); + samplingAlgorithm.call(); + + /* create a train-test-split */ + Instances data = new Instances(new FileReader(sampleFile)); + data.setClassIndex(data.numAttributes() - 1); + List split = WekaUtil.getStratifiedSplit(data, 0, .7f); + + /* initialize mlplan with a tiny search space, and let it run for 30 seconds */ + MLPlanWekaBuilder builder = AbstractMLPlanBuilder.forWeka(); + builder.withNodeEvaluationTimeOut(new TimeOut(30, TimeUnit.SECONDS)); + builder.withCandidateEvaluationTimeOut(new TimeOut(10, TimeUnit.SECONDS)); + builder.withTimeOut(new TimeOut(300, TimeUnit.SECONDS)); + builder.withNumCpus(1); + MLPlan mlplan = new MLPlan(builder, split.get(0)); + mlplan.setPortionOfDataForPhase2(0f); + mlplan.setLoggerName("mlplan"); + + new JFXPanel(); + AlgorithmVisualizationWindow window = new AlgorithmVisualizationWindow(mlplan, new GraphViewPlugin(), new NodeInfoGUIPlugin<>(new JaicoreNodeInfoGenerator<>(new TFDNodeInfoGenerator())), new SearchRolloutHistogramPlugin<>(), + new SolutionPerformanceTimelinePlugin(), new HASCOModelStatisticsPlugin(), new OutOfSampleErrorPlotPlugin(split.get(0), split.get(1))); + Platform.runLater(window); + + try { + long start = System.currentTimeMillis(); + Classifier optimizedClassifier = mlplan.call(); + long trainTime = (int) (System.currentTimeMillis() - start) / 1000; + System.out.println("Finished build of the classifier."); + System.out.println("Chosen model is: " + ((MLPipeline) mlplan.getSelectedClassifier()).toString()); + System.out.println("Training time was " + trainTime + "s."); + + /* evaluate solution produced by mlplan */ + Evaluation eval = new Evaluation(split.get(0)); + eval.evaluateModel(optimizedClassifier, split.get(1)); + System.out.println("Error Rate of the solution produced by ML-Plan: " + ((100 - eval.pctCorrect()) / 100f) + ". Internally believed error was " + mlplan.getInternalValidationErrorOfSelectedClassifier()); + } catch (NoSuchElementException e) { + System.out.println("Building the classifier failed: " + e.getMessage()); + } + } + +} diff --git a/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/multilabel/meka/ML2PlanARFFExample.java b/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/multilabel/meka/ML2PlanARFFExample.java index 15c806f22e..4d22159fa9 100644 --- a/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/multilabel/meka/ML2PlanARFFExample.java +++ b/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/multilabel/meka/ML2PlanARFFExample.java @@ -15,13 +15,13 @@ import ai.libs.jaicore.ml.weka.dataset.splitter.ArbitrarySplitter; import ai.libs.jaicore.ml.weka.dataset.splitter.IDatasetSplitter; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNodeInfoGenerator; +import ai.libs.jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; +import ai.libs.jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; import ai.libs.mlplan.core.AbstractMLPlanBuilder; import ai.libs.mlplan.core.MLPlan; import ai.libs.mlplan.core.MLPlanMekaBuilder; import ai.libs.mlplan.gui.outofsampleplots.OutOfSampleErrorPlotPlugin; import ai.libs.mlplan.multiclass.MLPlanClassifierConfig; -import jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; -import jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import meka.core.MLUtils; diff --git a/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/multilabel/meka/ML2PlanAutoMLCExperimenter.java b/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/multilabel/meka/ML2PlanAutoMLCExperimenter.java index 9a3d66b843..80647cc051 100644 --- a/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/multilabel/meka/ML2PlanAutoMLCExperimenter.java +++ b/softwareconfiguration/mlplan/src/example/java/ai/libs/mlplan/examples/multilabel/meka/ML2PlanAutoMLCExperimenter.java @@ -40,12 +40,12 @@ import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.InstanceWiseF1AsLoss; import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.RankLoss; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNodeInfoGenerator; +import ai.libs.jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; +import ai.libs.jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; import ai.libs.mlplan.core.AbstractMLPlanBuilder; import ai.libs.mlplan.core.MLPlan; import ai.libs.mlplan.core.MLPlanMekaBuilder; import ai.libs.mlplan.multiclass.MLPlanClassifierConfig; -import jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; -import jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import meka.classifiers.multilabel.Evaluation; diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/cli/MLPlanCLI.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/cli/MLPlanCLI.java index b6c8313cb1..0866d875e1 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/cli/MLPlanCLI.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/cli/MLPlanCLI.java @@ -1,499 +1,499 @@ -package ai.libs.mlplan.cli; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import ai.libs.hasco.gui.statsplugin.HASCOModelStatisticsPlugin; -import ai.libs.jaicore.basic.TimeOut; -import ai.libs.jaicore.concurrent.GlobalTimer; -import ai.libs.jaicore.graphvisualizer.plugin.graphview.GraphViewPlugin; -import ai.libs.jaicore.graphvisualizer.plugin.nodeinfo.NodeInfoGUIPlugin; -import ai.libs.jaicore.graphvisualizer.plugin.solutionperformanceplotter.SolutionPerformanceTimelinePlugin; -import ai.libs.jaicore.graphvisualizer.window.AlgorithmVisualizationWindow; -import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.AutoMEKAGGPFitnessMeasureLoss; -import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.ExactMatchLoss; -import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.F1MacroAverageLLoss; -import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.HammingLoss; -import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.InstanceWiseF1AsLoss; -import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.JaccardLoss; -import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.RankLoss; -import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.MeanSquaredErrorLoss; -import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.PrecisionAsLoss; -import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.RootMeanSquaredErrorLoss; -import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.ZeroOneLoss; -import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNodeInfoGenerator; -import ai.libs.mlplan.core.AbstractMLPlanBuilder; -import ai.libs.mlplan.core.AbstractMLPlanSingleLabelBuilder; -import ai.libs.mlplan.core.MLPlan; -import ai.libs.mlplan.core.MLPlanMekaBuilder; -import ai.libs.mlplan.gui.outofsampleplots.OutOfSampleErrorPlotPlugin; -import ai.libs.mlplan.multiclass.wekamlplan.weka.model.MLPipeline; -import jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; -import jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; -import javafx.application.Platform; -import javafx.embed.swing.JFXPanel; -import meka.classifiers.multilabel.MultiLabelClassifier; -import meka.core.MLUtils; -import meka.core.Metrics; -import meka.core.Result; -import weka.classifiers.Classifier; -import weka.classifiers.evaluation.Evaluation; -import weka.core.Instances; -import weka.core.SerializationHelper; - -/** - * Enables command-line usage of ML-Plan. - * - * @author Helena Graf - * - */ -@SuppressWarnings("restriction") -public class MLPlanCLI { - - // CLI variables - private static Logger logger = LoggerFactory.getLogger("MLPlanCLI"); - - // MLPlan options - private static String trainOption = "train"; - private static String testOption = "test"; - private static String totalTimeoutOption = "timeoutTotal"; - private static String nodeEvaluationTimeoutOption = "timeoutNodeEval"; - private static String solutionEvaluationTimeoutOption = "timeoutSolutionEval"; - private static String algorithmConfigurationOption = "algorithmConfig"; - private static String searchSpaceConfigurationOption = "searchSpaceConfig"; - private static String evaluationMeasureOption = "evaluationMeasure"; - private static String numCPUsOption = "numCPUS"; - private static String randomSeedOption = "randomSeed"; - private static String multiLabelOption = "multilabel"; - private static String positiveClassIndex = "positiveClassIndex"; - - // MLPlan options standard values - private static String totalTimeout = "150"; - private static String nodeEvaluationTimeout = "60"; - private static String solutionEvaluationTimeout = "60"; - private static String numCPUS = "4"; - private static String randomSeed = "0"; - - // Communication options - private static String modelFileOption = "modelFile"; - private static String resultsFileOption = "resultsFile"; - private static String printModelOption = "printModel"; - private static String visualizeOption = "visualize"; - private static String helpOption = "help"; - - // Communication options standard values - private static String modelFile = "model.txt"; - private static String resultsFile = "results.txt"; - - private MLPlanCLI() { - // Intentionally left blank - } - - private static Options generateOptions() { - // MLPLan options - final Option train = Option.builder("t").required(false).hasArg().longOpt(trainOption).desc("location of the .arff training data file").build(); - final Option test = Option.builder("T").required(false).longOpt(testOption).hasArg().desc("location of the .arff test data file").build(); - final Option totalTimeout = Option.builder("tt").longOpt(totalTimeoutOption).required(false).hasArg().desc("timeout for the complete run of mlplan in seconds").build(); - final Option nodeEvaluationTimeout = Option.builder("tne").longOpt(nodeEvaluationTimeoutOption).required(false).hasArg().desc("timeout for the evaluation of a single node in seconds").build(); - final Option solutionEvaluation = Option.builder("tse").longOpt(solutionEvaluationTimeoutOption).required(false).hasArg().desc("timeout for the evaluation of a solution in seconds").build(); - final Option algorithmConfiguration = Option.builder("ac").longOpt(algorithmConfigurationOption).required(false).hasArg().desc("configuration file for mlplan").build(); - final Option searchSpaceConfiguration = Option.builder("sc").longOpt(searchSpaceConfigurationOption).required(false).hasArg().desc("search space configuration file, or alternatively: weka, weka-tiny, sklearn, sklearn-ul, meka") - .build(); - final Option evaluationMeasure = Option.builder("em").longOpt(evaluationMeasureOption).required(false).hasArg().desc( - "measure for assessing solution quality, allowed values: \nsinglelabel: \nERRORRATE, MEAN_SQUARED_ERROR, PRECISION, ROOT_MEAN_SQUARED_ERROR \nmultilabel: \nAUTO_MEKA_GGP_FITNESS, AUTO_MEKA_GGP_FITNESS_LOSS, EXACT_MATCH_ACCURARY, EXACT_MATCH_LOSS, F1_MACRO_AVG_D, F1_MACRO_AVG_D_LOSS, F1_MACRO_AVG_L, F1_MACRO_AVG_L_LOSS, HAMMING_ACCURACY, HAMMING_LOSS, JACCARD_LOSS, JACCARD_SCORE, RANK_LOSS, RANK_SCORE") - .build(); - final Option positiveClass = Option.builder("pci").longOpt(positiveClassIndex).required(false).hasArg(true).desc("Index of the class (in the list of classes) which is to be considered as the positive class").build(); - final Option numCPUS = Option.builder("ncpus").longOpt(numCPUsOption).required(false).hasArg().desc("number of used CPUs, default: " + MLPlanCLI.numCPUS).build(); - final Option randomSeed = Option.builder("rs").longOpt(randomSeedOption).required(false).hasArg().desc("randomization seed, default: " + MLPlanCLI.randomSeed).build(); - final Option multiLabel = Option.builder("ml").longOpt(multiLabelOption).required(false).hasArg(false).desc("enable for multilabel settings").build(); - - // Communication options - final Option modelFile = Option.builder("mf").longOpt(modelFileOption).required(false).hasArg() - .desc("serialize model to the given output file, \"off\" if no model file shall be written; turn off for search spaces that contain non-serializable models").build(); - final Option resultsFile = Option.builder("rf").longOpt(resultsFileOption).required(false).hasArg().desc("serialize model to the given output file, \"off\" if no results file shall be written").build(); - final Option visualize = Option.builder("v").longOpt(visualizeOption).required(false).hasArg(false).desc("enable visualization").build(); - final Option printModel = Option.builder("p").longOpt(printModelOption).required(false).hasArg(false).desc("whether a visual representation of the final model shall be added to the model file").build(); - final Option help = Option.builder("h").longOpt(helpOption).required(false).hasArg(false).desc("supply help").build(); - - // Add options to Options - final Options options = new Options(); - options.addOption(train); - options.addOption(test); - options.addOption(totalTimeout); - options.addOption(nodeEvaluationTimeout); - options.addOption(solutionEvaluation); - options.addOption(algorithmConfiguration); - options.addOption(searchSpaceConfiguration); - options.addOption(evaluationMeasure); - options.addOption(numCPUS); - options.addOption(randomSeed); - options.addOption(multiLabel); - options.addOption(resultsFile); - options.addOption(modelFile); - options.addOption(visualize); - options.addOption(printModel); - options.addOption(help); - options.addOption(positiveClass); - return options; - } - - private static CommandLine generateCommandLine(final Options options, final String[] commandLineArguments) { - final CommandLineParser cmdLineParser = new DefaultParser(); - CommandLine commandLine = null; - try { - commandLine = cmdLineParser.parse(options, commandLineArguments); - } - - catch (ParseException parseException) { - logger.error("ERROR: Unable to parse command-line arguments {} due to {}", Arrays.toString(commandLineArguments), parseException); - } - - return commandLine; - } - - private static void printUsage(final Options options) { - final HelpFormatter formatter = new HelpFormatter(); - final String syntax = "mlplan"; - final PrintWriter pw = new PrintWriter(System.out); - formatter.printUsage(pw, 400, syntax, options); - pw.println("use -h or --help for help"); - pw.flush(); - } - - private static void printHelp(final Options options) { - final HelpFormatter formatter = new HelpFormatter(); - final String syntax = "mlplan [options]"; - formatter.printHelp(syntax, options); - } - - private static void runMLPlan(final CommandLine commandLine) throws Exception { - - File trainDataFile = new File(commandLine.getOptionValue(trainOption)); - logger.info("Load train data file: {}", trainDataFile.getAbsolutePath()); - - Instances trainData = new Instances(new FileReader(trainDataFile)); - if (commandLine.hasOption(multiLabelOption)) { - MLUtils.prepareData(trainData); - } else { - trainData.setClassIndex(trainData.numAttributes() - 1); - } - - AbstractMLPlanBuilder builder; - if (commandLine.hasOption(searchSpaceConfigurationOption)) { - switch (commandLine.getOptionValue(searchSpaceConfigurationOption)) { - case "weka": - builder = AbstractMLPlanBuilder.forWeka(); - break; - case "weka-tiny": - builder = AbstractMLPlanBuilder.forWeka().withTinyWekaSearchSpace(); - break; - case "sklearn": - builder = AbstractMLPlanBuilder.forSKLearn(); - break; - case "sklearn-ul": - builder = AbstractMLPlanBuilder.forSKLearn().withUnlimitedLengthPipelineSearchSpace(); - break; - case "meka": - builder = AbstractMLPlanBuilder.forMeka(); - break; - default: - throw new IllegalArgumentException("Could not identify search space configuration"); - } - } else { - builder = AbstractMLPlanBuilder.forWeka(); - } - - if (commandLine.hasOption(multiLabelOption)) { - MLPlanMekaBuilder mekaBuilder = (MLPlanMekaBuilder) builder; - switch (commandLine.getOptionValue(evaluationMeasureOption)) { - case "AUTO_MEKA_GGP_FITNESS": - mekaBuilder.withPerformanceMeasure(new AutoMEKAGGPFitnessMeasureLoss()); - break; - case "EXACT_MATCH": - mekaBuilder.withPerformanceMeasure(new ExactMatchLoss()); - break; - case "F1_MACRO_AVG_D": - mekaBuilder.withPerformanceMeasure(new InstanceWiseF1AsLoss()); - break; - case "F1_MACRO_AVG_L": - mekaBuilder.withPerformanceMeasure(new F1MacroAverageLLoss()); - break; - case "HAMMING": - mekaBuilder.withPerformanceMeasure(new HammingLoss()); - break; - case "JACCARD": - mekaBuilder.withPerformanceMeasure(new JaccardLoss()); - break; - case "RANK_LOSS": - mekaBuilder.withPerformanceMeasure(new RankLoss()); - break; - default: - throw new IllegalArgumentException("Invalid multilabel measure " + commandLine.getOptionValue(evaluationMeasureOption)); - } - } else { - AbstractMLPlanSingleLabelBuilder slcBuilder = (AbstractMLPlanSingleLabelBuilder) builder; - - switch (commandLine.getOptionValue(evaluationMeasureOption)) { - case "ERRORRATE": - slcBuilder.withPerformanceMeasure(new ZeroOneLoss()); - break; - case "MEAN_SQUARED_ERROR": - slcBuilder.withPerformanceMeasure(new MeanSquaredErrorLoss()); - break; - case "PRECISION": - int classIndex = Integer.parseInt(commandLine.getOptionValue(positiveClassIndex, "0")); - slcBuilder.withPerformanceMeasure(new PrecisionAsLoss(classIndex)); - break; - case "ROOT_MEAN_SQUARED_ERROR": - slcBuilder.withPerformanceMeasure(new RootMeanSquaredErrorLoss()); - break; - default: - throw new IllegalArgumentException("Invalid singlelabel measure " + commandLine.getOptionValue(evaluationMeasureOption)); - } - } - - if (commandLine.hasOption(algorithmConfigurationOption)) { - File algoConfigFile = new File(commandLine.getOptionValue(algorithmConfigurationOption)); - builder.withAlgorithmConfigFile(algoConfigFile); - } - builder.withNodeEvaluationTimeOut(new TimeOut(Integer.parseInt(commandLine.getOptionValue(nodeEvaluationTimeoutOption, nodeEvaluationTimeout)), TimeUnit.SECONDS)); - builder.withCandidateEvaluationTimeOut(new TimeOut(Integer.parseInt(commandLine.getOptionValue(solutionEvaluationTimeoutOption, solutionEvaluationTimeout)), TimeUnit.SECONDS)); - builder.withTimeOut(new TimeOut(Integer.parseInt(commandLine.getOptionValue(totalTimeoutOption, totalTimeout)), TimeUnit.SECONDS)); - builder.withNumCpus(Integer.parseInt(commandLine.getOptionValue(numCPUsOption, numCPUS))); - - MLPlan mlplan = builder.build(trainData); - mlplan.setLoggerName("mlplan"); - mlplan.setRandomSeed(Integer.parseInt(commandLine.getOptionValue(randomSeedOption, randomSeed))); - - Instances testData = null; - if (commandLine.hasOption(testOption)) { - File testDataFile = new File(commandLine.getOptionValue(testOption)); - logger.info("Load test data file: {}", testDataFile.getAbsolutePath()); - testData = new Instances(new FileReader(testDataFile)); - if (commandLine.hasOption(multiLabelOption)) { - MLUtils.prepareData(testData); - } else { - testData.setClassIndex(testData.numAttributes() - 1); - } - } - - if (commandLine.hasOption(visualizeOption)) { - new JFXPanel(); - AlgorithmVisualizationWindow window; - if (commandLine.hasOption(testOption)) { - window = new AlgorithmVisualizationWindow(mlplan, new GraphViewPlugin(), new NodeInfoGUIPlugin<>(new JaicoreNodeInfoGenerator<>(new TFDNodeInfoGenerator())), new SearchRolloutHistogramPlugin<>(), - new SolutionPerformanceTimelinePlugin(), new HASCOModelStatisticsPlugin(), new OutOfSampleErrorPlotPlugin(trainData, testData)); - } else { - window = new AlgorithmVisualizationWindow(mlplan, new GraphViewPlugin(), new NodeInfoGUIPlugin<>(new JaicoreNodeInfoGenerator<>(new TFDNodeInfoGenerator())), new SearchRolloutHistogramPlugin<>(), - new SolutionPerformanceTimelinePlugin(), new HASCOModelStatisticsPlugin()); - } - Platform.runLater(window); - } - - logger.info("Build mlplan classifier"); - Classifier optimizedClassifier = mlplan.call(); - - logger.info("Open timeout tasks: {}", GlobalTimer.getInstance().getActiveTasks()); - - if (!"off".equals(commandLine.getOptionValue(modelFileOption))) { - serializeModel(commandLine, mlplan.getSelectedClassifier()); - } - - if (commandLine.hasOption(testOption)) { - double error = -1; - - if (commandLine.hasOption(multiLabelOption)) { - logger.info("Assess test performance..."); - Result result = meka.classifiers.multilabel.Evaluation.evaluateModel((MultiLabelClassifier) mlplan.getSelectedClassifier(), trainData, testData); - - switch (commandLine.getOptionValue(evaluationMeasureOption, "AUTO_MEKA_GGP_FITNESS_LOSS")) { - case "AUTO_MEKA_GGP_FITNESS": - error = (Metrics.P_ExactMatch(result.allTrueValues(), result.allPredictions(0.5)) + (1 - Metrics.L_Hamming(result.allTrueValues(), result.allPredictions(0.5))) - + Metrics.P_FmacroAvgL(result.allTrueValues(), result.allPredictions(0.5)) + (1 - Metrics.L_RankLoss(result.allTrueValues(), result.allPredictions()))) / 4.0; - break; - case "AUTO_MEKA_GGP_FITNESS_LOSS": - error = 1 - (Metrics.P_ExactMatch(result.allTrueValues(), result.allPredictions(0.5)) + (1 - Metrics.L_Hamming(result.allTrueValues(), result.allPredictions(0.5))) - + Metrics.P_FmacroAvgL(result.allTrueValues(), result.allPredictions(0.5)) + (1 - Metrics.L_RankLoss(result.allTrueValues(), result.allPredictions()))) / 4.0; - break; - case "EXACT_MATCH_ACCURARY": - error = Metrics.P_ExactMatch(result.allTrueValues(), result.allPredictions(0.5)); - break; - case "EXACT_MATCH_LOSS": - error = 1 - Metrics.P_ExactMatch(result.allTrueValues(), result.allPredictions(0.5)); - break; - case "F1_MACRO_AVG_D": - error = Metrics.P_FmacroAvgD(result.allTrueValues(), result.allPredictions(0.5)); - break; - case "F1_MACRO_AVG_D_LOSS": - error = 1 - Metrics.P_FmacroAvgD(result.allTrueValues(), result.allPredictions(0.5)); - break; - case "F1_MACRO_AVG_L": - error = Metrics.P_FmacroAvgL(result.allTrueValues(), result.allPredictions(0.5)); - break; - case "F1_MACRO_AVG_L_LOSS": - error = 1 - Metrics.P_FmacroAvgL(result.allTrueValues(), result.allPredictions(0.5)); - break; - case "HAMMING_ACCURACY": - error = Metrics.P_Hamming(result.allTrueValues(), result.allPredictions(0.5)); - break; - case "HAMMING_LOSS": - error = Metrics.L_Hamming(result.allTrueValues(), result.allPredictions(0.5)); - break; - case "JACCARD_LOSS": - error = Metrics.L_JaccardDist(result.allTrueValues(), result.allPredictions(0.5)); - break; - case "JACCARD_SCORE": - error = Metrics.P_JaccardIndex(result.allTrueValues(), result.allPredictions(0.5)); - break; - case "RANK_LOSS": - error = Metrics.L_RankLoss(result.allTrueValues(), result.allPredictions()); - break; - case "RANK_SCORE": - error = 1 - Metrics.L_RankLoss(result.allTrueValues(), result.allPredictions()); - break; - default: - throw new IllegalArgumentException("Invalid multilabel measure " + commandLine.getOptionValue(evaluationMeasureOption)); - } - - if (!"off".equals(commandLine.getOptionValue(resultsFileOption))) { - writeMultiLabelEvaluationFile(result, mlplan.getInternalValidationErrorOfSelectedClassifier(), commandLine, mlplan.getSelectedClassifier()); - } - } else { - Evaluation eval = new Evaluation(trainData); - logger.info("Assess test performance..."); - eval.evaluateModel(optimizedClassifier, testData); - - switch (commandLine.getOptionValue(evaluationMeasureOption, "ERRORRATE")) { - case "ERRORRATE": - error = eval.errorRate(); - break; - case "MEAN_SQUARED_ERROR": - error = Math.pow(eval.rootMeanSquaredError(), 2); - break; - case "ROOT_MEAN_SQUARED_ERROR": - error = eval.rootMeanSquaredError(); - break; - case "PRECISION": - error = 1 - eval.precision(Integer.parseInt(commandLine.getOptionValue(positiveClassIndex, "0"))); - break; - default: - throw new IllegalArgumentException("Invalid singlelabel measure " + commandLine.getOptionValue(evaluationMeasureOption)); - } - - if (!"off".equals(commandLine.getOptionValue(resultsFileOption))) { - writeSingleLabelEvaluationFile(eval, mlplan.getInternalValidationErrorOfSelectedClassifier(), commandLine, mlplan.getSelectedClassifier()); - } - } - - logger.info("Test error was {}. Internally estimated error for this model was {}", error, mlplan.getInternalValidationErrorOfSelectedClassifier()); - } - - logger.info("Experiment done."); - } - - private static void serializeModel(final CommandLine commandLine, final Classifier bestClassifier) throws Exception { - SerializationHelper.write(commandLine.getOptionValue(modelFileOption, modelFile), bestClassifier); - } - - private static void writeMultiLabelEvaluationFile(final Result result, final double internalError, final CommandLine commandLine, final Classifier bestModel) { - StringBuilder builder = new StringBuilder(); - builder.append("Internally believed error: "); - builder.append(internalError); - builder.append(System.lineSeparator()); - builder.append(System.lineSeparator()); - builder.append("Best Model: "); - builder.append(System.lineSeparator()); - builder.append(bestModel.toString()); - builder.append(System.lineSeparator()); - builder.append(System.lineSeparator()); - builder.append(result.toString()); - builder.append(System.lineSeparator()); - builder.append(System.lineSeparator()); - if (commandLine.hasOption(printModelOption)) { - builder.append("Classifier Representation: "); - builder.append(System.lineSeparator()); - builder.append(System.lineSeparator()); - if (bestModel instanceof MLPipeline) { - builder.append(((MLPipeline) bestModel).getBaseClassifier().toString()); - } else { - builder.append(bestModel.toString()); - } - } - - writeFile(commandLine.getOptionValue(resultsFileOption, resultsFile), builder.toString()); - } - - private static void writeSingleLabelEvaluationFile(final Evaluation eval, final double internalError, final CommandLine commandLine, final Classifier bestModel) throws Exception { - StringBuilder builder = new StringBuilder(); - builder.append("Internally believed error: "); - builder.append(internalError); - builder.append(System.lineSeparator()); - builder.append(System.lineSeparator()); - builder.append("Best Model: "); - builder.append(System.lineSeparator()); - builder.append(bestModel.toString()); - builder.append(System.lineSeparator()); - builder.append(System.lineSeparator()); - builder.append(eval.toSummaryString("Summary", true)); - builder.append(System.lineSeparator()); - builder.append(eval.toClassDetailsString("Class Details")); - builder.append(System.lineSeparator()); - builder.append("Evaluation Overview"); - builder.append(System.lineSeparator()); - builder.append(eval.toCumulativeMarginDistributionString()); - builder.append(System.lineSeparator()); - builder.append(eval.toMatrixString("Matrix")); - if (commandLine.hasOption(printModelOption)) { - builder.append("Classifier Representation: "); - builder.append(System.lineSeparator()); - builder.append(System.lineSeparator()); - if (bestModel instanceof MLPipeline) { - builder.append(((MLPipeline) bestModel).getBaseClassifier().toString()); - } else { - builder.append(bestModel.toString()); - } - } - - writeFile(commandLine.getOptionValue(resultsFileOption, resultsFile), builder.toString()); - } - - private static void writeFile(final String fileName, final String value) { - try (BufferedWriter bw = new BufferedWriter(new FileWriter(new File(fileName)))) { - bw.write(value); - } catch (IOException e) { - logger.error("Could not write value to file {}: {}", fileName, value); - } - } - - public static void main(final String[] args) throws Exception { - final Options options = generateOptions(); - if (args.length == 0) { - printUsage(options); - } else { - CommandLine commandLine = generateCommandLine(options, args); - if (commandLine != null) { - if (commandLine.hasOption(helpOption)) { - printHelp(options); - } else { - runMLPlan(commandLine); - } - } - } - } -} +package ai.libs.mlplan.cli; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ai.libs.hasco.gui.statsplugin.HASCOModelStatisticsPlugin; +import ai.libs.jaicore.basic.TimeOut; +import ai.libs.jaicore.concurrent.GlobalTimer; +import ai.libs.jaicore.graphvisualizer.plugin.graphview.GraphViewPlugin; +import ai.libs.jaicore.graphvisualizer.plugin.nodeinfo.NodeInfoGUIPlugin; +import ai.libs.jaicore.graphvisualizer.plugin.solutionperformanceplotter.SolutionPerformanceTimelinePlugin; +import ai.libs.jaicore.graphvisualizer.window.AlgorithmVisualizationWindow; +import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.AutoMEKAGGPFitnessMeasureLoss; +import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.ExactMatchLoss; +import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.F1MacroAverageLLoss; +import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.HammingLoss; +import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.InstanceWiseF1AsLoss; +import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.JaccardLoss; +import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.RankLoss; +import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.MeanSquaredErrorLoss; +import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.PrecisionAsLoss; +import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.RootMeanSquaredErrorLoss; +import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.ZeroOneLoss; +import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNodeInfoGenerator; +import ai.libs.jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; +import ai.libs.jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; +import ai.libs.mlplan.core.AbstractMLPlanBuilder; +import ai.libs.mlplan.core.AbstractMLPlanSingleLabelBuilder; +import ai.libs.mlplan.core.MLPlan; +import ai.libs.mlplan.core.MLPlanMekaBuilder; +import ai.libs.mlplan.gui.outofsampleplots.OutOfSampleErrorPlotPlugin; +import ai.libs.mlplan.multiclass.wekamlplan.weka.model.MLPipeline; +import javafx.application.Platform; +import javafx.embed.swing.JFXPanel; +import meka.classifiers.multilabel.MultiLabelClassifier; +import meka.core.MLUtils; +import meka.core.Metrics; +import meka.core.Result; +import weka.classifiers.Classifier; +import weka.classifiers.evaluation.Evaluation; +import weka.core.Instances; +import weka.core.SerializationHelper; + +/** + * Enables command-line usage of ML-Plan. + * + * @author Helena Graf + * + */ +@SuppressWarnings("restriction") +public class MLPlanCLI { + + // CLI variables + private static Logger logger = LoggerFactory.getLogger("MLPlanCLI"); + + // MLPlan options + private static String trainOption = "train"; + private static String testOption = "test"; + private static String totalTimeoutOption = "timeoutTotal"; + private static String nodeEvaluationTimeoutOption = "timeoutNodeEval"; + private static String solutionEvaluationTimeoutOption = "timeoutSolutionEval"; + private static String algorithmConfigurationOption = "algorithmConfig"; + private static String searchSpaceConfigurationOption = "searchSpaceConfig"; + private static String evaluationMeasureOption = "evaluationMeasure"; + private static String numCPUsOption = "numCPUS"; + private static String randomSeedOption = "randomSeed"; + private static String multiLabelOption = "multilabel"; + private static String positiveClassIndex = "positiveClassIndex"; + + // MLPlan options standard values + private static String totalTimeout = "150"; + private static String nodeEvaluationTimeout = "60"; + private static String solutionEvaluationTimeout = "60"; + private static String numCPUS = "4"; + private static String randomSeed = "0"; + + // Communication options + private static String modelFileOption = "modelFile"; + private static String resultsFileOption = "resultsFile"; + private static String printModelOption = "printModel"; + private static String visualizeOption = "visualize"; + private static String helpOption = "help"; + + // Communication options standard values + private static String modelFile = "model.txt"; + private static String resultsFile = "results.txt"; + + private MLPlanCLI() { + // Intentionally left blank + } + + private static Options generateOptions() { + // MLPLan options + final Option train = Option.builder("t").required(false).hasArg().longOpt(trainOption).desc("location of the .arff training data file").build(); + final Option test = Option.builder("T").required(false).longOpt(testOption).hasArg().desc("location of the .arff test data file").build(); + final Option totalTimeout = Option.builder("tt").longOpt(totalTimeoutOption).required(false).hasArg().desc("timeout for the complete run of mlplan in seconds").build(); + final Option nodeEvaluationTimeout = Option.builder("tne").longOpt(nodeEvaluationTimeoutOption).required(false).hasArg().desc("timeout for the evaluation of a single node in seconds").build(); + final Option solutionEvaluation = Option.builder("tse").longOpt(solutionEvaluationTimeoutOption).required(false).hasArg().desc("timeout for the evaluation of a solution in seconds").build(); + final Option algorithmConfiguration = Option.builder("ac").longOpt(algorithmConfigurationOption).required(false).hasArg().desc("configuration file for mlplan").build(); + final Option searchSpaceConfiguration = Option.builder("sc").longOpt(searchSpaceConfigurationOption).required(false).hasArg().desc("search space configuration file, or alternatively: weka, weka-tiny, sklearn, sklearn-ul, meka") + .build(); + final Option evaluationMeasure = Option.builder("em").longOpt(evaluationMeasureOption).required(false).hasArg().desc( + "measure for assessing solution quality, allowed values: \nsinglelabel: \nERRORRATE, MEAN_SQUARED_ERROR, PRECISION, ROOT_MEAN_SQUARED_ERROR \nmultilabel: \nAUTO_MEKA_GGP_FITNESS, AUTO_MEKA_GGP_FITNESS_LOSS, EXACT_MATCH_ACCURARY, EXACT_MATCH_LOSS, F1_MACRO_AVG_D, F1_MACRO_AVG_D_LOSS, F1_MACRO_AVG_L, F1_MACRO_AVG_L_LOSS, HAMMING_ACCURACY, HAMMING_LOSS, JACCARD_LOSS, JACCARD_SCORE, RANK_LOSS, RANK_SCORE") + .build(); + final Option positiveClass = Option.builder("pci").longOpt(positiveClassIndex).required(false).hasArg(true).desc("Index of the class (in the list of classes) which is to be considered as the positive class").build(); + final Option numCPUS = Option.builder("ncpus").longOpt(numCPUsOption).required(false).hasArg().desc("number of used CPUs, default: " + MLPlanCLI.numCPUS).build(); + final Option randomSeed = Option.builder("rs").longOpt(randomSeedOption).required(false).hasArg().desc("randomization seed, default: " + MLPlanCLI.randomSeed).build(); + final Option multiLabel = Option.builder("ml").longOpt(multiLabelOption).required(false).hasArg(false).desc("enable for multilabel settings").build(); + + // Communication options + final Option modelFile = Option.builder("mf").longOpt(modelFileOption).required(false).hasArg() + .desc("serialize model to the given output file, \"off\" if no model file shall be written; turn off for search spaces that contain non-serializable models").build(); + final Option resultsFile = Option.builder("rf").longOpt(resultsFileOption).required(false).hasArg().desc("serialize model to the given output file, \"off\" if no results file shall be written").build(); + final Option visualize = Option.builder("v").longOpt(visualizeOption).required(false).hasArg(false).desc("enable visualization").build(); + final Option printModel = Option.builder("p").longOpt(printModelOption).required(false).hasArg(false).desc("whether a visual representation of the final model shall be added to the model file").build(); + final Option help = Option.builder("h").longOpt(helpOption).required(false).hasArg(false).desc("supply help").build(); + + // Add options to Options + final Options options = new Options(); + options.addOption(train); + options.addOption(test); + options.addOption(totalTimeout); + options.addOption(nodeEvaluationTimeout); + options.addOption(solutionEvaluation); + options.addOption(algorithmConfiguration); + options.addOption(searchSpaceConfiguration); + options.addOption(evaluationMeasure); + options.addOption(numCPUS); + options.addOption(randomSeed); + options.addOption(multiLabel); + options.addOption(resultsFile); + options.addOption(modelFile); + options.addOption(visualize); + options.addOption(printModel); + options.addOption(help); + options.addOption(positiveClass); + return options; + } + + private static CommandLine generateCommandLine(final Options options, final String[] commandLineArguments) { + final CommandLineParser cmdLineParser = new DefaultParser(); + CommandLine commandLine = null; + try { + commandLine = cmdLineParser.parse(options, commandLineArguments); + } + + catch (ParseException parseException) { + logger.error("ERROR: Unable to parse command-line arguments {} due to {}", Arrays.toString(commandLineArguments), parseException); + } + + return commandLine; + } + + private static void printUsage(final Options options) { + final HelpFormatter formatter = new HelpFormatter(); + final String syntax = "mlplan"; + final PrintWriter pw = new PrintWriter(System.out); + formatter.printUsage(pw, 400, syntax, options); + pw.println("use -h or --help for help"); + pw.flush(); + } + + private static void printHelp(final Options options) { + final HelpFormatter formatter = new HelpFormatter(); + final String syntax = "mlplan [options]"; + formatter.printHelp(syntax, options); + } + + private static void runMLPlan(final CommandLine commandLine) throws Exception { + + File trainDataFile = new File(commandLine.getOptionValue(trainOption)); + logger.info("Load train data file: {}", trainDataFile.getAbsolutePath()); + + Instances trainData = new Instances(new FileReader(trainDataFile)); + if (commandLine.hasOption(multiLabelOption)) { + MLUtils.prepareData(trainData); + } else { + trainData.setClassIndex(trainData.numAttributes() - 1); + } + + AbstractMLPlanBuilder builder; + if (commandLine.hasOption(searchSpaceConfigurationOption)) { + switch (commandLine.getOptionValue(searchSpaceConfigurationOption)) { + case "weka": + builder = AbstractMLPlanBuilder.forWeka(); + break; + case "weka-tiny": + builder = AbstractMLPlanBuilder.forWeka().withTinyWekaSearchSpace(); + break; + case "sklearn": + builder = AbstractMLPlanBuilder.forSKLearn(); + break; + case "sklearn-ul": + builder = AbstractMLPlanBuilder.forSKLearn().withUnlimitedLengthPipelineSearchSpace(); + break; + case "meka": + builder = AbstractMLPlanBuilder.forMeka(); + break; + default: + throw new IllegalArgumentException("Could not identify search space configuration"); + } + } else { + builder = AbstractMLPlanBuilder.forWeka(); + } + + if (commandLine.hasOption(multiLabelOption)) { + MLPlanMekaBuilder mekaBuilder = (MLPlanMekaBuilder) builder; + switch (commandLine.getOptionValue(evaluationMeasureOption)) { + case "AUTO_MEKA_GGP_FITNESS": + mekaBuilder.withPerformanceMeasure(new AutoMEKAGGPFitnessMeasureLoss()); + break; + case "EXACT_MATCH": + mekaBuilder.withPerformanceMeasure(new ExactMatchLoss()); + break; + case "F1_MACRO_AVG_D": + mekaBuilder.withPerformanceMeasure(new InstanceWiseF1AsLoss()); + break; + case "F1_MACRO_AVG_L": + mekaBuilder.withPerformanceMeasure(new F1MacroAverageLLoss()); + break; + case "HAMMING": + mekaBuilder.withPerformanceMeasure(new HammingLoss()); + break; + case "JACCARD": + mekaBuilder.withPerformanceMeasure(new JaccardLoss()); + break; + case "RANK_LOSS": + mekaBuilder.withPerformanceMeasure(new RankLoss()); + break; + default: + throw new IllegalArgumentException("Invalid multilabel measure " + commandLine.getOptionValue(evaluationMeasureOption)); + } + } else { + AbstractMLPlanSingleLabelBuilder slcBuilder = (AbstractMLPlanSingleLabelBuilder) builder; + + switch (commandLine.getOptionValue(evaluationMeasureOption)) { + case "ERRORRATE": + slcBuilder.withPerformanceMeasure(new ZeroOneLoss()); + break; + case "MEAN_SQUARED_ERROR": + slcBuilder.withPerformanceMeasure(new MeanSquaredErrorLoss()); + break; + case "PRECISION": + int classIndex = Integer.parseInt(commandLine.getOptionValue(positiveClassIndex, "0")); + slcBuilder.withPerformanceMeasure(new PrecisionAsLoss(classIndex)); + break; + case "ROOT_MEAN_SQUARED_ERROR": + slcBuilder.withPerformanceMeasure(new RootMeanSquaredErrorLoss()); + break; + default: + throw new IllegalArgumentException("Invalid singlelabel measure " + commandLine.getOptionValue(evaluationMeasureOption)); + } + } + + if (commandLine.hasOption(algorithmConfigurationOption)) { + File algoConfigFile = new File(commandLine.getOptionValue(algorithmConfigurationOption)); + builder.withAlgorithmConfigFile(algoConfigFile); + } + builder.withNodeEvaluationTimeOut(new TimeOut(Integer.parseInt(commandLine.getOptionValue(nodeEvaluationTimeoutOption, nodeEvaluationTimeout)), TimeUnit.SECONDS)); + builder.withCandidateEvaluationTimeOut(new TimeOut(Integer.parseInt(commandLine.getOptionValue(solutionEvaluationTimeoutOption, solutionEvaluationTimeout)), TimeUnit.SECONDS)); + builder.withTimeOut(new TimeOut(Integer.parseInt(commandLine.getOptionValue(totalTimeoutOption, totalTimeout)), TimeUnit.SECONDS)); + builder.withNumCpus(Integer.parseInt(commandLine.getOptionValue(numCPUsOption, numCPUS))); + + MLPlan mlplan = builder.build(trainData); + mlplan.setLoggerName("mlplan"); + mlplan.setRandomSeed(Integer.parseInt(commandLine.getOptionValue(randomSeedOption, randomSeed))); + + Instances testData = null; + if (commandLine.hasOption(testOption)) { + File testDataFile = new File(commandLine.getOptionValue(testOption)); + logger.info("Load test data file: {}", testDataFile.getAbsolutePath()); + testData = new Instances(new FileReader(testDataFile)); + if (commandLine.hasOption(multiLabelOption)) { + MLUtils.prepareData(testData); + } else { + testData.setClassIndex(testData.numAttributes() - 1); + } + } + + if (commandLine.hasOption(visualizeOption)) { + new JFXPanel(); + AlgorithmVisualizationWindow window; + if (commandLine.hasOption(testOption)) { + window = new AlgorithmVisualizationWindow(mlplan, new GraphViewPlugin(), new NodeInfoGUIPlugin<>(new JaicoreNodeInfoGenerator<>(new TFDNodeInfoGenerator())), new SearchRolloutHistogramPlugin<>(), + new SolutionPerformanceTimelinePlugin(), new HASCOModelStatisticsPlugin(), new OutOfSampleErrorPlotPlugin(trainData, testData)); + } else { + window = new AlgorithmVisualizationWindow(mlplan, new GraphViewPlugin(), new NodeInfoGUIPlugin<>(new JaicoreNodeInfoGenerator<>(new TFDNodeInfoGenerator())), new SearchRolloutHistogramPlugin<>(), + new SolutionPerformanceTimelinePlugin(), new HASCOModelStatisticsPlugin()); + } + Platform.runLater(window); + } + + logger.info("Build mlplan classifier"); + Classifier optimizedClassifier = mlplan.call(); + + logger.info("Open timeout tasks: {}", GlobalTimer.getInstance().getActiveTasks()); + + if (!"off".equals(commandLine.getOptionValue(modelFileOption))) { + serializeModel(commandLine, mlplan.getSelectedClassifier()); + } + + if (commandLine.hasOption(testOption)) { + double error = -1; + + if (commandLine.hasOption(multiLabelOption)) { + logger.info("Assess test performance..."); + Result result = meka.classifiers.multilabel.Evaluation.evaluateModel((MultiLabelClassifier) mlplan.getSelectedClassifier(), trainData, testData); + + switch (commandLine.getOptionValue(evaluationMeasureOption, "AUTO_MEKA_GGP_FITNESS_LOSS")) { + case "AUTO_MEKA_GGP_FITNESS": + error = (Metrics.P_ExactMatch(result.allTrueValues(), result.allPredictions(0.5)) + (1 - Metrics.L_Hamming(result.allTrueValues(), result.allPredictions(0.5))) + + Metrics.P_FmacroAvgL(result.allTrueValues(), result.allPredictions(0.5)) + (1 - Metrics.L_RankLoss(result.allTrueValues(), result.allPredictions()))) / 4.0; + break; + case "AUTO_MEKA_GGP_FITNESS_LOSS": + error = 1 - (Metrics.P_ExactMatch(result.allTrueValues(), result.allPredictions(0.5)) + (1 - Metrics.L_Hamming(result.allTrueValues(), result.allPredictions(0.5))) + + Metrics.P_FmacroAvgL(result.allTrueValues(), result.allPredictions(0.5)) + (1 - Metrics.L_RankLoss(result.allTrueValues(), result.allPredictions()))) / 4.0; + break; + case "EXACT_MATCH_ACCURARY": + error = Metrics.P_ExactMatch(result.allTrueValues(), result.allPredictions(0.5)); + break; + case "EXACT_MATCH_LOSS": + error = 1 - Metrics.P_ExactMatch(result.allTrueValues(), result.allPredictions(0.5)); + break; + case "F1_MACRO_AVG_D": + error = Metrics.P_FmacroAvgD(result.allTrueValues(), result.allPredictions(0.5)); + break; + case "F1_MACRO_AVG_D_LOSS": + error = 1 - Metrics.P_FmacroAvgD(result.allTrueValues(), result.allPredictions(0.5)); + break; + case "F1_MACRO_AVG_L": + error = Metrics.P_FmacroAvgL(result.allTrueValues(), result.allPredictions(0.5)); + break; + case "F1_MACRO_AVG_L_LOSS": + error = 1 - Metrics.P_FmacroAvgL(result.allTrueValues(), result.allPredictions(0.5)); + break; + case "HAMMING_ACCURACY": + error = Metrics.P_Hamming(result.allTrueValues(), result.allPredictions(0.5)); + break; + case "HAMMING_LOSS": + error = Metrics.L_Hamming(result.allTrueValues(), result.allPredictions(0.5)); + break; + case "JACCARD_LOSS": + error = Metrics.L_JaccardDist(result.allTrueValues(), result.allPredictions(0.5)); + break; + case "JACCARD_SCORE": + error = Metrics.P_JaccardIndex(result.allTrueValues(), result.allPredictions(0.5)); + break; + case "RANK_LOSS": + error = Metrics.L_RankLoss(result.allTrueValues(), result.allPredictions()); + break; + case "RANK_SCORE": + error = 1 - Metrics.L_RankLoss(result.allTrueValues(), result.allPredictions()); + break; + default: + throw new IllegalArgumentException("Invalid multilabel measure " + commandLine.getOptionValue(evaluationMeasureOption)); + } + + if (!"off".equals(commandLine.getOptionValue(resultsFileOption))) { + writeMultiLabelEvaluationFile(result, mlplan.getInternalValidationErrorOfSelectedClassifier(), commandLine, mlplan.getSelectedClassifier()); + } + } else { + Evaluation eval = new Evaluation(trainData); + logger.info("Assess test performance..."); + eval.evaluateModel(optimizedClassifier, testData); + + switch (commandLine.getOptionValue(evaluationMeasureOption, "ERRORRATE")) { + case "ERRORRATE": + error = eval.errorRate(); + break; + case "MEAN_SQUARED_ERROR": + error = Math.pow(eval.rootMeanSquaredError(), 2); + break; + case "ROOT_MEAN_SQUARED_ERROR": + error = eval.rootMeanSquaredError(); + break; + case "PRECISION": + error = 1 - eval.precision(Integer.parseInt(commandLine.getOptionValue(positiveClassIndex, "0"))); + break; + default: + throw new IllegalArgumentException("Invalid singlelabel measure " + commandLine.getOptionValue(evaluationMeasureOption)); + } + + if (!"off".equals(commandLine.getOptionValue(resultsFileOption))) { + writeSingleLabelEvaluationFile(eval, mlplan.getInternalValidationErrorOfSelectedClassifier(), commandLine, mlplan.getSelectedClassifier()); + } + } + + logger.info("Test error was {}. Internally estimated error for this model was {}", error, mlplan.getInternalValidationErrorOfSelectedClassifier()); + } + + logger.info("Experiment done."); + } + + private static void serializeModel(final CommandLine commandLine, final Classifier bestClassifier) throws Exception { + SerializationHelper.write(commandLine.getOptionValue(modelFileOption, modelFile), bestClassifier); + } + + private static void writeMultiLabelEvaluationFile(final Result result, final double internalError, final CommandLine commandLine, final Classifier bestModel) { + StringBuilder builder = new StringBuilder(); + builder.append("Internally believed error: "); + builder.append(internalError); + builder.append(System.lineSeparator()); + builder.append(System.lineSeparator()); + builder.append("Best Model: "); + builder.append(System.lineSeparator()); + builder.append(bestModel.toString()); + builder.append(System.lineSeparator()); + builder.append(System.lineSeparator()); + builder.append(result.toString()); + builder.append(System.lineSeparator()); + builder.append(System.lineSeparator()); + if (commandLine.hasOption(printModelOption)) { + builder.append("Classifier Representation: "); + builder.append(System.lineSeparator()); + builder.append(System.lineSeparator()); + if (bestModel instanceof MLPipeline) { + builder.append(((MLPipeline) bestModel).getBaseClassifier().toString()); + } else { + builder.append(bestModel.toString()); + } + } + + writeFile(commandLine.getOptionValue(resultsFileOption, resultsFile), builder.toString()); + } + + private static void writeSingleLabelEvaluationFile(final Evaluation eval, final double internalError, final CommandLine commandLine, final Classifier bestModel) throws Exception { + StringBuilder builder = new StringBuilder(); + builder.append("Internally believed error: "); + builder.append(internalError); + builder.append(System.lineSeparator()); + builder.append(System.lineSeparator()); + builder.append("Best Model: "); + builder.append(System.lineSeparator()); + builder.append(bestModel.toString()); + builder.append(System.lineSeparator()); + builder.append(System.lineSeparator()); + builder.append(eval.toSummaryString("Summary", true)); + builder.append(System.lineSeparator()); + builder.append(eval.toClassDetailsString("Class Details")); + builder.append(System.lineSeparator()); + builder.append("Evaluation Overview"); + builder.append(System.lineSeparator()); + builder.append(eval.toCumulativeMarginDistributionString()); + builder.append(System.lineSeparator()); + builder.append(eval.toMatrixString("Matrix")); + if (commandLine.hasOption(printModelOption)) { + builder.append("Classifier Representation: "); + builder.append(System.lineSeparator()); + builder.append(System.lineSeparator()); + if (bestModel instanceof MLPipeline) { + builder.append(((MLPipeline) bestModel).getBaseClassifier().toString()); + } else { + builder.append(bestModel.toString()); + } + } + + writeFile(commandLine.getOptionValue(resultsFileOption, resultsFile), builder.toString()); + } + + private static void writeFile(final String fileName, final String value) { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(new File(fileName)))) { + bw.write(value); + } catch (IOException e) { + logger.error("Could not write value to file {}: {}", fileName, value); + } + } + + public static void main(final String[] args) throws Exception { + final Options options = generateOptions(); + if (args.length == 0) { + printUsage(options); + } else { + CommandLine commandLine = generateCommandLine(options, args); + if (commandLine != null) { + if (commandLine.hasOption(helpOption)) { + printHelp(options); + } else { + runMLPlan(commandLine); + } + } + } + } +} diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/AbstractMLPlanBuilder.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/AbstractMLPlanBuilder.java index b73076f480..b616c04c5a 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/AbstractMLPlanBuilder.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/AbstractMLPlanBuilder.java @@ -1,496 +1,496 @@ -package ai.libs.mlplan.core; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.TimeUnit; -import java.util.function.Predicate; - -import org.aeonbits.owner.ConfigFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import ai.libs.hasco.core.HASCOFactory; -import ai.libs.hasco.model.Component; -import ai.libs.hasco.serialization.ComponentLoader; -import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDAndBestFirstFactory; -import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDFactory; -import ai.libs.jaicore.basic.FileUtil; -import ai.libs.jaicore.basic.ILoggingCustomizable; -import ai.libs.jaicore.basic.TimeOut; -import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.IClassifierEvaluator; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.LearningCurveExtrapolationEvaluator; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.ClassifierEvaluatorConstructionFailedException; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.IClassifierEvaluatorFactory; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.MonteCarloCrossValidationEvaluatorFactory; -import ai.libs.jaicore.ml.weka.dataset.splitter.IDatasetSplitter; -import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import ai.libs.mlpipeline_evaluation.PerformanceDBAdapter; -import ai.libs.mlplan.multiclass.MLPlanClassifierConfig; -import ai.libs.mlplan.multiclass.wekamlplan.IClassifierFactory; -import ai.libs.mlplan.multiclass.wekamlplan.weka.PreferenceBasedNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirstFactory; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.problemtransformers.GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS; -import weka.core.Instances; - -/** - * The MLPlanBuilder helps to easily configure and initialize ML-Plan with specific parameter settings. - * For convenient use, the MLPlanBuilder also offers methods for initializing ML-Plan with default - * configuration to use ML-Plan for single label classification in combination with WEKA or scikit-learn - * or for multi-label classification in combination with MEKA and consequently with WEKA (for baselearners - * of multi-label reduction strategies). - * - * @author mwever, fmohr - */ -public abstract class AbstractMLPlanBuilder implements IMLPlanBuilder, ILoggingCustomizable { - - /* Logging */ - private Logger logger = LoggerFactory.getLogger(AbstractMLPlanBuilder.class); - private String loggerName = AbstractMLPlanBuilder.class.getName(); - - private static final String RES_ALGORITHM_CONFIG = "mlplan/mlplan.properties"; - private static final String FS_ALGORITHM_CONFIG = "conf/mlplan.properties"; - - /* Default configuration values */ - private static final File DEF_ALGORITHM_CONFIG = FileUtil.getExistingFileWithHighestPriority(RES_ALGORITHM_CONFIG, FS_ALGORITHM_CONFIG); - - /* Builder (self) status variables */ - private boolean factoryPreparedWithData = false; - - /* Data for initializing ML-Plan */ - private MLPlanClassifierConfig algorithmConfig; - - @SuppressWarnings("rawtypes") - private HASCOViaFDFactory hascoFactory = new HASCOViaFDFactory, Double>(); - private Predicate priorizingPredicate = null; - private File searchSpaceFile; - private String requestedHASCOInterface; - private IClassifierFactory classifierFactory; - - private INodeEvaluator preferredNodeEvaluator = null; - private PipelineValidityCheckingNodeEvaluator pipelineValidityCheckingNodeEvaluator; - /* The splitter is used to create the split for separating search and selection data */ - private IDatasetSplitter searchSelectionDatasetSplitter; - private IClassifierEvaluatorFactory factoryForPipelineEvaluationInSearchPhase = null; - private IClassifierEvaluatorFactory factoryForPipelineEvaluationInSelectionPhase = null; - - private Collection components = new LinkedList<>(); - private String performanceMeasureName; - - /* Use caching */ - private boolean useCache; - private PerformanceDBAdapter dbAdapter = null; - - /* The problem input for ML-Plan. */ - private Instances dataset; - - protected AbstractMLPlanBuilder() { - super(); - this.withAlgorithmConfigFile(DEF_ALGORITHM_CONFIG); - this.withRandomCompletionBasedBestFirstSearch(); - } - - public static MLPlanSKLearnBuilder forSKLearn() throws IOException { - return new MLPlanSKLearnBuilder(); - } - - public static MLPlanWekaBuilder forWeka() throws IOException { - return new MLPlanWekaBuilder(); - } - - public static MLPlanMekaBuilder forMeka() throws IOException { - return new MLPlanMekaBuilder(); - } - - /** - * This ADDs a new preferred node evaluator; requires that the search will be a best-first search. - * - * It is possible to specify several preferred node evaluators, which will be ordered by the order in which they are specified. The latest given evaluator is the most preferred one. - * - * @param preferredNodeEvaluator - * @return - */ - public AbstractMLPlanBuilder withPreferredNodeEvaluator(final INodeEvaluator preferredNodeEvaluator) { - if (this.factoryPreparedWithData) { - throw new IllegalStateException("The method prepareNodeEvaluatorInFactoryWithData has already been called. No changes to the preferred node evaluator possible anymore"); - } - - /* first update the preferred node evaluator */ - if (this.preferredNodeEvaluator == null) { - this.preferredNodeEvaluator = preferredNodeEvaluator; - } else { - this.preferredNodeEvaluator = new AlternativeNodeEvaluator<>(preferredNodeEvaluator, this.preferredNodeEvaluator); - } - this.update(); - return this; - } - - @SuppressWarnings("unchecked") - public AbstractMLPlanBuilder withSearchFactory(@SuppressWarnings("rawtypes") final IOptimalPathInORGraphSearchFactory searchFactory, @SuppressWarnings("rawtypes") final AlgorithmicProblemReduction transformer) { - this.hascoFactory.setSearchFactory(searchFactory); - this.hascoFactory.setSearchProblemTransformer(transformer); - return this; - } - - @SuppressWarnings("unchecked") - public AbstractMLPlanBuilder withRandomCompletionBasedBestFirstSearch() { - this.hascoFactory.setSearchFactory(new StandardBestFirstFactory()); - this.update(); - return this; - } - - public Collection getComponents() throws IOException { - return new ComponentLoader(this.searchSpaceFile).getComponents(); - } - - /***********************************************************************************************************************************************************************************************************************/ - /***********************************************************************************************************************************************************************************************************************/ - /***********************************************************************************************************************************************************************************************************************/ - /***********************************************************************************************************************************************************************************************************************/ - - /** - * Loads the MLPlanClassifierConfig with default values and replaces all properties according to the properties defined in the given config file. - * - * @param algorithmConfigFile The file specifying the property values to replace the default configuration. - * @return The MLPlanBuilder object. - * @throws IOException An IOException is thrown if there are issues reading the config file. - */ - public AbstractMLPlanBuilder withAlgorithmConfigFile(final File algorithmConfigFile) { - return this.withAlgorithmConfig((MLPlanClassifierConfig) ConfigFactory.create(MLPlanClassifierConfig.class).loadPropertiesFromFile(algorithmConfigFile)); - } - - /** - * Loads the MLPlanClassifierConfig with default values and replaces all properties according to the properties defined in the given config file. - * - * @param config The algorithm configuration. - * @return The MLPlanBuilder object. - * @throws IOException An IOException is thrown if there are issues reading the config file. - */ - public AbstractMLPlanBuilder withAlgorithmConfig(final MLPlanClassifierConfig config) { - this.algorithmConfig = config; - this.hascoFactory.withAlgorithmConfig(this.algorithmConfig); - this.update(); - return this; - } - - /** - * Creates a preferred node evaluator that can be used to prefer components over other components. - * @param preferredComponentsFile The file containing a priority list of component names. - * @return The builder object. - * @throws IOException Thrown if a problem occurs while trying to read the file containing the priority list. - */ - public AbstractMLPlanBuilder withPreferredComponentsFile(final File preferredComponentsFile) throws IOException { - this.getAlgorithmConfig().setProperty(MLPlanClassifierConfig.PREFERRED_COMPONENTS, preferredComponentsFile.getAbsolutePath()); - List ordering; - if (!preferredComponentsFile.exists()) { - this.logger.warn("The configured file for preferred components \"{}\" does not exist. Not using any particular ordering.", preferredComponentsFile.getAbsolutePath()); - ordering = new ArrayList<>(); - } else { - ordering = FileUtil.readFileAsList(preferredComponentsFile); - } - return this.withPreferredNodeEvaluator(new PreferenceBasedNodeEvaluator(this.components, ordering)); - } - - /** - * Sets the name of the performance measure that is used. - * @param name The name of the performance measure. - */ - public void setPerformanceMeasureName(final String name) { - this.performanceMeasureName = name; - } - - /** - * Set the data for which ML-Plan is supposed to find the best pipeline. - * @param dataset The dataset for which ML-Plan is to be run. - * @return The builder object. - */ - public AbstractMLPlanBuilder withDataset(final Instances dataset) { - this.dataset = dataset; - return this; - } - - /** - * Specify the search space in which ML-Plan is required to work. - * - * @param searchSpaceConfig The file of the search space configuration. - * @return The builder object. - * @throws IOException Thrown if the given file does not exist. - */ - public AbstractMLPlanBuilder withSearchSpaceConfigFile(final File searchSpaceConfig) throws IOException { - FileUtil.requireFileExists(searchSpaceConfig); - this.searchSpaceFile = searchSpaceConfig; - this.components.clear(); - this.components.addAll(new ComponentLoader(this.searchSpaceFile).getComponents()); - return this; - } - - /** - * Set the classifier factory that translates CompositionInstance objects to classifiers that can be evaluated. - * - * @param classifierFactory The classifier factory to be used to translate CompositionInstance objects to classifiers. - * @return The builder object. - */ - public AbstractMLPlanBuilder withClassifierFactory(final IClassifierFactory classifierFactory) { - this.classifierFactory = classifierFactory; - return this; - } - - /** - * Set the dataset splitter that is used for generating the holdout data portion that is put aside during search. - * @param datasetSplitter The dataset splitter to be used. - * @return The builder obect. - */ - public AbstractMLPlanBuilder withDatasetSplitterForSearchSelectionSplit(final IDatasetSplitter datasetSplitter) { - this.searchSelectionDatasetSplitter = datasetSplitter; - return this; - } - - public AbstractMLPlanBuilder withRequestedInterface(final String requestedInterface) { - this.requestedHASCOInterface = requestedInterface; - return this; - } - - /** - * @param timeout The timeout for ML-Plan to search for the best classifier. - * @return The builder object. - */ - public AbstractMLPlanBuilder withTimeOut(final TimeOut timeout) { - this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_TIMEOUT, timeout.milliseconds() + ""); - this.update(); - return this; - } - - /** - * @return The timeout for ML-Plan to search for the best classifier. - */ - public TimeOut getTimeOut() { - return new TimeOut(this.algorithmConfig.timeout(), TimeUnit.MILLISECONDS); - } - - /** - * @param timeout The timeout for a single candidate evaluation. - * @return The builder object. - */ - public AbstractMLPlanBuilder withNodeEvaluationTimeOut(final TimeOut timeout) { - this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_RANDOM_COMPLETIONS_TIMEOUT_NODE, timeout.milliseconds() + ""); - this.update(); - return this; - } - - /** - * @return The timeout for ML-Plan to search for the best classifier. - */ - public TimeOut getNodeEvaluationTimeOut() { - return new TimeOut(this.algorithmConfig.timeoutForNodeEvaluation(), TimeUnit.MILLISECONDS); - } - - /** - * @param timeout The timeout for a single candidate evaluation. - * @return The builder object. - */ - public AbstractMLPlanBuilder withCandidateEvaluationTimeOut(final TimeOut timeout) { - this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_RANDOM_COMPLETIONS_TIMEOUT_PATH, timeout.milliseconds() + ""); - this.update(); - return this; - } - - /** - * @return The timeout for ML-Plan to search for the best classifier. - */ - public TimeOut getCandidateEvaluationTimeOut() { - return new TimeOut(this.algorithmConfig.timeoutForCandidateEvaluation(), TimeUnit.MILLISECONDS); - } - - @Override - public PipelineEvaluator getClassifierEvaluationInSearchPhase(final Instances data, final int seed, final int fullDatasetSize) throws ClassifierEvaluatorConstructionFailedException { - Objects.requireNonNull(this.factoryForPipelineEvaluationInSearchPhase, "No factory for pipeline evaluation in search phase has been set!"); - - IClassifierEvaluator evaluator = this.factoryForPipelineEvaluationInSearchPhase.getIClassifierEvaluator(data, seed); - if (evaluator instanceof LearningCurveExtrapolationEvaluator) { - ((LearningCurveExtrapolationEvaluator) evaluator).setFullDatasetSize(fullDatasetSize); - } - - return new PipelineEvaluator(this.getClassifierFactory(), evaluator, this.getAlgorithmConfig().timeoutForCandidateEvaluation()); - } - - @Override - public PipelineEvaluator getClassifierEvaluationInSelectionPhase(final Instances data, final int seed) throws ClassifierEvaluatorConstructionFailedException { - if (this.factoryForPipelineEvaluationInSelectionPhase == null) { - throw new IllegalStateException("No factory for pipeline evaluation in selection phase has been set!"); - } - return new PipelineEvaluator(this.getClassifierFactory(), this.factoryForPipelineEvaluationInSelectionPhase.getIClassifierEvaluator(data, seed), Integer.MAX_VALUE); - } - - /** - * Sets the evaluator factory for the search phase. - * @param evaluatorFactory The evaluator factory for the search phase. - * @return The builder object. - */ - public void withSearchPhaseEvaluatorFactory(final IClassifierEvaluatorFactory evaluatorFactory) { - this.factoryForPipelineEvaluationInSearchPhase = evaluatorFactory; - } - - /** - * @return The factory for the classifier evaluator of the search phase. - */ - protected IClassifierEvaluatorFactory getSearchEvaluatorFactory() { - return this.factoryForPipelineEvaluationInSearchPhase; - } - - /** - * Sets the evaluator factory for the selection phase. - * @param evaluatorFactory The evaluator factory for the selection phase. - * @return The builder object. - */ - public AbstractMLPlanBuilder withSelectionPhaseEvaluatorFactory(final MonteCarloCrossValidationEvaluatorFactory evaluatorFactory) { - this.factoryForPipelineEvaluationInSelectionPhase = evaluatorFactory; - return this; - } - - /** - * Sets the number of cpus that may be used by ML-Plan. - * @param numCpus The number of cpus to use. - * @return The builder object. - */ - public AbstractMLPlanBuilder withNumCpus(final int numCpus) { - this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_CPUS, numCpus + ""); - this.update(); - return this; - } - - /** - * @return The factory for the classifier evaluator of the selection phase. - */ - protected IClassifierEvaluatorFactory getSelectionEvaluatorFactory() { - return this.factoryForPipelineEvaluationInSelectionPhase; - } - - @Override - public String getPerformanceMeasureName() { - return this.performanceMeasureName; - } - - @Override - @SuppressWarnings("rawtypes") - public HASCOFactory getHASCOFactory() { - return this.hascoFactory; - } - - @Override - public IClassifierFactory getClassifierFactory() { - return this.classifierFactory; - } - - @Override - public String getLoggerName() { - return this.loggerName; - } - - @Override - public void setLoggerName(final String name) { - this.logger = LoggerFactory.getLogger(name); - this.loggerName = name; - } - - @Override - public String getRequestedInterface() { - return this.requestedHASCOInterface; - } - - @Override - public IDatasetSplitter getSearchSelectionDatasetSplitter() { - return this.searchSelectionDatasetSplitter; - } - - @Override - public File getSearchSpaceConfigFile() { - return this.searchSpaceFile; - } - - @Override - public MLPlanClassifierConfig getAlgorithmConfig() { - return this.algorithmConfig; - } - - @Override - public boolean getUseCache() { - return this.useCache; - } - - @Override - public PerformanceDBAdapter getDBAdapter() { - return this.dbAdapter; - } - - @Override - public void prepareNodeEvaluatorInFactoryWithData(final Instances data) { - if (!(this.hascoFactory instanceof HASCOViaFDAndBestFirstFactory)) { - return; - } - if (this.factoryPreparedWithData) { - throw new IllegalStateException("Factory has already been prepared with data. This can only be done once!"); - } - this.factoryPreparedWithData = true; - - /* nothing to do if there are no preferred node evaluators */ - if (this.pipelineValidityCheckingNodeEvaluator == null && this.preferredNodeEvaluator == null) { - return; - } - - /* now determine the real node evaluator to be used. A semantic node evaluator has highest priority */ - INodeEvaluator actualNodeEvaluator; - if (this.pipelineValidityCheckingNodeEvaluator != null) { - this.pipelineValidityCheckingNodeEvaluator.setComponents(this.components); - this.pipelineValidityCheckingNodeEvaluator.setData(data); - if (this.preferredNodeEvaluator != null) { - actualNodeEvaluator = new AlternativeNodeEvaluator<>(this.pipelineValidityCheckingNodeEvaluator, this.preferredNodeEvaluator); - } else { - actualNodeEvaluator = this.pipelineValidityCheckingNodeEvaluator; - } - } else { - actualNodeEvaluator = this.preferredNodeEvaluator; - } - - /* update the preferred node evaluator in the HascoFactory */ - this.preferredNodeEvaluator = actualNodeEvaluator; - this.update(); - } - - @SuppressWarnings("unchecked") - private void update() { - this.hascoFactory.setSearchProblemTransformer(new GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS(this.preferredNodeEvaluator, this.priorizingPredicate, - this.algorithmConfig.randomSeed(), this.algorithmConfig.numberOfRandomCompletions(), this.algorithmConfig.timeoutForCandidateEvaluation(), this.algorithmConfig.timeoutForNodeEvaluation())); - this.hascoFactory.withAlgorithmConfig(this.getAlgorithmConfig()); - } - - /** - * Builds an ML-Plan object for the given dataset as input. - * @param dataset The dataset for which an ML-Plan object is to be built. - * @return The ML-Plan object configured with this builder. - */ - public MLPlan build(final Instances dataset) { - this.dataset = dataset; - return this.build(); - } - - /** - * Builds an ML-Plan object with the dataset provided earlier to this builder. - * @return The ML-Plan object configured with this builder. - */ - public MLPlan build() { - Objects.requireNonNull(this.dataset, "A dataset needs to be provided as input to ML-Plan"); - MLPlan mlplan = new MLPlan(this, this.dataset); - mlplan.setTimeout(this.getTimeOut()); - return mlplan; - } - -} +package ai.libs.mlplan.core; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; + +import org.aeonbits.owner.ConfigFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ai.libs.hasco.core.HASCOFactory; +import ai.libs.hasco.model.Component; +import ai.libs.hasco.serialization.ComponentLoader; +import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDAndBestFirstFactory; +import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDFactory; +import ai.libs.jaicore.basic.FileUtil; +import ai.libs.jaicore.basic.ILoggingCustomizable; +import ai.libs.jaicore.basic.TimeOut; +import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.IClassifierEvaluator; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.LearningCurveExtrapolationEvaluator; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.ClassifierEvaluatorConstructionFailedException; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.IClassifierEvaluatorFactory; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.MonteCarloCrossValidationEvaluatorFactory; +import ai.libs.jaicore.ml.weka.dataset.splitter.IDatasetSplitter; +import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirstFactory; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.problemtransformers.GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS; +import ai.libs.mlpipeline_evaluation.PerformanceDBAdapter; +import ai.libs.mlplan.multiclass.MLPlanClassifierConfig; +import ai.libs.mlplan.multiclass.wekamlplan.IClassifierFactory; +import ai.libs.mlplan.multiclass.wekamlplan.weka.PreferenceBasedNodeEvaluator; +import weka.core.Instances; + +/** + * The MLPlanBuilder helps to easily configure and initialize ML-Plan with specific parameter settings. + * For convenient use, the MLPlanBuilder also offers methods for initializing ML-Plan with default + * configuration to use ML-Plan for single label classification in combination with WEKA or scikit-learn + * or for multi-label classification in combination with MEKA and consequently with WEKA (for baselearners + * of multi-label reduction strategies). + * + * @author mwever, fmohr + */ +public abstract class AbstractMLPlanBuilder implements IMLPlanBuilder, ILoggingCustomizable { + + /* Logging */ + private Logger logger = LoggerFactory.getLogger(AbstractMLPlanBuilder.class); + private String loggerName = AbstractMLPlanBuilder.class.getName(); + + private static final String RES_ALGORITHM_CONFIG = "mlplan/mlplan.properties"; + private static final String FS_ALGORITHM_CONFIG = "conf/mlplan.properties"; + + /* Default configuration values */ + private static final File DEF_ALGORITHM_CONFIG = FileUtil.getExistingFileWithHighestPriority(RES_ALGORITHM_CONFIG, FS_ALGORITHM_CONFIG); + + /* Builder (self) status variables */ + private boolean factoryPreparedWithData = false; + + /* Data for initializing ML-Plan */ + private MLPlanClassifierConfig algorithmConfig; + + @SuppressWarnings("rawtypes") + private HASCOViaFDFactory hascoFactory = new HASCOViaFDFactory, Double>(); + private Predicate priorizingPredicate = null; + private File searchSpaceFile; + private String requestedHASCOInterface; + private IClassifierFactory classifierFactory; + + private INodeEvaluator preferredNodeEvaluator = null; + private PipelineValidityCheckingNodeEvaluator pipelineValidityCheckingNodeEvaluator; + /* The splitter is used to create the split for separating search and selection data */ + private IDatasetSplitter searchSelectionDatasetSplitter; + private IClassifierEvaluatorFactory factoryForPipelineEvaluationInSearchPhase = null; + private IClassifierEvaluatorFactory factoryForPipelineEvaluationInSelectionPhase = null; + + private Collection components = new LinkedList<>(); + private String performanceMeasureName; + + /* Use caching */ + private boolean useCache; + private PerformanceDBAdapter dbAdapter = null; + + /* The problem input for ML-Plan. */ + private Instances dataset; + + protected AbstractMLPlanBuilder() { + super(); + this.withAlgorithmConfigFile(DEF_ALGORITHM_CONFIG); + this.withRandomCompletionBasedBestFirstSearch(); + } + + public static MLPlanSKLearnBuilder forSKLearn() throws IOException { + return new MLPlanSKLearnBuilder(); + } + + public static MLPlanWekaBuilder forWeka() throws IOException { + return new MLPlanWekaBuilder(); + } + + public static MLPlanMekaBuilder forMeka() throws IOException { + return new MLPlanMekaBuilder(); + } + + /** + * This ADDs a new preferred node evaluator; requires that the search will be a best-first search. + * + * It is possible to specify several preferred node evaluators, which will be ordered by the order in which they are specified. The latest given evaluator is the most preferred one. + * + * @param preferredNodeEvaluator + * @return + */ + public AbstractMLPlanBuilder withPreferredNodeEvaluator(final INodeEvaluator preferredNodeEvaluator) { + if (this.factoryPreparedWithData) { + throw new IllegalStateException("The method prepareNodeEvaluatorInFactoryWithData has already been called. No changes to the preferred node evaluator possible anymore"); + } + + /* first update the preferred node evaluator */ + if (this.preferredNodeEvaluator == null) { + this.preferredNodeEvaluator = preferredNodeEvaluator; + } else { + this.preferredNodeEvaluator = new AlternativeNodeEvaluator<>(preferredNodeEvaluator, this.preferredNodeEvaluator); + } + this.update(); + return this; + } + + @SuppressWarnings("unchecked") + public AbstractMLPlanBuilder withSearchFactory(@SuppressWarnings("rawtypes") final IOptimalPathInORGraphSearchFactory searchFactory, @SuppressWarnings("rawtypes") final AlgorithmicProblemReduction transformer) { + this.hascoFactory.setSearchFactory(searchFactory); + this.hascoFactory.setSearchProblemTransformer(transformer); + return this; + } + + @SuppressWarnings("unchecked") + public AbstractMLPlanBuilder withRandomCompletionBasedBestFirstSearch() { + this.hascoFactory.setSearchFactory(new StandardBestFirstFactory()); + this.update(); + return this; + } + + public Collection getComponents() throws IOException { + return new ComponentLoader(this.searchSpaceFile).getComponents(); + } + + /***********************************************************************************************************************************************************************************************************************/ + /***********************************************************************************************************************************************************************************************************************/ + /***********************************************************************************************************************************************************************************************************************/ + /***********************************************************************************************************************************************************************************************************************/ + + /** + * Loads the MLPlanClassifierConfig with default values and replaces all properties according to the properties defined in the given config file. + * + * @param algorithmConfigFile The file specifying the property values to replace the default configuration. + * @return The MLPlanBuilder object. + * @throws IOException An IOException is thrown if there are issues reading the config file. + */ + public AbstractMLPlanBuilder withAlgorithmConfigFile(final File algorithmConfigFile) { + return this.withAlgorithmConfig((MLPlanClassifierConfig) ConfigFactory.create(MLPlanClassifierConfig.class).loadPropertiesFromFile(algorithmConfigFile)); + } + + /** + * Loads the MLPlanClassifierConfig with default values and replaces all properties according to the properties defined in the given config file. + * + * @param config The algorithm configuration. + * @return The MLPlanBuilder object. + * @throws IOException An IOException is thrown if there are issues reading the config file. + */ + public AbstractMLPlanBuilder withAlgorithmConfig(final MLPlanClassifierConfig config) { + this.algorithmConfig = config; + this.hascoFactory.withAlgorithmConfig(this.algorithmConfig); + this.update(); + return this; + } + + /** + * Creates a preferred node evaluator that can be used to prefer components over other components. + * @param preferredComponentsFile The file containing a priority list of component names. + * @return The builder object. + * @throws IOException Thrown if a problem occurs while trying to read the file containing the priority list. + */ + public AbstractMLPlanBuilder withPreferredComponentsFile(final File preferredComponentsFile) throws IOException { + this.getAlgorithmConfig().setProperty(MLPlanClassifierConfig.PREFERRED_COMPONENTS, preferredComponentsFile.getAbsolutePath()); + List ordering; + if (!preferredComponentsFile.exists()) { + this.logger.warn("The configured file for preferred components \"{}\" does not exist. Not using any particular ordering.", preferredComponentsFile.getAbsolutePath()); + ordering = new ArrayList<>(); + } else { + ordering = FileUtil.readFileAsList(preferredComponentsFile); + } + return this.withPreferredNodeEvaluator(new PreferenceBasedNodeEvaluator(this.components, ordering)); + } + + /** + * Sets the name of the performance measure that is used. + * @param name The name of the performance measure. + */ + public void setPerformanceMeasureName(final String name) { + this.performanceMeasureName = name; + } + + /** + * Set the data for which ML-Plan is supposed to find the best pipeline. + * @param dataset The dataset for which ML-Plan is to be run. + * @return The builder object. + */ + public AbstractMLPlanBuilder withDataset(final Instances dataset) { + this.dataset = dataset; + return this; + } + + /** + * Specify the search space in which ML-Plan is required to work. + * + * @param searchSpaceConfig The file of the search space configuration. + * @return The builder object. + * @throws IOException Thrown if the given file does not exist. + */ + public AbstractMLPlanBuilder withSearchSpaceConfigFile(final File searchSpaceConfig) throws IOException { + FileUtil.requireFileExists(searchSpaceConfig); + this.searchSpaceFile = searchSpaceConfig; + this.components.clear(); + this.components.addAll(new ComponentLoader(this.searchSpaceFile).getComponents()); + return this; + } + + /** + * Set the classifier factory that translates CompositionInstance objects to classifiers that can be evaluated. + * + * @param classifierFactory The classifier factory to be used to translate CompositionInstance objects to classifiers. + * @return The builder object. + */ + public AbstractMLPlanBuilder withClassifierFactory(final IClassifierFactory classifierFactory) { + this.classifierFactory = classifierFactory; + return this; + } + + /** + * Set the dataset splitter that is used for generating the holdout data portion that is put aside during search. + * @param datasetSplitter The dataset splitter to be used. + * @return The builder obect. + */ + public AbstractMLPlanBuilder withDatasetSplitterForSearchSelectionSplit(final IDatasetSplitter datasetSplitter) { + this.searchSelectionDatasetSplitter = datasetSplitter; + return this; + } + + public AbstractMLPlanBuilder withRequestedInterface(final String requestedInterface) { + this.requestedHASCOInterface = requestedInterface; + return this; + } + + /** + * @param timeout The timeout for ML-Plan to search for the best classifier. + * @return The builder object. + */ + public AbstractMLPlanBuilder withTimeOut(final TimeOut timeout) { + this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_TIMEOUT, timeout.milliseconds() + ""); + this.update(); + return this; + } + + /** + * @return The timeout for ML-Plan to search for the best classifier. + */ + public TimeOut getTimeOut() { + return new TimeOut(this.algorithmConfig.timeout(), TimeUnit.MILLISECONDS); + } + + /** + * @param timeout The timeout for a single candidate evaluation. + * @return The builder object. + */ + public AbstractMLPlanBuilder withNodeEvaluationTimeOut(final TimeOut timeout) { + this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_RANDOM_COMPLETIONS_TIMEOUT_NODE, timeout.milliseconds() + ""); + this.update(); + return this; + } + + /** + * @return The timeout for ML-Plan to search for the best classifier. + */ + public TimeOut getNodeEvaluationTimeOut() { + return new TimeOut(this.algorithmConfig.timeoutForNodeEvaluation(), TimeUnit.MILLISECONDS); + } + + /** + * @param timeout The timeout for a single candidate evaluation. + * @return The builder object. + */ + public AbstractMLPlanBuilder withCandidateEvaluationTimeOut(final TimeOut timeout) { + this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_RANDOM_COMPLETIONS_TIMEOUT_PATH, timeout.milliseconds() + ""); + this.update(); + return this; + } + + /** + * @return The timeout for ML-Plan to search for the best classifier. + */ + public TimeOut getCandidateEvaluationTimeOut() { + return new TimeOut(this.algorithmConfig.timeoutForCandidateEvaluation(), TimeUnit.MILLISECONDS); + } + + @Override + public PipelineEvaluator getClassifierEvaluationInSearchPhase(final Instances data, final int seed, final int fullDatasetSize) throws ClassifierEvaluatorConstructionFailedException { + Objects.requireNonNull(this.factoryForPipelineEvaluationInSearchPhase, "No factory for pipeline evaluation in search phase has been set!"); + + IClassifierEvaluator evaluator = this.factoryForPipelineEvaluationInSearchPhase.getIClassifierEvaluator(data, seed); + if (evaluator instanceof LearningCurveExtrapolationEvaluator) { + ((LearningCurveExtrapolationEvaluator) evaluator).setFullDatasetSize(fullDatasetSize); + } + + return new PipelineEvaluator(this.getClassifierFactory(), evaluator, this.getAlgorithmConfig().timeoutForCandidateEvaluation()); + } + + @Override + public PipelineEvaluator getClassifierEvaluationInSelectionPhase(final Instances data, final int seed) throws ClassifierEvaluatorConstructionFailedException { + if (this.factoryForPipelineEvaluationInSelectionPhase == null) { + throw new IllegalStateException("No factory for pipeline evaluation in selection phase has been set!"); + } + return new PipelineEvaluator(this.getClassifierFactory(), this.factoryForPipelineEvaluationInSelectionPhase.getIClassifierEvaluator(data, seed), Integer.MAX_VALUE); + } + + /** + * Sets the evaluator factory for the search phase. + * @param evaluatorFactory The evaluator factory for the search phase. + * @return The builder object. + */ + public void withSearchPhaseEvaluatorFactory(final IClassifierEvaluatorFactory evaluatorFactory) { + this.factoryForPipelineEvaluationInSearchPhase = evaluatorFactory; + } + + /** + * @return The factory for the classifier evaluator of the search phase. + */ + protected IClassifierEvaluatorFactory getSearchEvaluatorFactory() { + return this.factoryForPipelineEvaluationInSearchPhase; + } + + /** + * Sets the evaluator factory for the selection phase. + * @param evaluatorFactory The evaluator factory for the selection phase. + * @return The builder object. + */ + public AbstractMLPlanBuilder withSelectionPhaseEvaluatorFactory(final MonteCarloCrossValidationEvaluatorFactory evaluatorFactory) { + this.factoryForPipelineEvaluationInSelectionPhase = evaluatorFactory; + return this; + } + + /** + * Sets the number of cpus that may be used by ML-Plan. + * @param numCpus The number of cpus to use. + * @return The builder object. + */ + public AbstractMLPlanBuilder withNumCpus(final int numCpus) { + this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_CPUS, numCpus + ""); + this.update(); + return this; + } + + /** + * @return The factory for the classifier evaluator of the selection phase. + */ + protected IClassifierEvaluatorFactory getSelectionEvaluatorFactory() { + return this.factoryForPipelineEvaluationInSelectionPhase; + } + + @Override + public String getPerformanceMeasureName() { + return this.performanceMeasureName; + } + + @Override + @SuppressWarnings("rawtypes") + public HASCOFactory getHASCOFactory() { + return this.hascoFactory; + } + + @Override + public IClassifierFactory getClassifierFactory() { + return this.classifierFactory; + } + + @Override + public String getLoggerName() { + return this.loggerName; + } + + @Override + public void setLoggerName(final String name) { + this.logger = LoggerFactory.getLogger(name); + this.loggerName = name; + } + + @Override + public String getRequestedInterface() { + return this.requestedHASCOInterface; + } + + @Override + public IDatasetSplitter getSearchSelectionDatasetSplitter() { + return this.searchSelectionDatasetSplitter; + } + + @Override + public File getSearchSpaceConfigFile() { + return this.searchSpaceFile; + } + + @Override + public MLPlanClassifierConfig getAlgorithmConfig() { + return this.algorithmConfig; + } + + @Override + public boolean getUseCache() { + return this.useCache; + } + + @Override + public PerformanceDBAdapter getDBAdapter() { + return this.dbAdapter; + } + + @Override + public void prepareNodeEvaluatorInFactoryWithData(final Instances data) { + if (!(this.hascoFactory instanceof HASCOViaFDAndBestFirstFactory)) { + return; + } + if (this.factoryPreparedWithData) { + throw new IllegalStateException("Factory has already been prepared with data. This can only be done once!"); + } + this.factoryPreparedWithData = true; + + /* nothing to do if there are no preferred node evaluators */ + if (this.pipelineValidityCheckingNodeEvaluator == null && this.preferredNodeEvaluator == null) { + return; + } + + /* now determine the real node evaluator to be used. A semantic node evaluator has highest priority */ + INodeEvaluator actualNodeEvaluator; + if (this.pipelineValidityCheckingNodeEvaluator != null) { + this.pipelineValidityCheckingNodeEvaluator.setComponents(this.components); + this.pipelineValidityCheckingNodeEvaluator.setData(data); + if (this.preferredNodeEvaluator != null) { + actualNodeEvaluator = new AlternativeNodeEvaluator<>(this.pipelineValidityCheckingNodeEvaluator, this.preferredNodeEvaluator); + } else { + actualNodeEvaluator = this.pipelineValidityCheckingNodeEvaluator; + } + } else { + actualNodeEvaluator = this.preferredNodeEvaluator; + } + + /* update the preferred node evaluator in the HascoFactory */ + this.preferredNodeEvaluator = actualNodeEvaluator; + this.update(); + } + + @SuppressWarnings("unchecked") + private void update() { + this.hascoFactory.setSearchProblemTransformer(new GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS(this.preferredNodeEvaluator, this.priorizingPredicate, + this.algorithmConfig.randomSeed(), this.algorithmConfig.numberOfRandomCompletions(), this.algorithmConfig.timeoutForCandidateEvaluation(), this.algorithmConfig.timeoutForNodeEvaluation())); + this.hascoFactory.withAlgorithmConfig(this.getAlgorithmConfig()); + } + + /** + * Builds an ML-Plan object for the given dataset as input. + * @param dataset The dataset for which an ML-Plan object is to be built. + * @return The ML-Plan object configured with this builder. + */ + public MLPlan build(final Instances dataset) { + this.dataset = dataset; + return this.build(); + } + + /** + * Builds an ML-Plan object with the dataset provided earlier to this builder. + * @return The ML-Plan object configured with this builder. + */ + public MLPlan build() { + Objects.requireNonNull(this.dataset, "A dataset needs to be provided as input to ML-Plan"); + MLPlan mlplan = new MLPlan(this, this.dataset); + mlplan.setTimeout(this.getTimeOut()); + return mlplan; + } + +} diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/IMLPlanBuilder.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/IMLPlanBuilder.java index 0770e72623..c82623621c 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/IMLPlanBuilder.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/IMLPlanBuilder.java @@ -6,10 +6,10 @@ import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.ClassifierEvaluatorConstructionFailedException; import ai.libs.jaicore.ml.weka.dataset.splitter.IDatasetSplitter; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; import ai.libs.mlpipeline_evaluation.PerformanceDBAdapter; import ai.libs.mlplan.multiclass.MLPlanClassifierConfig; import ai.libs.mlplan.multiclass.wekamlplan.IClassifierFactory; -import jaicore.search.probleminputs.GraphSearchInput; import weka.core.Instances; /** diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlan.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlan.java index d528be39d6..ec747631c0 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlan.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlan.java @@ -1,331 +1,331 @@ -package ai.libs.mlplan.core; - -import java.io.IOException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.eventbus.Subscribe; - -import ai.libs.hasco.core.HASCOFactory; -import ai.libs.hasco.core.HASCOSolutionCandidate; -import ai.libs.hasco.events.HASCOSolutionEvent; -import ai.libs.hasco.exceptions.ComponentInstantiationFailedException; -import ai.libs.hasco.model.ComponentInstance; -import ai.libs.hasco.optimizingfactory.OptimizingFactory; -import ai.libs.hasco.optimizingfactory.OptimizingFactoryProblem; -import ai.libs.hasco.variants.forwarddecomposition.twophase.TwoPhaseHASCO; -import ai.libs.hasco.variants.forwarddecomposition.twophase.TwoPhaseHASCOFactory; -import ai.libs.hasco.variants.forwarddecomposition.twophase.TwoPhaseSoftwareConfigurationProblem; -import ai.libs.jaicore.basic.ILoggingCustomizable; -import ai.libs.jaicore.basic.MathExt; -import ai.libs.jaicore.basic.algorithm.AAlgorithm; -import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; -import ai.libs.jaicore.basic.algorithm.events.AlgorithmEvent; -import ai.libs.jaicore.basic.algorithm.events.AlgorithmFinishedEvent; -import ai.libs.jaicore.basic.algorithm.events.AlgorithmInitializedEvent; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; -import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.events.MCCVSplitEvaluationEvent; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.ClassifierEvaluatorConstructionFailedException; -import ai.libs.jaicore.ml.learningcurve.extrapolation.LearningCurveExtrapolatedEvent; -import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import ai.libs.mlplan.core.events.ClassifierCreatedEvent; -import ai.libs.mlplan.core.events.ClassifierFoundEvent; -import ai.libs.mlplan.multiclass.MLPlanClassifierConfig; -import jaicore.search.core.interfaces.GraphGenerator; -import jaicore.search.probleminputs.GraphSearchInput; -import weka.classifiers.Classifier; -import weka.core.Instances; - -public class MLPlan extends AAlgorithm implements ILoggingCustomizable { - - /** Logger for controlled output. */ - private Logger logger = LoggerFactory.getLogger(MLPlan.class); - private String loggerName; - - private Classifier selectedClassifier; - private double internalValidationErrorOfSelectedClassifier; - private ComponentInstance componentInstanceOfSelectedClassifier; - - private final IMLPlanBuilder builder; - private final Instances data; - private TwoPhaseHASCOFactory, TFDNode, String> twoPhaseHASCOFactory; - private OptimizingFactory, Double> optimizingFactory; - - private boolean buildSelectedClasifierOnGivenData = true; - - public MLPlan(final IMLPlanBuilder builder, final Instances data) { - super(builder.getAlgorithmConfig(), data); - builder.prepareNodeEvaluatorInFactoryWithData(data); - /* sanity checks */ - if (builder.getSearchSpaceConfigFile() == null || !builder.getSearchSpaceConfigFile().exists()) { - throw new IllegalArgumentException("The search space configuration file must be set in MLPlanBuilder, and it must be set to a file that exists!"); - } - if (builder.getClassifierFactory() == null) { - throw new IllegalArgumentException("ClassifierFactory must be set in MLPlanBuilder!"); - } - /* store builder and data for main algorithm */ - this.builder = builder; - this.data = data; - } - - @Override - public AlgorithmEvent nextWithException() throws AlgorithmException, InterruptedException, AlgorithmExecutionCanceledException, AlgorithmTimeoutedException { - switch (this.getState()) { - case created: - this.logger.info("Starting an ML-Plan instance."); - AlgorithmInitializedEvent event = this.activate(); - - /* check number of CPUs assigned */ - if (this.getConfig().cpus() < 1) { - throw new IllegalStateException("Cannot generate search where number of CPUs is " + this.getConfig().cpus()); - } - - /* set up exact splits */ - final double dataPortionUsedForSelection = this.getConfig().dataPortionForSelection(); - this.logger.debug("Splitting given {} data points into search data ({}%) and selection data ({}%).", this.data.size(), MathExt.round((1 - dataPortionUsedForSelection) * 100, 2), MathExt.round(dataPortionUsedForSelection, 2)); - Instances dataShownToSearch; - if (dataPortionUsedForSelection > 0) { - dataShownToSearch = this.builder.getSearchSelectionDatasetSplitter().split(this.getInput(), this.getConfig().randomSeed(), dataPortionUsedForSelection).get(1); - } else { - dataShownToSearch = this.getInput(); - } - if (dataShownToSearch.isEmpty()) { - throw new IllegalStateException("Cannot search on no data."); - } - - /* dynamically compute blow-ups */ - if (Double.isNaN(this.getConfig().expectedBlowupInSelection())) { - double blowUpInSelectionPhase = 1; - this.getConfig().setProperty(MLPlanClassifierConfig.K_BLOWUP_SELECTION, String.valueOf(blowUpInSelectionPhase)); - this.logger.info("No expected blow-up for selection phase has been defined. Automatically configuring {}", blowUpInSelectionPhase); - } - if (!this.buildSelectedClasifierOnGivenData) { - this.getConfig().setProperty(MLPlanClassifierConfig.K_BLOWUP_POSTPROCESS, String.valueOf(0)); - this.logger.info("Selected classifier won't be built, so now blow-up is calculated."); - } - else if (Double.isNaN(this.getConfig().expectedBlowupInPostprocessing())) { - double blowUpInPostprocessing = 1; - this.getConfig().setProperty(MLPlanClassifierConfig.K_BLOWUP_POSTPROCESS, String.valueOf(blowUpInPostprocessing)); - this.logger.info("No expected blow-up for postprocessing phase has been defined. Automatically configuring {}", blowUpInPostprocessing); - } - - /* setup the pipeline evaluators */ - this.logger.debug("Setting up the pipeline evaluators."); - PipelineEvaluator classifierEvaluatorForSearch; - PipelineEvaluator classifierEvaluatorForSelection; - try { - classifierEvaluatorForSearch = this.builder.getClassifierEvaluationInSearchPhase(dataShownToSearch, this.getConfig().randomSeed(), MLPlan.this.getInput().size()); - classifierEvaluatorForSelection = this.builder.getClassifierEvaluationInSelectionPhase(dataShownToSearch, this.getConfig().randomSeed()); - } catch (ClassifierEvaluatorConstructionFailedException e2) { - throw new AlgorithmException(e2, "Could not create the pipeline evaluator"); - } - classifierEvaluatorForSearch.registerListener(this); // events will be forwarded - classifierEvaluatorForSelection.registerListener(this); // events will be forwarded - - /* communicate the parameters with which ML-Plan will run */ - if (this.logger.isInfoEnabled()) { - this.logger.info( - "Starting ML-Plan with the following setup:\n\tDataset: {}\n\tTarget: {}\n\tCPUs: {}\n\tTimeout: {}s\n\tTimeout for single candidate evaluation: {}s\n\tTimeout for node evaluation: {}s\n\tRandom Completions per node evaluation: {}\n\tPortion of data for selection phase: {}%\n\tPipeline evaluation during search: {}\n\tPipeline evaluation during selection: {}\n\tBlow-ups are {} for selection phase and {} for post-processing phase.", - this.getInput().hashCode(), this.builder.getPerformanceMeasureName(), this.getConfig().cpus(), this.getTimeout().seconds(), this.getConfig().timeoutForCandidateEvaluation() / 1000, - this.getConfig().timeoutForNodeEvaluation() / 1000, this.getConfig().numberOfRandomCompletions(), MathExt.round(this.getConfig().dataPortionForSelection() * 100, 2), classifierEvaluatorForSearch, - classifierEvaluatorForSelection, this.getConfig().expectedBlowupInSelection(), this.getConfig().expectedBlowupInPostprocessing()); - } - - /* create 2-phase software configuration problem */ - this.logger.debug("Creating 2-phase software configuration problem."); - TwoPhaseSoftwareConfigurationProblem problem = null; - try { - problem = new TwoPhaseSoftwareConfigurationProblem(this.builder.getSearchSpaceConfigFile(), this.builder.getRequestedInterface(), classifierEvaluatorForSearch, classifierEvaluatorForSelection); - } catch (IOException e1) { - throw new AlgorithmException(e1, "Could not activate ML-Plan!"); - } - - /* create 2-phase HASCO */ - this.logger.info("Creating the twoPhaseHASCOFactory."); - OptimizingFactoryProblem optimizingFactoryProblem = new OptimizingFactoryProblem<>(this.builder.getClassifierFactory(), problem); - HASCOFactory, TFDNode, String, Double> hascoFactory = this.builder.getHASCOFactory(); - this.twoPhaseHASCOFactory = new TwoPhaseHASCOFactory<>(hascoFactory); - - this.twoPhaseHASCOFactory.setConfig(this.getConfig()); - this.optimizingFactory = new OptimizingFactory<>(optimizingFactoryProblem, this.twoPhaseHASCOFactory); - this.logger.info("Setting logger of {} to {}.optimizingfactory", this.optimizingFactory.getClass().getName(), this.loggerName); - this.optimizingFactory.setLoggerName(this.loggerName + ".optimizingfactory"); - this.optimizingFactory.registerListener(new Object() { - @Subscribe - public void receiveEventFromFactory(final AlgorithmEvent event) { - if (event instanceof AlgorithmInitializedEvent || event instanceof AlgorithmFinishedEvent) { - return; - } - if (event instanceof HASCOSolutionEvent) { - @SuppressWarnings("unchecked") - HASCOSolutionCandidate solution = ((HASCOSolutionEvent) event).getSolutionCandidate(); - try { - MLPlan.this.logger.info("Received new solution {} with score {} and evaluation time {}ms", MLPlan.this.builder.getClassifierFactory().getComponentInstantiation(solution.getComponentInstance()), - solution.getScore(), solution.getTimeToEvaluateCandidate()); - } catch (Exception e) { - MLPlan.this.logger.warn("Could not print log due to exception while preparing the log message.", e); - } - - if (dataPortionUsedForSelection == 0.0 && solution.getScore() < MLPlan.this.internalValidationErrorOfSelectedClassifier) { - try { - MLPlan.this.selectedClassifier = MLPlan.this.builder.getClassifierFactory().getComponentInstantiation(solution.getComponentInstance()); - MLPlan.this.internalValidationErrorOfSelectedClassifier = solution.getScore(); - MLPlan.this.componentInstanceOfSelectedClassifier = solution.getComponentInstance(); - } catch (ComponentInstantiationFailedException e) { - MLPlan.this.logger.error("Could not update selectedClassifier with newly best seen solution due to issues building the classifier from its ComponentInstance description.", e); - } - } - - try { - MLPlan.this.post( - new ClassifierFoundEvent(MLPlan.this.getId(), solution.getComponentInstance(), MLPlan.this.builder.getClassifierFactory().getComponentInstantiation(solution.getComponentInstance()), solution.getScore())); - } catch (ComponentInstantiationFailedException e) { - MLPlan.this.logger.error("An issue occurred while preparing the description for the post of a ClassifierFoundEvent", e); - } - } else { - MLPlan.this.post(event); - } - } - }); - - this.logger.info("Initializing the optimization factory."); - this.optimizingFactory.init(); - this.logger.info("Started and activated ML-Plan."); - return event; - - case active: - - /* train the classifier returned by the optimizing factory */ - long startOptimizationTime = System.currentTimeMillis(); - try { - this.selectedClassifier = this.optimizingFactory.call(); - this.logger.info("2-Phase-HASCO has chosen classifier {}, which will now be built on the entire data given, i.e. {} data points.", this.selectedClassifier, this.getInput().size()); - } catch (AlgorithmException | InterruptedException | AlgorithmExecutionCanceledException | AlgorithmTimeoutedException e) { - this.terminate(); // send the termination event - throw e; - } - this.internalValidationErrorOfSelectedClassifier = this.optimizingFactory.getPerformanceOfObject(); - this.componentInstanceOfSelectedClassifier = this.optimizingFactory.getComponentInstanceOfObject(); - if (this.buildSelectedClasifierOnGivenData) { - long startBuildTime = System.currentTimeMillis(); - try { - this.selectedClassifier.buildClassifier(this.getInput()); - } catch (Exception e) { - throw new AlgorithmException(e, "Training the classifier failed!"); - } - long endBuildTime = System.currentTimeMillis(); - this.logger.info("Selected model has been built on entire dataset. Build time of chosen model was {}ms. Total construction time was {}ms. The chosen classifier is: {}", endBuildTime - startBuildTime, - endBuildTime - startOptimizationTime, this.selectedClassifier); - } else { - this.logger.info("Selected model has not been built, since model building has been disabled. Total construction time was {}ms.", System.currentTimeMillis() - startOptimizationTime); - } - return this.terminate(); - - default: - throw new IllegalStateException("Cannot do anything in state " + this.getState()); - } - - } - - @Override - public Classifier call() throws AlgorithmException, InterruptedException, AlgorithmExecutionCanceledException, AlgorithmTimeoutedException { - while (this.hasNext()) { - this.nextWithException(); - } - return this.selectedClassifier; - } - - @Override - public void setLoggerName(final String name) { - this.loggerName = name; - this.logger.info("Switching logger name to {}", name); - this.logger = LoggerFactory.getLogger(name); - this.logger.info("Activated ML-Plan logger {}. Now setting logger of twoPhaseHASCO to {}.2phasehasco", name, name); - if (this.optimizingFactory != null) { - this.logger.info("Setting logger of {} to {}.optimizingfactory", this.optimizingFactory.getClass().getName(), this.loggerName); - this.optimizingFactory.setLoggerName(this.loggerName + ".optimizingfactory"); - } else { - this.logger.debug("Optimizingfactory has not been set yet, so not customizing its logger."); - } - - this.logger.info("Switched ML-Plan logger to {}", name); - } - - public void setPortionOfDataForPhase2(final float portion) { - this.getConfig().setProperty(MLPlanClassifierConfig.SELECTION_PORTION, String.valueOf(portion)); - } - - @Override - public String getLoggerName() { - return this.loggerName; - } - - @Override - public MLPlanClassifierConfig getConfig() { - return (MLPlanClassifierConfig) super.getConfig(); - } - - public void setRandomSeed(final int seed) { - this.getConfig().setProperty(MLPlanClassifierConfig.K_RANDOM_SEED, String.valueOf(seed)); - } - - public Classifier getSelectedClassifier() { - return this.selectedClassifier; - } - - public ComponentInstance getComponentInstanceOfSelectedClassifier() { - return this.componentInstanceOfSelectedClassifier; - } - - @SuppressWarnings("unchecked") - public GraphGenerator getGraphGenerator() { - return ((TwoPhaseHASCO, TFDNode, String>) this.optimizingFactory.getOptimizer()).getGraphGenerator(); - } - - public double getInternalValidationErrorOfSelectedClassifier() { - return this.internalValidationErrorOfSelectedClassifier; - } - - @Override - public synchronized void cancel() { - this.logger.info("Received cancel. First canceling optimizer, then invoking general shutdown."); - this.optimizingFactory.cancel(); - this.logger.debug("Now canceling main ML-Plan routine"); - super.cancel(); - assert this.isCanceled() : "Canceled-flag is not positive at the end of the cancel routine!"; - this.logger.info("Completed cancellation of ML-Plan. Cancel status is {}", this.isCanceled()); - } - - public OptimizingFactory, Double> getOptimizingFactory() { - return this.optimizingFactory; - } - - @Subscribe - public void receiveClassifierCreatedEvent(final ClassifierCreatedEvent e) { - this.post(e); - } - - @Subscribe - public void receiveClassifierCreatedEvent(final LearningCurveExtrapolatedEvent e) { - this.post(e); - } - - @Subscribe - public void receiveClassifierCreatedEvent(final MCCVSplitEvaluationEvent e) { - this.post(e); - } - - public TwoPhaseHASCOFactory, TFDNode, String> getTwoPhaseHASCOFactory() { - return this.twoPhaseHASCOFactory; - } - - public boolean isBuildSelectedClasifierOnGivenData() { - return this.buildSelectedClasifierOnGivenData; - } - - public void setBuildSelectedClasifierOnGivenData(final boolean buildSelectedClasifierOnGivenData) { - this.buildSelectedClasifierOnGivenData = buildSelectedClasifierOnGivenData; - } -} +package ai.libs.mlplan.core; + +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.eventbus.Subscribe; + +import ai.libs.hasco.core.HASCOFactory; +import ai.libs.hasco.core.HASCOSolutionCandidate; +import ai.libs.hasco.events.HASCOSolutionEvent; +import ai.libs.hasco.exceptions.ComponentInstantiationFailedException; +import ai.libs.hasco.model.ComponentInstance; +import ai.libs.hasco.optimizingfactory.OptimizingFactory; +import ai.libs.hasco.optimizingfactory.OptimizingFactoryProblem; +import ai.libs.hasco.variants.forwarddecomposition.twophase.TwoPhaseHASCO; +import ai.libs.hasco.variants.forwarddecomposition.twophase.TwoPhaseHASCOFactory; +import ai.libs.hasco.variants.forwarddecomposition.twophase.TwoPhaseSoftwareConfigurationProblem; +import ai.libs.jaicore.basic.ILoggingCustomizable; +import ai.libs.jaicore.basic.MathExt; +import ai.libs.jaicore.basic.algorithm.AAlgorithm; +import ai.libs.jaicore.basic.algorithm.AlgorithmExecutionCanceledException; +import ai.libs.jaicore.basic.algorithm.events.AlgorithmEvent; +import ai.libs.jaicore.basic.algorithm.events.AlgorithmFinishedEvent; +import ai.libs.jaicore.basic.algorithm.events.AlgorithmInitializedEvent; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmException; +import ai.libs.jaicore.basic.algorithm.exceptions.AlgorithmTimeoutedException; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.events.MCCVSplitEvaluationEvent; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.ClassifierEvaluatorConstructionFailedException; +import ai.libs.jaicore.ml.learningcurve.extrapolation.LearningCurveExtrapolatedEvent; +import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.mlplan.core.events.ClassifierCreatedEvent; +import ai.libs.mlplan.core.events.ClassifierFoundEvent; +import ai.libs.mlplan.multiclass.MLPlanClassifierConfig; +import weka.classifiers.Classifier; +import weka.core.Instances; + +public class MLPlan extends AAlgorithm implements ILoggingCustomizable { + + /** Logger for controlled output. */ + private Logger logger = LoggerFactory.getLogger(MLPlan.class); + private String loggerName; + + private Classifier selectedClassifier; + private double internalValidationErrorOfSelectedClassifier; + private ComponentInstance componentInstanceOfSelectedClassifier; + + private final IMLPlanBuilder builder; + private final Instances data; + private TwoPhaseHASCOFactory, TFDNode, String> twoPhaseHASCOFactory; + private OptimizingFactory, Double> optimizingFactory; + + private boolean buildSelectedClasifierOnGivenData = true; + + public MLPlan(final IMLPlanBuilder builder, final Instances data) { + super(builder.getAlgorithmConfig(), data); + builder.prepareNodeEvaluatorInFactoryWithData(data); + /* sanity checks */ + if (builder.getSearchSpaceConfigFile() == null || !builder.getSearchSpaceConfigFile().exists()) { + throw new IllegalArgumentException("The search space configuration file must be set in MLPlanBuilder, and it must be set to a file that exists!"); + } + if (builder.getClassifierFactory() == null) { + throw new IllegalArgumentException("ClassifierFactory must be set in MLPlanBuilder!"); + } + /* store builder and data for main algorithm */ + this.builder = builder; + this.data = data; + } + + @Override + public AlgorithmEvent nextWithException() throws AlgorithmException, InterruptedException, AlgorithmExecutionCanceledException, AlgorithmTimeoutedException { + switch (this.getState()) { + case created: + this.logger.info("Starting an ML-Plan instance."); + AlgorithmInitializedEvent event = this.activate(); + + /* check number of CPUs assigned */ + if (this.getConfig().cpus() < 1) { + throw new IllegalStateException("Cannot generate search where number of CPUs is " + this.getConfig().cpus()); + } + + /* set up exact splits */ + final double dataPortionUsedForSelection = this.getConfig().dataPortionForSelection(); + this.logger.debug("Splitting given {} data points into search data ({}%) and selection data ({}%).", this.data.size(), MathExt.round((1 - dataPortionUsedForSelection) * 100, 2), MathExt.round(dataPortionUsedForSelection, 2)); + Instances dataShownToSearch; + if (dataPortionUsedForSelection > 0) { + dataShownToSearch = this.builder.getSearchSelectionDatasetSplitter().split(this.getInput(), this.getConfig().randomSeed(), dataPortionUsedForSelection).get(1); + } else { + dataShownToSearch = this.getInput(); + } + if (dataShownToSearch.isEmpty()) { + throw new IllegalStateException("Cannot search on no data."); + } + + /* dynamically compute blow-ups */ + if (Double.isNaN(this.getConfig().expectedBlowupInSelection())) { + double blowUpInSelectionPhase = 1; + this.getConfig().setProperty(MLPlanClassifierConfig.K_BLOWUP_SELECTION, String.valueOf(blowUpInSelectionPhase)); + this.logger.info("No expected blow-up for selection phase has been defined. Automatically configuring {}", blowUpInSelectionPhase); + } + if (!this.buildSelectedClasifierOnGivenData) { + this.getConfig().setProperty(MLPlanClassifierConfig.K_BLOWUP_POSTPROCESS, String.valueOf(0)); + this.logger.info("Selected classifier won't be built, so now blow-up is calculated."); + } + else if (Double.isNaN(this.getConfig().expectedBlowupInPostprocessing())) { + double blowUpInPostprocessing = 1; + this.getConfig().setProperty(MLPlanClassifierConfig.K_BLOWUP_POSTPROCESS, String.valueOf(blowUpInPostprocessing)); + this.logger.info("No expected blow-up for postprocessing phase has been defined. Automatically configuring {}", blowUpInPostprocessing); + } + + /* setup the pipeline evaluators */ + this.logger.debug("Setting up the pipeline evaluators."); + PipelineEvaluator classifierEvaluatorForSearch; + PipelineEvaluator classifierEvaluatorForSelection; + try { + classifierEvaluatorForSearch = this.builder.getClassifierEvaluationInSearchPhase(dataShownToSearch, this.getConfig().randomSeed(), MLPlan.this.getInput().size()); + classifierEvaluatorForSelection = this.builder.getClassifierEvaluationInSelectionPhase(dataShownToSearch, this.getConfig().randomSeed()); + } catch (ClassifierEvaluatorConstructionFailedException e2) { + throw new AlgorithmException(e2, "Could not create the pipeline evaluator"); + } + classifierEvaluatorForSearch.registerListener(this); // events will be forwarded + classifierEvaluatorForSelection.registerListener(this); // events will be forwarded + + /* communicate the parameters with which ML-Plan will run */ + if (this.logger.isInfoEnabled()) { + this.logger.info( + "Starting ML-Plan with the following setup:\n\tDataset: {}\n\tTarget: {}\n\tCPUs: {}\n\tTimeout: {}s\n\tTimeout for single candidate evaluation: {}s\n\tTimeout for node evaluation: {}s\n\tRandom Completions per node evaluation: {}\n\tPortion of data for selection phase: {}%\n\tPipeline evaluation during search: {}\n\tPipeline evaluation during selection: {}\n\tBlow-ups are {} for selection phase and {} for post-processing phase.", + this.getInput().hashCode(), this.builder.getPerformanceMeasureName(), this.getConfig().cpus(), this.getTimeout().seconds(), this.getConfig().timeoutForCandidateEvaluation() / 1000, + this.getConfig().timeoutForNodeEvaluation() / 1000, this.getConfig().numberOfRandomCompletions(), MathExt.round(this.getConfig().dataPortionForSelection() * 100, 2), classifierEvaluatorForSearch, + classifierEvaluatorForSelection, this.getConfig().expectedBlowupInSelection(), this.getConfig().expectedBlowupInPostprocessing()); + } + + /* create 2-phase software configuration problem */ + this.logger.debug("Creating 2-phase software configuration problem."); + TwoPhaseSoftwareConfigurationProblem problem = null; + try { + problem = new TwoPhaseSoftwareConfigurationProblem(this.builder.getSearchSpaceConfigFile(), this.builder.getRequestedInterface(), classifierEvaluatorForSearch, classifierEvaluatorForSelection); + } catch (IOException e1) { + throw new AlgorithmException(e1, "Could not activate ML-Plan!"); + } + + /* create 2-phase HASCO */ + this.logger.info("Creating the twoPhaseHASCOFactory."); + OptimizingFactoryProblem optimizingFactoryProblem = new OptimizingFactoryProblem<>(this.builder.getClassifierFactory(), problem); + HASCOFactory, TFDNode, String, Double> hascoFactory = this.builder.getHASCOFactory(); + this.twoPhaseHASCOFactory = new TwoPhaseHASCOFactory<>(hascoFactory); + + this.twoPhaseHASCOFactory.setConfig(this.getConfig()); + this.optimizingFactory = new OptimizingFactory<>(optimizingFactoryProblem, this.twoPhaseHASCOFactory); + this.logger.info("Setting logger of {} to {}.optimizingfactory", this.optimizingFactory.getClass().getName(), this.loggerName); + this.optimizingFactory.setLoggerName(this.loggerName + ".optimizingfactory"); + this.optimizingFactory.registerListener(new Object() { + @Subscribe + public void receiveEventFromFactory(final AlgorithmEvent event) { + if (event instanceof AlgorithmInitializedEvent || event instanceof AlgorithmFinishedEvent) { + return; + } + if (event instanceof HASCOSolutionEvent) { + @SuppressWarnings("unchecked") + HASCOSolutionCandidate solution = ((HASCOSolutionEvent) event).getSolutionCandidate(); + try { + MLPlan.this.logger.info("Received new solution {} with score {} and evaluation time {}ms", MLPlan.this.builder.getClassifierFactory().getComponentInstantiation(solution.getComponentInstance()), + solution.getScore(), solution.getTimeToEvaluateCandidate()); + } catch (Exception e) { + MLPlan.this.logger.warn("Could not print log due to exception while preparing the log message.", e); + } + + if (dataPortionUsedForSelection == 0.0 && solution.getScore() < MLPlan.this.internalValidationErrorOfSelectedClassifier) { + try { + MLPlan.this.selectedClassifier = MLPlan.this.builder.getClassifierFactory().getComponentInstantiation(solution.getComponentInstance()); + MLPlan.this.internalValidationErrorOfSelectedClassifier = solution.getScore(); + MLPlan.this.componentInstanceOfSelectedClassifier = solution.getComponentInstance(); + } catch (ComponentInstantiationFailedException e) { + MLPlan.this.logger.error("Could not update selectedClassifier with newly best seen solution due to issues building the classifier from its ComponentInstance description.", e); + } + } + + try { + MLPlan.this.post( + new ClassifierFoundEvent(MLPlan.this.getId(), solution.getComponentInstance(), MLPlan.this.builder.getClassifierFactory().getComponentInstantiation(solution.getComponentInstance()), solution.getScore())); + } catch (ComponentInstantiationFailedException e) { + MLPlan.this.logger.error("An issue occurred while preparing the description for the post of a ClassifierFoundEvent", e); + } + } else { + MLPlan.this.post(event); + } + } + }); + + this.logger.info("Initializing the optimization factory."); + this.optimizingFactory.init(); + this.logger.info("Started and activated ML-Plan."); + return event; + + case active: + + /* train the classifier returned by the optimizing factory */ + long startOptimizationTime = System.currentTimeMillis(); + try { + this.selectedClassifier = this.optimizingFactory.call(); + this.logger.info("2-Phase-HASCO has chosen classifier {}, which will now be built on the entire data given, i.e. {} data points.", this.selectedClassifier, this.getInput().size()); + } catch (AlgorithmException | InterruptedException | AlgorithmExecutionCanceledException | AlgorithmTimeoutedException e) { + this.terminate(); // send the termination event + throw e; + } + this.internalValidationErrorOfSelectedClassifier = this.optimizingFactory.getPerformanceOfObject(); + this.componentInstanceOfSelectedClassifier = this.optimizingFactory.getComponentInstanceOfObject(); + if (this.buildSelectedClasifierOnGivenData) { + long startBuildTime = System.currentTimeMillis(); + try { + this.selectedClassifier.buildClassifier(this.getInput()); + } catch (Exception e) { + throw new AlgorithmException(e, "Training the classifier failed!"); + } + long endBuildTime = System.currentTimeMillis(); + this.logger.info("Selected model has been built on entire dataset. Build time of chosen model was {}ms. Total construction time was {}ms. The chosen classifier is: {}", endBuildTime - startBuildTime, + endBuildTime - startOptimizationTime, this.selectedClassifier); + } else { + this.logger.info("Selected model has not been built, since model building has been disabled. Total construction time was {}ms.", System.currentTimeMillis() - startOptimizationTime); + } + return this.terminate(); + + default: + throw new IllegalStateException("Cannot do anything in state " + this.getState()); + } + + } + + @Override + public Classifier call() throws AlgorithmException, InterruptedException, AlgorithmExecutionCanceledException, AlgorithmTimeoutedException { + while (this.hasNext()) { + this.nextWithException(); + } + return this.selectedClassifier; + } + + @Override + public void setLoggerName(final String name) { + this.loggerName = name; + this.logger.info("Switching logger name to {}", name); + this.logger = LoggerFactory.getLogger(name); + this.logger.info("Activated ML-Plan logger {}. Now setting logger of twoPhaseHASCO to {}.2phasehasco", name, name); + if (this.optimizingFactory != null) { + this.logger.info("Setting logger of {} to {}.optimizingfactory", this.optimizingFactory.getClass().getName(), this.loggerName); + this.optimizingFactory.setLoggerName(this.loggerName + ".optimizingfactory"); + } else { + this.logger.debug("Optimizingfactory has not been set yet, so not customizing its logger."); + } + + this.logger.info("Switched ML-Plan logger to {}", name); + } + + public void setPortionOfDataForPhase2(final float portion) { + this.getConfig().setProperty(MLPlanClassifierConfig.SELECTION_PORTION, String.valueOf(portion)); + } + + @Override + public String getLoggerName() { + return this.loggerName; + } + + @Override + public MLPlanClassifierConfig getConfig() { + return (MLPlanClassifierConfig) super.getConfig(); + } + + public void setRandomSeed(final int seed) { + this.getConfig().setProperty(MLPlanClassifierConfig.K_RANDOM_SEED, String.valueOf(seed)); + } + + public Classifier getSelectedClassifier() { + return this.selectedClassifier; + } + + public ComponentInstance getComponentInstanceOfSelectedClassifier() { + return this.componentInstanceOfSelectedClassifier; + } + + @SuppressWarnings("unchecked") + public GraphGenerator getGraphGenerator() { + return ((TwoPhaseHASCO, TFDNode, String>) this.optimizingFactory.getOptimizer()).getGraphGenerator(); + } + + public double getInternalValidationErrorOfSelectedClassifier() { + return this.internalValidationErrorOfSelectedClassifier; + } + + @Override + public synchronized void cancel() { + this.logger.info("Received cancel. First canceling optimizer, then invoking general shutdown."); + this.optimizingFactory.cancel(); + this.logger.debug("Now canceling main ML-Plan routine"); + super.cancel(); + assert this.isCanceled() : "Canceled-flag is not positive at the end of the cancel routine!"; + this.logger.info("Completed cancellation of ML-Plan. Cancel status is {}", this.isCanceled()); + } + + public OptimizingFactory, Double> getOptimizingFactory() { + return this.optimizingFactory; + } + + @Subscribe + public void receiveClassifierCreatedEvent(final ClassifierCreatedEvent e) { + this.post(e); + } + + @Subscribe + public void receiveClassifierCreatedEvent(final LearningCurveExtrapolatedEvent e) { + this.post(e); + } + + @Subscribe + public void receiveClassifierCreatedEvent(final MCCVSplitEvaluationEvent e) { + this.post(e); + } + + public TwoPhaseHASCOFactory, TFDNode, String> getTwoPhaseHASCOFactory() { + return this.twoPhaseHASCOFactory; + } + + public boolean isBuildSelectedClasifierOnGivenData() { + return this.buildSelectedClasifierOnGivenData; + } + + public void setBuildSelectedClasifierOnGivenData(final boolean buildSelectedClasifierOnGivenData) { + this.buildSelectedClasifierOnGivenData = buildSelectedClasifierOnGivenData; + } +} diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanBuilder.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanBuilder.java index 658d3f64aa..da68737a74 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanBuilder.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanBuilder.java @@ -1,582 +1,582 @@ -package ai.libs.mlplan.core; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Predicate; - -import org.aeonbits.owner.ConfigFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import ai.libs.hasco.core.HASCOFactory; -import ai.libs.hasco.model.Component; -import ai.libs.hasco.serialization.ComponentLoader; -import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDAndBestFirstFactory; -import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDFactory; -import ai.libs.jaicore.basic.FileUtil; -import ai.libs.jaicore.basic.MathExt; -import ai.libs.jaicore.basic.TimeOut; -import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; -import ai.libs.jaicore.logging.ToJSONStringUtil; -import ai.libs.jaicore.ml.core.dataset.IInstance; -import ai.libs.jaicore.ml.core.dataset.sampling.inmemory.ASamplingAlgorithm; -import ai.libs.jaicore.ml.core.dataset.sampling.inmemory.factories.interfaces.ISamplingAlgorithmFactory; -import ai.libs.jaicore.ml.core.evaluation.measure.IMeasure; -import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.AutoMEKAGGPFitnessMeasureLoss; -import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.EMultilabelPerformanceMeasure; -import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.EMultiClassPerformanceMeasure; -import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.MultiClassMeasureBuilder; -import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.ZeroOneLoss; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.IClassifierEvaluator; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.LearningCurveExtrapolationEvaluator; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.ClassifierEvaluatorConstructionFailedException; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.IClassifierEvaluatorFactory; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.LearningCurveExtrapolationEvaluatorFactory; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.MonteCarloCrossValidationEvaluatorFactory; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.splitevaluation.ISplitBasedClassifierEvaluator; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.splitevaluation.SimpleMLCSplitBasedClassifierEvaluator; -import ai.libs.jaicore.ml.evaluation.evaluators.weka.splitevaluation.SimpleSLCSplitBasedClassifierEvaluator; -import ai.libs.jaicore.ml.learningcurve.extrapolation.LearningCurveExtrapolationMethod; -import ai.libs.jaicore.ml.weka.dataset.splitter.ArbitrarySplitter; -import ai.libs.jaicore.ml.weka.dataset.splitter.IDatasetSplitter; -import ai.libs.jaicore.ml.weka.dataset.splitter.MulticlassClassStratifiedSplitter; -import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import ai.libs.mlpipeline_evaluation.CacheEvaluatorMeasureBridge; -import ai.libs.mlpipeline_evaluation.PerformanceDBAdapter; -import ai.libs.mlplan.multiclass.MLPlanClassifierConfig; -import ai.libs.mlplan.multiclass.wekamlplan.IClassifierFactory; -import ai.libs.mlplan.multiclass.wekamlplan.sklearn.SKLearnClassifierFactory; -import ai.libs.mlplan.multiclass.wekamlplan.weka.PreferenceBasedNodeEvaluator; -import ai.libs.mlplan.multiclass.wekamlplan.weka.WEKAPipelineFactory; -import ai.libs.mlplan.multiclass.wekamlplan.weka.WekaPipelineValidityCheckingNodeEvaluator; -import ai.libs.mlplan.multilabel.MekaPipelineFactory; -import jaicore.search.algorithms.standard.bestfirst.StandardBestFirstFactory; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; -import jaicore.search.probleminputs.GraphSearchInput; -import jaicore.search.problemtransformers.GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS; -import weka.core.Instances; - -/** - * The MLPlanBuilder helps to easily configure and initialize ML-Plan with specific parameter settings. - * For convenient use, the MLPlanBuilder also offers methods for initializing ML-Plan with default - * configuration to use ML-Plan for single label classification in combination with WEKA or scikit-learn - * or for multi-label classification in combination with MEKA and consequently with WEKA (for baselearners - * of multi-label reduction strategies). - * - * @author mwever, fmohr - */ -public class MLPlanBuilder { - - /* Logging */ - private Logger logger = LoggerFactory.getLogger(MLPlanBuilder.class); - - private static final String SLC_REQUESTED_HASCO_INTERFACE = "AbstractClassifier"; - private static final String MLC_REQUESTED_HASCO_INTERFACE = "MLClassifier"; - - /* Search space configuration files for default configurations */ - private static final File SPC_TINYTEST = new File("resources/automl/searchmodels/weka/tinytest.json"); - private static final File SPC_AUTO_WEKA = new File("resources/automl/searchmodels/weka/weka-all-autoweka.json"); - private static final File SPC_SKLEARN = new File("resources/automl/searchmodels/sklearn/sklearn-mlplan.json"); - private static final File SPC_SKLEARN_UL = new File("resources/automl/searchmodels/sklearn/ml-plan-ul.json"); - private static final File SPC_MEKA = new File("resources/automl/searchmodels/meka/meka-multilabel.json"); - - /* Preferred classifier lists to define an order for the classifiers to be evaluated. */ - private static final File PREFC_AUTO_WEKA = new File("resources/mlplan/weka-precedenceList.txt"); - private static final File PREFC_SKLEARN = new File("resources/mlplan/sklearn-precedenceList.txt"); - private static final File PREFC_SKLEARN_UL = new File("resources/mlplan/sklearn-ul-precedenceList.txt"); - private static final File PREFC_MEKA = new File("resources/mlplan/meka-preferenceList.txt"); - - /* Default values initially set when creating a builder. */ - private static final File DEFAULT_ALGORITHM_CONFIG_FILE = new File("conf/mlplan.properties"); - private static final boolean DEFAULT_USE_CACHE = false; - private static final Predicate DEFAULT_PRIORIZING_PREDICATE = null; - private static final String DEFAULT_REQUESTED_HASCO_INTERFACE = SLC_REQUESTED_HASCO_INTERFACE; - - /** - * Default configurations including search space configuration files and lists of preferences with respect to the classifiers to be evaluated. - * - * @author mwever - */ - private enum EDefaultConfig { - TINYTEST(SPC_TINYTEST, PREFC_AUTO_WEKA), AUTO_WEKA(SPC_AUTO_WEKA, PREFC_AUTO_WEKA), SKLEARN(SPC_SKLEARN, PREFC_SKLEARN), SKLEARN_UL(SPC_SKLEARN_UL, PREFC_SKLEARN_UL), MEKA(SPC_MEKA, PREFC_MEKA); - - /* Search space configuration file */ - private final File searchSpaceConfigurationFile; - /* File containing a list of components defining an ordering of preference. */ - private final File preferredComponentsFile; - - private EDefaultConfig(final File spcFile, final File preferredComponentsFile) { - this.searchSpaceConfigurationFile = spcFile; - this.preferredComponentsFile = preferredComponentsFile; - } - - public File getSearchSpaceConfigFile() { - return this.searchSpaceConfigurationFile; - } - - public File getPreferredComponentsFile() { - return this.preferredComponentsFile; - } - } - - private boolean factoryPreparedWithData = false; - - private MLPlanClassifierConfig algorithmConfig; - - @SuppressWarnings("rawtypes") - private HASCOViaFDFactory hascoFactory = new HASCOViaFDFactory, Double>(); - private File searchSpaceConfigFile; - private Collection components; - private IClassifierFactory classifierFactory; - private String requestedHASCOInterface; - - private PipelineValidityCheckingNodeEvaluator pipelineValidityCheckingNodeEvaluator; - private INodeEvaluator preferredNodeEvaluator = null; - - /* The splitter is used to create the split for separating search and selection data */ - private IDatasetSplitter searchSelectionDatasetSplitter = new MulticlassClassStratifiedSplitter(); - private IDatasetSplitter searchPhaseDatasetSplitter = new MulticlassClassStratifiedSplitter(); - private IDatasetSplitter selectionPhaseDatasetSplitter = new MulticlassClassStratifiedSplitter(); - - private boolean useCache; - private PerformanceDBAdapter dbAdapter = null; - - private EMultiClassPerformanceMeasure singleLabelPerformanceMeasure; - private EMultilabelPerformanceMeasure multiLabelPerformanceMeasure; - private ISplitBasedClassifierEvaluator splitBasedClassifierEvaluator; - - private Predicate priorizingPredicate = null; - - private IClassifierEvaluatorFactory factoryForPipelineEvaluationInSearchPhase = null; - private IClassifierEvaluatorFactory factoryForPipelineEvaluationInSelectionPhase = null; - - public MLPlanBuilder() { - super(); - - /* Setting up all generic default values. */ - try { - this.withAlgorithmConfigFile(DEFAULT_ALGORITHM_CONFIG_FILE); - } catch (IllegalArgumentException e) { - this.logger.error("The default algorithm configuration file could not be loaded.", e); - } - this.useCache = DEFAULT_USE_CACHE; - this.priorizingPredicate = DEFAULT_PRIORIZING_PREDICATE; - this.requestedHASCOInterface = DEFAULT_REQUESTED_HASCO_INTERFACE; - } - - public MLPlanBuilder(final File searchSpaceConfigFile, final File algorithmConfigFile, final EMultiClassPerformanceMeasure performanceMeasure) { - this(); - this.withAlgorithmConfigFile(algorithmConfigFile); - this.searchSpaceConfigFile = searchSpaceConfigFile; - this.singleLabelPerformanceMeasure = performanceMeasure; - this.useCache = false; - } - - public MLPlanBuilder(final File searchSpaceConfigFile, final File algorithmConfigFile, final EMultiClassPerformanceMeasure performanceMeasure, final PerformanceDBAdapter dbAdapter) { - this(searchSpaceConfigFile, algorithmConfigFile, performanceMeasure); - this.useCache = true; - this.dbAdapter = dbAdapter; - } - - /** - * Set the classifier factory that translates CompositionInstance objects to classifiers that can be evaluated. - * - * @param classifierFactory The classifier factory to be used to translate CompositionInstance objects to classifiers. - */ - public void withClassifierFactory(final IClassifierFactory classifierFactory) { - this.classifierFactory = classifierFactory; - } - - public MLPlanBuilder withSearchSpaceConfigFile(final File searchSpaceConfig) throws IOException { - FileUtil.requireFileExists(searchSpaceConfig); - this.searchSpaceConfigFile = searchSpaceConfig; - this.components = new ComponentLoader(searchSpaceConfig).getComponents(); - return this; - } - - public MLPlanBuilder withDatasetSplitterForSearchSelectionSplit(final IDatasetSplitter datasetSplitter) { - this.searchSelectionDatasetSplitter = datasetSplitter; - return this; - } - - public MLPlanBuilder withSearchPhaseDatasetSplitter(final IDatasetSplitter datasetSplitter) { - this.searchPhaseDatasetSplitter = datasetSplitter; - return this; - } - - public MLPlanBuilder withSelectionPhaseDatasetSplitter(final IDatasetSplitter datasetSplitter) { - this.selectionPhaseDatasetSplitter = datasetSplitter; - return this; - } - - public MLPlanBuilder withRequestedInterface(final String requestedInterface) { - this.requestedHASCOInterface = requestedInterface; - return this; - } - - /** - * Configures the MLPlanBuilder to deal with the AutoSKLearn search space configuration. - * - * @return Returns the current MLPlanBuilder object with the AutoSKLearn search space configuration. - * @throws IOException Throws an IOException if the search space config file could not be loaded. - */ - public MLPlanBuilder withAutoSKLearnConfig() throws IOException { - this.classifierFactory = new SKLearnClassifierFactory(); - return this.withDefaultConfiguration(EDefaultConfig.SKLEARN); - } - - public MLPlanBuilder withTpotConfig() throws IOException { - this.classifierFactory = new SKLearnClassifierFactory(); - return this.withDefaultConfiguration(EDefaultConfig.SKLEARN_UL); - } - - public MLPlanBuilder withAutoWEKAConfiguration() throws IOException { - this.classifierFactory = new WEKAPipelineFactory(); - this.pipelineValidityCheckingNodeEvaluator = new WekaPipelineValidityCheckingNodeEvaluator(); - return this.withDefaultConfiguration(EDefaultConfig.AUTO_WEKA); - } - - public MLPlanBuilder withTinyTestConfiguration() throws IOException { - this.classifierFactory = new WEKAPipelineFactory(); - this.pipelineValidityCheckingNodeEvaluator = new WekaPipelineValidityCheckingNodeEvaluator(); - return this.withDefaultConfiguration(EDefaultConfig.TINYTEST); - } - - public MLPlanBuilder withMekaDefaultConfiguration() throws IOException { - this.withDefaultConfiguration(EDefaultConfig.MEKA); - this.singleLabelPerformanceMeasure = null; - this.multiLabelPerformanceMeasure = EMultilabelPerformanceMeasure.AUTO_MEKA_GGP_FITNESS_LOSS; - this.splitBasedClassifierEvaluator = new SimpleMLCSplitBasedClassifierEvaluator(new AutoMEKAGGPFitnessMeasureLoss()); - this.classifierFactory = new MekaPipelineFactory(); - this.requestedHASCOInterface = MLC_REQUESTED_HASCO_INTERFACE; - this.withDatasetSplitterForSearchSelectionSplit(new ArbitrarySplitter()); - this.withSearchPhaseDatasetSplitter(new ArbitrarySplitter()); - this.withSelectionPhaseDatasetSplitter(new ArbitrarySplitter()); - return this; - } - - private MLPlanBuilder withDefaultConfiguration(final EDefaultConfig defConfig) throws IOException { - if (this.searchSpaceConfigFile == null) { - this.withSearchSpaceConfigFile(defConfig.getSearchSpaceConfigFile()); - } - this.withPreferredComponentsFile(defConfig.preferredComponentsFile); - this.withRandomCompletionBasedBestFirstSearch(); - if (defConfig != EDefaultConfig.MEKA && this.singleLabelPerformanceMeasure == null) { - this.singleLabelPerformanceMeasure = EMultiClassPerformanceMeasure.ERRORRATE; - this.withSingleLabelClassificationMeasure(this.singleLabelPerformanceMeasure); - } - - /* use MCCV for pipeline evaluation */ - int mccvIterationsDuringSearch = 5; - int mccvIterationsDuringSelection = 5; - double mccvPortion = 0.7; - if (!(this.factoryForPipelineEvaluationInSearchPhase instanceof MonteCarloCrossValidationEvaluatorFactory)) { - this.factoryForPipelineEvaluationInSearchPhase = new MonteCarloCrossValidationEvaluatorFactory().withNumMCIterations(mccvIterationsDuringSearch).withTrainFoldSize(mccvPortion).withSplitBasedEvaluator(new SimpleSLCSplitBasedClassifierEvaluator(new ZeroOneLoss())); - } - if (!(this.factoryForPipelineEvaluationInSelectionPhase instanceof MonteCarloCrossValidationEvaluatorFactory)) { - this.factoryForPipelineEvaluationInSelectionPhase = new MonteCarloCrossValidationEvaluatorFactory().withNumMCIterations(mccvIterationsDuringSearch).withTrainFoldSize(mccvPortion).withSplitBasedEvaluator(new SimpleSLCSplitBasedClassifierEvaluator(new ZeroOneLoss())); - } - - /* configure blow-ups for MCCV */ - double blowUpInSelectionPhase = MathExt.round(1f / mccvPortion * mccvIterationsDuringSelection / mccvIterationsDuringSearch, 2); - this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_BLOWUP_SELECTION, String.valueOf(blowUpInSelectionPhase)); - double blowUpInPostprocessing = MathExt.round((1 / (1 - this.algorithmConfig.dataPortionForSelection())) / mccvIterationsDuringSelection, 2); - this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_BLOWUP_POSTPROCESS, String.valueOf(blowUpInPostprocessing)); - return this; - } - - public MLPlanBuilder withPreferredComponentsFile(final File preferredComponentsFile) throws IOException { - this.getAlgorithmConfig().setProperty(MLPlanClassifierConfig.PREFERRED_COMPONENTS, preferredComponentsFile.getAbsolutePath()); - List ordering; - if (!preferredComponentsFile.exists()) { - this.logger.warn("The configured file for preferred components \"{}\" does not exist. Not using any particular ordering.", preferredComponentsFile.getAbsolutePath()); - ordering = new ArrayList<>(); - } else { - ordering = FileUtil.readFileAsList(preferredComponentsFile); - } - return this.withPreferredNodeEvaluator(new PreferenceBasedNodeEvaluator(this.components, ordering)); - } - - /** - * Loads the MLPlanClassifierConfig with default values and replaces all properties according to the properties defined in the given config file. - * - * @param algorithmConfigFile The file specifying the property values to replace the default configuration. - * @return The MLPlanBuilder object. - * @throws IOException An IOException is thrown if there are issues reading the config file. - */ - public MLPlanBuilder withAlgorithmConfigFile(final File algorithmConfigFile) { - return this.withAlgorithmConfig((MLPlanClassifierConfig) ConfigFactory.create(MLPlanClassifierConfig.class).loadPropertiesFromFile(algorithmConfigFile)); - } - - public MLPlanBuilder withAlgorithmConfig(final MLPlanClassifierConfig config) { - this.algorithmConfig = config; - this.hascoFactory.withAlgorithmConfig(this.algorithmConfig); - this.updateEverything(); - return this; - } - - public MLPlanBuilder withSingleLabelClassificationMeasure(final EMultiClassPerformanceMeasure measure) { - this.singleLabelPerformanceMeasure = measure; - return this.withSplitBasedClassifierEvaluator(this.getSingleLabelEvaluationMeasurementBridge(new MultiClassMeasureBuilder().getEvaluator(measure))); - } - - public MLPlanBuilder withMultiLabelClassificationMeasure(final EMultilabelPerformanceMeasure measure) { - this.multiLabelPerformanceMeasure = measure; - return this.withSplitBasedClassifierEvaluator(this.getMultiLabelEvaluationMeasurementBridge(new MultiClassMeasureBuilder().getEvaluator(measure))); - } - - /** - * This ADDs a new preferred node evaluator; requires that the search will be a best-first search. - * - * It is possible to specify several preferred node evaluators, which will be ordered by the order in which they are specified. The latest given evaluator is the most preferred one. - * - * @param preferredNodeEvaluator - * @return - */ - public MLPlanBuilder withPreferredNodeEvaluator(final INodeEvaluator preferredNodeEvaluator) { - if (this.factoryPreparedWithData) { - throw new IllegalStateException("The method prepareNodeEvaluatorInFactoryWithData has already been called. No changes to the preferred node evaluator possible anymore"); - } - - /* first update the preferred node evaluator */ - if (this.preferredNodeEvaluator == null) { - this.preferredNodeEvaluator = preferredNodeEvaluator; - } else { - this.preferredNodeEvaluator = new AlternativeNodeEvaluator<>(preferredNodeEvaluator, this.preferredNodeEvaluator); - } - this.updateEverything(); - return this; - } - - public MLPlanBuilder withSplitBasedClassifierEvaluator(final ISplitBasedClassifierEvaluator evaluator) { - this.splitBasedClassifierEvaluator = evaluator; - return this; - } - - @SuppressWarnings("unchecked") - public MLPlanBuilder withSearchFactory(@SuppressWarnings("rawtypes") final IOptimalPathInORGraphSearchFactory searchFactory, @SuppressWarnings("rawtypes") final AlgorithmicProblemReduction transformer) { - this.hascoFactory.setSearchFactory(searchFactory); - this.hascoFactory.setSearchProblemTransformer(transformer); - return this; - } - - @SuppressWarnings("unchecked") - public MLPlanBuilder withRandomCompletionBasedBestFirstSearch() { - this.hascoFactory.setSearchFactory(new StandardBestFirstFactory()); - this.updateEverything(); - return this; - } - - public MLPlanBuilder withTimeoutForSingleSolutionEvaluation(final TimeOut timeout) { - this.getAlgorithmConfig().setProperty(MLPlanClassifierConfig.K_RANDOM_COMPLETIONS_TIMEOUT_PATH, String.valueOf(timeout.milliseconds())); - this.updateEverything(); - return this; - } - - public MLPlanBuilder withTimeoutForNodeEvaluation(final TimeOut timeout) { - this.getAlgorithmConfig().setProperty(MLPlanClassifierConfig.K_RANDOM_COMPLETIONS_TIMEOUT_NODE, String.valueOf(timeout.milliseconds())); - this.updateEverything(); - return this; - } - - public void prepareNodeEvaluatorInFactoryWithData(final Instances data) { - if (!(this.hascoFactory instanceof HASCOViaFDAndBestFirstFactory)) { - return; - } - if (this.factoryPreparedWithData) { - throw new IllegalStateException("Factory has already been prepared with data. This can only be done once!"); - } - this.factoryPreparedWithData = true; - - /* nothing to do if there are no preferred node evaluators */ - if (this.pipelineValidityCheckingNodeEvaluator == null && this.preferredNodeEvaluator == null) { - return; - } - - /* now determine the real node evaluator to be used. A semantic node evaluator has highest priority */ - INodeEvaluator actualNodeEvaluator; - if (this.pipelineValidityCheckingNodeEvaluator != null) { - this.pipelineValidityCheckingNodeEvaluator.setComponents(this.components); - this.pipelineValidityCheckingNodeEvaluator.setData(data); - if (this.preferredNodeEvaluator != null) { - actualNodeEvaluator = new AlternativeNodeEvaluator<>(this.pipelineValidityCheckingNodeEvaluator, this.preferredNodeEvaluator); - } else { - actualNodeEvaluator = this.pipelineValidityCheckingNodeEvaluator; - } - } else { - actualNodeEvaluator = this.preferredNodeEvaluator; - } - - /* update the preferred node evaluator in the HascoFactory */ - this.preferredNodeEvaluator = actualNodeEvaluator; - this.updateEverything(); - } - - @SuppressWarnings("unchecked") - private void updateSearchProblemTransformer() { - this.hascoFactory.setSearchProblemTransformer(new GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS(this.preferredNodeEvaluator, this.priorizingPredicate, - this.algorithmConfig.randomSeed(), this.algorithmConfig.numberOfRandomCompletions(), this.algorithmConfig.timeoutForCandidateEvaluation(), this.algorithmConfig.timeoutForNodeEvaluation())); - - } - - private void updateAlgorithmConfigOfHASCO() { - this.hascoFactory.withAlgorithmConfig(this.getAlgorithmConfig()); - } - - private void updateEverything() { - this.updateSearchProblemTransformer(); - this.updateAlgorithmConfigOfHASCO(); - } - - /** - * @return The dataset splitter that is used for separating search and selection data. - */ - public IDatasetSplitter getSearchSelectionDatasetSplitter() { - return this.searchSelectionDatasetSplitter; - } - - /** - * @return The dataset splitter to be used in search phase for generating benchmark splits. - */ - public IDatasetSplitter getSearchPhaseDatasetSplitter() { - return this.searchPhaseDatasetSplitter; - } - - /** - * @return The dataset splitter to be used in selection phase for generating benchmark splits. - */ - public IDatasetSplitter getSelectionPhaseDatasetSplitter() { - return this.selectionPhaseDatasetSplitter; - } - - /** - * @return The interface that is requested to be provided by a solution candidate component instance. - */ - public String getRequestedInterface() { - return this.requestedHASCOInterface; - } - - // public void withExtrapolatedSaturationPointEvaluation(final int[] anchorpoints, final ISamplingAlgorithmFactory> subsamplingAlgorithmFactory, - // final double trainSplitForAnchorpointsMeasurement, final LearningCurveExtrapolationMethod extrapolationMethod) { - // this.builderForPipelineEvaluationInSearchPhase = new ExtrapolatedSaturationPointEvaluatorFactory(anchorpoints, subsamplingAlgorithmFactory, trainSplitForAnchorpointsMeasurement, extrapolationMethod); - // - // } - - public void withLearningCurveExtrapolationEvaluation(final int[] anchorpoints, final ISamplingAlgorithmFactory> subsamplingAlgorithmFactory, - final double trainSplitForAnchorpointsMeasurement, final LearningCurveExtrapolationMethod extrapolationMethod) { - this.factoryForPipelineEvaluationInSearchPhase = new LearningCurveExtrapolationEvaluatorFactory(anchorpoints, subsamplingAlgorithmFactory, trainSplitForAnchorpointsMeasurement, extrapolationMethod); - // this.factoryForPipelineEvaluationInSelectionPhase = new LearningCurveExtrapolationEvaluatorFactory(anchorpoints, subsamplingAlgorithmFactory, trainSplitForAnchorpointsMeasurement, extrapolationMethod); - this.factoryForPipelineEvaluationInSelectionPhase = new MonteCarloCrossValidationEvaluatorFactory().withNumMCIterations(3).withTrainFoldSize(.7).withSplitBasedEvaluator(new SimpleSLCSplitBasedClassifierEvaluator(new ZeroOneLoss())); - this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_BLOWUP_SELECTION, "" + 4); // evaluating on 1000 in selection MCCV is, assuming quadratic growth, roughly max 4 times costlier than search phase evaluations - } - - public boolean getUseCache() { - return this.useCache; - } - - public PerformanceDBAdapter getDBAdapter() { - return this.dbAdapter; - } - - public IClassifierFactory getClassifierFactory() { - return this.classifierFactory; - } - - public Collection getComponents() { - return this.components; - } - - public File getSearchSpaceConfigFile() { - return this.searchSpaceConfigFile; - } - - public MLPlanClassifierConfig getAlgorithmConfig() { - return this.algorithmConfig; - } - - public EMultiClassPerformanceMeasure getSingleLabelPerformanceMeasure() { - return this.singleLabelPerformanceMeasure; - } - - public EMultilabelPerformanceMeasure getMultiLabelPerformanceMeasure() { - return this.multiLabelPerformanceMeasure; - } - - public ISplitBasedClassifierEvaluator getSingleLabelEvaluationMeasurementBridge(final IMeasure measure) { - if (this.splitBasedClassifierEvaluator == null) { - if (this.getUseCache()) { - return new CacheEvaluatorMeasureBridge(measure, this.getDBAdapter()); - } else { - return new SimpleSLCSplitBasedClassifierEvaluator(measure); - } - } else { - return this.splitBasedClassifierEvaluator; - } - } - - public ISplitBasedClassifierEvaluator getMultiLabelEvaluationMeasurementBridge(final IMeasure measure) { - if (this.splitBasedClassifierEvaluator == null) { - return new SimpleMLCSplitBasedClassifierEvaluator(measure); - } else { - return this.splitBasedClassifierEvaluator; - } - } - - @SuppressWarnings("rawtypes") - public HASCOFactory getHASCOFactory() { - return this.hascoFactory; - } - - // public ISplitBasedClassifierEvaluator getEvaluationMeasurementBridge() { - // if (this.splitBasedClassifierEvaluator != null) { - // return this.splitBasedClassifierEvaluator; - // } - // - // if (this.measure != null) { - // return this.getSingleLabelEvaluationMeasurementBridge(this.measure); - // } else { - // throw new IllegalStateException("Can not create evaluator measure bridge without a measure."); - // } - // } - - @Override - public String toString() { - Map fields = new HashMap<>(); - fields.put("algorithmConfig", this.getAlgorithmConfig()); - fields.put("classifierFactory", this.classifierFactory); - return ToJSONStringUtil.toJSONString(fields); - } - - public IClassifierEvaluatorFactory getFactoryForPipelineEvaluationInSearchPhase() { - return this.factoryForPipelineEvaluationInSearchPhase; - } - - public IClassifierEvaluatorFactory getFactoryForPipelineEvaluationInSelectionPhase() { - return this.factoryForPipelineEvaluationInSelectionPhase; - } - - public PipelineEvaluator getClassifierEvaluationInSearchPhase(final Instances data, final int seed, final int fullDatasetSize) throws ClassifierEvaluatorConstructionFailedException { - if (this.factoryForPipelineEvaluationInSearchPhase == null) { - throw new IllegalStateException("No factory for pipeline evaluation in search phase has been set!"); - } - IClassifierEvaluator evaluator = this.factoryForPipelineEvaluationInSearchPhase.getIClassifierEvaluator(data, seed); - if (evaluator instanceof LearningCurveExtrapolationEvaluator) { - ((LearningCurveExtrapolationEvaluator) evaluator).setFullDatasetSize(fullDatasetSize); - } - return new PipelineEvaluator(this.getClassifierFactory(), evaluator, this.getAlgorithmConfig().timeoutForCandidateEvaluation()); - } - - public PipelineEvaluator getClassifierEvaluationInSelectionPhase(final Instances data, final int seed) throws ClassifierEvaluatorConstructionFailedException { - if (this.factoryForPipelineEvaluationInSelectionPhase == null) { - throw new IllegalStateException("No factory for pipeline evaluation in selection phase has been set!"); - } - return new PipelineEvaluator(this.getClassifierFactory(), this.factoryForPipelineEvaluationInSelectionPhase.getIClassifierEvaluator(data, seed), Integer.MAX_VALUE); - } -} +package ai.libs.mlplan.core; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; + +import org.aeonbits.owner.ConfigFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ai.libs.hasco.core.HASCOFactory; +import ai.libs.hasco.model.Component; +import ai.libs.hasco.serialization.ComponentLoader; +import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDAndBestFirstFactory; +import ai.libs.hasco.variants.forwarddecomposition.HASCOViaFDFactory; +import ai.libs.jaicore.basic.FileUtil; +import ai.libs.jaicore.basic.MathExt; +import ai.libs.jaicore.basic.TimeOut; +import ai.libs.jaicore.basic.algorithm.reduction.AlgorithmicProblemReduction; +import ai.libs.jaicore.logging.ToJSONStringUtil; +import ai.libs.jaicore.ml.core.dataset.IInstance; +import ai.libs.jaicore.ml.core.dataset.sampling.inmemory.ASamplingAlgorithm; +import ai.libs.jaicore.ml.core.dataset.sampling.inmemory.factories.interfaces.ISamplingAlgorithmFactory; +import ai.libs.jaicore.ml.core.evaluation.measure.IMeasure; +import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.AutoMEKAGGPFitnessMeasureLoss; +import ai.libs.jaicore.ml.core.evaluation.measure.multilabel.EMultilabelPerformanceMeasure; +import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.EMultiClassPerformanceMeasure; +import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.MultiClassMeasureBuilder; +import ai.libs.jaicore.ml.core.evaluation.measure.singlelabel.ZeroOneLoss; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.IClassifierEvaluator; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.LearningCurveExtrapolationEvaluator; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.ClassifierEvaluatorConstructionFailedException; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.IClassifierEvaluatorFactory; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.LearningCurveExtrapolationEvaluatorFactory; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.factory.MonteCarloCrossValidationEvaluatorFactory; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.splitevaluation.ISplitBasedClassifierEvaluator; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.splitevaluation.SimpleMLCSplitBasedClassifierEvaluator; +import ai.libs.jaicore.ml.evaluation.evaluators.weka.splitevaluation.SimpleSLCSplitBasedClassifierEvaluator; +import ai.libs.jaicore.ml.learningcurve.extrapolation.LearningCurveExtrapolationMethod; +import ai.libs.jaicore.ml.weka.dataset.splitter.ArbitrarySplitter; +import ai.libs.jaicore.ml.weka.dataset.splitter.IDatasetSplitter; +import ai.libs.jaicore.ml.weka.dataset.splitter.MulticlassClassStratifiedSplitter; +import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.StandardBestFirstFactory; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.core.interfaces.IOptimalPathInORGraphSearchFactory; +import ai.libs.jaicore.search.probleminputs.GraphSearchInput; +import ai.libs.jaicore.search.problemtransformers.GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS; +import ai.libs.mlpipeline_evaluation.CacheEvaluatorMeasureBridge; +import ai.libs.mlpipeline_evaluation.PerformanceDBAdapter; +import ai.libs.mlplan.multiclass.MLPlanClassifierConfig; +import ai.libs.mlplan.multiclass.wekamlplan.IClassifierFactory; +import ai.libs.mlplan.multiclass.wekamlplan.sklearn.SKLearnClassifierFactory; +import ai.libs.mlplan.multiclass.wekamlplan.weka.PreferenceBasedNodeEvaluator; +import ai.libs.mlplan.multiclass.wekamlplan.weka.WEKAPipelineFactory; +import ai.libs.mlplan.multiclass.wekamlplan.weka.WekaPipelineValidityCheckingNodeEvaluator; +import ai.libs.mlplan.multilabel.MekaPipelineFactory; +import weka.core.Instances; + +/** + * The MLPlanBuilder helps to easily configure and initialize ML-Plan with specific parameter settings. + * For convenient use, the MLPlanBuilder also offers methods for initializing ML-Plan with default + * configuration to use ML-Plan for single label classification in combination with WEKA or scikit-learn + * or for multi-label classification in combination with MEKA and consequently with WEKA (for baselearners + * of multi-label reduction strategies). + * + * @author mwever, fmohr + */ +public class MLPlanBuilder { + + /* Logging */ + private Logger logger = LoggerFactory.getLogger(MLPlanBuilder.class); + + private static final String SLC_REQUESTED_HASCO_INTERFACE = "AbstractClassifier"; + private static final String MLC_REQUESTED_HASCO_INTERFACE = "MLClassifier"; + + /* Search space configuration files for default configurations */ + private static final File SPC_TINYTEST = new File("resources/automl/searchmodels/weka/tinytest.json"); + private static final File SPC_AUTO_WEKA = new File("resources/automl/searchmodels/weka/weka-all-autoweka.json"); + private static final File SPC_SKLEARN = new File("resources/automl/searchmodels/sklearn/sklearn-mlplan.json"); + private static final File SPC_SKLEARN_UL = new File("resources/automl/searchmodels/sklearn/ml-plan-ul.json"); + private static final File SPC_MEKA = new File("resources/automl/searchmodels/meka/meka-multilabel.json"); + + /* Preferred classifier lists to define an order for the classifiers to be evaluated. */ + private static final File PREFC_AUTO_WEKA = new File("resources/mlplan/weka-precedenceList.txt"); + private static final File PREFC_SKLEARN = new File("resources/mlplan/sklearn-precedenceList.txt"); + private static final File PREFC_SKLEARN_UL = new File("resources/mlplan/sklearn-ul-precedenceList.txt"); + private static final File PREFC_MEKA = new File("resources/mlplan/meka-preferenceList.txt"); + + /* Default values initially set when creating a builder. */ + private static final File DEFAULT_ALGORITHM_CONFIG_FILE = new File("conf/mlplan.properties"); + private static final boolean DEFAULT_USE_CACHE = false; + private static final Predicate DEFAULT_PRIORIZING_PREDICATE = null; + private static final String DEFAULT_REQUESTED_HASCO_INTERFACE = SLC_REQUESTED_HASCO_INTERFACE; + + /** + * Default configurations including search space configuration files and lists of preferences with respect to the classifiers to be evaluated. + * + * @author mwever + */ + private enum EDefaultConfig { + TINYTEST(SPC_TINYTEST, PREFC_AUTO_WEKA), AUTO_WEKA(SPC_AUTO_WEKA, PREFC_AUTO_WEKA), SKLEARN(SPC_SKLEARN, PREFC_SKLEARN), SKLEARN_UL(SPC_SKLEARN_UL, PREFC_SKLEARN_UL), MEKA(SPC_MEKA, PREFC_MEKA); + + /* Search space configuration file */ + private final File searchSpaceConfigurationFile; + /* File containing a list of components defining an ordering of preference. */ + private final File preferredComponentsFile; + + private EDefaultConfig(final File spcFile, final File preferredComponentsFile) { + this.searchSpaceConfigurationFile = spcFile; + this.preferredComponentsFile = preferredComponentsFile; + } + + public File getSearchSpaceConfigFile() { + return this.searchSpaceConfigurationFile; + } + + public File getPreferredComponentsFile() { + return this.preferredComponentsFile; + } + } + + private boolean factoryPreparedWithData = false; + + private MLPlanClassifierConfig algorithmConfig; + + @SuppressWarnings("rawtypes") + private HASCOViaFDFactory hascoFactory = new HASCOViaFDFactory, Double>(); + private File searchSpaceConfigFile; + private Collection components; + private IClassifierFactory classifierFactory; + private String requestedHASCOInterface; + + private PipelineValidityCheckingNodeEvaluator pipelineValidityCheckingNodeEvaluator; + private INodeEvaluator preferredNodeEvaluator = null; + + /* The splitter is used to create the split for separating search and selection data */ + private IDatasetSplitter searchSelectionDatasetSplitter = new MulticlassClassStratifiedSplitter(); + private IDatasetSplitter searchPhaseDatasetSplitter = new MulticlassClassStratifiedSplitter(); + private IDatasetSplitter selectionPhaseDatasetSplitter = new MulticlassClassStratifiedSplitter(); + + private boolean useCache; + private PerformanceDBAdapter dbAdapter = null; + + private EMultiClassPerformanceMeasure singleLabelPerformanceMeasure; + private EMultilabelPerformanceMeasure multiLabelPerformanceMeasure; + private ISplitBasedClassifierEvaluator splitBasedClassifierEvaluator; + + private Predicate priorizingPredicate = null; + + private IClassifierEvaluatorFactory factoryForPipelineEvaluationInSearchPhase = null; + private IClassifierEvaluatorFactory factoryForPipelineEvaluationInSelectionPhase = null; + + public MLPlanBuilder() { + super(); + + /* Setting up all generic default values. */ + try { + this.withAlgorithmConfigFile(DEFAULT_ALGORITHM_CONFIG_FILE); + } catch (IllegalArgumentException e) { + this.logger.error("The default algorithm configuration file could not be loaded.", e); + } + this.useCache = DEFAULT_USE_CACHE; + this.priorizingPredicate = DEFAULT_PRIORIZING_PREDICATE; + this.requestedHASCOInterface = DEFAULT_REQUESTED_HASCO_INTERFACE; + } + + public MLPlanBuilder(final File searchSpaceConfigFile, final File algorithmConfigFile, final EMultiClassPerformanceMeasure performanceMeasure) { + this(); + this.withAlgorithmConfigFile(algorithmConfigFile); + this.searchSpaceConfigFile = searchSpaceConfigFile; + this.singleLabelPerformanceMeasure = performanceMeasure; + this.useCache = false; + } + + public MLPlanBuilder(final File searchSpaceConfigFile, final File algorithmConfigFile, final EMultiClassPerformanceMeasure performanceMeasure, final PerformanceDBAdapter dbAdapter) { + this(searchSpaceConfigFile, algorithmConfigFile, performanceMeasure); + this.useCache = true; + this.dbAdapter = dbAdapter; + } + + /** + * Set the classifier factory that translates CompositionInstance objects to classifiers that can be evaluated. + * + * @param classifierFactory The classifier factory to be used to translate CompositionInstance objects to classifiers. + */ + public void withClassifierFactory(final IClassifierFactory classifierFactory) { + this.classifierFactory = classifierFactory; + } + + public MLPlanBuilder withSearchSpaceConfigFile(final File searchSpaceConfig) throws IOException { + FileUtil.requireFileExists(searchSpaceConfig); + this.searchSpaceConfigFile = searchSpaceConfig; + this.components = new ComponentLoader(searchSpaceConfig).getComponents(); + return this; + } + + public MLPlanBuilder withDatasetSplitterForSearchSelectionSplit(final IDatasetSplitter datasetSplitter) { + this.searchSelectionDatasetSplitter = datasetSplitter; + return this; + } + + public MLPlanBuilder withSearchPhaseDatasetSplitter(final IDatasetSplitter datasetSplitter) { + this.searchPhaseDatasetSplitter = datasetSplitter; + return this; + } + + public MLPlanBuilder withSelectionPhaseDatasetSplitter(final IDatasetSplitter datasetSplitter) { + this.selectionPhaseDatasetSplitter = datasetSplitter; + return this; + } + + public MLPlanBuilder withRequestedInterface(final String requestedInterface) { + this.requestedHASCOInterface = requestedInterface; + return this; + } + + /** + * Configures the MLPlanBuilder to deal with the AutoSKLearn search space configuration. + * + * @return Returns the current MLPlanBuilder object with the AutoSKLearn search space configuration. + * @throws IOException Throws an IOException if the search space config file could not be loaded. + */ + public MLPlanBuilder withAutoSKLearnConfig() throws IOException { + this.classifierFactory = new SKLearnClassifierFactory(); + return this.withDefaultConfiguration(EDefaultConfig.SKLEARN); + } + + public MLPlanBuilder withTpotConfig() throws IOException { + this.classifierFactory = new SKLearnClassifierFactory(); + return this.withDefaultConfiguration(EDefaultConfig.SKLEARN_UL); + } + + public MLPlanBuilder withAutoWEKAConfiguration() throws IOException { + this.classifierFactory = new WEKAPipelineFactory(); + this.pipelineValidityCheckingNodeEvaluator = new WekaPipelineValidityCheckingNodeEvaluator(); + return this.withDefaultConfiguration(EDefaultConfig.AUTO_WEKA); + } + + public MLPlanBuilder withTinyTestConfiguration() throws IOException { + this.classifierFactory = new WEKAPipelineFactory(); + this.pipelineValidityCheckingNodeEvaluator = new WekaPipelineValidityCheckingNodeEvaluator(); + return this.withDefaultConfiguration(EDefaultConfig.TINYTEST); + } + + public MLPlanBuilder withMekaDefaultConfiguration() throws IOException { + this.withDefaultConfiguration(EDefaultConfig.MEKA); + this.singleLabelPerformanceMeasure = null; + this.multiLabelPerformanceMeasure = EMultilabelPerformanceMeasure.AUTO_MEKA_GGP_FITNESS_LOSS; + this.splitBasedClassifierEvaluator = new SimpleMLCSplitBasedClassifierEvaluator(new AutoMEKAGGPFitnessMeasureLoss()); + this.classifierFactory = new MekaPipelineFactory(); + this.requestedHASCOInterface = MLC_REQUESTED_HASCO_INTERFACE; + this.withDatasetSplitterForSearchSelectionSplit(new ArbitrarySplitter()); + this.withSearchPhaseDatasetSplitter(new ArbitrarySplitter()); + this.withSelectionPhaseDatasetSplitter(new ArbitrarySplitter()); + return this; + } + + private MLPlanBuilder withDefaultConfiguration(final EDefaultConfig defConfig) throws IOException { + if (this.searchSpaceConfigFile == null) { + this.withSearchSpaceConfigFile(defConfig.getSearchSpaceConfigFile()); + } + this.withPreferredComponentsFile(defConfig.preferredComponentsFile); + this.withRandomCompletionBasedBestFirstSearch(); + if (defConfig != EDefaultConfig.MEKA && this.singleLabelPerformanceMeasure == null) { + this.singleLabelPerformanceMeasure = EMultiClassPerformanceMeasure.ERRORRATE; + this.withSingleLabelClassificationMeasure(this.singleLabelPerformanceMeasure); + } + + /* use MCCV for pipeline evaluation */ + int mccvIterationsDuringSearch = 5; + int mccvIterationsDuringSelection = 5; + double mccvPortion = 0.7; + if (!(this.factoryForPipelineEvaluationInSearchPhase instanceof MonteCarloCrossValidationEvaluatorFactory)) { + this.factoryForPipelineEvaluationInSearchPhase = new MonteCarloCrossValidationEvaluatorFactory().withNumMCIterations(mccvIterationsDuringSearch).withTrainFoldSize(mccvPortion).withSplitBasedEvaluator(new SimpleSLCSplitBasedClassifierEvaluator(new ZeroOneLoss())); + } + if (!(this.factoryForPipelineEvaluationInSelectionPhase instanceof MonteCarloCrossValidationEvaluatorFactory)) { + this.factoryForPipelineEvaluationInSelectionPhase = new MonteCarloCrossValidationEvaluatorFactory().withNumMCIterations(mccvIterationsDuringSearch).withTrainFoldSize(mccvPortion).withSplitBasedEvaluator(new SimpleSLCSplitBasedClassifierEvaluator(new ZeroOneLoss())); + } + + /* configure blow-ups for MCCV */ + double blowUpInSelectionPhase = MathExt.round(1f / mccvPortion * mccvIterationsDuringSelection / mccvIterationsDuringSearch, 2); + this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_BLOWUP_SELECTION, String.valueOf(blowUpInSelectionPhase)); + double blowUpInPostprocessing = MathExt.round((1 / (1 - this.algorithmConfig.dataPortionForSelection())) / mccvIterationsDuringSelection, 2); + this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_BLOWUP_POSTPROCESS, String.valueOf(blowUpInPostprocessing)); + return this; + } + + public MLPlanBuilder withPreferredComponentsFile(final File preferredComponentsFile) throws IOException { + this.getAlgorithmConfig().setProperty(MLPlanClassifierConfig.PREFERRED_COMPONENTS, preferredComponentsFile.getAbsolutePath()); + List ordering; + if (!preferredComponentsFile.exists()) { + this.logger.warn("The configured file for preferred components \"{}\" does not exist. Not using any particular ordering.", preferredComponentsFile.getAbsolutePath()); + ordering = new ArrayList<>(); + } else { + ordering = FileUtil.readFileAsList(preferredComponentsFile); + } + return this.withPreferredNodeEvaluator(new PreferenceBasedNodeEvaluator(this.components, ordering)); + } + + /** + * Loads the MLPlanClassifierConfig with default values and replaces all properties according to the properties defined in the given config file. + * + * @param algorithmConfigFile The file specifying the property values to replace the default configuration. + * @return The MLPlanBuilder object. + * @throws IOException An IOException is thrown if there are issues reading the config file. + */ + public MLPlanBuilder withAlgorithmConfigFile(final File algorithmConfigFile) { + return this.withAlgorithmConfig((MLPlanClassifierConfig) ConfigFactory.create(MLPlanClassifierConfig.class).loadPropertiesFromFile(algorithmConfigFile)); + } + + public MLPlanBuilder withAlgorithmConfig(final MLPlanClassifierConfig config) { + this.algorithmConfig = config; + this.hascoFactory.withAlgorithmConfig(this.algorithmConfig); + this.updateEverything(); + return this; + } + + public MLPlanBuilder withSingleLabelClassificationMeasure(final EMultiClassPerformanceMeasure measure) { + this.singleLabelPerformanceMeasure = measure; + return this.withSplitBasedClassifierEvaluator(this.getSingleLabelEvaluationMeasurementBridge(new MultiClassMeasureBuilder().getEvaluator(measure))); + } + + public MLPlanBuilder withMultiLabelClassificationMeasure(final EMultilabelPerformanceMeasure measure) { + this.multiLabelPerformanceMeasure = measure; + return this.withSplitBasedClassifierEvaluator(this.getMultiLabelEvaluationMeasurementBridge(new MultiClassMeasureBuilder().getEvaluator(measure))); + } + + /** + * This ADDs a new preferred node evaluator; requires that the search will be a best-first search. + * + * It is possible to specify several preferred node evaluators, which will be ordered by the order in which they are specified. The latest given evaluator is the most preferred one. + * + * @param preferredNodeEvaluator + * @return + */ + public MLPlanBuilder withPreferredNodeEvaluator(final INodeEvaluator preferredNodeEvaluator) { + if (this.factoryPreparedWithData) { + throw new IllegalStateException("The method prepareNodeEvaluatorInFactoryWithData has already been called. No changes to the preferred node evaluator possible anymore"); + } + + /* first update the preferred node evaluator */ + if (this.preferredNodeEvaluator == null) { + this.preferredNodeEvaluator = preferredNodeEvaluator; + } else { + this.preferredNodeEvaluator = new AlternativeNodeEvaluator<>(preferredNodeEvaluator, this.preferredNodeEvaluator); + } + this.updateEverything(); + return this; + } + + public MLPlanBuilder withSplitBasedClassifierEvaluator(final ISplitBasedClassifierEvaluator evaluator) { + this.splitBasedClassifierEvaluator = evaluator; + return this; + } + + @SuppressWarnings("unchecked") + public MLPlanBuilder withSearchFactory(@SuppressWarnings("rawtypes") final IOptimalPathInORGraphSearchFactory searchFactory, @SuppressWarnings("rawtypes") final AlgorithmicProblemReduction transformer) { + this.hascoFactory.setSearchFactory(searchFactory); + this.hascoFactory.setSearchProblemTransformer(transformer); + return this; + } + + @SuppressWarnings("unchecked") + public MLPlanBuilder withRandomCompletionBasedBestFirstSearch() { + this.hascoFactory.setSearchFactory(new StandardBestFirstFactory()); + this.updateEverything(); + return this; + } + + public MLPlanBuilder withTimeoutForSingleSolutionEvaluation(final TimeOut timeout) { + this.getAlgorithmConfig().setProperty(MLPlanClassifierConfig.K_RANDOM_COMPLETIONS_TIMEOUT_PATH, String.valueOf(timeout.milliseconds())); + this.updateEverything(); + return this; + } + + public MLPlanBuilder withTimeoutForNodeEvaluation(final TimeOut timeout) { + this.getAlgorithmConfig().setProperty(MLPlanClassifierConfig.K_RANDOM_COMPLETIONS_TIMEOUT_NODE, String.valueOf(timeout.milliseconds())); + this.updateEverything(); + return this; + } + + public void prepareNodeEvaluatorInFactoryWithData(final Instances data) { + if (!(this.hascoFactory instanceof HASCOViaFDAndBestFirstFactory)) { + return; + } + if (this.factoryPreparedWithData) { + throw new IllegalStateException("Factory has already been prepared with data. This can only be done once!"); + } + this.factoryPreparedWithData = true; + + /* nothing to do if there are no preferred node evaluators */ + if (this.pipelineValidityCheckingNodeEvaluator == null && this.preferredNodeEvaluator == null) { + return; + } + + /* now determine the real node evaluator to be used. A semantic node evaluator has highest priority */ + INodeEvaluator actualNodeEvaluator; + if (this.pipelineValidityCheckingNodeEvaluator != null) { + this.pipelineValidityCheckingNodeEvaluator.setComponents(this.components); + this.pipelineValidityCheckingNodeEvaluator.setData(data); + if (this.preferredNodeEvaluator != null) { + actualNodeEvaluator = new AlternativeNodeEvaluator<>(this.pipelineValidityCheckingNodeEvaluator, this.preferredNodeEvaluator); + } else { + actualNodeEvaluator = this.pipelineValidityCheckingNodeEvaluator; + } + } else { + actualNodeEvaluator = this.preferredNodeEvaluator; + } + + /* update the preferred node evaluator in the HascoFactory */ + this.preferredNodeEvaluator = actualNodeEvaluator; + this.updateEverything(); + } + + @SuppressWarnings("unchecked") + private void updateSearchProblemTransformer() { + this.hascoFactory.setSearchProblemTransformer(new GraphSearchProblemInputToGraphSearchWithSubpathEvaluationInputTransformerViaRDFS(this.preferredNodeEvaluator, this.priorizingPredicate, + this.algorithmConfig.randomSeed(), this.algorithmConfig.numberOfRandomCompletions(), this.algorithmConfig.timeoutForCandidateEvaluation(), this.algorithmConfig.timeoutForNodeEvaluation())); + + } + + private void updateAlgorithmConfigOfHASCO() { + this.hascoFactory.withAlgorithmConfig(this.getAlgorithmConfig()); + } + + private void updateEverything() { + this.updateSearchProblemTransformer(); + this.updateAlgorithmConfigOfHASCO(); + } + + /** + * @return The dataset splitter that is used for separating search and selection data. + */ + public IDatasetSplitter getSearchSelectionDatasetSplitter() { + return this.searchSelectionDatasetSplitter; + } + + /** + * @return The dataset splitter to be used in search phase for generating benchmark splits. + */ + public IDatasetSplitter getSearchPhaseDatasetSplitter() { + return this.searchPhaseDatasetSplitter; + } + + /** + * @return The dataset splitter to be used in selection phase for generating benchmark splits. + */ + public IDatasetSplitter getSelectionPhaseDatasetSplitter() { + return this.selectionPhaseDatasetSplitter; + } + + /** + * @return The interface that is requested to be provided by a solution candidate component instance. + */ + public String getRequestedInterface() { + return this.requestedHASCOInterface; + } + + // public void withExtrapolatedSaturationPointEvaluation(final int[] anchorpoints, final ISamplingAlgorithmFactory> subsamplingAlgorithmFactory, + // final double trainSplitForAnchorpointsMeasurement, final LearningCurveExtrapolationMethod extrapolationMethod) { + // this.builderForPipelineEvaluationInSearchPhase = new ExtrapolatedSaturationPointEvaluatorFactory(anchorpoints, subsamplingAlgorithmFactory, trainSplitForAnchorpointsMeasurement, extrapolationMethod); + // + // } + + public void withLearningCurveExtrapolationEvaluation(final int[] anchorpoints, final ISamplingAlgorithmFactory> subsamplingAlgorithmFactory, + final double trainSplitForAnchorpointsMeasurement, final LearningCurveExtrapolationMethod extrapolationMethod) { + this.factoryForPipelineEvaluationInSearchPhase = new LearningCurveExtrapolationEvaluatorFactory(anchorpoints, subsamplingAlgorithmFactory, trainSplitForAnchorpointsMeasurement, extrapolationMethod); + // this.factoryForPipelineEvaluationInSelectionPhase = new LearningCurveExtrapolationEvaluatorFactory(anchorpoints, subsamplingAlgorithmFactory, trainSplitForAnchorpointsMeasurement, extrapolationMethod); + this.factoryForPipelineEvaluationInSelectionPhase = new MonteCarloCrossValidationEvaluatorFactory().withNumMCIterations(3).withTrainFoldSize(.7).withSplitBasedEvaluator(new SimpleSLCSplitBasedClassifierEvaluator(new ZeroOneLoss())); + this.algorithmConfig.setProperty(MLPlanClassifierConfig.K_BLOWUP_SELECTION, "" + 4); // evaluating on 1000 in selection MCCV is, assuming quadratic growth, roughly max 4 times costlier than search phase evaluations + } + + public boolean getUseCache() { + return this.useCache; + } + + public PerformanceDBAdapter getDBAdapter() { + return this.dbAdapter; + } + + public IClassifierFactory getClassifierFactory() { + return this.classifierFactory; + } + + public Collection getComponents() { + return this.components; + } + + public File getSearchSpaceConfigFile() { + return this.searchSpaceConfigFile; + } + + public MLPlanClassifierConfig getAlgorithmConfig() { + return this.algorithmConfig; + } + + public EMultiClassPerformanceMeasure getSingleLabelPerformanceMeasure() { + return this.singleLabelPerformanceMeasure; + } + + public EMultilabelPerformanceMeasure getMultiLabelPerformanceMeasure() { + return this.multiLabelPerformanceMeasure; + } + + public ISplitBasedClassifierEvaluator getSingleLabelEvaluationMeasurementBridge(final IMeasure measure) { + if (this.splitBasedClassifierEvaluator == null) { + if (this.getUseCache()) { + return new CacheEvaluatorMeasureBridge(measure, this.getDBAdapter()); + } else { + return new SimpleSLCSplitBasedClassifierEvaluator(measure); + } + } else { + return this.splitBasedClassifierEvaluator; + } + } + + public ISplitBasedClassifierEvaluator getMultiLabelEvaluationMeasurementBridge(final IMeasure measure) { + if (this.splitBasedClassifierEvaluator == null) { + return new SimpleMLCSplitBasedClassifierEvaluator(measure); + } else { + return this.splitBasedClassifierEvaluator; + } + } + + @SuppressWarnings("rawtypes") + public HASCOFactory getHASCOFactory() { + return this.hascoFactory; + } + + // public ISplitBasedClassifierEvaluator getEvaluationMeasurementBridge() { + // if (this.splitBasedClassifierEvaluator != null) { + // return this.splitBasedClassifierEvaluator; + // } + // + // if (this.measure != null) { + // return this.getSingleLabelEvaluationMeasurementBridge(this.measure); + // } else { + // throw new IllegalStateException("Can not create evaluator measure bridge without a measure."); + // } + // } + + @Override + public String toString() { + Map fields = new HashMap<>(); + fields.put("algorithmConfig", this.getAlgorithmConfig()); + fields.put("classifierFactory", this.classifierFactory); + return ToJSONStringUtil.toJSONString(fields); + } + + public IClassifierEvaluatorFactory getFactoryForPipelineEvaluationInSearchPhase() { + return this.factoryForPipelineEvaluationInSearchPhase; + } + + public IClassifierEvaluatorFactory getFactoryForPipelineEvaluationInSelectionPhase() { + return this.factoryForPipelineEvaluationInSelectionPhase; + } + + public PipelineEvaluator getClassifierEvaluationInSearchPhase(final Instances data, final int seed, final int fullDatasetSize) throws ClassifierEvaluatorConstructionFailedException { + if (this.factoryForPipelineEvaluationInSearchPhase == null) { + throw new IllegalStateException("No factory for pipeline evaluation in search phase has been set!"); + } + IClassifierEvaluator evaluator = this.factoryForPipelineEvaluationInSearchPhase.getIClassifierEvaluator(data, seed); + if (evaluator instanceof LearningCurveExtrapolationEvaluator) { + ((LearningCurveExtrapolationEvaluator) evaluator).setFullDatasetSize(fullDatasetSize); + } + return new PipelineEvaluator(this.getClassifierFactory(), evaluator, this.getAlgorithmConfig().timeoutForCandidateEvaluation()); + } + + public PipelineEvaluator getClassifierEvaluationInSelectionPhase(final Instances data, final int seed) throws ClassifierEvaluatorConstructionFailedException { + if (this.factoryForPipelineEvaluationInSelectionPhase == null) { + throw new IllegalStateException("No factory for pipeline evaluation in selection phase has been set!"); + } + return new PipelineEvaluator(this.getClassifierFactory(), this.factoryForPipelineEvaluationInSelectionPhase.getIClassifierEvaluator(data, seed), Integer.MAX_VALUE); + } +} diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanMekaBuilder.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanMekaBuilder.java index 9cfa36d0e5..4e93134868 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanMekaBuilder.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanMekaBuilder.java @@ -16,7 +16,7 @@ public class MLPlanMekaBuilder extends AbstractMLPlanBuilder { - private static final String RES_SSC_MEKA_COMPLETE = "automl/searchmodels/meka/meka-multilabel.json"; + private static final String RES_SSC_MEKA_COMPLETE = "automl/searchmodels/meka/mlplan-meka.json"; private static final String FS_SSC_MEKA_COMPLETE = "conf/mlplan-meka.json"; private static final String RES_PREFC_MEKA = "mlplan/meka-preferenceList.txt"; diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanSKLearnBuilder.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanSKLearnBuilder.java index 7eb192514f..f064287913 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanSKLearnBuilder.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/MLPlanSKLearnBuilder.java @@ -25,8 +25,13 @@ public class MLPlanSKLearnBuilder extends AbstractMLPlanSingleLabelBuilder { private Logger logger = LoggerFactory.getLogger(MLPlanSKLearnBuilder.class); - private static final String PYTHON_REQUIRED_VERSION = "Python 3.6.*"; - private static final String[] PYTHON_REQUIRED_MODULES = { "numpy", "json", "pickle", "os", "sys", "warnings", "scipy.io.arff", "sklearn" }; + private static final String MSG_MODULE_NOT_AVAILABLE = "Could not load python module {}: {}"; + private static final String PYTHON_MINIMUM_REQUIRED_VERSION = "Python 3.5.0"; + private static final int PYTHON_MINIMUM_REQUIRED_VERSION_REL = 3; + private static final int PYTHON_MINIMUM_REQUIRED_VERSION_MAJ = 5; + private static final int PYTHON_MINIMUM_REQUIRED_VERSION_MIN = 0; + + private static final String[] PYTHON_REQUIRED_MODULES = { "arff", "numpy", "json", "pickle", "os", "sys", "warnings", "scipy", "sklearn" }; private static final String COMMAND_PYTHON = "python"; private static final String[] COMMAND_PYTHON_VERSION = { COMMAND_PYTHON, "--version" }; @@ -101,9 +106,21 @@ private void checkPythonSetup() { } } String versionString = sb.toString(); - String regEx = PYTHON_REQUIRED_VERSION.replaceAll("\\.", "\\\\\\.").replaceAll("\\*", "[0-9]"); - if (!versionString.matches(regEx)) { - throw new SystemRequirementsNotMetException("The installed python version does not match the required " + PYTHON_REQUIRED_VERSION); + if (!versionString.startsWith("Python ")) { + throw new SystemRequirementsNotMetException("Could not detect valid python version."); + } + + String[] versionSplit = versionString.substring(7).split("\\."); + if (versionSplit.length != 3) { + throw new SystemRequirementsNotMetException("Could not parse python version to be of the shape X.X.X"); + } + + int rel = Integer.parseInt(versionSplit[0]); + int maj = Integer.parseInt(versionSplit[1]); + int min = Integer.parseInt(versionSplit[2]); + + if (!this.isValidVersion(rel, maj, min)) { + throw new SystemRequirementsNotMetException("Python version does not conform the minimum required python version of " + PYTHON_MINIMUM_REQUIRED_VERSION); } /* Check whether we have all required python modules available*/ @@ -137,8 +154,16 @@ private void checkPythonSetup() { } } if (!errorSB.toString().isEmpty() && errorSB.toString().contains(PYTHON_MODULE_NOT_FOUND_ERROR_MSG)) { - this.logger.debug("Could not load python module {}: {}", module, errorSB); - modulesNotFound.add(module); + if (module.equals("arff")) { + this.logger.debug(MSG_MODULE_NOT_AVAILABLE, "liac-arff", errorSB); + modulesNotFound.add("liac-arff"); + } else if (module.equals("sklearn")) { + this.logger.debug(MSG_MODULE_NOT_AVAILABLE, "scikit-learn", errorSB); + modulesNotFound.add("scikit-learn"); + } else { + this.logger.debug(MSG_MODULE_NOT_AVAILABLE, module, errorSB); + modulesNotFound.add(module); + } } } if (!modulesNotFound.isEmpty()) { @@ -151,6 +176,11 @@ private void checkPythonSetup() { } } + private boolean isValidVersion(final int rel, final int maj, final int min) { + return ((rel > PYTHON_MINIMUM_REQUIRED_VERSION_REL) || (rel == PYTHON_MINIMUM_REQUIRED_VERSION_REL && maj > PYTHON_MINIMUM_REQUIRED_VERSION_MAJ) + || (rel == PYTHON_MINIMUM_REQUIRED_VERSION_REL && maj == PYTHON_MINIMUM_REQUIRED_VERSION_MAJ && min >= PYTHON_MINIMUM_REQUIRED_VERSION_MIN)); + } + @Override protected IDatasetSplitter getDefaultDatasetSplitter() { return new MulticlassClassStratifiedSplitter(); diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/PipelineEvaluator.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/PipelineEvaluator.java index 6e8a1dd71f..1166c5211d 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/PipelineEvaluator.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/PipelineEvaluator.java @@ -14,6 +14,7 @@ import ai.libs.jaicore.basic.events.IEvent; import ai.libs.jaicore.basic.events.IEventEmitter; import ai.libs.jaicore.ml.evaluation.evaluators.weka.IClassifierEvaluator; +import ai.libs.jaicore.ml.scikitwrapper.ScikitLearnWrapper; import ai.libs.jaicore.timing.TimedObjectEvaluator; import ai.libs.mlplan.core.events.ClassifierCreatedEvent; import ai.libs.mlplan.multiclass.wekamlplan.IClassifierFactory; @@ -71,9 +72,13 @@ public Double evaluateSupervised(final ComponentInstance c) throws InterruptedEx } Classifier classifier = this.classifierFactory.getComponentInstantiation(c); this.eventBus.post(new ClassifierCreatedEvent(c, classifier)); // inform listeners about the creation of the classifier - this.logger.debug("Starting benchmark {} for classifier {}", this.benchmark, classifier.getClass().getName()); + if (this.logger.isDebugEnabled()) { + this.logger.debug("Starting benchmark {} for classifier {}", this.benchmark, (classifier instanceof ScikitLearnWrapper) ? classifier.toString() : classifier.getClass().getName()); + } Double score = this.benchmark.evaluate(classifier); - this.logger.info("Obtained score {} for classifier {}", score, classifier.getClass().getName()); + if (this.logger.isInfoEnabled()) { + this.logger.info("Obtained score {} for classifier {}", score, (classifier instanceof ScikitLearnWrapper) ? classifier.toString() : classifier.getClass().getName()); + } return score; } catch (ComponentInstantiationFailedException e) { throw new ObjectEvaluationFailedException("Evaluation of composition failed as the component instantiation could not be built.", e); diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/PipelineValidityCheckingNodeEvaluator.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/PipelineValidityCheckingNodeEvaluator.java index 92d062e798..29aabce4d4 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/PipelineValidityCheckingNodeEvaluator.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/core/PipelineValidityCheckingNodeEvaluator.java @@ -4,7 +4,7 @@ import ai.libs.hasco.model.Component; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; import weka.core.Instances; public abstract class PipelineValidityCheckingNodeEvaluator implements INodeEvaluator { diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/MLPlanWekaClassifier.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/MLPlanWekaClassifier.java index b9f8342622..89d0fbbbfd 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/MLPlanWekaClassifier.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/MLPlanWekaClassifier.java @@ -18,11 +18,11 @@ import ai.libs.jaicore.graphvisualizer.window.AlgorithmVisualizationWindow; import ai.libs.jaicore.ml.evaluation.IInstancesClassifier; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNodeInfoGenerator; +import ai.libs.jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; +import ai.libs.jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; import ai.libs.mlplan.core.AbstractMLPlanBuilder; import ai.libs.mlplan.core.MLPlan; import ai.libs.mlplan.multiclass.MLPlanClassifierConfig; -import jaicore.search.gui.plugins.rollouthistograms.SearchRolloutHistogramPlugin; -import jaicore.search.model.travesaltree.JaicoreNodeInfoGenerator; import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import weka.classifiers.Classifier; diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/sklearn/SKLearnClassifierFactory.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/sklearn/SKLearnClassifierFactory.java index cae420f830..e218836478 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/sklearn/SKLearnClassifierFactory.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/sklearn/SKLearnClassifierFactory.java @@ -69,7 +69,7 @@ public String extractSKLearnConstructInstruction(final ComponentInstance groundC importSet.add("from " + fromSB.toString() + " import " + className + "\n"); if (groundComponent.getComponent().getName().startsWith("sklearn.feature_selection.f_classif")) { - sb.append("sklearn.feature_selection.f_classif(features, targets)"); + sb.append("f_classif(features, targets)"); return sb.toString(); } diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/weka/PreferenceBasedNodeEvaluator.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/weka/PreferenceBasedNodeEvaluator.java index 8450586207..f75c63a5a0 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/weka/PreferenceBasedNodeEvaluator.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/weka/PreferenceBasedNodeEvaluator.java @@ -12,26 +12,32 @@ import ai.libs.hasco.model.Component; import ai.libs.hasco.model.ComponentInstance; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; -import jaicore.search.model.travesaltree.Node; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.INodeEvaluator; +import ai.libs.jaicore.search.model.travesaltree.Node; public class PreferenceBasedNodeEvaluator implements INodeEvaluator { private final Collection components; - private final List ORDERING_OF_CLASSIFIERS; + private final List orderingOfComponents; private final static Logger logger = LoggerFactory.getLogger(PreferenceBasedNodeEvaluator.class); private boolean sentLogMessageForHavingEnteredSecondSubPhase = false; + private String methodPrefix = "resolveAbstractClassifierWith"; - public PreferenceBasedNodeEvaluator(final Collection components, final List ORDERING_OF_CLASSIFIERS) { + public PreferenceBasedNodeEvaluator(final Collection components, final List orderingOfComponents) { super(); this.components = components; - this.ORDERING_OF_CLASSIFIERS = ORDERING_OF_CLASSIFIERS; + this.orderingOfComponents = orderingOfComponents; } public PreferenceBasedNodeEvaluator(final Collection components) { this(components, new ArrayList<>()); } + public PreferenceBasedNodeEvaluator(final Collection components, final List orderingOfComponents, final String methodPrefix) { + this(components, orderingOfComponents); + this.methodPrefix = methodPrefix; + } + @Override public Double f(final Node n) { List appliedMethods = new LinkedList<>(); @@ -59,15 +65,15 @@ public Double f(final Node n) { } } else { classifierName = instance.getComponent().getName(); - lastMethod = lastMethod || appliedMethods.get(appliedMethods.size() - 1).startsWith("resolveAbstractClassifierWith"); + lastMethod = lastMethod || appliedMethods.get(appliedMethods.size() - 1).startsWith(this.methodPrefix); } if (lastMethod) { if (isPipeline) { - score += this.ORDERING_OF_CLASSIFIERS.size() + 1; + score += this.orderingOfComponents.size() + 1; } - score += (this.ORDERING_OF_CLASSIFIERS.contains(classifierName) ? this.ORDERING_OF_CLASSIFIERS.indexOf(classifierName) + 1 : this.ORDERING_OF_CLASSIFIERS.size() + 1); + score += (this.orderingOfComponents.contains(classifierName) ? this.orderingOfComponents.indexOf(classifierName) + 1 : this.orderingOfComponents.size() + 1); score *= 1.0e-10; } else { score = null; @@ -85,6 +91,6 @@ public Double f(final Node n) { @Override public String toString() { - return "PreferenceBasedNodeEvaluator [ORDERING_OF_CLASSIFIERS=" + this.ORDERING_OF_CLASSIFIERS + "]"; + return "PreferenceBasedNodeEvaluator [ORDERING_OF_CLASSIFIERS=" + this.orderingOfComponents + "]"; } } diff --git a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/weka/WekaPipelineValidityCheckingNodeEvaluator.java b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/weka/WekaPipelineValidityCheckingNodeEvaluator.java index 0b15a680b3..b6faa21e0b 100644 --- a/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/weka/WekaPipelineValidityCheckingNodeEvaluator.java +++ b/softwareconfiguration/mlplan/src/main/java/ai/libs/mlplan/multiclass/wekamlplan/weka/WekaPipelineValidityCheckingNodeEvaluator.java @@ -8,9 +8,9 @@ import ai.libs.hasco.model.ComponentInstance; import ai.libs.jaicore.ml.WekaUtil; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.exceptions.ControlledNodeEvaluationException; +import ai.libs.jaicore.search.model.travesaltree.Node; import ai.libs.mlplan.core.PipelineValidityCheckingNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.exceptions.ControlledNodeEvaluationException; -import jaicore.search.model.travesaltree.Node; import weka.core.Attribute; import weka.core.Instance; import weka.core.Instances; diff --git a/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/AutoMLAlgorithmResultProductionTester.java b/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/AutoMLAlgorithmResultProductionTester.java index ec5d151f30..a049d2a530 100644 --- a/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/AutoMLAlgorithmResultProductionTester.java +++ b/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/AutoMLAlgorithmResultProductionTester.java @@ -47,7 +47,7 @@ public abstract class AutoMLAlgorithmResultProductionTester { private static final Logger logger = LoggerFactory.getLogger(AutoMLAlgorithmResultProductionTester.class); - private static final TimeOut timeout = new TimeOut(2, TimeUnit.MINUTES); + private static final TimeOut timeout = new TimeOut(10, TimeUnit.MINUTES); // creates the test data @Parameters(name = "{0}") @@ -56,27 +56,27 @@ public static Collection data() throws IOException, Exceptio problemSets.add(new OpenMLProblemSet(3)); // kr-vs-kp problemSets.add(new OpenMLProblemSet(1150)); // AP_Breast_Lung problemSets.add(new OpenMLProblemSet(1156)); // AP_Omentum_Ovary - // problemSets.add(new OpenMLProblemSet(1152)); // AP_Prostate_Ovary - // problemSets.add(new OpenMLProblemSet(1240)); // AirlinesCodrnaAdult + problemSets.add(new OpenMLProblemSet(1152)); // AP_Prostate_Ovary + problemSets.add(new OpenMLProblemSet(1240)); // AirlinesCodrnaAdult problemSets.add(new OpenMLProblemSet(1457)); // amazon problemSets.add(new OpenMLProblemSet(1501)); // semeion - // problemSets.add(new OpenMLProblemSet(149)); // CovPokElec - // problemSets.add(new OpenMLProblemSet(41103)); // cifar-10 - // problemSets.add(new OpenMLProblemSet(40668)); // connect-4 + problemSets.add(new OpenMLProblemSet(149)); // CovPokElec + problemSets.add(new OpenMLProblemSet(41103)); // cifar-10 + problemSets.add(new OpenMLProblemSet(40668)); // connect-4 problemSets.add(new OpenMLProblemSet(1590)); // adult - // problemSets.add(new OpenMLProblemSet(182)); // satimage - // problemSets.add(new OpenMLProblemSet(24)); // mushroom + problemSets.add(new OpenMLProblemSet(182)); // satimage + problemSets.add(new OpenMLProblemSet(24)); // mushroom problemSets.add(new OpenMLProblemSet(39)); // ecoli problemSets.add(new OpenMLProblemSet(44)); // spambase problemSets.add(new OpenMLProblemSet(60)); // waveform-5000 problemSets.add(new OpenMLProblemSet(61)); // iris problemSets.add(new OpenMLProblemSet(9)); // autos - // problemSets.add(new OpenMLProblemSet(1039)); // hiva-agnostic - // problemSets.add(new OpenMLProblemSet(1104)); // leukemia - // problemSets.add(new OpenMLProblemSet(1101)); // lymphoma_2classes + problemSets.add(new OpenMLProblemSet(1039)); // hiva-agnostic + problemSets.add(new OpenMLProblemSet(1104)); // leukemia + problemSets.add(new OpenMLProblemSet(1101)); // lymphoma_2classes problemSets.add(new OpenMLProblemSet(554)); // mnist - // problemSets.add(new OpenMLProblemSet(1101)); // lymphoma_2classes - // problemSets.add(new OpenMLProblemSet(155)); // pokerhand + problemSets.add(new OpenMLProblemSet(1101)); // lymphoma_2classes + problemSets.add(new OpenMLProblemSet(155)); // pokerhand problemSets.add(new OpenMLProblemSet(40691)); // winequality OpenMLProblemSet[][] data = new OpenMLProblemSet[problemSets.size()][1]; @@ -99,17 +99,17 @@ public void testThatModelIsTrained() throws Exception { assertFalse("The thread should not be interrupted when calling the AutoML-tool!", Thread.currentThread().isInterrupted()); /* create instances and set attribute */ - logger.info("Loading dataset {} from {} for test.", this.problemSet.getName(), this.problemSet.getDatasetSource().getX()); - File cacheFile = new File("testrsc/openml/" + this.problemSet.getId() + ".arff"); + logger.info("Loading dataset {} from {} for test.", problemSet.getName(), problemSet.getDatasetSource().getX()); + File cacheFile = new File("testrsc/openml/" + problemSet.getId() + ".arff"); if (!cacheFile.exists()) { logger.info("Cache file does not exist, creating it."); cacheFile.getParentFile().mkdirs(); - Instances dataset = this.problemSet.getDatasetSource().getX().getDataSet(); + Instances dataset = problemSet.getDatasetSource().getX().getDataSet(); DataSink.write(cacheFile.getAbsolutePath(), dataset); } logger.info("Loading ARFF file from cache."); Instances dataset = new Instances(new FileReader(cacheFile)); - Attribute targetAttribute = dataset.attribute(this.problemSet.getDatasetSource().getY()); + Attribute targetAttribute = dataset.attribute(problemSet.getDatasetSource().getY()); dataset.setClassIndex(targetAttribute.index()); String datasetname = dataset.relationName(); @@ -128,7 +128,7 @@ public void testThatModelIsTrained() throws Exception { /* get algorithm */ logger.info("Loading the algorithm"); - IAlgorithm algorithm = this.getAutoMLAlgorithm(train); // AutoML-tools should deliver a classifier + IAlgorithm algorithm = getAutoMLAlgorithm(train); // AutoML-tools should deliver a classifier assert algorithm != null : "The factory method has returned NULL as the algorithm object"; if (algorithm instanceof ILoggingCustomizable) { ((ILoggingCustomizable) algorithm).setLoggerName("testedalgorithm"); diff --git a/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanConfigConsistencyTester.java b/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanConfigConsistencyTester.java index 8faa872d7b..61d7df0c06 100644 --- a/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanConfigConsistencyTester.java +++ b/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanConfigConsistencyTester.java @@ -16,13 +16,13 @@ import ai.libs.jaicore.basic.TimeOut; import ai.libs.jaicore.basic.algorithm.events.AlgorithmEvent; import ai.libs.jaicore.basic.algorithm.events.AlgorithmInitializedEvent; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.BestFirst; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; +import ai.libs.jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; import ai.libs.mlplan.core.AbstractMLPlanBuilder; import ai.libs.mlplan.core.MLPlan; import ai.libs.mlplan.core.PipelineEvaluator; import ai.libs.mlplan.multiclass.MLPlanClassifierConfig; -import jaicore.search.algorithms.standard.bestfirst.BestFirst; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.AlternativeNodeEvaluator; -import jaicore.search.algorithms.standard.bestfirst.nodeevaluation.RandomCompletionBasedNodeEvaluator; import weka.core.Instances; /** diff --git a/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanGraphGeneratorTest.java b/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanGraphGeneratorTest.java index 8faa9f61ad..64d8f51bec 100644 --- a/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanGraphGeneratorTest.java +++ b/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanGraphGeneratorTest.java @@ -8,9 +8,9 @@ import ai.libs.jaicore.basic.sets.SetUtil.Pair; import ai.libs.jaicore.planning.hierarchical.algorithms.forwarddecomposition.graphgenerators.tfd.TFDNode; import ai.libs.jaicore.search.GraphGeneratorTester; +import ai.libs.jaicore.search.core.interfaces.GraphGenerator; import ai.libs.mlplan.core.AbstractMLPlanBuilder; import ai.libs.mlplan.core.MLPlan; -import jaicore.search.core.interfaces.GraphGenerator; import weka.core.Instances; public class MLPlanGraphGeneratorTest extends GraphGeneratorTester { diff --git a/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanResultDeliveryTester.java b/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanResultDeliveryTester.java index 66ef5a5391..02441bc572 100644 --- a/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanResultDeliveryTester.java +++ b/softwareconfiguration/mlplan/src/test/java/ai/libs/automl/mlplan/test/MLPlanResultDeliveryTester.java @@ -17,9 +17,9 @@ public class MLPlanResultDeliveryTester extends AutoMLAlgorithmResultProductionT public IAlgorithm getAutoMLAlgorithm(final Instances data) { try { AbstractMLPlanBuilder builder = AbstractMLPlanBuilder.forWeka(); - builder.withNodeEvaluationTimeOut(new TimeOut(15, TimeUnit.MINUTES)); - builder.withCandidateEvaluationTimeOut(new TimeOut(5, TimeUnit.MINUTES)); - builder.withNumCpus(4); + builder.withNodeEvaluationTimeOut(new TimeOut(5, TimeUnit.MINUTES)); + builder.withCandidateEvaluationTimeOut(new TimeOut(1, TimeUnit.MINUTES)); + builder.withNumCpus(8); MLPlan mlplan = new MLPlan(builder, data); mlplan.setRandomSeed(1); mlplan.setPortionOfDataForPhase2(.0f);