Project Import
parent
5347f216f8
commit
e30bdf2c06
|
|
@ -0,0 +1,55 @@
|
|||
# Covers the OneClick Learning files
|
||||
save/
|
||||
log/
|
||||
|
||||
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/dictionaries
|
||||
.idea/
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.xml
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# CMake
|
||||
cmake-build-debug/
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: de.unibonn:realKD:0.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.guava:guava:20.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: jline:jline:2.14.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-guava:2.8.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.javassist:javassist:3.19.0-GA" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.findbugs:annotations:2.0.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jfree:jfreechart:1.0.19" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jfree:jcommon:1.0.23" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.sf.opencsv:opencsv:2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: nz.ac.waikato.cms.weka:weka-stable:3.6.12" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.sf.squirrel-sql.thirdparty-non-maven:java-cup:0.11a" level="project" />
|
||||
<orderEntry type="library" name="Maven: junit:junit:4.11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: edu.uab:consapt:0.10.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.1" level="project" />
|
||||
<orderEntry type="module-library">
|
||||
<library name="Maven: com.oracle:javafx:8">
|
||||
<CLASSES>
|
||||
<root url="jar://$USER_HOME$/bin/jdk/jre/lib/ext/jfxrt.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="Maven: org.jetbrains:annotations:15.0" level="project" />
|
||||
<orderEntry type="library" name="SPMF" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
|
||||
pwd=`pwd`
|
||||
|
||||
cd "./ressource"
|
||||
rm -v *.att *.tmp *.*dat
|
||||
|
||||
cd "../log"
|
||||
rm -v *.csv *.txt *.log
|
||||
|
||||
cd ".."
|
||||
rmdir log
|
||||
|
||||
cd $pwd
|
||||
Binary file not shown.
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>fr.irisa.lacodam</groupId>
|
||||
<artifactId>OneClick Learning</artifactId>
|
||||
<version>0.1</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<!-- RealKD -->
|
||||
<groupId>de.unibonn</groupId>
|
||||
<artifactId>realKD</artifactId>
|
||||
<version>0.4.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- Gson: Java to Json conversion -->
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- JavaFX -->
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>javafx</artifactId>
|
||||
<version>8</version>
|
||||
<systemPath>${java.home}/lib/ext/jfxrt.jar</systemPath>
|
||||
<scope>system</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>RELEASE</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>realKD</id>
|
||||
<url>https://bitbucket.org/realKD/releases/raw/master/releases</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
<updatePolicy>always</updatePolicy>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
<updatePolicy>always</updatePolicy>
|
||||
<checksumPolicy>warn</checksumPolicy>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,2 @@
|
|||
Manifest-Version: 1.0
|
||||
Main-Class: fr.insa.ocm.view.OCLApplication
|
||||
|
|
@ -0,0 +1,394 @@
|
|||
package fr.insa.ocm.model;
|
||||
|
||||
import fr.insa.ocm.model.wrapper.api.AbstractAlgorithmLauncher;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.DecimalFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
public class DebugLogger {
|
||||
|
||||
public enum MessageSeverity{
|
||||
INFO, MEDIUM, HIGH, CRITICAL;
|
||||
|
||||
/**
|
||||
* With A and B a message severity.
|
||||
* A is higher or equals than B iff compareMatrix[A.getIndex][B.getIndex] is true;
|
||||
*/
|
||||
private final boolean[][] compareMatrix =
|
||||
{{true, false, false, false},
|
||||
{true, true, false, false},
|
||||
{true, true, true, false},
|
||||
{true, true, true, true}};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (this){
|
||||
case INFO:
|
||||
return "[Info]";
|
||||
case MEDIUM:
|
||||
return "[Medium]";
|
||||
case HIGH:
|
||||
return "[High]";
|
||||
case CRITICAL:
|
||||
return "[CRITICAL]";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public int getIndex(){
|
||||
switch (this){
|
||||
case INFO:
|
||||
return 0;
|
||||
case MEDIUM:
|
||||
return 1;
|
||||
case HIGH:
|
||||
return 2;
|
||||
case CRITICAL:
|
||||
return 3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHigher(MessageSeverity messageSeverity){
|
||||
return compareMatrix[this.getIndex()][messageSeverity.getIndex()];
|
||||
}
|
||||
}
|
||||
|
||||
// Informations used to print log message correctly
|
||||
private static final Semaphore semaphoreSERR = new Semaphore(1);
|
||||
private static final MessageSeverity threshold = MessageSeverity.INFO;
|
||||
private static long startLog;
|
||||
private static final DecimalFormat decimalFormat = new DecimalFormat("#0.000000");
|
||||
|
||||
// Paths used to serialize the debug informations
|
||||
public static final String directoryLog = "./log/";
|
||||
public static final String directorySave = "./save/";
|
||||
private static final String banditLog = directoryLog +"bandit.csv";
|
||||
private static final String coactiveLog = directoryLog +"coactive.csv";
|
||||
private static final String pathLog = directoryLog +"debug.log";
|
||||
private static final String qualityLog = directoryLog +"quality.log";
|
||||
private static final String algorithmLog = directoryLog +"algorithm.log";
|
||||
private static final String selectionDistributionLog = directoryLog + "selectionDistribution.log";
|
||||
|
||||
|
||||
static {
|
||||
List<String> listDirectory = new ArrayList<>();
|
||||
listDirectory.add(directoryLog);
|
||||
listDirectory.add(directorySave);
|
||||
for(String directory : listDirectory) {
|
||||
try {
|
||||
Path directoryPath = Paths.get(directory);
|
||||
if (!directoryPath.toFile().exists()) {
|
||||
Files.createDirectory(directoryPath);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
try(BufferedWriter writerLog = new BufferedWriter(new FileWriter(pathLog))){
|
||||
writerLog.write("OneClick Mining launched at: " + LocalDateTime.now());
|
||||
writerLog.newLine();
|
||||
writerLog.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try(BufferedWriter writerQuality = new BufferedWriter(new FileWriter(qualityLog))){
|
||||
writerQuality.write("id; quality");
|
||||
writerQuality.newLine();
|
||||
writerQuality.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
startLog = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints in the standard error channel you debug message with the default priority INFO.
|
||||
* @param msg The message you want to print.
|
||||
*/
|
||||
public static void printDebug(String msg){
|
||||
if (MessageSeverity.INFO.isHigher(threshold)){
|
||||
semaphoreSERR.acquireUninterruptibly();
|
||||
writeDebug("[Info]"+ msg);
|
||||
semaphoreSERR.release();
|
||||
}
|
||||
}
|
||||
|
||||
public static void printDebug(String msg, MessageSeverity msgSev){
|
||||
if (msgSev.isHigher(threshold)){
|
||||
semaphoreSERR.acquireUninterruptibly();
|
||||
writeDebug(msgSev + msg);
|
||||
semaphoreSERR.release();
|
||||
}
|
||||
}
|
||||
|
||||
public static void printQuality(String msg){
|
||||
try(BufferedWriter writer = new BufferedWriter(new FileWriter(qualityLog, true))){
|
||||
writer.write(msg);
|
||||
writer.newLine();
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void initializeBanditLog(){
|
||||
// Write the columns name at the beginning of the log file for the bandit.
|
||||
try(BufferedWriter writerBandit = new BufferedWriter(new FileWriter(banditLog))) {
|
||||
List<String> listAlgorithmNames = OCMManager.algorithmLauncherGetListAlgorithmName();
|
||||
|
||||
if (OCMManager.banditGetWeights().length == listAlgorithmNames.size()) {
|
||||
StringBuilder strBandit = new StringBuilder("");
|
||||
|
||||
strBandit = strBandit.append("Time;");
|
||||
for (int i = 0; i < listAlgorithmNames.size() - 1; ++i) {
|
||||
strBandit = strBandit.append(listAlgorithmNames.get(i)).append(';');
|
||||
}
|
||||
strBandit = strBandit.append(listAlgorithmNames.get(listAlgorithmNames.size() - 1)).append('\n');
|
||||
|
||||
writerBandit.write(strBandit.toString());
|
||||
writerBandit.close();
|
||||
} else {
|
||||
DebugLogger.printDebug("DebugLogger: The number of arms in the bandit does not match with the number of algorithms in the Algorithm Launcher", MessageSeverity.MEDIUM);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void logBandit(){
|
||||
try(BufferedWriter writerBandit = new BufferedWriter(new FileWriter(banditLog, true))){
|
||||
double[] armsBandit = OCMManager.banditGetWeights();
|
||||
StringBuilder strBandit = new StringBuilder("");
|
||||
|
||||
// Concatenate the values of the bandit within the string builder.
|
||||
strBandit = strBandit.append((System.currentTimeMillis() - startLog)/1000).append(';');
|
||||
for(int i = 0; i < armsBandit.length-1; ++i){
|
||||
strBandit.append(decimalFormat.format(armsBandit[i]));
|
||||
strBandit.append(';');
|
||||
}
|
||||
strBandit.append(decimalFormat.format(armsBandit[armsBandit.length-1]));
|
||||
strBandit.append('\n');
|
||||
|
||||
writerBandit.write(strBandit.toString());
|
||||
writerBandit.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void initializeCoactiveLog(){
|
||||
// Write the columns name at the beginning of the log file for the coactive learning.
|
||||
try(BufferedWriter writerCoactive = new BufferedWriter(new FileWriter(coactiveLog))){
|
||||
List<String> listAttributeNames = OCMManager.algorithmLauncherGetListAttributeName();
|
||||
List<String> listAlgorithmNames = OCMManager.algorithmLauncherGetListAlgorithmName();
|
||||
|
||||
if(OCMManager.coactiveGetWeights().length == listAttributeNames.size() + listAlgorithmNames.size() + Pattern.MeasureType.values().length){
|
||||
StringBuilder strCoactive = new StringBuilder("");
|
||||
|
||||
strCoactive.append("Time;");
|
||||
|
||||
// Add the names of the interestingness measures
|
||||
for(Pattern.MeasureType measure : Pattern.MeasureType.values()){
|
||||
strCoactive.append(measure.toString());
|
||||
strCoactive.append(';');
|
||||
}
|
||||
|
||||
// Add the names of the attributes
|
||||
for(int i = 0; i < listAttributeNames.size()-1; ++i){
|
||||
strCoactive.append(listAttributeNames.get(i));
|
||||
strCoactive.append(";");
|
||||
}
|
||||
strCoactive.append(listAttributeNames.get(listAttributeNames.size()-1));
|
||||
strCoactive.append(';');
|
||||
|
||||
// Add the names of the algorithms since they have a weight associated.
|
||||
for(String algorithmName : listAlgorithmNames){
|
||||
if(listAlgorithmNames.indexOf(algorithmName) != listAlgorithmNames.size()-1){
|
||||
strCoactive.append(algorithmName);
|
||||
strCoactive.append(';');
|
||||
} else {
|
||||
strCoactive.append(algorithmName);
|
||||
}
|
||||
}
|
||||
|
||||
writerCoactive.write(strCoactive.toString());
|
||||
writerCoactive.newLine();
|
||||
writerCoactive.close();
|
||||
} else {
|
||||
DebugLogger.printDebug("DebugLogger: The number of weights in the coactive learning does not match with the number of attributes in the Algorithm Launcher", MessageSeverity.MEDIUM);
|
||||
}
|
||||
|
||||
} catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void logCoactive(){
|
||||
try(BufferedWriter writerCoactive = new BufferedWriter(new FileWriter(coactiveLog, true))){
|
||||
double[] weightsCoactive = OCMManager.coactiveGetWeights();
|
||||
StringBuilder strCoactive = new StringBuilder("");
|
||||
|
||||
// Concatenate the values of the bandit within the string builder.
|
||||
strCoactive.append((System.currentTimeMillis() - startLog)/1000);
|
||||
strCoactive.append(';');
|
||||
for(int i = 0; i < weightsCoactive.length-1; ++i){
|
||||
strCoactive.append(decimalFormat.format(weightsCoactive[i]));
|
||||
strCoactive.append(';');
|
||||
}
|
||||
strCoactive.append(decimalFormat.format(weightsCoactive[weightsCoactive.length-1]));
|
||||
strCoactive.append('\n');
|
||||
|
||||
writerCoactive.write(strCoactive.toString());
|
||||
writerCoactive.close();
|
||||
} catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void initializeAlgorithmLog(){
|
||||
try(BufferedWriter writerAlgorithm = new BufferedWriter(new FileWriter(algorithmLog))){
|
||||
StringBuilder strAlgorithm = new StringBuilder("");
|
||||
|
||||
strAlgorithm.append("Time;");
|
||||
for(String algorithmName : AbstractAlgorithmLauncher.getAllAvailableAlgorithm()){
|
||||
strAlgorithm.append(algorithmName);
|
||||
strAlgorithm.append(';');
|
||||
}
|
||||
|
||||
strAlgorithm.deleteCharAt(strAlgorithm.length()-1);
|
||||
|
||||
writerAlgorithm.write(strAlgorithm.toString());
|
||||
writerAlgorithm.newLine();
|
||||
|
||||
writerAlgorithm.close();
|
||||
} catch (IOException e) {
|
||||
DebugLogger.printDebug("DebugLogger: Unable to startMonitoring the logging of the number of algorithm launched.", MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
public static void logAlgorithm(){
|
||||
try(BufferedWriter writerAlgorithm = new BufferedWriter(new FileWriter(algorithmLog, true))){
|
||||
StringBuilder strAlgorithm = new StringBuilder("");
|
||||
|
||||
strAlgorithm.append((System.currentTimeMillis() - startLog)/1000);
|
||||
strAlgorithm.append(';');
|
||||
|
||||
final Map<String, Integer> mapStatAlgorithmCall = AbstractAlgorithmLauncher.getStatsAlgorithmsLaunched();
|
||||
for(String algorithmName : AbstractAlgorithmLauncher.getAllAvailableAlgorithm()){
|
||||
strAlgorithm.append(mapStatAlgorithmCall.getOrDefault(algorithmName, 0));
|
||||
strAlgorithm.append(';');
|
||||
}
|
||||
|
||||
strAlgorithm.deleteCharAt(strAlgorithm.length()-1);
|
||||
|
||||
writerAlgorithm.write(strAlgorithm.toString());
|
||||
writerAlgorithm.newLine();
|
||||
|
||||
writerAlgorithm.close();
|
||||
} catch (IOException e){
|
||||
DebugLogger.printDebug("DebugLogger: Unable to log the current algorithm call count.", MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
public static void initializeSelectionDistributionLog(){
|
||||
try(BufferedWriter writerSD = new BufferedWriter(new FileWriter(selectionDistributionLog))){
|
||||
List<String> listAlgorithmName = OCMManager.algorithmLauncherGetListAlgorithmName();
|
||||
StringBuilder strName = new StringBuilder("");
|
||||
|
||||
strName.append("Time;");
|
||||
for(String name : listAlgorithmName){
|
||||
strName.append(name);
|
||||
strName.append(';');
|
||||
}
|
||||
|
||||
strName.deleteCharAt(strName.length()-1);
|
||||
|
||||
writerSD.write(strName.toString());
|
||||
writerSD.newLine();
|
||||
|
||||
writerSD.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static long lastSD = 0;
|
||||
public static void logSelectionDistribution(double[] dbl){
|
||||
if((System.currentTimeMillis() - startLog) / 1000 > lastSD) {
|
||||
lastSD = (System.currentTimeMillis() - startLog) / 1000;
|
||||
try (BufferedWriter writerTemporary = new BufferedWriter(new FileWriter(selectionDistributionLog, true))) {
|
||||
StringBuilder strAlgorithm = new StringBuilder("");
|
||||
|
||||
strAlgorithm.append((System.currentTimeMillis() - startLog) / 1000);
|
||||
strAlgorithm.append(';');
|
||||
|
||||
for (Double d : dbl) {
|
||||
strAlgorithm.append(decimalFormat.format(d));
|
||||
strAlgorithm.append(';');
|
||||
}
|
||||
|
||||
strAlgorithm.deleteCharAt(strAlgorithm.length() - 1);
|
||||
|
||||
writerTemporary.write(strAlgorithm.toString());
|
||||
writerTemporary.newLine();
|
||||
|
||||
writerTemporary.close();
|
||||
} catch (IOException e) {
|
||||
DebugLogger.printDebug("DebugLogger: Unable to log the logSelectionDistribution.", MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int lastB = 0;
|
||||
public static void logBeta(double d){
|
||||
if((System.currentTimeMillis() - startLog) / 1000 > lastB) {
|
||||
try (BufferedWriter writerTemporary = new BufferedWriter(new FileWriter(directoryLog + "beta.log", true))) {
|
||||
String strAlgorithm = ""
|
||||
+ (System.currentTimeMillis() - startLog) / 1000
|
||||
+ ';'
|
||||
+ decimalFormat.format(d);
|
||||
|
||||
writerTemporary.write(strAlgorithm);
|
||||
writerTemporary.newLine();
|
||||
|
||||
writerTemporary.close();
|
||||
} catch (IOException e) {
|
||||
DebugLogger.printDebug("DebugLogger: Unable to log the logSelectionDistribution.", MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//********** Internal Methods **********//
|
||||
|
||||
private static void writeDebug(String msg){
|
||||
try(BufferedWriter writer = new BufferedWriter(new FileWriter(pathLog, true))){
|
||||
writer.write("(");
|
||||
writer.write(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
||||
writer.write(") - ");
|
||||
writer.write(msg);
|
||||
writer.newLine();
|
||||
writer.close();
|
||||
} catch (IOException exception){
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
package fr.insa.ocm.model;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import fr.insa.ocm.model.utils.Rank;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import static java.lang.Integer.parseInt;
|
||||
|
||||
@Deprecated
|
||||
public class Main {
|
||||
|
||||
@Deprecated
|
||||
public static void main(String[] args) throws FileNotFoundException {
|
||||
//Redirecting standard error in a log file.
|
||||
File file = new File("log.txt");
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
PrintStream ps = new PrintStream(fos);
|
||||
// System.setErr(ps);
|
||||
|
||||
System.out.println("Welcome - OneClick Mining");
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
System.out.print("Please enter the path to the CSV file: ");
|
||||
String path = scanner.nextLine();
|
||||
|
||||
if(path.equals("")){
|
||||
path = "ressource/presidentielle2017.csv";
|
||||
}
|
||||
|
||||
OCMManager.initialize(Pattern.WrapperType.REALKD, path);
|
||||
System.out.println("Waiting for round 1 ...");
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
List<Pattern> results = OCMManager.getNewRanking(new Rank<>(), new Rank<>(),new Rank<>());
|
||||
int round = 1;
|
||||
boolean exit = false;
|
||||
while (!exit) {
|
||||
System.out.println("==========================");
|
||||
System.out.println("Current patterns - Round "+round);
|
||||
System.out.println("==========================\n");
|
||||
|
||||
|
||||
int i = 1;
|
||||
for (Pattern pattern : results) {
|
||||
System.out.format("%2d. %-60s %-15s %-15s %-15s %-15s\n", i, "Pattern", "Freq.", "Lift", "Rel. short.", "Target dev.");
|
||||
// System.out.format(" %-60s %-15f %-15f %-15f %-15f\n", pattern.toString(), pattern.getFrequency(), pattern.getLift(), pattern.getRelativeShortness(), pattern.getTargetDeviation());
|
||||
i++;
|
||||
}
|
||||
|
||||
boolean hasChosen = false;
|
||||
String selected = "", rejected = "";
|
||||
int[] selectedNb = {}, rejectedNb = {};
|
||||
while (!hasChosen) {
|
||||
System.out.print("\nPlease type your selected patterns (ex: 1 3 14): ");
|
||||
selected = scanner.nextLine();
|
||||
System.out.print("Please type your rejected patterns: ");
|
||||
rejected = scanner.nextLine();
|
||||
System.out.println(rejected);
|
||||
|
||||
int min = 1, max = results.size();
|
||||
selectedNb = parseStringToNumber(selected, min, max);
|
||||
rejectedNb = parseStringToNumber(rejected, min, max);
|
||||
|
||||
if (rejectedNb != null && selectedNb != null) {
|
||||
if (!(allDifferent(selectedNb))) {
|
||||
System.out.println("You can't select a pattern twice.");
|
||||
}
|
||||
else if (!(allDifferent(rejectedNb))) {
|
||||
System.out.println("You can't reject a pattern twice.");
|
||||
}
|
||||
else if (!(allDifferent(selectedNb, rejectedNb))) {
|
||||
System.out.println("You can't select and reject the same pattern.");
|
||||
} else {
|
||||
hasChosen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("You have selected patterns: " + selected + ".");
|
||||
System.out.println("You have rejected patterns: " + rejected + ".");
|
||||
|
||||
System.out.println("Results size: " + results.size());
|
||||
Rank<Pattern> selectedPatterns = new Rank<>();
|
||||
for (int index : selectedNb) {
|
||||
selectedPatterns.add(results.get(index-1));
|
||||
}
|
||||
Rank<Pattern> rejectedPatterns = new Rank<>();
|
||||
for (int index : rejectedNb) {
|
||||
rejectedPatterns.add(results.get(index-1));
|
||||
}
|
||||
int maxSelectedOrRejected = getMax(selectedNb, rejectedNb);
|
||||
Rank<Pattern> neutralPatterns = new Rank<>();
|
||||
if (maxSelectedOrRejected != -1) {
|
||||
for (int val=1; i<maxSelectedOrRejected; ++i) {
|
||||
neutralPatterns.add(results.get(i));
|
||||
}
|
||||
}
|
||||
neutralPatterns.removeAll(selectedPatterns);
|
||||
neutralPatterns.removeAll(rejectedPatterns);
|
||||
|
||||
System.out.print("Type m for MINING or exit to stop the program)");
|
||||
String mining = scanner.nextLine();
|
||||
|
||||
if (mining.equals("exit")) {
|
||||
exit = true;
|
||||
}
|
||||
|
||||
results = OCMManager.getNewRanking(selectedPatterns, neutralPatterns, rejectedPatterns);
|
||||
round++;
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] parseStringToNumber(String str, int min, int max) {
|
||||
if (str.length() == 0) {
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
int localMin = min, localMax = max;
|
||||
String[] s = str.split(" ");
|
||||
int[] sNb = new int[s.length];
|
||||
for(int j = 0; j<s.length; ++j) {
|
||||
sNb[j] = parseInt(s[j]);
|
||||
if (sNb[j] > max) {
|
||||
localMax = sNb[j];
|
||||
}
|
||||
if (sNb[j] < min) {
|
||||
localMin = sNb[j];
|
||||
}
|
||||
}
|
||||
if (localMax > max || localMin < min) {
|
||||
System.out.println("You must enter existing patterns from 1 to "+max);
|
||||
return null;
|
||||
}
|
||||
return sNb;
|
||||
}
|
||||
|
||||
private static boolean allDifferent(int[] tab) {
|
||||
for (int i=0; i<tab.length-1; ++i) {
|
||||
for (int j = i+1; j<tab.length; ++j) {
|
||||
if (tab[i] == tab[j]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean allDifferent(int[] tab1, int[] tab2) {
|
||||
for(int i : tab1) {
|
||||
for(int j : tab2) {
|
||||
if (i == j) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int getMax(int[] tab1, int[] tab2) {
|
||||
int max = -1;
|
||||
for(int i : tab1) {
|
||||
if (i>max) {
|
||||
max = i;
|
||||
}
|
||||
}
|
||||
for(int i : tab2) {
|
||||
if(i>max) {
|
||||
max = i;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
package fr.insa.ocm.model;
|
||||
|
||||
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.api.Cache;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.api.CoactiveLearning;
|
||||
import fr.insa.ocm.model.oneclicklearning.algorithmmanager.AlgorithmManager;
|
||||
import fr.insa.ocm.model.utils.PatternWarehouse;
|
||||
import fr.insa.ocm.model.utils.SystemState;
|
||||
import fr.insa.ocm.model.utils.Rank;
|
||||
import fr.insa.ocm.model.utils.exceptions.NotInitializedException;
|
||||
import fr.insa.ocm.model.utils.serialize.SearchSave;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OCMManager {
|
||||
|
||||
private static Pattern.WrapperType currentWrapperType;
|
||||
private static Cache.CacheType currentCacheType = Cache.CacheType.SET;
|
||||
private static CoactiveLearning.CoactiveType currentCoactiveType = CoactiveLearning.CoactiveType.SET;
|
||||
|
||||
private static final OCMManager INSTANCE = new OCMManager();
|
||||
|
||||
// Main modules of OCM.
|
||||
private AlgorithmManager algorithmManager;
|
||||
private CoactiveLearning coactiveLearning;
|
||||
private Cache cache;
|
||||
|
||||
private PatternWarehouse patternWarehouse;
|
||||
|
||||
// The current System State.
|
||||
private SystemState currentState;
|
||||
|
||||
// Boolean to check if OCMManager has been initialized
|
||||
private boolean isInitialized = false;
|
||||
|
||||
// OCMManager does not call the same method if the user asked for the first ranking of not.
|
||||
private boolean firstRanking;
|
||||
|
||||
private OCMManager() {
|
||||
algorithmManager = new AlgorithmManager();
|
||||
coactiveLearning = currentCoactiveType.newInstance();
|
||||
cache = currentCacheType.newInstance();
|
||||
patternWarehouse = new PatternWarehouse();
|
||||
|
||||
firstRanking = true;
|
||||
}
|
||||
|
||||
//********** Initializing Methods **********//
|
||||
|
||||
public static void initialize(Pattern.WrapperType wrapperType,
|
||||
String filePath){
|
||||
|
||||
DebugLogger.printDebug("OCMManager: Initializing.");
|
||||
|
||||
INSTANCE.currentState = new SystemState(new Rank<>());
|
||||
INSTANCE.algorithmManager.initialize(wrapperType, filePath);
|
||||
|
||||
try{
|
||||
INSTANCE.coactiveLearning.initialize();
|
||||
|
||||
INSTANCE.isInitialized = true;
|
||||
} catch (NotInitializedException exception) {
|
||||
DebugLogger.printDebug("OCMManager: The AlgorithmManager has not been initialized correctly, thus it is impossible to load data in the CoactiveLearningRanking module", DebugLogger.MessageSeverity.CRITICAL);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
currentWrapperType = wrapperType;
|
||||
|
||||
DebugLogger.printDebug("OCMManager: Initialized correctly.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user loads a new data file, but not for the first time.
|
||||
* @param wrapperType The type of wrapper the user has selected.
|
||||
* @param cacheType The type of cache the user has selected.
|
||||
* @param coactiveType The type of coactive learning the user has selected.
|
||||
* @param filePath The path leading to the data to load.
|
||||
*/
|
||||
public static void reload(Pattern.WrapperType wrapperType,
|
||||
@NotNull Cache.CacheType cacheType,
|
||||
@NotNull CoactiveLearning.CoactiveType coactiveType,
|
||||
String filePath){
|
||||
|
||||
INSTANCE.algorithmManager.stopMining();
|
||||
|
||||
INSTANCE.algorithmManager = new AlgorithmManager();
|
||||
INSTANCE.coactiveLearning = coactiveType.newInstance();
|
||||
INSTANCE.cache = cacheType.newInstance();
|
||||
INSTANCE.patternWarehouse = new PatternWarehouse();
|
||||
|
||||
currentCacheType = cacheType;
|
||||
|
||||
initialize(wrapperType, filePath);
|
||||
}
|
||||
|
||||
//********** Public Methods **********//
|
||||
|
||||
@NotNull
|
||||
public static List<Pattern> getNewRanking(List<Pattern> interestingPatterns,
|
||||
List<Pattern> neutralPatterns,
|
||||
List<Pattern> trashedPatterns) {
|
||||
if (isInitialized()) {
|
||||
List<Pattern> bestPatterns;
|
||||
|
||||
if(INSTANCE.firstRanking) {
|
||||
bestPatterns = firstNewRanking();
|
||||
INSTANCE.firstRanking = false;
|
||||
} else {
|
||||
DebugLogger.printDebug("OCMManager: Creating a new ranking.");
|
||||
|
||||
INSTANCE.algorithmManager.stopMining();
|
||||
INSTANCE.patternWarehouse.addToWarehouse(interestingPatterns);
|
||||
INSTANCE.currentState.update(interestingPatterns, neutralPatterns, trashedPatterns);
|
||||
INSTANCE.coactiveLearning.updateWeight(INSTANCE.currentState);
|
||||
bestPatterns = INSTANCE.cache.getBestPattern();
|
||||
INSTANCE.currentState = new SystemState(bestPatterns);
|
||||
INSTANCE.algorithmManager.startMining();
|
||||
|
||||
DebugLogger.printDebug("OCMManager: Ranking created.");
|
||||
}
|
||||
|
||||
return bestPatterns;
|
||||
} else {
|
||||
DebugLogger.printDebug("OCMManger: The AlgorithmManager has not been initialized correctly, thus it is impossible to get a new ranking", DebugLogger.MessageSeverity.CRITICAL);
|
||||
throw new NotInitializedException();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<Pattern> firstNewRanking(){
|
||||
return INSTANCE.cache.getBestPattern();
|
||||
}
|
||||
|
||||
public static void requestStop(){
|
||||
INSTANCE.algorithmManager.stopMining();
|
||||
}
|
||||
|
||||
//********** Proxy Methods **********//
|
||||
|
||||
// Coactive Learning //
|
||||
public static double coactiveGetUtility(List<Pattern> rank){
|
||||
return INSTANCE.coactiveLearning.getUtility(rank);
|
||||
}
|
||||
|
||||
public static double[] coactiveGetWeights(){
|
||||
return INSTANCE.coactiveLearning.getWeights();
|
||||
}
|
||||
|
||||
public static int coactiveGetNbRound(){
|
||||
return INSTANCE.coactiveLearning.getNbCycles();
|
||||
}
|
||||
|
||||
// Algorithm Manager //
|
||||
public static void algorithmManagerUpdateReward(int arm, double reward){
|
||||
INSTANCE.algorithmManager.banditUpdateReward(arm, reward);
|
||||
}
|
||||
|
||||
public static void algorithmManagerPauseMining(){
|
||||
INSTANCE.algorithmManager.pauseMining();
|
||||
}
|
||||
|
||||
public static void algorithmManagerResumeMining(){
|
||||
INSTANCE.algorithmManager.resumeMining();
|
||||
}
|
||||
|
||||
public static void algorithmManagerStartMining(){
|
||||
INSTANCE.algorithmManager.startMining();
|
||||
}
|
||||
|
||||
public static void algorithmManagerStopMining(){
|
||||
INSTANCE.algorithmManager.stopMining();
|
||||
}
|
||||
|
||||
public static boolean algorithmManagerIsMining(){
|
||||
return INSTANCE.algorithmManager.isMining();
|
||||
}
|
||||
|
||||
public static int algorithmManagerGetNbAlgoLaunched() {
|
||||
return INSTANCE.algorithmManager.getNbAlgoLaunched();
|
||||
}
|
||||
|
||||
public static int algorithmManagerGetNbPatternFound() {
|
||||
return INSTANCE.algorithmManager.getNbPatternFound();
|
||||
}
|
||||
|
||||
// Bandit //
|
||||
public static double[] banditGetWeights(){
|
||||
return INSTANCE.algorithmManager.banditGetWeights();
|
||||
}
|
||||
|
||||
// Algorithm Launcher //
|
||||
public static List<String> algorithmLauncherGetListAlgorithmName(){
|
||||
return INSTANCE.algorithmManager.algorithmLauncherGetListAlgorithmName();
|
||||
}
|
||||
|
||||
public static List<String> algorithmLauncherGetListAttributeName(){
|
||||
return INSTANCE.algorithmManager.algorithmLauncherGetListAttributeName();
|
||||
}
|
||||
|
||||
// Cache //
|
||||
public static void cacheAddPatterns(List<Pattern> newPatterns, double time, int arm){
|
||||
INSTANCE.cache.addPatterns(newPatterns, time, arm);
|
||||
}
|
||||
|
||||
public static int cacheGetSizeListBestPatterns(){
|
||||
return INSTANCE.cache.getSizeListBestPatterns();
|
||||
}
|
||||
|
||||
public static void cacheSetSizeListBestPatterns(int size){
|
||||
INSTANCE.cache.setSizeListBestPatterns(size);
|
||||
}
|
||||
|
||||
// Pattern Warehouse //
|
||||
public static List<Pattern> patternWarehouseGetPatterns(){
|
||||
return INSTANCE.patternWarehouse.getStockedPatterns();
|
||||
}
|
||||
|
||||
//********** Serializing Methods **********//
|
||||
|
||||
/**
|
||||
* Static entry point to restore a previous OCMManager, aka to restore a previous user search.
|
||||
* @param searchSave The deserialized form of the user search state.
|
||||
*/
|
||||
public static void deserialize(SearchSave searchSave){
|
||||
INSTANCE.deserializeInstance(searchSave);
|
||||
}
|
||||
|
||||
private void deserializeInstance(SearchSave searchSave){
|
||||
algorithmManager.stopMining();
|
||||
algorithmManager.reload(searchSave.getMultiArmedBandit());
|
||||
|
||||
coactiveLearning = searchSave.getCoactiveLearning();
|
||||
cache = searchSave.getCache();
|
||||
patternWarehouse = searchSave.getPatternWarehouse();
|
||||
currentState = searchSave.getCurrentState();
|
||||
isInitialized = searchSave.getInitialized();
|
||||
firstRanking = searchSave.getFirstRanking();
|
||||
}
|
||||
|
||||
public static void serialize(SearchSave searchSave){
|
||||
INSTANCE.serializeInstance(searchSave);
|
||||
}
|
||||
|
||||
private void serializeInstance(SearchSave searchSave){
|
||||
algorithmManager.save(searchSave);
|
||||
|
||||
searchSave.setCoactiveLearning(coactiveLearning);
|
||||
searchSave.setCache(cache);
|
||||
searchSave.setPatternWarehouse(patternWarehouse);
|
||||
searchSave.setCurrentState(currentState);
|
||||
searchSave.setInitialized(isInitialized);
|
||||
searchSave.setFirstRanking(firstRanking);
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
public static boolean isInitialized(){ return INSTANCE.isInitialized; }
|
||||
|
||||
public static Pattern.WrapperType getCurrentUsedWrapperType(){
|
||||
return currentWrapperType;
|
||||
}
|
||||
|
||||
// Setters //
|
||||
}
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.algorithmmanager;
|
||||
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.oneclicklearning.bandit.CesaBianciBandit;
|
||||
import fr.insa.ocm.model.oneclicklearning.bandit.MultiArmedBandit;
|
||||
import fr.insa.ocm.model.utils.exceptions.NotInitializedException;
|
||||
import fr.insa.ocm.model.utils.serialize.SearchSave;
|
||||
import fr.insa.ocm.model.wrapper.api.AbstractPattern;
|
||||
import fr.insa.ocm.model.wrapper.api.AlgorithmLauncher;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
/**
|
||||
* <h1>Algorithm Manager</h1>
|
||||
* <p>Manages the startMonitoring and stop of the different data mining algorithm. Also manages their resultsts</p>
|
||||
*/
|
||||
public class AlgorithmManager {
|
||||
|
||||
// These semaphores are used to synchronize differents mining threads.
|
||||
private static Semaphore operationBandit = new Semaphore(1);
|
||||
private static Semaphore operationInfo = new Semaphore(1);
|
||||
private static Semaphore operationCoactive = new Semaphore(1);
|
||||
|
||||
/**
|
||||
* <h1>Mining Thread</h1>
|
||||
* <p>Thread that runs algorithms one by one while not stop.</p>
|
||||
*/
|
||||
private class MiningThread extends Thread {
|
||||
|
||||
private volatile boolean stopRequested;
|
||||
private int currentAlgorithm;
|
||||
|
||||
/**
|
||||
* Creates a new MiningThread instance
|
||||
*/
|
||||
private MiningThread() {
|
||||
this.stopRequested = false;
|
||||
this.setName("Miner #"+nextThreadID);
|
||||
nextThreadID++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs the thread until {@link #stopMining()} is called.
|
||||
* The method runs data mining algorithm selected by the bandit one by one.
|
||||
* If the thread is stop before adding data to the cache, this step is skip to end the thread.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
DebugLogger.printDebug("MiningThread (" + Thread.currentThread().getName() + "): is mining.");
|
||||
while (!stopRequested) {
|
||||
AlgorithmManager.operationBandit.acquireUninterruptibly();
|
||||
currentAlgorithm = bandit.getArmToUse();
|
||||
AlgorithmManager.operationBandit.release();
|
||||
|
||||
double startTime = System.currentTimeMillis();
|
||||
List<Pattern> results = algorithmLauncher.startAlgorithm(currentAlgorithm);
|
||||
double elapsedTime = System.currentTimeMillis() - startTime;
|
||||
|
||||
if (!stopRequested) {
|
||||
|
||||
operationInfo.acquireUninterruptibly();
|
||||
nbAlgoLaunched++;
|
||||
nbPatternFound += results.size();
|
||||
operationInfo.release();
|
||||
|
||||
|
||||
operationCoactive.acquireUninterruptibly();
|
||||
OCMManager.cacheAddPatterns(results, elapsedTime, currentAlgorithm);
|
||||
operationCoactive.release();
|
||||
}
|
||||
}
|
||||
|
||||
DebugLogger.printDebug(Thread.currentThread().getName() +": is stopping.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the thread and stop, if possible, the current running algorithm
|
||||
*/
|
||||
private void stopMining(){
|
||||
this.stopRequested = true;
|
||||
algorithmLauncher.stopAlgorithm();
|
||||
}
|
||||
}
|
||||
|
||||
//private static final AlgorithmManager INSTANCE = new AlgorithmManager();
|
||||
private static final int MAX_THREAD = 1; // TODO : Il faut prendre en compte dans les wrappers d'algorithm le fait qu'on soit en multithreadé pour > 1;
|
||||
|
||||
private MultiArmedBandit bandit;
|
||||
private AlgorithmLauncher algorithmLauncher;
|
||||
private List<MiningThread> listCurrentThread;
|
||||
|
||||
private static int nextThreadID = 0;
|
||||
|
||||
private volatile boolean isMining;
|
||||
private volatile boolean hasBeenInitialized;
|
||||
private volatile int nbAlgoLaunched;
|
||||
private volatile int nbPatternFound;
|
||||
|
||||
/**
|
||||
* Creates a new instance of AlgorithmManager
|
||||
*/
|
||||
public AlgorithmManager(){
|
||||
nbAlgoLaunched = 0;
|
||||
nbPatternFound = 0;
|
||||
|
||||
listCurrentThread = new ArrayList<>();
|
||||
|
||||
isMining = false;
|
||||
hasBeenInitialized = false;
|
||||
}
|
||||
|
||||
//********** Initializing Methods **********//
|
||||
|
||||
public void initialize(AbstractPattern.WrapperType wrapperType,
|
||||
String filePath){
|
||||
|
||||
if(!this.isMining) {
|
||||
algorithmLauncher = wrapperType.getAlgorithmLauncher(filePath);
|
||||
|
||||
if (algorithmLauncher != null) {
|
||||
bandit = new CesaBianciBandit(algorithmLauncher.getNbAlgorithms());
|
||||
hasBeenInitialized = true;
|
||||
} else {
|
||||
DebugLogger.printDebug("ERR: Unable to loadData the AlgorithmManager, have you correctly set the type of library you want to use ?", DebugLogger.MessageSeverity.CRITICAL);
|
||||
}
|
||||
} else {
|
||||
DebugLogger.printDebug("LOG: Unable to loadData the AlgorithmManger when it is currently mining.", DebugLogger.MessageSeverity.HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
//********** Serializing Methods **********//
|
||||
|
||||
public void reload(MultiArmedBandit bandit){
|
||||
this.stopAllMiners();
|
||||
|
||||
this.bandit = bandit;
|
||||
this.nbAlgoLaunched = 0;
|
||||
}
|
||||
|
||||
public void save(SearchSave searchSave){
|
||||
searchSave.setMultiArmedBandit(bandit);
|
||||
}
|
||||
|
||||
//********** Public Methods **********//
|
||||
|
||||
/**
|
||||
* Starts the data mining in a thread, {@link MiningThread}.
|
||||
*/
|
||||
public void startMining() {
|
||||
if(hasBeenInitialized) {
|
||||
try {
|
||||
operationInfo.acquire();
|
||||
nbAlgoLaunched = 0;
|
||||
nbPatternFound = 0;
|
||||
operationInfo.release();
|
||||
resumeMining();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
DebugLogger.printDebug("LOG: Cannot startMonitoring mining since the AlgorithmManager has not been initialized", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void resumeMining(){
|
||||
if(hasBeenInitialized) {
|
||||
isMining = true;
|
||||
|
||||
// Creating the new threads.
|
||||
for (int i = 0; i < MAX_THREAD; i++) {
|
||||
MiningThread newMiningThread = new MiningThread();
|
||||
newMiningThread.setDaemon(true);
|
||||
newMiningThread.start();
|
||||
listCurrentThread.add(newMiningThread);
|
||||
}
|
||||
} else {
|
||||
DebugLogger.printDebug("LOG: Cannot resume mining since the AlgorithmManager has not been initialized", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
public void pauseMining(){
|
||||
this.stopAllMiners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the data mining.
|
||||
*/
|
||||
public void stopMining(){
|
||||
pauseMining();
|
||||
}
|
||||
|
||||
//********** Internal Methods **********//
|
||||
|
||||
private synchronized void stopAllMiners(){
|
||||
listCurrentThread.forEach(miningThread -> {
|
||||
if(miningThread != null){
|
||||
miningThread.stopMining();
|
||||
try {
|
||||
DebugLogger.printDebug("AlgorithmManager: Waiting for the stop of "+ miningThread.getName());
|
||||
miningThread.join();
|
||||
DebugLogger.printDebug("AlgorithmManager: "+ miningThread.getName() +" has stopped");
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
listCurrentThread.clear();
|
||||
|
||||
this.isMining = false;
|
||||
}
|
||||
|
||||
//********** Proxy Methods **********//
|
||||
|
||||
|
||||
// Bandit //
|
||||
public void banditUpdateReward(int arm, double reward){
|
||||
bandit.updateReward(arm, reward);
|
||||
}
|
||||
|
||||
public double[] banditGetWeights(){
|
||||
return bandit.getWeights();
|
||||
}
|
||||
|
||||
// Algorithm Launcher //
|
||||
|
||||
public List<String> algorithmLauncherGetListAlgorithmName(){
|
||||
return algorithmLauncher.getListAlgorithmName();
|
||||
}
|
||||
|
||||
public List<String> algorithmLauncherGetListAttributeName(){ return algorithmLauncher.getListAttributeName(); }
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
public int getNbAlgoLaunched(){
|
||||
return nbAlgoLaunched;
|
||||
}
|
||||
|
||||
public int getNbPatternFound(){
|
||||
return nbPatternFound;
|
||||
}
|
||||
|
||||
public boolean isMining(){
|
||||
return isMining;
|
||||
}
|
||||
|
||||
public int getNbAttributeMeasures() throws NotInitializedException {
|
||||
if(hasBeenInitialized){
|
||||
return algorithmLauncher.getNbAlgorithms() + algorithmLauncher.getNbAttributes();
|
||||
} else {
|
||||
DebugLogger.printDebug("ERR: Cannot get the number of attribute measure if the AlgorithmManager is not initialized", DebugLogger.MessageSeverity.HIGH);
|
||||
throw new NotInitializedException();
|
||||
}
|
||||
}
|
||||
|
||||
//********** Old Methods **********//
|
||||
|
||||
|
||||
// /**
|
||||
// * Returns the bandit instance used by the {@link AlgorithmManager}.
|
||||
// * @return The instance of the bandit used by the {@link AlgorithmManager}.
|
||||
// */
|
||||
// public MultiArmedBandit getBandit(){
|
||||
// return bandit;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Imports the data from a CSV file.
|
||||
// * Do not check if the file exists.
|
||||
// * @param filePath The path to the CSV file.
|
||||
// */
|
||||
// public void importData(String filePath) {
|
||||
// algorithmLauncher.importData(filePath);
|
||||
// CoactiveLearningRanking.getInstance().init(algorithmLauncher.getNbAttributes() + algorithmLauncher.getNbAlgorithms());
|
||||
// }
|
||||
//
|
||||
// public void reloadData(String filePath){
|
||||
// algorithmLauncher = new AlgorithmLauncherRealKD();
|
||||
// algorithmLauncher.importData(filePath);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.bandit;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.utils.RandomSelector;
|
||||
|
||||
/**
|
||||
* <h1>Cesa Bianci Bandit algorithm</h1>
|
||||
* <p>Provides an implementation of the CesiaBianci Bandit algorithm which solved the
|
||||
* multi-armed bandit problem</p>
|
||||
*/
|
||||
public class CesaBianciBandit implements MultiArmedBandit {
|
||||
|
||||
// The currend weights, v
|
||||
@Expose private volatile double[] weights;
|
||||
// The currend round
|
||||
@Expose private int round;
|
||||
// The value that normalizes the sum of v
|
||||
@Expose private double V;
|
||||
|
||||
//TODO Javadoc for serializing purpose only
|
||||
@SuppressWarnings("unused")
|
||||
public CesaBianciBandit(){}
|
||||
|
||||
public CesaBianciBandit(double[] weights, int round, double V){
|
||||
this.weights = weights;
|
||||
this.round = round;
|
||||
this.V = V;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new CesaBianciBandit instances, with a given number of arms/
|
||||
* @param nbOfArms the number of arms for the instance
|
||||
*/
|
||||
public CesaBianciBandit(int nbOfArms){
|
||||
round = 1;
|
||||
V = 0;
|
||||
weights = new double[nbOfArms];
|
||||
for(int i = 0; i< weights.length; ++i) {
|
||||
weights[i] = 1./ (double) weights.length;
|
||||
}
|
||||
V = 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateReward(int arm, double reward) {
|
||||
if (arm >= weights.length) {
|
||||
throw new IndexOutOfBoundsException("Arm value should be at most: "+(weights.length-1));
|
||||
}
|
||||
|
||||
|
||||
double beta = getBeta();
|
||||
double gamma = getMixtureCoefficient(beta);
|
||||
double n = getLearningRate(gamma);
|
||||
double[] pi = getSelectionDistribution(gamma);
|
||||
|
||||
double[] g = new double[weights.length];
|
||||
V = 0;
|
||||
for(int i=0; i<g.length; ++i) {
|
||||
if (i==arm) {
|
||||
g[i] = (reward + beta)/pi[arm];
|
||||
}
|
||||
else {
|
||||
g[i] = beta/pi[arm];
|
||||
}
|
||||
weights[i] = weights[i] * Math.exp(n*g[i]);
|
||||
V += weights[i];
|
||||
}
|
||||
//Normalize the sum of weights to 1, so the weights don't grow exponentially
|
||||
for (int i=0; i<weights.length; ++i) {
|
||||
weights[i] = weights[i]/V;
|
||||
}
|
||||
V = 1;
|
||||
|
||||
round++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArmToUse() {
|
||||
// double beta = getBeta();
|
||||
// double gamma = getMixtureCoefficient(beta);
|
||||
// return RandomSelector.randomPick(getSelectionDistribution(gamma));
|
||||
return RandomSelector.randomPick(getSelectionDistribution(1/(0.01*((double)round)+1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the value beta for the CesaBianci algorithm
|
||||
* @return the beta value
|
||||
*/
|
||||
public double getBeta() {
|
||||
double temp = Math.log(10*weights.length);
|
||||
temp = temp / (weights.length*Math.pow(2,Math.floor(Math.log10(round))));
|
||||
temp = Math.sqrt(temp);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the mixture coefficient for the CesaBianci algorithm. Also called gamma.
|
||||
* @param beta the beta value for the CesaBianci algorithm
|
||||
* @return the mixture coefficient, gamma
|
||||
*/
|
||||
public double getMixtureCoefficient(double beta) {
|
||||
// return (4*weights.length*beta)/(3+beta);
|
||||
return (4*beta)/(3+beta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the learning rate for the CesaBianci algorithm. Also called eta
|
||||
* @param mixtureCoeff the mixture coefficient for the CesaBianci algorithm
|
||||
* @return the learning rate, eta
|
||||
*/
|
||||
public double getLearningRate(double mixtureCoeff) {
|
||||
return (mixtureCoeff/(2*weights.length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the selection distribution for the CesaBianci algorithm. Also called pi.
|
||||
* @param mixtureCoef the mixture coefficient for the CesaBianci algorithm
|
||||
* @return the selection distribution, pi
|
||||
*/
|
||||
public double[] getSelectionDistribution(double mixtureCoef) {
|
||||
double[] selectionDistibution = new double[weights.length];
|
||||
for (int i=0; i<selectionDistibution.length; ++i) {
|
||||
double temp = (1-mixtureCoef)*weights[i];
|
||||
selectionDistibution[i] = temp/V + mixtureCoef/weights.length;
|
||||
}
|
||||
|
||||
//FIXME
|
||||
|
||||
// System.arraycopy(weights, 0, selectionDistibution, 0, weights.length);
|
||||
DebugLogger.logSelectionDistribution(selectionDistibution);
|
||||
|
||||
return selectionDistibution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current weights. Also called v.
|
||||
* @return The current weights in an array of double.
|
||||
*/
|
||||
public double[] getWeights() {
|
||||
return weights;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.bandit;
|
||||
|
||||
/**
|
||||
* <h1>Multi-armed bandit problem representation</h1>
|
||||
* <p>This interface provides simple methods that answer to
|
||||
* the multi-armed bandit problem</p>
|
||||
*
|
||||
* @see <a href="https://en.wikipedia.org/wiki/Multi-armed_bandit">Multi-armed bandit - Wikipedia</a>
|
||||
*/
|
||||
public interface MultiArmedBandit {
|
||||
|
||||
/**
|
||||
* Updates the reward for a given arm
|
||||
* @param arm the arm associates to the reward
|
||||
* @param reward reward value for the given arm
|
||||
*/
|
||||
void updateReward(int arm, double reward);
|
||||
|
||||
/**
|
||||
* Returns the arm to use.
|
||||
* @return the arm
|
||||
*/
|
||||
int getArmToUse();
|
||||
|
||||
/**
|
||||
* Returns the current weights. Also called v.
|
||||
* @return The current weights in an array of double.
|
||||
*/
|
||||
double[] getWeights();
|
||||
|
||||
}
|
||||
41
src/main/java/fr/insa/ocm/model/oneclicklearning/cache/api/AbstractCache.java
vendored
Normal file
41
src/main/java/fr/insa/ocm/model/oneclicklearning/cache/api/AbstractCache.java
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.cache.api;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractCache implements Cache {
|
||||
|
||||
@Expose protected int sizeListBestPatterns;
|
||||
@Expose private CacheType cacheType;
|
||||
|
||||
/**
|
||||
* Deserializing constructor.
|
||||
* @param sizeListBestPatterns Deserializing parameter.
|
||||
* @param cacheType Deserializing parameter.
|
||||
*/
|
||||
protected AbstractCache(int sizeListBestPatterns,
|
||||
CacheType cacheType){
|
||||
this.sizeListBestPatterns = sizeListBestPatterns;
|
||||
this.cacheType = cacheType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract List<Pattern> getBestPattern();
|
||||
|
||||
@Override
|
||||
public abstract void addPatterns(List<Pattern> newPatterns, double time, int arm);
|
||||
|
||||
@Override
|
||||
public int getSizeListBestPatterns() {
|
||||
return sizeListBestPatterns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSizeListBestPatterns(int size) {
|
||||
if(size > 0){
|
||||
sizeListBestPatterns = size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.cache.api;
|
||||
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.rank.CacheRanking;
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.set.CacheSet;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Cache {
|
||||
|
||||
enum CacheType{
|
||||
RANKING, SET;
|
||||
|
||||
@NotNull
|
||||
public Cache newInstance(){
|
||||
switch (this){
|
||||
case RANKING:
|
||||
return new CacheRanking();
|
||||
case SET:
|
||||
return new CacheSet();
|
||||
default:
|
||||
return new CacheSet();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (this){
|
||||
case RANKING:
|
||||
return "Ranking";
|
||||
case SET:
|
||||
return "Set";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Pattern> getBestPattern();
|
||||
|
||||
void addPatterns(List<Pattern> newPatterns, double time, int arm);
|
||||
|
||||
int getSizeListBestPatterns();
|
||||
|
||||
void setSizeListBestPatterns(int size);
|
||||
}
|
||||
96
src/main/java/fr/insa/ocm/model/oneclicklearning/cache/rank/CacheRanking.java
vendored
Normal file
96
src/main/java/fr/insa/ocm/model/oneclicklearning/cache/rank/CacheRanking.java
vendored
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.cache.rank;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.api.AbstractCache;
|
||||
import fr.insa.ocm.model.utils.Rank;
|
||||
import fr.insa.ocm.model.utils.serialize.SearchSave;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <h1>CacheRanking</h1>
|
||||
* <p>Stocks the patterns while mining, and compute greedy ranking.</p>
|
||||
*/
|
||||
public class CacheRanking extends AbstractCache {
|
||||
|
||||
// Patterns currently in cache
|
||||
@Expose private double utility;
|
||||
// Greedy ranking for the cache
|
||||
@Expose private Rank<Pattern> greedyRanking;
|
||||
// Do all the computation of the greedy ranking
|
||||
private static GreedyRankingComputer greedyComputer;
|
||||
|
||||
/**
|
||||
* Deserializing constructor.
|
||||
* @param sizeListBestPatterns Deserializing parameter.
|
||||
* @param cacheType Deserializing parameter.
|
||||
* @param utility Deserializing parameter.
|
||||
* @param greedyRanking Deserializing parameter.
|
||||
*/
|
||||
public CacheRanking(int sizeListBestPatterns,
|
||||
CacheType cacheType,
|
||||
double utility,
|
||||
Rank<Pattern> greedyRanking){
|
||||
super(sizeListBestPatterns, cacheType);
|
||||
|
||||
this.utility = utility;
|
||||
this.greedyRanking = greedyRanking;
|
||||
|
||||
greedyComputer = new GreedyRankingComputer(this);
|
||||
greedyComputer.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new CacheRanking instance.
|
||||
*/
|
||||
public CacheRanking(){
|
||||
super(20, CacheType.RANKING);
|
||||
|
||||
greedyRanking = new Rank<>();
|
||||
utility = 0;
|
||||
|
||||
greedyComputer = new GreedyRankingComputer(this);
|
||||
greedyComputer.start();
|
||||
}
|
||||
|
||||
//********** Serializing Methods **********//
|
||||
|
||||
public void reload(CacheRanking cache){
|
||||
this.utility = cache.utility;
|
||||
this.greedyRanking = cache.greedyRanking;
|
||||
|
||||
greedyComputer = new GreedyRankingComputer(this);
|
||||
greedyComputer.start();
|
||||
}
|
||||
|
||||
public void save(SearchSave searchSave){
|
||||
searchSave.setCache(this);
|
||||
}
|
||||
|
||||
//********** Public Methods **********//
|
||||
|
||||
@Override
|
||||
public List<Pattern> getBestPattern() {
|
||||
greedyRanking = greedyComputer.getGreedyRanking();
|
||||
|
||||
return new Rank<>(greedyRanking);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds patterns from a given mining algorithm to the cache.
|
||||
* @param newPatterns The patterns from the mining algorithm
|
||||
* @param time The computation time of the mining algorithm
|
||||
* @param arm The index of the mining algorithm
|
||||
*/
|
||||
public void addPatterns(List<Pattern> newPatterns, double time, int arm){
|
||||
greedyComputer.addPatterns(newPatterns, time, arm);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void requestStop(){
|
||||
greedyComputer.requestedStop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
226
src/main/java/fr/insa/ocm/model/oneclicklearning/cache/rank/GreedyRankingComputer.java
vendored
Normal file
226
src/main/java/fr/insa/ocm/model/oneclicklearning/cache/rank/GreedyRankingComputer.java
vendored
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.cache.rank;
|
||||
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.api.Cache;
|
||||
import fr.insa.ocm.model.utils.Rank;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
class GreedyRankingComputer extends Thread {
|
||||
|
||||
private class GreedyCalculus implements Runnable{
|
||||
private Pattern bestPattern;
|
||||
private double bestUtility;
|
||||
private List<Pattern> candidatePatterns;
|
||||
private Rank<Pattern> greedyRankingCurrent;
|
||||
|
||||
GreedyCalculus(@NotNull final Rank<Pattern> greedyRankingCurrent,
|
||||
@NotNull List<Pattern> candidatePatterns){
|
||||
this.bestPattern = null;
|
||||
this.bestUtility = -1d;
|
||||
this.candidatePatterns = candidatePatterns;
|
||||
this.greedyRankingCurrent = new Rank<>(greedyRankingCurrent);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Pattern getBestPattern(){
|
||||
return bestPattern;
|
||||
}
|
||||
|
||||
double getBestUtility(){
|
||||
return bestUtility;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (Pattern p : candidatePatterns) {
|
||||
greedyRankingCurrent.add(p);
|
||||
double utility = OCMManager.coactiveGetUtility(greedyRankingCurrent);
|
||||
if (utility > bestUtility) {
|
||||
this.bestPattern = p;
|
||||
this.bestUtility = utility;
|
||||
}
|
||||
greedyRankingCurrent.remove(p);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private class AlgorithmPatternResults {
|
||||
int arm;
|
||||
double time;
|
||||
List<Pattern> listFoundPatterns;
|
||||
|
||||
AlgorithmPatternResults(int arm, double time, List<Pattern> listFoundPatterns){
|
||||
this.arm = arm;
|
||||
this.time = time;
|
||||
this.listFoundPatterns = listFoundPatterns;
|
||||
}
|
||||
}
|
||||
|
||||
private volatile boolean stopRequested;
|
||||
|
||||
private final List<AlgorithmPatternResults> queuedPatterns = new ArrayList<>();
|
||||
private final Rank<Pattern> greedyRanking = new Rank<>();
|
||||
private double rankingUtility;
|
||||
private CacheRanking cache;
|
||||
|
||||
private final Set<Integer> armsPulled = new HashSet<>();
|
||||
|
||||
GreedyRankingComputer(@NotNull CacheRanking cache){
|
||||
this.cache = cache;
|
||||
|
||||
stopRequested = false;
|
||||
rankingUtility = 0;
|
||||
|
||||
this.setDaemon(true);
|
||||
this.setName("Greedy Computer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(){
|
||||
List<Pattern> candidatePatterns = new ArrayList<>();
|
||||
AlgorithmPatternResults currentCandidate = new AlgorithmPatternResults(-1, -1, new ArrayList<>());
|
||||
|
||||
try {
|
||||
while (!stopRequested) {
|
||||
synchronized (queuedPatterns) {
|
||||
if (queuedPatterns.size() != 0) {
|
||||
currentCandidate = queuedPatterns.get(0);
|
||||
candidatePatterns.addAll(currentCandidate.listFoundPatterns);
|
||||
queuedPatterns.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (!candidatePatterns.isEmpty()) {
|
||||
|
||||
// The Patterns in the greedy ranking needs to be treated as simple Patterns to establish a new ranking.
|
||||
candidatePatterns.addAll(greedyRanking);
|
||||
|
||||
int greedySize = Math.min(cache.getSizeListBestPatterns(), candidatePatterns.size());
|
||||
Rank<Pattern> greedyRankingTmp = new Rank<>();
|
||||
|
||||
for (int i = 0; i < greedySize || candidatePatterns.isEmpty(); ++i) {
|
||||
Pattern bestPattern;
|
||||
double bestUtility;
|
||||
|
||||
Thread[] greedyComputation = new Thread[8];
|
||||
GreedyCalculus[] greedyCalculus = new GreedyCalculus[greedyComputation.length];
|
||||
|
||||
for (int j = 0; j < greedyComputation.length; ++j) {
|
||||
List<Pattern> subList = candidatePatterns.subList((j / greedyComputation.length) * candidatePatterns.size(), ((j + 1) / greedyComputation.length) * candidatePatterns.size());
|
||||
|
||||
greedyCalculus[j] = new GreedyCalculus(greedyRankingTmp, subList);
|
||||
|
||||
greedyComputation[j] = new Thread(greedyCalculus[j]);
|
||||
greedyComputation[j].setName("GreedyCalculus #" + j);
|
||||
greedyComputation[j].start();
|
||||
}
|
||||
|
||||
for (Thread threadGreedy : greedyComputation) {
|
||||
try {
|
||||
threadGreedy.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
bestPattern = greedyCalculus[0].getBestPattern();
|
||||
bestUtility = greedyCalculus[0].getBestUtility();
|
||||
|
||||
for (int j = 1; j < greedyComputation.length; ++j) {
|
||||
if (bestUtility < greedyCalculus[j].getBestUtility()) {
|
||||
bestPattern = greedyCalculus[j].getBestPattern();
|
||||
bestUtility = greedyCalculus[j].getBestUtility();
|
||||
}
|
||||
}
|
||||
|
||||
if (bestPattern == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (!greedyRankingTmp.contains(bestPattern)) {
|
||||
greedyRankingTmp.add(bestPattern);
|
||||
}
|
||||
candidatePatterns.remove(bestPattern); //It is ok because the cache will be resized with the greedyRankingCurrent
|
||||
|
||||
}
|
||||
|
||||
// Update the MultiArmedBandit
|
||||
double newUtility = OCMManager.coactiveGetUtility(greedyRankingTmp);
|
||||
// double reward = (newUtility - rankingUtility)/currentCandidate.time;
|
||||
double reward = (newUtility - rankingUtility) * (5 / currentCandidate.time);
|
||||
|
||||
//TODO Find a better way to calculate the reward.
|
||||
System.out.println("(arm, reward) = (" + currentCandidate.arm + ", " + reward + ")");
|
||||
OCMManager.algorithmManagerUpdateReward(currentCandidate.arm, reward);
|
||||
|
||||
rankingUtility = newUtility;
|
||||
|
||||
synchronized (greedyRanking) {
|
||||
greedyRanking.clear();
|
||||
greedyRanking.addAll(greedyRankingTmp);
|
||||
}
|
||||
|
||||
} else {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
} catch (NullPointerException e){
|
||||
DebugLogger.printDebug("GreedyRankingComputer: One of the best pattern found was null.", DebugLogger.MessageSeverity.HIGH);
|
||||
}
|
||||
|
||||
candidatePatterns.clear();
|
||||
|
||||
}
|
||||
} catch (InterruptedException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
void addPatterns(List<Pattern> newPatterns, double time, int arm){
|
||||
AlgorithmPatternResults patternResults = new AlgorithmPatternResults(arm, time, newPatterns);
|
||||
synchronized (armsPulled){
|
||||
// We don't want to see each time the same algorithms results (only for SPMF)
|
||||
if(OCMManager.getCurrentUsedWrapperType().equals(Pattern.WrapperType.SPMF)
|
||||
&& armsPulled.contains(arm)){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (queuedPatterns){
|
||||
if(queuedPatterns.size() <= 50) {
|
||||
queuedPatterns.add(patternResults);
|
||||
synchronized (armsPulled){
|
||||
armsPulled.add(arm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rank<Pattern> getGreedyRanking(){
|
||||
Rank<Pattern> greedyRankingResult;
|
||||
|
||||
synchronized (greedyRanking){
|
||||
greedyRankingResult = new Rank<>(greedyRanking);
|
||||
}
|
||||
|
||||
synchronized (armsPulled){
|
||||
armsPulled.clear();
|
||||
}
|
||||
|
||||
return greedyRankingResult;
|
||||
}
|
||||
|
||||
void requestedStop(){
|
||||
stopRequested = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.cache.set;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.api.AbstractCache;
|
||||
import fr.insa.ocm.model.utils.Rank;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class CacheSet extends AbstractCache {
|
||||
|
||||
private class PatternEntry{
|
||||
|
||||
double utility;
|
||||
Pattern pattern;
|
||||
|
||||
PatternEntry(Pattern pattern, double utility){
|
||||
this.pattern = pattern;
|
||||
this.utility = utility;
|
||||
}
|
||||
|
||||
// Sorting desc
|
||||
int compare(PatternEntry patternEntry){
|
||||
double r = this.utility - patternEntry.utility;
|
||||
if(r < 0){
|
||||
return 1;
|
||||
} else if(r > 0){
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "" + utility;
|
||||
}
|
||||
}
|
||||
|
||||
// Stocks the best patterns of each arms.
|
||||
private Map<Integer, List<PatternEntry>> cachePattern;
|
||||
|
||||
// Stocks the previous utility for each arms.
|
||||
private Map<Integer, Double> previousUtility;
|
||||
|
||||
/**
|
||||
* Deserializing constructor.
|
||||
* @param sizeListBestPatterns Deserializing parameter.
|
||||
* @param cacheType Deserializing parameter.
|
||||
*/
|
||||
public CacheSet(int sizeListBestPatterns,
|
||||
CacheType cacheType){
|
||||
super(sizeListBestPatterns, cacheType);
|
||||
|
||||
this.previousUtility = previousUtility;
|
||||
|
||||
cachePattern = Collections.synchronizedMap(new HashMap<>());
|
||||
}
|
||||
|
||||
public CacheSet(){
|
||||
super(20, CacheType.SET);
|
||||
|
||||
cachePattern = Collections.synchronizedMap(new HashMap<>());
|
||||
previousUtility = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pattern> getBestPattern() {
|
||||
List<Pattern> listPattern = new ArrayList<>();
|
||||
List<PatternEntry> intermediateList = new ArrayList<>();
|
||||
final double[] weightsBandit = OCMManager.banditGetWeights();
|
||||
|
||||
cachePattern.forEach((integer, patternEntries) -> {
|
||||
int numberPattern = (int) (weightsBandit[integer]*sizeListBestPatterns);
|
||||
numberPattern = numberPattern==0 ? 1 : numberPattern;
|
||||
|
||||
intermediateList.addAll(patternEntries.subList(0, numberPattern));
|
||||
});
|
||||
|
||||
intermediateList.sort(PatternEntry::compare);
|
||||
intermediateList.forEach(patternEntry -> listPattern.add(patternEntry.pattern));
|
||||
|
||||
cachePattern.clear();
|
||||
return new Rank<>(listPattern);
|
||||
}
|
||||
|
||||
// TODO -- Find how useful time could be ?
|
||||
public void addPatterns(List<Pattern> newPatterns, double time, int arm){
|
||||
if(!cachePattern.containsKey(arm)){
|
||||
List<PatternEntry> listPatternEntry = new ArrayList<>();
|
||||
Rank<Pattern> rank = new Rank<>();
|
||||
|
||||
for(Pattern pattern : newPatterns){
|
||||
rank.add(pattern);
|
||||
|
||||
double utility = OCMManager.coactiveGetUtility(rank);
|
||||
PatternEntry entry = new PatternEntry(pattern, utility);
|
||||
listPatternEntry.add(entry);
|
||||
|
||||
rank.clear();
|
||||
}
|
||||
|
||||
// Get the best patterns.
|
||||
listPatternEntry.sort(PatternEntry::compare);
|
||||
listPatternEntry = listPatternEntry.subList(0, sizeListBestPatterns);
|
||||
|
||||
// Calculate the reward.
|
||||
List<Pattern> listPatterns = new ArrayList<>();
|
||||
listPatternEntry.forEach(patternEntry -> listPatterns.add(patternEntry.pattern));
|
||||
|
||||
double newUtility = OCMManager.coactiveGetUtility(listPatterns);
|
||||
double oldUtility = previousUtility.getOrDefault(arm, newUtility);
|
||||
|
||||
double reward = (newUtility - oldUtility) * 2.5 ;
|
||||
System.out.println("(arm, reward) = (" + arm + ", " + reward + ")");
|
||||
System.out.println("\tOld utility: "+oldUtility+"\n\tNew utility: "+newUtility);
|
||||
|
||||
OCMManager.algorithmManagerUpdateReward(arm, reward);
|
||||
|
||||
// Update informations
|
||||
cachePattern.put(arm, listPatternEntry);
|
||||
previousUtility.put(arm, newUtility);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.coactivelearning.api;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.utils.SystemState;
|
||||
import fr.insa.ocm.model.utils.Vector;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractCoactiveLearning implements CoactiveLearning {
|
||||
|
||||
@Expose
|
||||
protected CoactiveType coactiveType;
|
||||
|
||||
@Expose
|
||||
protected Vector weights;
|
||||
@Expose
|
||||
protected SystemState previousSystemState;
|
||||
@Expose
|
||||
protected int nbCycles;
|
||||
@Expose
|
||||
protected int nbInterestingnessMeasures;
|
||||
|
||||
/**
|
||||
* Deserializer constructor.
|
||||
*
|
||||
* @param weights Deserializer parameter.
|
||||
* @param previousSystemState Deserializer parameter.
|
||||
* @param nbCycles Deserializer parameter.
|
||||
* @param nbInterestingnessMeasures Deserializer parameter.
|
||||
* @param coactiveType Deserializer parameter.
|
||||
*/
|
||||
protected AbstractCoactiveLearning(Vector weights,
|
||||
SystemState previousSystemState,
|
||||
int nbCycles,
|
||||
int nbInterestingnessMeasures,
|
||||
CoactiveType coactiveType) {
|
||||
this.weights = weights;
|
||||
this.previousSystemState = previousSystemState;
|
||||
this.nbCycles = nbCycles;
|
||||
this.nbInterestingnessMeasures = nbInterestingnessMeasures;
|
||||
|
||||
this.coactiveType = coactiveType;
|
||||
}
|
||||
|
||||
protected AbstractCoactiveLearning(CoactiveType coactiveType) {
|
||||
previousSystemState = new SystemState(new ArrayList<>());
|
||||
nbCycles = 1;
|
||||
}
|
||||
|
||||
//********** Initializing Methods **********//
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
nbInterestingnessMeasures = Pattern.MeasureType.values().length + OCMManager.algorithmLauncherGetListAlgorithmName().size() + OCMManager.algorithmLauncherGetListAttributeName().size();
|
||||
double[] initWeights = new double[nbInterestingnessMeasures];
|
||||
for (int i = 0; i < nbInterestingnessMeasures; i++) {
|
||||
initWeights[i] = 1.0 / nbInterestingnessMeasures;
|
||||
}
|
||||
weights = new Vector(initWeights);
|
||||
}
|
||||
|
||||
//********** Public Methods **********//
|
||||
|
||||
@Override
|
||||
public abstract void updateWeight(SystemState newState);
|
||||
|
||||
@Override
|
||||
public abstract double getUtility(List<Pattern> listPatterns);
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
@Override
|
||||
public abstract double[] getWeights();
|
||||
|
||||
@Override
|
||||
public abstract int getNbCycles();
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.coactivelearning.api;
|
||||
|
||||
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.ranking.CoactiveLearningRanking;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.set.CoactiveLearningSet;
|
||||
import fr.insa.ocm.model.utils.SystemState;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CoactiveLearning {
|
||||
|
||||
enum CoactiveType {
|
||||
RANKING, SET;
|
||||
|
||||
public CoactiveLearning newInstance(){
|
||||
switch (this){
|
||||
case RANKING:
|
||||
return new CoactiveLearningRanking();
|
||||
case SET:
|
||||
return new CoactiveLearningSet();
|
||||
default:
|
||||
return new CoactiveLearningSet();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (this){
|
||||
case RANKING:
|
||||
return "Ranking";
|
||||
case SET:
|
||||
return "Set";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void initialize();
|
||||
|
||||
void updateWeight(SystemState newState);
|
||||
|
||||
double getUtility(List<Pattern> listPatterns);
|
||||
|
||||
double[] getWeights();
|
||||
|
||||
int getNbCycles();
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.coactivelearning.ranking;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.api.AbstractCoactiveLearning;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.api.CoactiveLearning;
|
||||
import fr.insa.ocm.model.utils.Rank;
|
||||
import fr.insa.ocm.model.utils.SystemState;
|
||||
import fr.insa.ocm.model.utils.Vector;
|
||||
import fr.insa.ocm.model.utils.serialize.SearchSave;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import java.lang.Math;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <h1>Coactive Learning Algorithm</h1>
|
||||
* <p>Provides methods for the coactive learning algorithm.</p>
|
||||
*/
|
||||
public class CoactiveLearningRanking extends AbstractCoactiveLearning {
|
||||
|
||||
private static final int D_MAX_BORN = 250; //born d to this max value
|
||||
@Expose private int d;
|
||||
|
||||
/**
|
||||
* Deserializer constructor.
|
||||
* @param weights Deserializer parameter.
|
||||
* @param previousSystemState Deserializer parameter.
|
||||
* @param nbCycles Deserializer parameter.
|
||||
* @param nbInterestingnessMeasures Deserializer parameter.
|
||||
* @param coactiveType Deserializer parameter.
|
||||
* @param d Deserializer parameter.
|
||||
*/
|
||||
public CoactiveLearningRanking(Vector weights,
|
||||
SystemState previousSystemState,
|
||||
int nbCycles,
|
||||
int nbInterestingnessMeasures,
|
||||
CoactiveType coactiveType,
|
||||
int d){
|
||||
super(weights, previousSystemState, nbCycles, nbInterestingnessMeasures, coactiveType);
|
||||
|
||||
this.d = d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CoactiveLearningRanking instance.
|
||||
*/
|
||||
public CoactiveLearningRanking() {
|
||||
super(CoactiveType.RANKING);
|
||||
d = 1;
|
||||
}
|
||||
|
||||
//********** Public Methods **********//
|
||||
|
||||
/**
|
||||
* Updates the weight vector w(t) with the user selection.
|
||||
* The user selection is the patterns he has selected, rejected and not selected or rejected.
|
||||
* @param newState Actual system state which contains the selected, rejected and neutral patterns.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void updateWeight(SystemState newState){
|
||||
if(!newState.getProposedRanking().isEmpty()){
|
||||
double s = Math.pow(OCMManager.cacheGetSizeListBestPatterns(), 1/d);
|
||||
double theta_t = 1/(2*s*Math.sqrt(Math.pow(2, Math.floor(Math.log10(nbCycles)))));
|
||||
double z = 0;
|
||||
|
||||
Vector phi_userRanking = auxiliaryFunctionPhi(newState.getUserRanking());
|
||||
Vector phi_proposedRanking = auxiliaryFunctionPhi(newState.getProposedRanking());
|
||||
for(int i = 0; i<nbInterestingnessMeasures; i++){
|
||||
weights.getValues()[i] = weights.getValues()[i]* Math.exp(theta_t*(phi_userRanking.getValues()[i] - phi_proposedRanking.getValues()[i]));
|
||||
z += weights.getValues()[i];
|
||||
}
|
||||
|
||||
for(int i = 0; i<nbInterestingnessMeasures; i++){
|
||||
weights.getValues()[i] = weights.getValues()[i]/z;
|
||||
}
|
||||
previousSystemState = newState;
|
||||
if (d < D_MAX_BORN) {
|
||||
d++;
|
||||
}
|
||||
nbCycles++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getUtility(List<Pattern> listPatterns){
|
||||
if(listPatterns instanceof Rank<?>){
|
||||
return this.getUtilityRanking(new Rank<>(listPatterns));
|
||||
} else {
|
||||
DebugLogger.printDebug("CoactiveLearningRanking: getUtility recieved a List<Pattern> instead of a Rank<Pattern>.", DebugLogger.MessageSeverity.HIGH);
|
||||
}
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the utility of an given pattern rank.
|
||||
* @param rank The rank to get its utility
|
||||
* @return The utility value of the given rank
|
||||
*/
|
||||
private double getUtilityRanking(Rank<Pattern> rank){
|
||||
return Vector.scalarProduct(weights, auxiliaryFunctionPhi(rank));
|
||||
}
|
||||
|
||||
//********** Internal Methods **********//
|
||||
|
||||
/**
|
||||
* Computes the auxiliary function Phi.
|
||||
* @param rank The pattern rank
|
||||
* @return The vector computes with the function Phi.
|
||||
*/
|
||||
private synchronized Vector auxiliaryFunctionPhi(Rank<Pattern> rank){
|
||||
Vector phiVectorResult = new Vector();
|
||||
for(int i = 0; i<nbInterestingnessMeasures; i++){
|
||||
Vector phiVector_f = new Vector();
|
||||
int count = 1;
|
||||
for (Pattern p: rank) {
|
||||
int notPresent = 1;
|
||||
double interestingnessValue;
|
||||
if(nbCycles!=1 && (previousSystemState.getInterestingPatterns().contains(p) || previousSystemState.getTrashedPatterns().contains(p))){
|
||||
notPresent = 0;
|
||||
}
|
||||
|
||||
interestingnessValue = p.getAttributesVector().getValues()[i];
|
||||
|
||||
phiVector_f.put(notPresent*interestingnessValue/Math.log10(count+1));
|
||||
count++;
|
||||
}
|
||||
phiVectorResult.put(phiVector_f.norm(d));
|
||||
}
|
||||
return phiVectorResult;
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
public synchronized int getNbCycles(){ return nbCycles; }
|
||||
|
||||
public synchronized double[] getWeights(){
|
||||
return weights.getValues();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
package fr.insa.ocm.model.oneclicklearning.coactivelearning.set;
|
||||
|
||||
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.api.AbstractCoactiveLearning;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.api.CoactiveLearning;
|
||||
import fr.insa.ocm.model.utils.SystemState;
|
||||
import fr.insa.ocm.model.utils.Vector;
|
||||
import fr.insa.ocm.model.utils.serialize.SearchSave;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CoactiveLearningSet extends AbstractCoactiveLearning {
|
||||
|
||||
/**
|
||||
* Deserializer constructor.
|
||||
* @param weights Deserializer parameter.
|
||||
* @param previousSystemState Deserializer parameter.
|
||||
* @param nbCycles Deserializer parameter.
|
||||
* @param nbInterestingnessMeasures Deserializer parameter.
|
||||
* @param coactiveType Deserializer parameter.
|
||||
*/
|
||||
public CoactiveLearningSet(Vector weights,
|
||||
SystemState previousSystemState,
|
||||
int nbCycles,
|
||||
int nbInterestingnessMeasures,
|
||||
CoactiveType coactiveType){
|
||||
super(weights, previousSystemState, nbCycles, nbInterestingnessMeasures, coactiveType);
|
||||
}
|
||||
|
||||
public CoactiveLearningSet(){
|
||||
super(CoactiveType.SET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void updateWeight(SystemState newState) {
|
||||
if(!newState.getProposedRanking().isEmpty()){
|
||||
double s = OCMManager.cacheGetSizeListBestPatterns();
|
||||
double theta_t = 1/(2*s*Math.sqrt(Math.pow(2, Math.floor(Math.log10(nbCycles)))));
|
||||
double z = 0;
|
||||
|
||||
// Vector phi_userRanking = auxiliaryFunctionPhi(newState.getUserRanking());
|
||||
Vector phi_intersting = auxiliaryFunctionPhi(newState.getInterestingPatterns());
|
||||
Vector phi_neutral = auxiliaryFunctionPhi(newState.getNeutralPatterns());
|
||||
Vector phi_proposedRanking = auxiliaryFunctionPhi(newState.getProposedRanking());
|
||||
|
||||
for(int i = 0; i<nbInterestingnessMeasures; i++){
|
||||
weights.getValues()[i] = weights.get(i) * Math.exp(theta_t*((phi_intersting.get(i) + 0.5*phi_neutral.get(i)) - phi_proposedRanking.get(i)));
|
||||
z += weights.get(i);
|
||||
}
|
||||
|
||||
for(int i = 0; i<nbInterestingnessMeasures; i++){
|
||||
weights.getValues()[i] = weights.get(i)/z;
|
||||
}
|
||||
previousSystemState = newState;
|
||||
|
||||
nbCycles++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getUtility(List<Pattern> listPatterns) {
|
||||
return Vector.scalarProduct(weights, auxiliaryFunctionPhi(listPatterns));
|
||||
}
|
||||
|
||||
//********** Internal Methods **********//
|
||||
|
||||
/**
|
||||
* Computes the auxiliary function Phi.
|
||||
* @param listPatterns The pattern rank
|
||||
* @return The vector computes with the function Phi.
|
||||
*/
|
||||
private synchronized Vector auxiliaryFunctionPhi(List<Pattern> listPatterns){
|
||||
Vector phiVectorResult = new Vector();
|
||||
for(int i = 0; i < nbInterestingnessMeasures; ++i){
|
||||
double sum = 0d;
|
||||
for(Pattern pattern : listPatterns){
|
||||
sum += pattern.getAttributesVector().get(i);
|
||||
}
|
||||
phiVectorResult.put(sum);
|
||||
}
|
||||
return phiVectorResult;
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
@Override
|
||||
public synchronized double[] getWeights() {
|
||||
return weights.getValues();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNbCycles() {
|
||||
return nbCycles;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package fr.insa.ocm.model.utils;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/***
|
||||
* This class should keep all the patterns the user has found interesting
|
||||
*/
|
||||
public class PatternWarehouse {
|
||||
|
||||
@Expose private List<Pattern> patterns;
|
||||
|
||||
public PatternWarehouse(List<Pattern> listPatterns){
|
||||
patterns = listPatterns;
|
||||
}
|
||||
|
||||
public PatternWarehouse(){
|
||||
patterns = new ArrayList<>();
|
||||
}
|
||||
|
||||
//********** Public Methods **********//
|
||||
|
||||
public synchronized List<Pattern> getStockedPatterns(){
|
||||
List<Pattern> stockedPatterns = new ArrayList<>();
|
||||
|
||||
patterns.forEach(pattern -> stockedPatterns.add(pattern.copy()));
|
||||
|
||||
return stockedPatterns;
|
||||
}
|
||||
|
||||
public synchronized void addToWarehouse(Collection<Pattern> collection){
|
||||
collection.forEach(pattern -> {
|
||||
if(!patterns.contains(pattern)){
|
||||
patterns.add(pattern);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private synchronized void emptyWarehouse(){ patterns.clear(); }
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package fr.insa.ocm.model.utils;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* RandomSelector contains method to operate probabilistic selection on an array.
|
||||
*/
|
||||
public final class RandomSelector {
|
||||
|
||||
/**
|
||||
* Returns the selected index based on the weights (probabilities).
|
||||
* Linear O(n) version.
|
||||
* @param weights the probabilities
|
||||
* @return the selected index, -1 if an error occurs.
|
||||
*/
|
||||
public static int randomPick(double[] weights) {
|
||||
double weightSum = 0;
|
||||
for (double weight : weights) {
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
double randomValue = new Random().nextDouble()*weightSum;
|
||||
|
||||
for(int i=0; i<weights.length; ++i) {
|
||||
randomValue -= weights[i];
|
||||
if (randomValue <= 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
//return -1 if not found
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package fr.insa.ocm.model.utils;
|
||||
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class Rank<X extends Pattern> extends ArrayList<X> {
|
||||
|
||||
public Rank(){
|
||||
super();
|
||||
}
|
||||
|
||||
public Rank(int size){
|
||||
super(size);
|
||||
}
|
||||
|
||||
public Rank(Rank<X> rank){ super(rank); }
|
||||
|
||||
public Rank(List<X> list){ super(list); }
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package fr.insa.ocm.model.utils;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SystemState {
|
||||
|
||||
@Expose private Rank<Pattern> proposedRanking;
|
||||
@Expose private List<Pattern> interestingPatterns;
|
||||
@Expose private List<Pattern> neutralPatterns;
|
||||
@Expose private List<Pattern> trashedPatterns;
|
||||
|
||||
public List<Pattern> getInterestingPatterns() {
|
||||
return interestingPatterns;
|
||||
}
|
||||
|
||||
public List<Pattern> getNeutralPatterns() {
|
||||
return neutralPatterns;
|
||||
}
|
||||
|
||||
public List<Pattern> getTrashedPatterns() {
|
||||
return trashedPatterns;
|
||||
}
|
||||
|
||||
public SystemState(List<? extends Pattern> proposedRank) {
|
||||
proposedRanking = new Rank<>();
|
||||
this.proposedRanking.addAll(proposedRank);
|
||||
|
||||
}
|
||||
|
||||
public Rank<Pattern> getProposedRanking() {
|
||||
return proposedRanking;
|
||||
}
|
||||
|
||||
public Rank<Pattern> getUserRanking() {
|
||||
Rank<Pattern> userRanking = new Rank<>();
|
||||
userRanking.addAll(interestingPatterns);
|
||||
userRanking.addAll(neutralPatterns);
|
||||
return userRanking;
|
||||
}
|
||||
|
||||
private void setInterestingPatterns(List<Pattern> interestingPatterns) {
|
||||
this.interestingPatterns = interestingPatterns;
|
||||
}
|
||||
|
||||
private void setNeutralPatterns(List<Pattern> neutralPatterns) {
|
||||
this.neutralPatterns = neutralPatterns;
|
||||
}
|
||||
|
||||
private void setTrashedPatterns(List<Pattern> trashedPatterns) {
|
||||
this.trashedPatterns = trashedPatterns;
|
||||
}
|
||||
|
||||
public void update(List<Pattern> newInterestingPattern,
|
||||
List<Pattern> newNeutralPattern,
|
||||
List<Pattern> newTrashedPattern){
|
||||
setInterestingPatterns(newInterestingPattern);
|
||||
setNeutralPatterns(newNeutralPattern);
|
||||
setTrashedPatterns(newTrashedPattern);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
package fr.insa.ocm.model.utils;
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Vector {
|
||||
|
||||
@Expose private double[] values;
|
||||
|
||||
public Vector(){
|
||||
values = new double[0];
|
||||
}
|
||||
|
||||
public Vector(double[] vals) {
|
||||
values = new double[vals.length];
|
||||
|
||||
System.arraycopy(vals, 0, values,0, vals.length);
|
||||
}
|
||||
|
||||
public Vector(Vector orig){
|
||||
values = new double[orig.values.length];
|
||||
System.arraycopy(orig.values, 0, values, 0, values.length);
|
||||
}
|
||||
|
||||
//********* Getters/Setters Method ********//
|
||||
|
||||
public double[] getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public int size(){
|
||||
return values.length;
|
||||
}
|
||||
|
||||
//********* Public Method ********//
|
||||
|
||||
public double norm(int p) {
|
||||
if(p == 0){
|
||||
throw new ArithmeticException("Cannot ask the norm with p=0");
|
||||
}
|
||||
|
||||
double result = 0;
|
||||
for (double coords : this.values) {
|
||||
result += Math.pow((Math.abs(coords)),p);
|
||||
}
|
||||
|
||||
result = Math.pow(result,(1.0/p));
|
||||
|
||||
if(result == Double.NaN || result == Double.POSITIVE_INFINITY || result == Double.NEGATIVE_INFINITY){
|
||||
throw new ArithmeticException("Non valid number: "+ result +"\nVector: "+ this.toString() +"\n");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public double get(int index){
|
||||
if(index < 0 || index >= values.length){
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return values[index];
|
||||
}
|
||||
|
||||
public void put(Vector vector) {
|
||||
int oldValuesSize = this.values.length;
|
||||
int size = vector.values.length + oldValuesSize;
|
||||
|
||||
//Resize the current values array while keeping its content.
|
||||
values = Arrays.copyOf(values, size);
|
||||
|
||||
//Adding the vector given in parameter at the end of the current vector.
|
||||
System.arraycopy(vector.values, 0, values, oldValuesSize, size-oldValuesSize);
|
||||
}
|
||||
|
||||
public void put(double value) {
|
||||
values = Arrays.copyOf(values, values.length+1);
|
||||
values[values.length-1] = value;
|
||||
}
|
||||
|
||||
public static double scalarProduct(Vector vector1, Vector vector2) {
|
||||
|
||||
//Checking if both vectors have the same size
|
||||
if(vector1.values.length != vector2.values.length){
|
||||
throw new ArithmeticException("Scalar Product with different sized vectors");
|
||||
}
|
||||
|
||||
double result = 0;
|
||||
int vectorlength = vector1.values.length;
|
||||
|
||||
for(int i = 0; i < vectorlength; i++){
|
||||
result += vector1.values[i] * vector2.values[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void minusForEach(double value){
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] -= value;
|
||||
}
|
||||
}
|
||||
|
||||
//********* Standard Method ********//
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder stringBuilder = new StringBuilder("[");
|
||||
|
||||
for(int i = 0; i < values.length-1; ++i){
|
||||
if(i != values.length-1){
|
||||
stringBuilder = stringBuilder.append(values[i]);
|
||||
} else {
|
||||
stringBuilder = stringBuilder.append(values[i]).append(", ");
|
||||
}
|
||||
}
|
||||
stringBuilder = stringBuilder.append("]");
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
boolean vectorBool = false;
|
||||
if(obj instanceof Vector){
|
||||
Vector inputVector = (Vector) obj;
|
||||
|
||||
if(inputVector.values.length == values.length){
|
||||
vectorBool = true;
|
||||
|
||||
for(int i = 0; i < values.length; ++i){
|
||||
vectorBool = vectorBool && (inputVector.values[i] == values[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return vectorBool;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package fr.insa.ocm.model.utils.exceptions;
|
||||
|
||||
|
||||
public class NotInitializedException extends RuntimeException {
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
package fr.insa.ocm.model.utils.fastforward;
|
||||
|
||||
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FastForward implements Runnable {
|
||||
|
||||
// Used by the caller of FastForward to know when it is finished.
|
||||
private boolean finished;
|
||||
|
||||
// Used by the caller to force the stop of the fastforward.
|
||||
private boolean stopRequested;
|
||||
|
||||
// Defines the number of learning round the fastforward needs to do and the number of seconds to wait between each of them.
|
||||
private double numberRound;
|
||||
private double numberSecPerRound;
|
||||
|
||||
// Used to describe the current progress of the fastforward.
|
||||
private String currentOperation;
|
||||
private String remainingTime;
|
||||
private Double progressLearning;
|
||||
private Double progressMining;
|
||||
|
||||
// Provided by the caller, indicate which patterns to keep/trash.
|
||||
private List<Condition> listConditions;
|
||||
private Condition.ActionPatternChoice conditionPriority;
|
||||
|
||||
// Intermediate results, the caller needs to get the lasts results for the next learning round.
|
||||
private List<Pattern> listKeptPatterns;
|
||||
private List<Pattern> listNeutralPatterns;
|
||||
private List<Pattern> listTrashedPatterns;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param numberRounds The number of learning round to launch.
|
||||
* @param numberSecPerRound The number of seconds to wait between each learning round.
|
||||
* @param listCondition The list of conditions to keep/trash the patterns.
|
||||
* @param conditionPriority Choose what kind of condition is the most important.
|
||||
* @param listKeptPatterns The list of kept patterns selected during a previous search.
|
||||
* @param listNeutralPatterns The list of neutral patterns selected during a previous search.
|
||||
* @param listTrashedPatterns The list of trashed patterns selected during a previous search.
|
||||
*/
|
||||
public FastForward(double numberRounds, double numberSecPerRound,
|
||||
@NotNull List<Condition> listCondition,
|
||||
@NotNull Condition.ActionPatternChoice conditionPriority,
|
||||
@NotNull List<Pattern> listKeptPatterns,
|
||||
@NotNull List<Pattern> listNeutralPatterns,
|
||||
@NotNull List<Pattern> listTrashedPatterns){
|
||||
this.numberRound = numberRounds;
|
||||
this.numberSecPerRound = numberSecPerRound;
|
||||
this.listConditions = listCondition;
|
||||
this.conditionPriority = conditionPriority;
|
||||
|
||||
this.listKeptPatterns = listKeptPatterns;
|
||||
this.listNeutralPatterns = listNeutralPatterns;
|
||||
this.listTrashedPatterns = listTrashedPatterns;
|
||||
|
||||
finished = false;
|
||||
|
||||
stopRequested = false;
|
||||
|
||||
progressLearning = 0d;
|
||||
progressMining = 0d;
|
||||
currentOperation = "";
|
||||
remainingTime = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
final int nbIter = 100;
|
||||
try {
|
||||
for (int i = 0; i < numberRound && !stopRequested; ++i) {
|
||||
currentOperation = "Mining";
|
||||
for (int j = 0; j < nbIter && !stopRequested; ++j) {
|
||||
Thread.sleep((long)numberSecPerRound*1000/nbIter);
|
||||
progressMining = (j+1d)/nbIter;
|
||||
|
||||
int remainingTimeSec = (int)((numberRound-i) * numberSecPerRound - (numberSecPerRound/nbIter) * j);
|
||||
remainingTime = remainingTimeSec/60 + " min " + remainingTimeSec%60 + " sec";
|
||||
}
|
||||
|
||||
// We process the data gathered by the mining algorithms.
|
||||
currentOperation = "Processing data";
|
||||
|
||||
|
||||
List<Pattern> bestPatterns = OCMManager.getNewRanking(listKeptPatterns, listNeutralPatterns, listTrashedPatterns);
|
||||
List<Pattern> rawBestPatterns = new ArrayList<>(bestPatterns);
|
||||
|
||||
if(conditionPriority.equals(Condition.ActionPatternChoice.TRASH)){
|
||||
listTrashedPatterns = computeListPattern(bestPatterns, rawBestPatterns, listConditions, Condition.ActionPatternChoice.TRASH);
|
||||
bestPatterns.removeAll(listTrashedPatterns);
|
||||
listKeptPatterns = computeListPattern(bestPatterns, rawBestPatterns, listConditions, Condition.ActionPatternChoice.KEEP);
|
||||
bestPatterns.removeAll(listKeptPatterns);
|
||||
listNeutralPatterns = new ArrayList<>(bestPatterns);
|
||||
}else{
|
||||
listKeptPatterns = computeListPattern(bestPatterns, rawBestPatterns, listConditions, Condition.ActionPatternChoice.KEEP);
|
||||
bestPatterns.removeAll(listKeptPatterns);
|
||||
listTrashedPatterns = computeListPattern(bestPatterns, rawBestPatterns, listConditions, Condition.ActionPatternChoice.TRASH);
|
||||
bestPatterns.removeAll(listTrashedPatterns);
|
||||
listNeutralPatterns = new ArrayList<>(bestPatterns);
|
||||
}
|
||||
|
||||
int nbPatternRank = rawBestPatterns.size();
|
||||
double nbQuality = listKeptPatterns.size() - listTrashedPatterns.size();
|
||||
nbQuality = ((nbQuality/nbPatternRank)+1)/2;
|
||||
|
||||
System.err.println(listKeptPatterns.size() +"-"+ listNeutralPatterns.size()
|
||||
+ "-" + listTrashedPatterns.size() + " : " + nbQuality);
|
||||
|
||||
DebugLogger.printQuality(i +";"+ nbQuality);
|
||||
|
||||
progressLearning = ((i+1d)/numberRound);
|
||||
}
|
||||
}catch(InterruptedException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
currentOperation = "Finished";
|
||||
remainingTime = "Finished";
|
||||
|
||||
finished = true;
|
||||
}
|
||||
|
||||
//********** Internal Methods **********//
|
||||
|
||||
private List<Pattern> computeListPattern(List<Pattern> listPattern,
|
||||
List<Pattern> rawListPattern,
|
||||
List<Condition> listCondition,
|
||||
Condition.ActionPatternChoice actionOnPattern){
|
||||
List<Pattern> listResultPattern = new ArrayList<>();
|
||||
|
||||
for(Pattern pattern : listPattern){
|
||||
//Check if one of the condition to trash is met by the pattern.
|
||||
for(Condition condition : listCondition){
|
||||
if(condition.getActionPatternChoice().equals(actionOnPattern) && condition.isMet(pattern, rawListPattern)){
|
||||
listResultPattern.add(pattern);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return listResultPattern;
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
public boolean isFinished(){
|
||||
return finished;
|
||||
}
|
||||
|
||||
public String getCurrentOperation() {
|
||||
return currentOperation;
|
||||
}
|
||||
|
||||
public String getRemainingTime() {
|
||||
return remainingTime;
|
||||
}
|
||||
|
||||
public Double getProgressLearning() {
|
||||
return progressLearning;
|
||||
}
|
||||
|
||||
public Double getProgressMining() {
|
||||
return progressMining;
|
||||
}
|
||||
|
||||
public List<Pattern> getListKeptPatterns() {
|
||||
return listKeptPatterns;
|
||||
}
|
||||
|
||||
public List<Pattern> getListNeutralPatterns() {
|
||||
return listNeutralPatterns;
|
||||
}
|
||||
|
||||
public List<Pattern> getListTrashedPatterns() {
|
||||
return listTrashedPatterns;
|
||||
}
|
||||
|
||||
// Setters //
|
||||
public void setStopRequested() {
|
||||
this.stopRequested = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package fr.insa.ocm.model.utils.fastforward.condition;
|
||||
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Condition {
|
||||
|
||||
public enum ActionPatternChoice {
|
||||
KEEP, NEUTRAL, TRASH;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch(this){
|
||||
case KEEP:
|
||||
return "Keep";
|
||||
case NEUTRAL:
|
||||
return "Neutral";
|
||||
case TRASH:
|
||||
return "Trash";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ConditionType {
|
||||
CONDITION_ATTRIBUTE,
|
||||
CONDITION_ALGORITHM,
|
||||
CONDITION_MEASURE_STATIC,
|
||||
CONDITION_MEASURE_DYNAMIC,
|
||||
CONDITION_MEASURE_BETWEEN;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch(this){
|
||||
case CONDITION_ATTRIBUTE:
|
||||
return "Condition Attribute";
|
||||
case CONDITION_ALGORITHM:
|
||||
return "Condition Algorithm";
|
||||
case CONDITION_MEASURE_STATIC:
|
||||
return "Condition Measure Static";
|
||||
case CONDITION_MEASURE_BETWEEN:
|
||||
return "Condition Measure Between";
|
||||
case CONDITION_MEASURE_DYNAMIC:
|
||||
return "Condition Measure Dynamic";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Expose private ActionPatternChoice actionPatternChoice;
|
||||
@Expose private ConditionType conditionType;
|
||||
|
||||
/**
|
||||
* For Deserialization purpose only.
|
||||
*/
|
||||
protected Condition(){}
|
||||
|
||||
protected Condition(@NotNull ActionPatternChoice actionPatternChoice,
|
||||
@NotNull ConditionType conditionType){
|
||||
this.actionPatternChoice = actionPatternChoice;
|
||||
this.conditionType = conditionType;
|
||||
}
|
||||
|
||||
public abstract boolean isMet(Pattern pattern, List<Pattern> listPattern);
|
||||
|
||||
public ActionPatternChoice getActionPatternChoice(){ return actionPatternChoice; }
|
||||
|
||||
public ConditionType getConditionType(){ return conditionType; }
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package fr.insa.ocm.model.utils.fastforward.condition;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionAlgorithm extends Condition {
|
||||
|
||||
public enum AlgorithmState{
|
||||
CREATEDBY, NOT_CREATEDBY;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch(this){
|
||||
case CREATEDBY:
|
||||
return "has been created";
|
||||
case NOT_CREATEDBY:
|
||||
return "has not been created";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Expose private AlgorithmState algorithmState;
|
||||
@Expose private String algorithmName;
|
||||
|
||||
/**
|
||||
* For Deserialization purpose only.
|
||||
*/
|
||||
public ConditionAlgorithm(){}
|
||||
|
||||
public ConditionAlgorithm(@NotNull ActionPatternChoice actionPatternChoice,
|
||||
String algorithmName,
|
||||
AlgorithmState algorithmState){
|
||||
super(actionPatternChoice, ConditionType.CONDITION_ALGORITHM);
|
||||
|
||||
this.algorithmState = algorithmState;
|
||||
this.algorithmName = algorithmName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(Pattern pattern, @Nullable List<Pattern> listPattern) {
|
||||
return (pattern.getAlgorithmName().equals(algorithmName) && algorithmState.equals(AlgorithmState.CREATEDBY))
|
||||
|| (!pattern.getAlgorithmName().equals(algorithmName) && algorithmState.equals(AlgorithmState.NOT_CREATEDBY));
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
public AlgorithmState getAlgorithmState() {
|
||||
return algorithmState;
|
||||
}
|
||||
|
||||
public String getAlgorithmName() {
|
||||
return algorithmName;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package fr.insa.ocm.model.utils.fastforward.condition;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionAttribute extends Condition {
|
||||
|
||||
public enum AttributeState{
|
||||
PRESENT, ABSENT;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch(this){
|
||||
case PRESENT:
|
||||
return "present";
|
||||
case ABSENT:
|
||||
return "absent";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Expose private String attributeName;
|
||||
@Expose private AttributeState attributeState;
|
||||
|
||||
/**
|
||||
* For Deserialization purpose only.
|
||||
*/
|
||||
public ConditionAttribute(){}
|
||||
|
||||
public ConditionAttribute(ActionPatternChoice actionPatternChoice,
|
||||
String attributeName,
|
||||
AttributeState attributeState){
|
||||
super(actionPatternChoice, ConditionType.CONDITION_ATTRIBUTE);
|
||||
|
||||
this.attributeName = attributeName;
|
||||
this.attributeState = attributeState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(Pattern pattern, List<Pattern> listPattern) {
|
||||
return this.isMet(pattern);
|
||||
}
|
||||
|
||||
private boolean isMet(Pattern pattern) {
|
||||
boolean isMet = false;
|
||||
if(attributeState.equals(AttributeState.ABSENT)){
|
||||
isMet = true;
|
||||
}
|
||||
|
||||
// Search in all the attribute names of the pattern.
|
||||
// If the attribute should be absent to met the condition, if there is no such attribute in the pattern, isMet will remain true.
|
||||
// If the attribute should be present to met the condition, if there is a such attribute in the pattern, isMet will switch from false to true once.
|
||||
for (String patternAttributeName : pattern.getListAttributeNames()) {
|
||||
if(patternAttributeName.equals(attributeName)){
|
||||
isMet = !isMet;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isMet;
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
public String getAttributeName() {
|
||||
return attributeName;
|
||||
}
|
||||
|
||||
public AttributeState getAttributeState() {
|
||||
return attributeState;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
package fr.insa.ocm.model.utils.fastforward.condition;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionMeasureBetween extends Condition {
|
||||
|
||||
public enum IntervalChoice{
|
||||
INSIDE_IN_IN, INSIDE_IN_OUT, INSIDE_OUT_IN, INSIDE_OUT_OUT,
|
||||
OUTSIDE_IN_IN, OUTSIDE_IN_OUT, OUTSIDE_OUT_IN, OUTSIDE_OUT_OUT;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch(this){
|
||||
case INSIDE_IN_IN:
|
||||
return "is between [X;Y]";
|
||||
case INSIDE_IN_OUT:
|
||||
return "is between [X;Y[";
|
||||
case INSIDE_OUT_IN:
|
||||
return "is between ]X;Y]";
|
||||
case INSIDE_OUT_OUT:
|
||||
return "is between ]X;Y[";
|
||||
case OUTSIDE_IN_IN:
|
||||
return "is not between [X;Y]";
|
||||
case OUTSIDE_IN_OUT:
|
||||
return "is not between [X;Y[";
|
||||
case OUTSIDE_OUT_IN:
|
||||
return "is not between ]X;Y]";
|
||||
case OUTSIDE_OUT_OUT:
|
||||
return "is not between ]X;Y[";
|
||||
default:
|
||||
return "Oh no D:";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Expose private ConditionMeasureStatic lowerBound;
|
||||
@Expose private ConditionMeasureStatic higerBound;
|
||||
@Expose private IntervalChoice intervalChoice;
|
||||
|
||||
public ConditionMeasureBetween(){}
|
||||
|
||||
public ConditionMeasureBetween(@NotNull ActionPatternChoice actionPatternChoice,
|
||||
Pattern.MeasureType measureType,
|
||||
IntervalChoice intervalChoice, double thresholdValueLowerBound, double thresholdValueHigherBound){
|
||||
super(actionPatternChoice, ConditionType.CONDITION_MEASURE_BETWEEN);
|
||||
|
||||
ConditionMeasureStatic.OperatorType operatorTypeLowerBound = null;
|
||||
ConditionMeasureStatic.OperatorType operatorTypeHigherBound = null;
|
||||
|
||||
switch(intervalChoice){
|
||||
case INSIDE_IN_IN:
|
||||
operatorTypeLowerBound = ConditionMeasureStatic.OperatorType.GET;
|
||||
operatorTypeHigherBound = ConditionMeasureStatic.OperatorType.LET;
|
||||
break;
|
||||
case INSIDE_IN_OUT:
|
||||
operatorTypeLowerBound = ConditionMeasureStatic.OperatorType.GET;
|
||||
operatorTypeHigherBound = ConditionMeasureStatic.OperatorType.LT;
|
||||
break;
|
||||
case INSIDE_OUT_IN:
|
||||
operatorTypeLowerBound = ConditionMeasureStatic.OperatorType.GT;
|
||||
operatorTypeHigherBound = ConditionMeasureStatic.OperatorType.LET;
|
||||
break;
|
||||
case INSIDE_OUT_OUT:
|
||||
operatorTypeLowerBound = ConditionMeasureStatic.OperatorType.GT;
|
||||
operatorTypeHigherBound = ConditionMeasureStatic.OperatorType.LT;
|
||||
break;
|
||||
case OUTSIDE_IN_IN:
|
||||
operatorTypeLowerBound = ConditionMeasureStatic.OperatorType.LET;
|
||||
operatorTypeHigherBound = ConditionMeasureStatic.OperatorType.GET;
|
||||
break;
|
||||
case OUTSIDE_IN_OUT:
|
||||
operatorTypeLowerBound = ConditionMeasureStatic.OperatorType.LET;
|
||||
operatorTypeHigherBound = ConditionMeasureStatic.OperatorType.GT;
|
||||
break;
|
||||
case OUTSIDE_OUT_IN:
|
||||
operatorTypeLowerBound = ConditionMeasureStatic.OperatorType.LT;
|
||||
operatorTypeHigherBound = ConditionMeasureStatic.OperatorType.GET;
|
||||
break;
|
||||
case OUTSIDE_OUT_OUT:
|
||||
operatorTypeLowerBound = ConditionMeasureStatic.OperatorType.LT;
|
||||
operatorTypeHigherBound = ConditionMeasureStatic.OperatorType.GT;
|
||||
break;
|
||||
}
|
||||
|
||||
this.intervalChoice = intervalChoice;
|
||||
this.lowerBound = new ConditionMeasureStatic(actionPatternChoice, measureType, operatorTypeLowerBound, thresholdValueLowerBound);
|
||||
this.higerBound = new ConditionMeasureStatic(actionPatternChoice, measureType, operatorTypeHigherBound, thresholdValueHigherBound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(Pattern pattern, List<Pattern> listPattern) {
|
||||
switch(intervalChoice){
|
||||
case INSIDE_IN_IN:
|
||||
case INSIDE_IN_OUT:
|
||||
case INSIDE_OUT_IN:
|
||||
case INSIDE_OUT_OUT:
|
||||
return lowerBound.isMet(pattern, listPattern) && higerBound.isMet(pattern, listPattern);
|
||||
case OUTSIDE_IN_IN:
|
||||
case OUTSIDE_IN_OUT:
|
||||
case OUTSIDE_OUT_IN:
|
||||
case OUTSIDE_OUT_OUT:
|
||||
return lowerBound.isMet(pattern, listPattern) || higerBound.isMet(pattern, listPattern);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
public ConditionMeasureStatic getHigerBound() {
|
||||
return higerBound;
|
||||
}
|
||||
|
||||
public ConditionMeasureStatic getLowerBound() {
|
||||
return lowerBound;
|
||||
}
|
||||
|
||||
public IntervalChoice getIntervalChoice() {
|
||||
return intervalChoice;
|
||||
}
|
||||
|
||||
public Pattern.MeasureType getMeasureType(){ return lowerBound.getMeasure(); }
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
package fr.insa.ocm.model.utils.fastforward.condition;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionMeasureDynamic extends Condition {
|
||||
|
||||
public enum CatogoryType{
|
||||
HIGHEST, LOWEST;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch(this){
|
||||
case HIGHEST:
|
||||
return "highest";
|
||||
case LOWEST:
|
||||
return "lowest";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Expose private Pattern.MeasureType measure;
|
||||
@Expose private CatogoryType catogory;
|
||||
@Expose private int index;
|
||||
|
||||
/**
|
||||
* For Deserialization purpose only.
|
||||
*/
|
||||
public ConditionMeasureDynamic(){}
|
||||
|
||||
public ConditionMeasureDynamic(@NotNull ActionPatternChoice actionPatternChoice,
|
||||
Pattern.MeasureType measure,
|
||||
CatogoryType catogory,
|
||||
int index){
|
||||
super(actionPatternChoice, ConditionType.CONDITION_MEASURE_DYNAMIC);
|
||||
|
||||
this.measure = measure;
|
||||
this.catogory = catogory;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(Pattern pattern, List<Pattern> listPattern) {
|
||||
double measureValue = this.getMeasureFromPattern(pattern);
|
||||
double measureThresholdValue;
|
||||
boolean conditionIsMet = false;
|
||||
List<Pattern> sortedListPattern = this.getSortedListPattern(listPattern);
|
||||
|
||||
switch(catogory){
|
||||
case HIGHEST:
|
||||
measureThresholdValue = this.getMeasureFromPattern(sortedListPattern.get(index));
|
||||
conditionIsMet = measureValue >= measureThresholdValue;
|
||||
break;
|
||||
case LOWEST:
|
||||
measureThresholdValue = this.getMeasureFromPattern(sortedListPattern.get(sortedListPattern.size() - index));
|
||||
conditionIsMet = measureValue <= measureThresholdValue;
|
||||
break;
|
||||
}
|
||||
|
||||
return conditionIsMet;
|
||||
}
|
||||
|
||||
private double getMeasureFromPattern(Pattern pattern){
|
||||
return pattern.getMeasureValue(measure);
|
||||
}
|
||||
|
||||
private List<Pattern> getSortedListPattern(List<Pattern> listPattern){
|
||||
List<Pattern> sortedListPattern = new ArrayList<>(listPattern);
|
||||
|
||||
sortedListPattern.sort((pattern1, pattern2) -> {
|
||||
double measurePattern1 = this.getMeasureFromPattern(pattern1);
|
||||
double measurePattern2 = this.getMeasureFromPattern(pattern2);
|
||||
double difference = measurePattern1 - measurePattern2;
|
||||
if(difference < 0){
|
||||
return 1;
|
||||
}else if(difference > 0){
|
||||
return -1;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
return sortedListPattern;
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
public Pattern.MeasureType getMeasure() {
|
||||
return measure;
|
||||
}
|
||||
|
||||
public CatogoryType getCatogory() {
|
||||
return catogory;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package fr.insa.ocm.model.utils.fastforward.condition;
|
||||
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionMeasureStatic extends Condition {
|
||||
|
||||
public enum OperatorType{
|
||||
LT, LET, EQL, GET, GT;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String result;
|
||||
if(this == LT){
|
||||
result = "<";
|
||||
}else if(this == LET){
|
||||
result = "<=";
|
||||
}else if(this == EQL){
|
||||
result = "=";
|
||||
}else if(this == GET){
|
||||
result = ">=";
|
||||
}else{
|
||||
result = ">";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//TODO Javadoc, dire qu'on fait value1 Operation value2 et qu'on vérifie si c'est vrai
|
||||
public boolean isValid(double value1, double value2){
|
||||
switch (this){
|
||||
case LT:
|
||||
return value1 < value2;
|
||||
case LET:
|
||||
return value1 <= value2;
|
||||
case EQL:
|
||||
return value1 == value2;
|
||||
case GET:
|
||||
return value1 >= value2;
|
||||
case GT:
|
||||
return value1 > value2;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Expose private Pattern.MeasureType measure;
|
||||
@Expose private OperatorType operator;
|
||||
@Expose private double thresholdValue;
|
||||
|
||||
/**
|
||||
* For Deserialization purpose only.
|
||||
*/
|
||||
public ConditionMeasureStatic(){}
|
||||
|
||||
public ConditionMeasureStatic(ActionPatternChoice actionPatternChoice,
|
||||
Pattern.MeasureType measure,
|
||||
OperatorType operator,
|
||||
double thresholdValue){
|
||||
super(actionPatternChoice, ConditionType.CONDITION_MEASURE_STATIC);
|
||||
|
||||
this.measure = measure;
|
||||
this.operator = operator;
|
||||
this.thresholdValue = thresholdValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(Pattern pattern, List<Pattern> listPattern) {
|
||||
return this.isMet(pattern);
|
||||
}
|
||||
|
||||
private boolean isMet(Pattern pattern) {
|
||||
return operator.isValid(pattern.getMeasureValue(measure), thresholdValue);
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
public Pattern.MeasureType getMeasure() {
|
||||
return measure;
|
||||
}
|
||||
|
||||
public OperatorType getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public double getThresholdValue() {
|
||||
return thresholdValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
package fr.insa.ocm.model.utils.serialize;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.oneclicklearning.bandit.CesaBianciBandit;
|
||||
import fr.insa.ocm.model.oneclicklearning.bandit.MultiArmedBandit;
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.api.Cache;
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.rank.CacheRanking;
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.set.CacheSet;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.api.CoactiveLearning;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.ranking.CoactiveLearningRanking;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.set.CoactiveLearningSet;
|
||||
import fr.insa.ocm.model.utils.Rank;
|
||||
import fr.insa.ocm.model.utils.SystemState;
|
||||
import fr.insa.ocm.model.utils.Vector;
|
||||
import fr.insa.ocm.model.wrapper.api.AbstractPattern;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.model.wrapper.realkd.PatternRealKD;
|
||||
import fr.insa.ocm.model.wrapper.spmf.PatternSPMF;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OCMDeserializer {
|
||||
|
||||
private class PatternDeserializer implements JsonDeserializer<Pattern>{
|
||||
|
||||
@Override
|
||||
public Pattern deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
|
||||
JsonObject jsonPattern = jsonElement.getAsJsonObject();
|
||||
|
||||
AbstractPattern.WrapperType wrapperType;
|
||||
Vector attributeVector;
|
||||
String patternDescriptor;
|
||||
String algorithmType;
|
||||
double[] measures;
|
||||
List<String> listAttributeNames = new ArrayList<>();
|
||||
|
||||
wrapperType = jsonDeserializer.fromJson(jsonPattern.get("wrapperType"), Pattern.WrapperType.class);
|
||||
attributeVector = jsonDeserializer.fromJson(jsonPattern.get("attributeVector"), Vector.class);
|
||||
patternDescriptor = jsonElement.getAsJsonObject().get("patternDescriptor").getAsString();
|
||||
algorithmType = jsonElement.getAsJsonObject().get("algorithmType").getAsString();
|
||||
JsonArray jsonMeasures = jsonPattern.getAsJsonArray("measures");
|
||||
JsonArray jsonListAttributeNames = jsonElement.getAsJsonObject().get("listAttributeNames").getAsJsonArray();
|
||||
|
||||
measures = new double[jsonMeasures.size()];
|
||||
for(int i = 0; i < jsonMeasures.size(); ++i){
|
||||
measures[i] = jsonMeasures.get(i).getAsDouble();
|
||||
}
|
||||
for(int i = 0; i < jsonListAttributeNames.size(); ++i){
|
||||
listAttributeNames.add(jsonListAttributeNames.get(i).getAsString());
|
||||
}
|
||||
|
||||
// Special parts for each kind of pattern
|
||||
switch (wrapperType){
|
||||
case REALKD:
|
||||
String typePattern = jsonElement.getAsJsonObject().get("type").getAsString();
|
||||
|
||||
return new PatternRealKD(typePattern, listAttributeNames,
|
||||
attributeVector, measures,
|
||||
patternDescriptor, algorithmType);
|
||||
case SPMF:
|
||||
return new PatternSPMF(listAttributeNames, attributeVector,
|
||||
measures,
|
||||
patternDescriptor, algorithmType);
|
||||
default:
|
||||
DebugLogger.printDebug("OCMDeserialiazer: Impossible to retrieve the type of Pattern saved.", DebugLogger.MessageSeverity.HIGH);
|
||||
throw new RuntimeException("Impossible to determine the type of pattern to deserialize.");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private class BanditDeserializer implements JsonDeserializer<MultiArmedBandit>{
|
||||
|
||||
@Override
|
||||
public MultiArmedBandit deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
|
||||
JsonArray jsonWeights = jsonElement.getAsJsonObject().getAsJsonArray("weights");
|
||||
|
||||
double[] weights = new double[jsonWeights.size()];
|
||||
int round = jsonElement.getAsJsonObject().get("round").getAsInt();
|
||||
double V = jsonElement.getAsJsonObject().get("V").getAsDouble();
|
||||
|
||||
for(int i = 0; i < jsonWeights.size(); ++i){
|
||||
weights[i] = jsonWeights.get(i).getAsDouble();
|
||||
}
|
||||
|
||||
return new CesaBianciBandit(weights, round, V);
|
||||
}
|
||||
}
|
||||
|
||||
private class CacheDeserializer implements JsonDeserializer<Cache>{
|
||||
|
||||
@Override
|
||||
public Cache deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
|
||||
JsonObject jsonCache = jsonElement.getAsJsonObject();
|
||||
|
||||
Cache.CacheType cacheType = jsonDeserializer.fromJson(jsonCache.get("cacheType"), Cache.CacheType.class);
|
||||
Integer sizeListBestPatterns = jsonCache.get("sizeListBestPatterns").getAsInt();
|
||||
|
||||
switch (cacheType){
|
||||
case RANKING:
|
||||
Double utility = jsonCache.get("utility").getAsDouble();
|
||||
Rank<Pattern> greedyRanking = new Rank<>();
|
||||
|
||||
JsonArray jsonGreedyRanking = jsonCache.get("greedyRanking").getAsJsonArray();
|
||||
for(int i = 0; i < jsonGreedyRanking.size(); ++i){
|
||||
greedyRanking.add(jsonDeserializer.fromJson(jsonGreedyRanking.get(0), Pattern.class));
|
||||
}
|
||||
|
||||
return new CacheRanking(sizeListBestPatterns, cacheType,
|
||||
utility, greedyRanking);
|
||||
case SET:
|
||||
return new CacheSet(sizeListBestPatterns, cacheType);
|
||||
default:
|
||||
DebugLogger.printDebug("OCMDeserializer: Impossible to retrieve the type of Cache saved.", DebugLogger.MessageSeverity.HIGH);
|
||||
throw new RuntimeException("Impossible to determine the type of cache to deserialize.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CoactiveLearningDeserializer implements JsonDeserializer<CoactiveLearning>{
|
||||
|
||||
@Override
|
||||
public CoactiveLearning deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
|
||||
JsonObject jsonCoactive = jsonElement.getAsJsonObject();
|
||||
|
||||
// Deserialize common attributs of the CoactiveLearning
|
||||
CoactiveLearning.CoactiveType coactiveType =
|
||||
jsonDeserializer.fromJson(jsonCoactive.get("coactiveType"), CoactiveLearning.CoactiveType.class);
|
||||
Vector weights = jsonDeserializer.fromJson(jsonCoactive.get("weights"), Vector.class);
|
||||
SystemState previousSystemState =
|
||||
jsonDeserializer.fromJson(jsonCoactive.get("previousSystemState"), SystemState.class);
|
||||
int nbCycles = jsonCoactive.get("nbCycles").getAsInt();
|
||||
int nbInterestingnessMeasures = jsonCoactive.get("nbInterestingnessMeasures").getAsInt();
|
||||
|
||||
switch (coactiveType){
|
||||
case RANKING:
|
||||
int d = jsonCoactive.get("d").getAsInt();
|
||||
return new CoactiveLearningRanking(weights,
|
||||
previousSystemState,
|
||||
nbCycles,
|
||||
nbInterestingnessMeasures,
|
||||
coactiveType,
|
||||
d);
|
||||
case SET:
|
||||
return new CoactiveLearningSet(weights,
|
||||
previousSystemState,
|
||||
nbCycles,
|
||||
nbInterestingnessMeasures,
|
||||
coactiveType);
|
||||
default:
|
||||
DebugLogger.printDebug("OCMDeserializer: Impossible to retrieve the type of CoactiveLearning saved.", DebugLogger.MessageSeverity.HIGH);
|
||||
throw new RuntimeException("Impossible to determine the type of coactive learning to deserialize.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Gson jsonDeserializer;
|
||||
private SearchSave searchSave;
|
||||
|
||||
private String deserializedForm;
|
||||
private String pathLoadFile;
|
||||
|
||||
public OCMDeserializer(@NotNull String pathLoadFile){
|
||||
this.pathLoadFile = pathLoadFile;
|
||||
this.deserializedForm = "";
|
||||
|
||||
jsonDeserializer = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(MultiArmedBandit.class, new BanditDeserializer())
|
||||
.registerTypeAdapter(Pattern.class, new PatternDeserializer())
|
||||
.registerTypeAdapter(Cache.class, new CacheDeserializer())
|
||||
.registerTypeAdapter(CoactiveLearning.class, new CoactiveLearningDeserializer())
|
||||
.create();
|
||||
searchSave = new SearchSave();
|
||||
|
||||
this.deserialize();
|
||||
}
|
||||
|
||||
private void deserialize(){
|
||||
DebugLogger.printDebug("OCMDeserializer: Loading.");
|
||||
this.loadFile();
|
||||
|
||||
searchSave = jsonDeserializer.fromJson(deserializedForm, SearchSave.class);
|
||||
|
||||
DebugLogger.printDebug("OCMDeserializer: Deserializing.");
|
||||
OCMManager.deserialize(searchSave);
|
||||
}
|
||||
|
||||
private void loadFile(){
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
reader = new BufferedReader(new FileReader(new File(pathLoadFile)));
|
||||
|
||||
String line;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
while ((line = reader.readLine()) != null){
|
||||
stringBuilder = stringBuilder.append(line);
|
||||
}
|
||||
|
||||
deserializedForm = stringBuilder.toString();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(reader != null){
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package fr.insa.ocm.model.utils.serialize;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
public class OCMSerializer {
|
||||
|
||||
private Gson jsonSerializer;
|
||||
private SearchSave searchSave;
|
||||
|
||||
private String serializedForm;
|
||||
private String pathSaveFile;
|
||||
|
||||
public OCMSerializer(@NotNull String pathSaveFile){
|
||||
this.pathSaveFile = pathSaveFile;
|
||||
serializedForm = "";
|
||||
|
||||
jsonSerializer = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create();
|
||||
searchSave = new SearchSave();
|
||||
|
||||
this.serialize();
|
||||
}
|
||||
|
||||
private void serialize(){
|
||||
OCMManager.serialize(searchSave);
|
||||
|
||||
serializedForm = jsonSerializer.toJson(searchSave);
|
||||
|
||||
this.saveFile();
|
||||
}
|
||||
|
||||
private void saveFile(){
|
||||
BufferedWriter writer = null;
|
||||
try {
|
||||
writer = new BufferedWriter(new FileWriter(new File(pathSaveFile)));
|
||||
|
||||
writer.write(serializedForm);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(writer != null){
|
||||
try {
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package fr.insa.ocm.model.utils.serialize;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.oneclicklearning.algorithmmanager.AlgorithmManager;
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.api.Cache;
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.rank.CacheRanking;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.api.CoactiveLearning;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.ranking.CoactiveLearningRanking;
|
||||
import fr.insa.ocm.model.oneclicklearning.bandit.MultiArmedBandit;
|
||||
import fr.insa.ocm.model.utils.PatternWarehouse;
|
||||
import fr.insa.ocm.model.utils.SystemState;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SearchSave {
|
||||
|
||||
@Expose private MultiArmedBandit bandit;
|
||||
@Expose private Cache cache;
|
||||
@Expose private CoactiveLearning coactiveLearning;
|
||||
@Expose private PatternWarehouse patternWarehouse;
|
||||
@Expose private SystemState currentState;
|
||||
@Expose private boolean isInitialized;
|
||||
@Expose private boolean firstRanking;
|
||||
|
||||
public SearchSave(){}
|
||||
|
||||
//********** Saving Methods **********//
|
||||
|
||||
public void setMultiArmedBandit(MultiArmedBandit bandit){
|
||||
this.bandit = bandit;
|
||||
}
|
||||
|
||||
public void setCache(Cache cache){
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public void setCoactiveLearning(CoactiveLearning coactiveLearning){
|
||||
this.coactiveLearning = coactiveLearning;
|
||||
}
|
||||
|
||||
public void setPatternWarehouse(PatternWarehouse patternWarehouse){
|
||||
this.patternWarehouse = patternWarehouse;
|
||||
}
|
||||
|
||||
public void setCurrentState(SystemState currentState){
|
||||
this.currentState = currentState;
|
||||
}
|
||||
|
||||
public void setInitialized(boolean initialized) {
|
||||
isInitialized = initialized;
|
||||
}
|
||||
|
||||
public void setFirstRanking(boolean firstRanking) {
|
||||
this.firstRanking = firstRanking;
|
||||
}
|
||||
|
||||
//********** Loading Methods **********//
|
||||
|
||||
public MultiArmedBandit getMultiArmedBandit(){
|
||||
return bandit;
|
||||
}
|
||||
|
||||
public Cache getCache(){
|
||||
return cache;
|
||||
}
|
||||
|
||||
public CoactiveLearning getCoactiveLearning(){
|
||||
return coactiveLearning;
|
||||
}
|
||||
|
||||
public PatternWarehouse getPatternWarehouse(){
|
||||
return patternWarehouse;
|
||||
}
|
||||
|
||||
public SystemState getCurrentState() {
|
||||
return currentState;
|
||||
}
|
||||
|
||||
public boolean getInitialized() {
|
||||
return isInitialized;
|
||||
}
|
||||
|
||||
public boolean getFirstRanking() {
|
||||
return firstRanking;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package fr.insa.ocm.model.utils.serialize.condition;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Conditions {
|
||||
|
||||
@Expose private List<Condition> conditions;
|
||||
|
||||
public List<Condition> getConditions() {
|
||||
return conditions;
|
||||
}
|
||||
|
||||
public void setConditions(List<Condition> conditions) {
|
||||
this.conditions = conditions;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package fr.insa.ocm.model.utils.serialize.condition;
|
||||
|
||||
import com.google.gson.*;
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.oneclicklearning.bandit.MultiArmedBandit;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionsDeserializer {
|
||||
|
||||
private static class ConditionDeserializer implements JsonDeserializer<Condition>{
|
||||
|
||||
@Override
|
||||
public Condition deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
|
||||
Condition.ConditionType conditionType = jsonDeserializer.fromJson(jsonElement.getAsJsonObject().get("conditionType"), Condition.ConditionType.class);
|
||||
|
||||
switch (conditionType){
|
||||
case CONDITION_ATTRIBUTE:
|
||||
return jsonDeserializer.fromJson(jsonElement, ConditionAttribute.class);
|
||||
case CONDITION_ALGORITHM:
|
||||
return jsonDeserializer.fromJson(jsonElement, ConditionAttribute.class);
|
||||
case CONDITION_MEASURE_STATIC:
|
||||
return jsonDeserializer.fromJson(jsonElement, ConditionMeasureStatic.class);
|
||||
case CONDITION_MEASURE_DYNAMIC:
|
||||
return jsonDeserializer.fromJson(jsonElement, ConditionMeasureDynamic.class);
|
||||
case CONDITION_MEASURE_BETWEEN:
|
||||
return jsonDeserializer.fromJson(jsonElement, ConditionMeasureBetween.class);
|
||||
default:
|
||||
DebugLogger.printDebug("ConditionsDeserializer: Impossible to retrieve the type of Condition saved.", DebugLogger.MessageSeverity.HIGH);
|
||||
throw new RuntimeException("Impossible to determine the type of condition to deserialize.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Gson jsonDeserializer;
|
||||
|
||||
public static List<Condition> loadConditions(@NotNull String pathLoadFile){
|
||||
StringBuilder sbSerializedForm = new StringBuilder("");
|
||||
Conditions conditions;
|
||||
jsonDeserializer = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(Condition.class, new ConditionDeserializer())
|
||||
.create();
|
||||
|
||||
try(BufferedReader reader = new BufferedReader(new FileReader(pathLoadFile))){
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null){
|
||||
sbSerializedForm.append(line);
|
||||
}
|
||||
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
conditions = jsonDeserializer.fromJson(sbSerializedForm.toString(), Conditions.class);
|
||||
|
||||
return conditions.getConditions();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package fr.insa.ocm.model.utils.serialize.condition;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionsSerializer {
|
||||
|
||||
public static void saveConditions(@NotNull String pathSaveFile, @NotNull List<Condition> listConditions){
|
||||
Gson jsonSerializer = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
|
||||
.setPrettyPrinting()
|
||||
.create();
|
||||
Conditions conditions = new Conditions();
|
||||
String serializedForm;
|
||||
|
||||
// Wrapping the list of conditions before serializing it.
|
||||
conditions.setConditions(listConditions);
|
||||
serializedForm = jsonSerializer.toJson(conditions);
|
||||
|
||||
// Writing the serialized form to the file.
|
||||
try(BufferedWriter writer = new BufferedWriter(new FileWriter(pathSaveFile))){
|
||||
writer.write(serializedForm);
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package fr.insa.ocm.model.wrapper.api;
|
||||
|
||||
import fr.insa.ocm.model.wrapper.realkd.AlgorithmLauncherRealKD;
|
||||
import fr.insa.ocm.model.wrapper.spmf.AlgorithmLauncherSPMF;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class AbstractAlgorithmLauncher implements AlgorithmLauncher {
|
||||
|
||||
// The monitoring the system.
|
||||
// A map of the number of calls for each algorithms.
|
||||
protected static Map<String, Integer> mapNumberCallsPerAlgorithm = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
// The list of all the attribute names in the current dataset.
|
||||
protected List<String> listAttributeName;
|
||||
|
||||
protected AbstractAlgorithmLauncher(){
|
||||
listAttributeName = new ArrayList<>();
|
||||
}
|
||||
|
||||
public abstract int getNbAlgorithms();
|
||||
|
||||
public abstract List<Pattern> startAlgorithm(int algorithmNumber);
|
||||
|
||||
public abstract void stopAlgorithm();
|
||||
|
||||
@Override
|
||||
public int getNbAttributes() {
|
||||
return listAttributeName.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getListAttributeName() {
|
||||
return new ArrayList<>(listAttributeName);
|
||||
}
|
||||
|
||||
public abstract List<String> getListAlgorithmName();
|
||||
|
||||
public static Map<String, Integer> getStatsAlgorithmsLaunched() {
|
||||
return mapNumberCallsPerAlgorithm;
|
||||
}
|
||||
|
||||
public static List<String> getAllAvailableAlgorithm(){
|
||||
List<String> listAllAvailableAlgorithm = new ArrayList<>(AlgorithmLauncherRealKD.getListAvailableMiningAlgorithm());
|
||||
listAllAvailableAlgorithm.addAll(AlgorithmLauncherSPMF.getListAvailableMiningAlgorithm());
|
||||
return listAllAvailableAlgorithm;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
package fr.insa.ocm.model.wrapper.api;
|
||||
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import fr.insa.ocm.model.utils.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractPattern implements Pattern {
|
||||
|
||||
//Intern variables describing the pattern.
|
||||
|
||||
@Expose protected double[] measures;
|
||||
|
||||
@Expose protected Vector attributeVector = new Vector();
|
||||
@Expose protected List<String> listAttributeNames = new ArrayList<>();
|
||||
|
||||
@Expose protected String patternDescriptor = "";
|
||||
@Expose protected String algorithmType = "";
|
||||
@Expose protected WrapperType wrapperType;
|
||||
|
||||
protected AbstractPattern(){
|
||||
measures = new double[MeasureType.values().length];
|
||||
for(int i = 0; i < measures.length; ++i){
|
||||
measures[i] = 0d;
|
||||
}
|
||||
}
|
||||
|
||||
protected AbstractPattern(AbstractPattern pattern){
|
||||
this.measures = pattern.measures;
|
||||
|
||||
this.attributeVector = new Vector(pattern.attributeVector);
|
||||
this.listAttributeNames = new ArrayList<>(pattern.listAttributeNames);
|
||||
|
||||
this.patternDescriptor = pattern.patternDescriptor;
|
||||
this.algorithmType = pattern.algorithmType;
|
||||
this.wrapperType = pattern.wrapperType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMeasureValue(MeasureType measure){
|
||||
return measures[measure.getIndex()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the attribute vector used to compute the interestingness of this pattern.
|
||||
* @return The vector of presence of attributes. If the attribute of rank i is present in the pattern, the ith value is 1 else it is 0.
|
||||
*/
|
||||
@Override
|
||||
public Vector getAttributesVector(){
|
||||
return attributeVector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getListAttributeNames(){ return new ArrayList<>(listAttributeNames); }
|
||||
|
||||
@Override
|
||||
public String getAlgorithmName(){
|
||||
return algorithmType;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Vector contains an array of values from 0d to 1d. First come the measures (between 0d and 1d), then the attributes (0d or 1d), then the algorithm (0d or 1d).
|
||||
* @param algorithmLauncher The algorithm launcher from which the pattern ha been created.
|
||||
*/
|
||||
protected void computeAttributeVector(AlgorithmLauncher algorithmLauncher){
|
||||
List<String> listAllAttributeNames = algorithmLauncher.getListAttributeName();
|
||||
List<String> listAllAlgorithmNames = algorithmLauncher.getListAlgorithmName();
|
||||
int nbMeasure = measures.length;
|
||||
int nbAttr = listAllAttributeNames.size();
|
||||
int nbAlg = listAllAlgorithmNames.size();
|
||||
|
||||
double attributeValue[] = new double[nbMeasure + nbAttr + nbAlg];
|
||||
for(int i = 0; i < attributeValue.length; ++i){
|
||||
attributeValue[i] = 0d;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
System.arraycopy(measures, 0, attributeValue, 0, nbMeasure);
|
||||
|
||||
offset += nbMeasure;
|
||||
for(int i = offset; i < offset+nbAttr; ++i){
|
||||
if(listAttributeNames.contains(listAllAttributeNames.get(i-offset))){
|
||||
attributeValue[i] = 1d;
|
||||
}
|
||||
}
|
||||
|
||||
offset += nbAttr;
|
||||
for(int i = offset; i < offset+nbAlg; ++i){
|
||||
if(listAllAlgorithmNames.get(i-offset).equals(algorithmType)){
|
||||
attributeValue[i] = 1d;
|
||||
}
|
||||
}
|
||||
|
||||
attributeVector = new Vector(attributeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the list of attribute name of the current pattern.
|
||||
* The list of those name is lazy computed.
|
||||
*/
|
||||
protected void computeAttributeName(AlgorithmLauncher algorithmLauncher){
|
||||
List<String> listAlgoLaunAN = algorithmLauncher.getListAttributeName();
|
||||
|
||||
//For each attribute known in the initial data set, we search it in the pattern.
|
||||
//If and only if the attribute is present in the patten, it is added to the listAttributeNames of the current pattern.
|
||||
for (String attributeStr : listAlgoLaunAN) {
|
||||
if (patternDescriptor.contains(attributeStr)) {
|
||||
listAttributeNames.add(attributeStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//********** Standard Methods **********//
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
boolean patternBool = false;
|
||||
|
||||
if(obj instanceof AbstractPattern){
|
||||
AbstractPattern patternTmp = (AbstractPattern) obj;
|
||||
|
||||
patternBool = attributeVector.equals(patternTmp.attributeVector);
|
||||
}
|
||||
|
||||
return patternBool;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package fr.insa.ocm.model.wrapper.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface AlgorithmLauncher{
|
||||
|
||||
int getNbAlgorithms();
|
||||
|
||||
List<Pattern> startAlgorithm(int algorithmNumber);
|
||||
|
||||
void stopAlgorithm();
|
||||
|
||||
int getNbAttributes();
|
||||
|
||||
List<String> getListAttributeName();
|
||||
|
||||
List<String> getListAlgorithmName();
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package fr.insa.ocm.model.wrapper.api;
|
||||
|
||||
import fr.insa.ocm.model.utils.Vector;
|
||||
import fr.insa.ocm.model.wrapper.realkd.AlgorithmLauncherRealKD;
|
||||
import fr.insa.ocm.model.wrapper.spmf.AlgorithmLauncherSPMF;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Pattern{
|
||||
|
||||
enum WrapperType {
|
||||
REALKD, SPMF;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (this){
|
||||
case SPMF:
|
||||
return "SPMF";
|
||||
case REALKD:
|
||||
return "RealKD";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public AlgorithmLauncher getAlgorithmLauncher(String pathRawData){
|
||||
switch (this){
|
||||
case SPMF:
|
||||
return new AlgorithmLauncherSPMF(pathRawData);
|
||||
case REALKD:
|
||||
return new AlgorithmLauncherRealKD(pathRawData);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum MeasureType {
|
||||
FREQUENCY,
|
||||
RELATIVE_SHORTNESS,
|
||||
// LIFT,
|
||||
// SUBGROUP_INTERSTINGNESS,
|
||||
// TARGET_DEVIATION,
|
||||
RELATIVE_PERIODICITY;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (this) {
|
||||
case FREQUENCY:
|
||||
return "Frequency";
|
||||
case RELATIVE_SHORTNESS:
|
||||
return "Relative Shortness";
|
||||
// case LIFT:
|
||||
// return "Lift";
|
||||
// case SUBGROUP_INTERSTINGNESS:
|
||||
// return "SubGroup Interestingness";
|
||||
// case TARGET_DEVIATION:
|
||||
// return "Target Deviation";
|
||||
case RELATIVE_PERIODICITY:
|
||||
return "Relative Periodicity";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
MeasureType[] values = values();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if (values[i].equals(this)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static MeasureType getName(int index) {
|
||||
return values()[index];
|
||||
}
|
||||
}
|
||||
|
||||
double getMeasureValue(MeasureType measure);
|
||||
|
||||
Vector getAttributesVector();
|
||||
|
||||
String getAlgorithmName();
|
||||
|
||||
String toString();
|
||||
|
||||
List<String> getListAttributeNames();
|
||||
|
||||
Pattern copy();
|
||||
}
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
package fr.insa.ocm.model.wrapper.realkd;
|
||||
|
||||
import de.unibonn.realkd.algorithms.StoppableMiningAlgorithm;
|
||||
import de.unibonn.realkd.algorithms.association.AssociationMiningBeamSearch;
|
||||
import de.unibonn.realkd.algorithms.association.AssociationSampler;
|
||||
import de.unibonn.realkd.algorithms.emm.ExceptionalModelSampler;
|
||||
import de.unibonn.realkd.common.workspace.Workspace;
|
||||
import de.unibonn.realkd.common.workspace.Workspaces;
|
||||
import de.unibonn.realkd.data.propositions.*;
|
||||
import de.unibonn.realkd.data.table.DataTable;
|
||||
import de.unibonn.realkd.data.table.attribute.Attribute;
|
||||
import fr.insa.ocm.model.wrapper.api.AbstractAlgorithmLauncher;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class AlgorithmLauncherRealKD extends AbstractAlgorithmLauncher{
|
||||
|
||||
// The static list of all usable algorithms.
|
||||
// This list is instantiated only once in the static method "instantiateListAlgorithm"
|
||||
private static List<String> listAvailableMiningAlgorithm = null;
|
||||
|
||||
// The workspace contains the dataset
|
||||
private static String lastMiningAlgorithm;
|
||||
private Workspace currentWorkspace;
|
||||
|
||||
// Algorithm Launcher keeps the track of the current mining algorithm in order to stop it later if needed.
|
||||
private StoppableMiningAlgorithm currentMiningAlgorithm;
|
||||
private List<Pattern> patternResults;
|
||||
private PatternRealKD.PatternType typeOfPatternResult;
|
||||
|
||||
static{
|
||||
// Instantiate the list of available algorithm.
|
||||
listAvailableMiningAlgorithm = new ArrayList<>();
|
||||
listAvailableMiningAlgorithm.add("AssociationMiningBS");
|
||||
listAvailableMiningAlgorithm.add("AssociationSampler");
|
||||
|
||||
listAvailableMiningAlgorithm.forEach(s -> mapNumberCallsPerAlgorithm.put(s, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor of algorithm launcher, it needs a path to the data file and a path to the attribute file.
|
||||
*/
|
||||
public AlgorithmLauncherRealKD(String pathRawData){
|
||||
super();
|
||||
|
||||
patternResults = new ArrayList<>();
|
||||
currentMiningAlgorithm = null;
|
||||
|
||||
// The creation of a Workspace is only done with the factory "Workspaces"
|
||||
currentWorkspace = Workspaces.workspace();
|
||||
|
||||
this.importData(pathRawData);
|
||||
}
|
||||
|
||||
//********** Implemented methods **********//
|
||||
|
||||
/**
|
||||
* Getter to know the number of data mining algorithm that can be used.
|
||||
* @return The integer representing the number of data mining algorithm that cand be used.
|
||||
*/
|
||||
@Override
|
||||
public int getNbAlgorithms(){
|
||||
return listAvailableMiningAlgorithm.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method of the algorithm launcher : it starts the algorithm asked and at the end gives the pattern resulting.
|
||||
* The patterns in the list are directly usable by OCM.
|
||||
* @param algoNb The rank of the algorithm to launch.
|
||||
* @return The list of pattern resulting from the launched data mining algorithm.
|
||||
*/
|
||||
@Override
|
||||
public List<Pattern> startAlgorithm(int algoNb){
|
||||
//Clear all the precedent found results.
|
||||
patternResults.clear();
|
||||
|
||||
if(algoNb < listAvailableMiningAlgorithm.size()){
|
||||
//System.err.println("LOG: Getting the algorithm.");
|
||||
|
||||
//Get algorithm from the given number parameter.
|
||||
|
||||
StoppableMiningAlgorithm miningAlgorithm = getAlgorithm(listAvailableMiningAlgorithm.get(algoNb));
|
||||
|
||||
//If no valid algorithm has been found, it returns an empty result list.
|
||||
if(miningAlgorithm == null){
|
||||
System.err.println("ERR: getAlgorithm did not sent a valid algorithm.");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
//System.err.println("LOG: Algorithm begins its search.");
|
||||
|
||||
//Launch the data mining algorithm asked and gather the raw results.
|
||||
currentMiningAlgorithm = miningAlgorithm;
|
||||
Collection<de.unibonn.realkd.patterns.Pattern<?>> results = miningAlgorithm.call();
|
||||
currentMiningAlgorithm = null;
|
||||
|
||||
//System.err.println("LOG: Algorithm ends its search.\nConverting results.");
|
||||
|
||||
//Converts the raw result to have results usable for OCM.
|
||||
convertResults(results);
|
||||
//System.err.println("LOG: Results converted successfully.");
|
||||
|
||||
}else{
|
||||
System.err.println(algoNb + "is not a valid number of algorithm.");
|
||||
}
|
||||
|
||||
return patternResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to request a stop on the current launched algorithm.
|
||||
*/
|
||||
@Override
|
||||
public void stopAlgorithm(){
|
||||
if(currentMiningAlgorithm != null){
|
||||
currentMiningAlgorithm.requestStop();
|
||||
currentMiningAlgorithm = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports the data and the attributes from the csv files.
|
||||
* @param csv The path to the csv file.
|
||||
*/
|
||||
public void importData(String csv){
|
||||
CSVLoaderRealKD csvLoaderRealKD = new CSVLoaderRealKD(csv);
|
||||
csvLoaderRealKD.convert();
|
||||
DataTable dataTable = csvLoaderRealKD.createDataTable();
|
||||
|
||||
//Once the data table is created, it is incorporated in the current workspace.
|
||||
currentWorkspace.overwrite(dataTable);
|
||||
|
||||
//Creates all the propositional logic used by RealKD in its algorithms.
|
||||
currentWorkspace.overwrite(new PropositionalLogicFromTableBuilder().build(dataTable));
|
||||
|
||||
//Create the list of name of all attributes
|
||||
createListAttributeName();
|
||||
}
|
||||
|
||||
public List<String> getListAlgorithmName(){
|
||||
return new ArrayList<>(listAvailableMiningAlgorithm);
|
||||
}
|
||||
|
||||
//********** Package methods **********//
|
||||
|
||||
//********** Public methods **********//
|
||||
|
||||
public static List<String> getListAvailableMiningAlgorithm(){
|
||||
return new ArrayList<>(listAvailableMiningAlgorithm);
|
||||
}
|
||||
|
||||
//********** Internal methods **********//
|
||||
|
||||
/**
|
||||
* Method to get an algorithm from its name. The available names are listed in listAvailableMiningAlgorithm.
|
||||
* For each name in this list, an algorithm for the library RealKD is given.
|
||||
* @param name The name of the algorithm to get.
|
||||
* @return The stoppable mining algorithm corresponding to the given name.
|
||||
*/
|
||||
private StoppableMiningAlgorithm getAlgorithm(String name){
|
||||
lastMiningAlgorithm = name;
|
||||
int numberCalls;
|
||||
|
||||
if(name == null) {
|
||||
System.err.println("A Null argument was found instead of a valid parameter in getAlgorithm");
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (name) {
|
||||
case "AssociationMiningBS":
|
||||
typeOfPatternResult = PatternRealKD.PatternType.ASSOCIATION;
|
||||
numberCalls = mapNumberCallsPerAlgorithm.getOrDefault(name, 0);
|
||||
mapNumberCallsPerAlgorithm.put(name, numberCalls + 1);
|
||||
|
||||
return new AssociationMiningBeamSearch(currentWorkspace);
|
||||
|
||||
case "AssociationSampler":
|
||||
typeOfPatternResult = PatternRealKD.PatternType.ASSOCIATION;
|
||||
numberCalls = mapNumberCallsPerAlgorithm.getOrDefault(name, 0);
|
||||
mapNumberCallsPerAlgorithm.put(name, numberCalls + 1);
|
||||
|
||||
return new AssociationSampler(currentWorkspace);
|
||||
|
||||
case "ExceptionalModelSampler":
|
||||
typeOfPatternResult = PatternRealKD.PatternType.SUBGROUP;
|
||||
numberCalls = mapNumberCallsPerAlgorithm.getOrDefault(name, 0);
|
||||
mapNumberCallsPerAlgorithm.put(name, numberCalls + 1);
|
||||
|
||||
return new ExceptionalModelSampler(currentWorkspace);
|
||||
|
||||
default:
|
||||
System.err.println(name + " is not a valid algorithm name");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The results sent will be converted in an OCM format. It allows to use the results within the software OCM.
|
||||
* @param results Results should come directly from the RealKD librarie in order to be correctly converted.
|
||||
*/
|
||||
private void convertResults(Collection<de.unibonn.realkd.patterns.Pattern<?>> results){
|
||||
|
||||
//For each pattern from the library RealKD
|
||||
for(de.unibonn.realkd.patterns.Pattern pattern : results){
|
||||
|
||||
if(typeOfPatternResult != null){
|
||||
|
||||
//A type of pattern is required for the pattern to correctly work.
|
||||
patternResults.add(new PatternRealKD(pattern, this, typeOfPatternResult, lastMiningAlgorithm));
|
||||
|
||||
}else{
|
||||
|
||||
System.out.println("ERR: The current type of pattern is null");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
typeOfPatternResult = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called only once when the algorithm launcher is created.
|
||||
* It creates the list of attributes's name of the dataset for a later use.
|
||||
*/
|
||||
private void createListAttributeName(){
|
||||
|
||||
if(listAttributeName == null){
|
||||
listAttributeName = new ArrayList<>();
|
||||
|
||||
//Checks if the current workspace has no data tables, if there is none then an error is printed.
|
||||
if(currentWorkspace.getAllDatatables() == null || currentWorkspace.getAllDatatables().isEmpty()){
|
||||
System.err.println("ERR: No Attributes were found. Cannot instantiate listAttributeName in AlgorithmLauncherRealKD");
|
||||
return;
|
||||
}
|
||||
|
||||
//Adds all the attributes names of the first data table of the current workspace
|
||||
for(Attribute<?> attribute : currentWorkspace.getAllDatatables().get(0).attributes()){
|
||||
listAttributeName.add(attribute.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
package fr.insa.ocm.model.wrapper.realkd;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import de.unibonn.realkd.data.table.DataFormatException;
|
||||
import de.unibonn.realkd.data.table.DataTable;
|
||||
import de.unibonn.realkd.data.table.DataTableFromCSVFileBuilder;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
class CSVLoaderRealKD {
|
||||
|
||||
private enum AttributeType{
|
||||
NAME,
|
||||
NUMERIC,
|
||||
CATEGORIC
|
||||
}
|
||||
|
||||
private String csvPath;
|
||||
private String datPath;
|
||||
private String attPath;
|
||||
|
||||
private boolean isConverted;
|
||||
|
||||
CSVLoaderRealKD(@NotNull String csv){
|
||||
csvPath = csv;
|
||||
|
||||
//Remove the extension of the file name.
|
||||
String fileName = csvPath.substring(0, csvPath.lastIndexOf("."));
|
||||
|
||||
//Create the new name for the the new data file and new attribute file.
|
||||
datPath = fileName + ".dat";
|
||||
attPath = fileName + ".att";
|
||||
|
||||
isConverted = false;
|
||||
}
|
||||
|
||||
void convert(){
|
||||
if (csvPath == null || datPath == null || attPath == null){
|
||||
System.err.println("ERR: One of the path name is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
BufferedReader readerCSV = null;
|
||||
BufferedWriter writerDAT = null;
|
||||
BufferedWriter writerATT = null;
|
||||
|
||||
String[] attributeArr;
|
||||
AttributeType[] typeArr;
|
||||
try{
|
||||
readerCSV = new BufferedReader(new FileReader(new File(csvPath)));
|
||||
writerDAT = new BufferedWriter(new FileWriter(new File(datPath)));
|
||||
writerATT = new BufferedWriter(new FileWriter(new File(attPath)));
|
||||
|
||||
//Read the first line, which has the attributes.
|
||||
String line = readerCSV.readLine();
|
||||
if(line == null){
|
||||
System.err.println("ERR: Could not read the first line of the CSV file");
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
//Create the list of attributes for the attribute file
|
||||
attributeArr = line.split(";");
|
||||
|
||||
//Create the list of types of attributes for the attribute file
|
||||
//By default, the first attribute is always the name, all the other ones are numeric (unless detected categoric while reader)
|
||||
typeArr = new AttributeType[attributeArr.length];
|
||||
typeArr[0] = AttributeType.NAME;
|
||||
for(int i = 1; i < typeArr.length; ++i){
|
||||
typeArr[i] = AttributeType.NUMERIC;
|
||||
}
|
||||
|
||||
//Read the other lines which has the data and create the data file
|
||||
while((line = readerCSV.readLine()) != null){
|
||||
//Write the data inside the data file
|
||||
writerDAT.write(line);
|
||||
writerDAT.newLine();
|
||||
|
||||
//Check the type of each attribute (without the first one which is always name)
|
||||
String[] split = line.split(";");
|
||||
if(split.length != typeArr.length){
|
||||
System.err.println("ERR: The CSV is malformed, one line has one less or one more field than expected");
|
||||
System.err.println(line);
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
for(int i = 1; i < split.length; ++i){
|
||||
//If the attribute is set as numeric and the data is not empty and is not a number, than the corresponding attribute is categoric
|
||||
if(typeArr[i].equals(AttributeType.NUMERIC) && !split[i].equals("") && !split[i].matches("-?\\d+(\\.\\d+)?")) {
|
||||
typeArr[i] = AttributeType.CATEGORIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Create the attribute file
|
||||
for(int i = 0; i < attributeArr.length; ++i){
|
||||
writerATT.write(attributeArr[i] + ";" + typeArr[i].toString().toLowerCase() + ";" + attributeArr[i] + "\'s description");
|
||||
writerATT.newLine();
|
||||
}
|
||||
|
||||
isConverted = true;
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
//No matter what happens, close all the file handlers
|
||||
if(readerCSV != null){
|
||||
try {
|
||||
readerCSV.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(writerDAT != null){
|
||||
try {
|
||||
writerDAT.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(writerATT != null){
|
||||
try {
|
||||
writerATT.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to create a data table from a data csv file. Used internally to create the dataset.
|
||||
* @return The datatable (defined by RealKD) containing the data and its attributes in a usuable form for RealKD.
|
||||
*/
|
||||
DataTable createDataTable(){
|
||||
if(!isConverted){
|
||||
System.err.println("ERR: The CSV has not been converted, thus it is impossible the create the corresponding datatable");
|
||||
return null;
|
||||
}
|
||||
|
||||
DataTable resultDataTable = null;
|
||||
|
||||
//Builder to create a data table. It uses the data file and the attribute file to import the data and the attributes.
|
||||
//Then it gives an ID and a name for the soon to be created data table.
|
||||
DataTableFromCSVFileBuilder builder =
|
||||
new DataTableFromCSVFileBuilder()
|
||||
.setDataCSVFilename(datPath)
|
||||
.setAttributeMetadataCSVFilename(attPath)
|
||||
.setId("OCM")
|
||||
.setName("OCM");
|
||||
|
||||
try{
|
||||
//The builder tries to create the datable.
|
||||
resultDataTable = builder.build();
|
||||
}catch(DataFormatException dfException) {
|
||||
System.err.println("DataFormatException encountered when loading the CSV file.");
|
||||
System.err.println(dfException.getMessage());
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
return resultDataTable;
|
||||
}
|
||||
|
||||
public List<List<String>> loadCSV(){
|
||||
List<List<String>> stringCSV = new ArrayList<>();
|
||||
|
||||
BufferedReader readerCSV;
|
||||
|
||||
String[] tmp;
|
||||
int nbAttr;
|
||||
try {
|
||||
readerCSV = new BufferedReader(new FileReader(new File(csvPath)));
|
||||
|
||||
//Read the first line, which has the attributes.
|
||||
String line = readerCSV.readLine();
|
||||
if(line == null){
|
||||
System.err.println("ERR: Could not read the first line of the CSV file");
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
//Create the list of attributes for the attribute file
|
||||
tmp = line.split(";");
|
||||
nbAttr = tmp.length;
|
||||
|
||||
stringCSV.add(new ArrayList<>(Arrays.asList(tmp)));
|
||||
|
||||
while ((line = readerCSV.readLine()) != null){
|
||||
tmp = line.split(";");
|
||||
|
||||
if(tmp.length != nbAttr){
|
||||
System.err.println("ERR: The CSV is malformed, one line has one less or one more field than expected");
|
||||
System.err.println(line);
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
stringCSV.add(new ArrayList<>(Arrays.asList(tmp)));
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return stringCSV;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
package fr.insa.ocm.model.wrapper.realkd;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import de.unibonn.realkd.patterns.QualityMeasureId;
|
||||
import fr.insa.ocm.model.wrapper.api.AbstractPattern;
|
||||
import fr.insa.ocm.model.utils.Vector;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PatternRealKD extends AbstractPattern {
|
||||
|
||||
enum PatternType{
|
||||
ASSOCIATION, SUBGROUP, UNKNOWN;
|
||||
|
||||
static PatternType getPatternType(String str){
|
||||
switch (str.toLowerCase()){
|
||||
case "association":
|
||||
return PatternType.ASSOCIATION;
|
||||
case "subgroup":
|
||||
return PatternType.SUBGROUP;
|
||||
default:
|
||||
return PatternType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//The Pattern coming from the RealKD library.
|
||||
//private de.unibonn.realkd.patterns.Pattern pattern;
|
||||
|
||||
//The algorithm launcher from which come from this pattern.
|
||||
//private AlgorithmLauncherRealKD algorithmLauncher;
|
||||
|
||||
//The type of this pattern.
|
||||
@Expose private PatternType type;
|
||||
|
||||
//TODO Javadoc, for serialization only
|
||||
public PatternRealKD(){}
|
||||
|
||||
public PatternRealKD(String type, List<String> listAttributeNames,
|
||||
Vector attributeVector, double[] measures,
|
||||
String patternDescriptor, String algorithmType){
|
||||
this.type = PatternType.getPatternType(type);
|
||||
this.listAttributeNames = listAttributeNames;
|
||||
this.attributeVector = attributeVector;
|
||||
|
||||
this.measures = measures;
|
||||
|
||||
this.patternDescriptor = patternDescriptor;
|
||||
this.algorithmType = algorithmType;
|
||||
|
||||
wrapperType = WrapperType.REALKD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Package visible constructor of a PatternRealKD.
|
||||
* @param p The Pattern obtained from the data mining algorithm, the Pattern is the one from the RealKD library.
|
||||
* @param algorithmLauncherRealKD The Algorithm Launcher which had launched the data mining algorithm to obtain the Pattern.
|
||||
* @param patternType The type of Pattern that were given by the data mining algorithm, e.g. Association, SubGroup, etc.
|
||||
*/
|
||||
PatternRealKD(@NotNull de.unibonn.realkd.patterns.Pattern p,
|
||||
@NotNull AlgorithmLauncherRealKD algorithmLauncherRealKD,
|
||||
@NotNull PatternType patternType,
|
||||
@NotNull String algorithmType){
|
||||
type = patternType;
|
||||
this.algorithmType = algorithmType;
|
||||
|
||||
listAttributeNames = new ArrayList<>();
|
||||
wrapperType = WrapperType.REALKD;
|
||||
|
||||
initialize(p, algorithmLauncherRealKD);
|
||||
}
|
||||
|
||||
private PatternRealKD(@NotNull PatternRealKD patternRealKD){
|
||||
super(patternRealKD);
|
||||
|
||||
this.type = patternRealKD.type;
|
||||
}
|
||||
|
||||
//********** Implemented Methods **********//
|
||||
|
||||
public Pattern copy(){
|
||||
return new PatternRealKD(this);
|
||||
}
|
||||
|
||||
//********** Internal Methods **********//
|
||||
|
||||
private void initialize(de.unibonn.realkd.patterns.Pattern p, AlgorithmLauncherRealKD algorithmLauncherRealKD){
|
||||
patternDescriptor = p.descriptor().toString();
|
||||
|
||||
// The order of these operation is important.
|
||||
// computeAttributeVector uses the result of computeAttributeName
|
||||
computeAttributeName(algorithmLauncherRealKD);
|
||||
computeAttributeVector(algorithmLauncherRealKD);
|
||||
computeInterestingValues(p, algorithmLauncherRealKD);
|
||||
}
|
||||
|
||||
private void computeInterestingValues(de.unibonn.realkd.patterns.Pattern p, AlgorithmLauncherRealKD algorithmLauncherRealKD){
|
||||
if(type == PatternType.ASSOCIATION){
|
||||
// Frequency
|
||||
if(p.hasMeasure(QualityMeasureId.FREQUENCY)){
|
||||
measures[MeasureType.FREQUENCY.getIndex()] = p.value(QualityMeasureId.FREQUENCY);
|
||||
}else{
|
||||
measures[MeasureType.FREQUENCY.getIndex()] = 0.;
|
||||
}
|
||||
|
||||
// RelativeShortness
|
||||
double totalNumberAttribute = algorithmLauncherRealKD.getListAttributeName().size();
|
||||
if(totalNumberAttribute != 0) {
|
||||
measures[MeasureType.RELATIVE_SHORTNESS.getIndex()] = listAttributeNames.size() / totalNumberAttribute;
|
||||
}else{
|
||||
measures[MeasureType.RELATIVE_SHORTNESS.getIndex()] = 0.;
|
||||
}
|
||||
|
||||
// // Lift
|
||||
// if(p.hasMeasure(QualityMeasureId.LIFT)){
|
||||
// lift = p.value(QualityMeasureId.LIFT);
|
||||
// }else{
|
||||
// lift = 0.;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
//********** Standard Methods **********//
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder stringBuilder = new StringBuilder("");
|
||||
NumberFormat formatter = new DecimalFormat("#0.00");
|
||||
|
||||
stringBuilder = stringBuilder.append(patternDescriptor).append("\n");
|
||||
|
||||
if(type == PatternType.ASSOCIATION){
|
||||
stringBuilder = stringBuilder.append("[Frequency: ").append(formatter.format(measures[MeasureType.FREQUENCY.getIndex()]))
|
||||
.append(", RelativeShortness: ").append(formatter.format(measures[MeasureType.RELATIVE_SHORTNESS.getIndex()]))
|
||||
// .append(", Lift: ").append(formatter.format(getLift()))
|
||||
.append(", Algorithm: ").append(algorithmType).append("]\n");
|
||||
}
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
boolean patternBool = false;
|
||||
|
||||
if(obj instanceof PatternRealKD){
|
||||
PatternRealKD patternTmp = (PatternRealKD) obj;
|
||||
|
||||
patternBool = patternDescriptor.equals(patternTmp.patternDescriptor);
|
||||
}
|
||||
|
||||
return patternBool;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,263 @@
|
|||
package fr.insa.ocm.model.wrapper.spmf;
|
||||
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.wrapper.api.AbstractAlgorithmLauncher;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.model.wrapper.spmf.algorithm.*;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class AlgorithmLauncherSPMF extends AbstractAlgorithmLauncher {
|
||||
|
||||
// Settings to tune the algorithms
|
||||
private static volatile double minsupLCM = 0.6;
|
||||
private static volatile double minsupBIDEPlus = 0.5;
|
||||
private static volatile double minsupVMSP = 0.45;
|
||||
private static volatile int maxgapVMSP = 5;
|
||||
private static volatile double minsupPFPM = 0.5;
|
||||
private static volatile int minPeriodicityPFPM = 1;
|
||||
private static volatile int maxPeriodicityPFPM = 14;
|
||||
private static volatile boolean[] measuresPatternDescriptor = new boolean[Pattern.MeasureType.values().length];
|
||||
|
||||
// The list of all available algorithms to use for OCM.
|
||||
private static List<String> listAvailableMiningAlgorithm;
|
||||
|
||||
// The map which keep the link between real attribute name and its number designation.
|
||||
private Map<Integer, String> mapIdLabel;
|
||||
|
||||
// The path to the current data file
|
||||
private String pathConvertedData;
|
||||
|
||||
|
||||
static{
|
||||
listAvailableMiningAlgorithm = new ArrayList<>();
|
||||
listAvailableMiningAlgorithm.add(LCMSPMF.NAME);
|
||||
listAvailableMiningAlgorithm.add(BIDEPlusSPMF.NAME);
|
||||
listAvailableMiningAlgorithm.add(VMSPSPMF.NAME);
|
||||
listAvailableMiningAlgorithm.add(PFPMSPMF.NAME);
|
||||
|
||||
listAvailableMiningAlgorithm.forEach(s -> mapNumberCallsPerAlgorithm.put(s, 0));
|
||||
|
||||
for(int i = 0; i < measuresPatternDescriptor.length; ++i){
|
||||
// False for SubGroup and Target Deviation, true else.
|
||||
// measuresPatternDescriptor[i] = !(i == Pattern.MeasureType.SUBGROUP_INTERSTINGNESS.getIndex()
|
||||
// || i == Pattern.MeasureType.TARGET_DEVIATION.getIndex());
|
||||
measuresPatternDescriptor[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
public AlgorithmLauncherSPMF(String pathRawData){
|
||||
super();
|
||||
|
||||
listAttributeName = new ArrayList<>();
|
||||
mapIdLabel = new HashMap<>();
|
||||
|
||||
// Directly load the data once the AlgorithmLauncher is created.
|
||||
importData(pathRawData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNbAlgorithms() {
|
||||
return listAvailableMiningAlgorithm.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pattern> startAlgorithm(int algorithmNumber) {
|
||||
List<Pattern> listResult = new ArrayList<>();
|
||||
|
||||
if(algorithmNumber < 0 || algorithmNumber >= listAvailableMiningAlgorithm.size()){
|
||||
throw new UnsupportedOperationException("ERR: The algorithm id ask is not a valid one : "+ algorithmNumber + ".");
|
||||
}
|
||||
|
||||
MiningAlgorithmSPMF algorithm = getAlgorithm(listAvailableMiningAlgorithm.get(algorithmNumber));
|
||||
|
||||
if(algorithm == null) {
|
||||
DebugLogger.printDebug("AlgorithmLauncherSPMF: Unable to retrieve a valid algorithm instance.", DebugLogger.MessageSeverity.HIGH);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
algorithm.loadData(pathConvertedData);
|
||||
|
||||
// Calling the algorithm
|
||||
// System.err.println(Thread.currentThread().getName() + ": is launching " + lastMiningAlgorithm);
|
||||
listResult.addAll(algorithm.call());
|
||||
|
||||
return listResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopAlgorithm() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getListAlgorithmName() {
|
||||
return new ArrayList<>(listAvailableMiningAlgorithm);
|
||||
}
|
||||
|
||||
//********** Public methods **********//
|
||||
|
||||
public String getLabel(Integer id){
|
||||
return mapIdLabel.getOrDefault(id, "?");
|
||||
}
|
||||
|
||||
//********** Internal methods **********//
|
||||
|
||||
private MiningAlgorithmSPMF getAlgorithm(String name){
|
||||
MiningAlgorithmSPMF miningAlgorithm = null;
|
||||
|
||||
if(listAvailableMiningAlgorithm.contains(name)){
|
||||
int numberCalls = mapNumberCallsPerAlgorithm.getOrDefault(name, 0);
|
||||
mapNumberCallsPerAlgorithm.put(name, numberCalls+1);
|
||||
}
|
||||
|
||||
switch (name){
|
||||
case LCMSPMF.NAME:
|
||||
|
||||
miningAlgorithm = new LCMSPMF(minsupLCM, Duration.ZERO.plusDays(7), this);
|
||||
break;
|
||||
|
||||
case BIDEPlusSPMF.NAME:
|
||||
|
||||
miningAlgorithm = new BIDEPlusSPMF(minsupBIDEPlus, Duration.ZERO.plusDays(1), Duration.ZERO.plusDays(7), this);
|
||||
break;
|
||||
|
||||
case VMSPSPMF.NAME:
|
||||
|
||||
miningAlgorithm = new VMSPSPMF(minsupVMSP, maxgapVMSP, Duration.ZERO.plusDays(1), Duration.ZERO.plusDays(7), this);
|
||||
break;
|
||||
|
||||
case PFPMSPMF.NAME:
|
||||
|
||||
miningAlgorithm = new PFPMSPMF(Duration.ZERO.plusDays(7), minsupPFPM, minPeriodicityPFPM, maxPeriodicityPFPM, minPeriodicityPFPM, maxPeriodicityPFPM, this);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return miningAlgorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the data provided to the AlgorithmLauncher when it is created.
|
||||
* @param csv The path to the csv file where is the data.
|
||||
*/
|
||||
private void importData(String csv) {
|
||||
File fileData = new File(csv);
|
||||
|
||||
if(fileData.exists() && fileData.isFile()){
|
||||
String pathRawData = fileData.getAbsolutePath();
|
||||
|
||||
CSVLoaderSPMF csvLoader = new CSVLoaderSPMF(pathRawData);
|
||||
|
||||
listAttributeName = csvLoader.getListItem();
|
||||
mapIdLabel = csvLoader.getMapIdLabel();
|
||||
pathConvertedData = csvLoader.getPathConvertedData();
|
||||
}else{
|
||||
System.err.println("ERR: The given path is incorrect, no file found there : " + csv);
|
||||
}
|
||||
}
|
||||
|
||||
private void exportMapIdLabel(){
|
||||
try(BufferedWriter writer = new BufferedWriter(new FileWriter("mapIdLabel.txt"))){
|
||||
mapIdLabel.forEach((integer, str) -> {
|
||||
try {
|
||||
writer.write(integer + ";" + str);
|
||||
writer.newLine();
|
||||
} catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//********** Getters/Setters method **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
public static double getMinsupLCM(){ return AlgorithmLauncherSPMF.minsupLCM; }
|
||||
|
||||
public static double getMinsupBIDEPlus(){ return AlgorithmLauncherSPMF.minsupBIDEPlus; }
|
||||
|
||||
public static double getMinsupVMSP(){ return AlgorithmLauncherSPMF.minsupVMSP; }
|
||||
|
||||
public static double getMaxgapVMSP(){ return AlgorithmLauncherSPMF.maxgapVMSP; }
|
||||
|
||||
public static double getMinsupPFPM(){ return AlgorithmLauncherSPMF.minsupPFPM; }
|
||||
|
||||
public static int getMinPeriodicityPFPM(){ return AlgorithmLauncherSPMF.minPeriodicityPFPM; }
|
||||
|
||||
public static int getMaxPeriodicityPFPM(){ return AlgorithmLauncherSPMF.maxPeriodicityPFPM; }
|
||||
|
||||
public static boolean getMeasurePatternDescriptor(int index){
|
||||
return index >= 0 && index < measuresPatternDescriptor.length && measuresPatternDescriptor[index];
|
||||
}
|
||||
|
||||
public static List<String> getListAvailableMiningAlgorithm(){
|
||||
return new ArrayList<>(listAvailableMiningAlgorithm);
|
||||
}
|
||||
|
||||
// Setters //
|
||||
|
||||
public static void setMinsupLCM(double minsupLCM) {
|
||||
AlgorithmLauncherSPMF.minsupLCM = minsupLCM;
|
||||
}
|
||||
|
||||
public static void setMinsupBIDEPlus(double minsupBIDEPlus) {
|
||||
AlgorithmLauncherSPMF.minsupBIDEPlus = minsupBIDEPlus;
|
||||
}
|
||||
|
||||
public static void setMinsupVMSP(double minsupVMSP) {
|
||||
AlgorithmLauncherSPMF.minsupVMSP = minsupVMSP;
|
||||
}
|
||||
|
||||
public static void setMaxgapVMSP(int maxgapVMSP) {
|
||||
AlgorithmLauncherSPMF.maxgapVMSP = maxgapVMSP;
|
||||
}
|
||||
|
||||
public static void setMinsupPFPM(double minsupPFPM){
|
||||
AlgorithmLauncherSPMF.minsupPFPM = minsupPFPM;
|
||||
}
|
||||
|
||||
public static void setMinPeriodicityPFPM(int minPeriodicityPFPM) {
|
||||
AlgorithmLauncherSPMF.minPeriodicityPFPM = minPeriodicityPFPM;
|
||||
}
|
||||
|
||||
public static void setMaxPeriodicityPFPM(int maxPeriodicityPFPM) {
|
||||
AlgorithmLauncherSPMF.maxPeriodicityPFPM = maxPeriodicityPFPM;
|
||||
}
|
||||
|
||||
public static void setMeasuresPatternDescriptor(boolean b, int index){
|
||||
if(index >= 0 && index < measuresPatternDescriptor.length){
|
||||
measuresPatternDescriptor[index] = b;
|
||||
}
|
||||
}
|
||||
|
||||
//********** Main method **********//
|
||||
|
||||
/**
|
||||
* For quick testing purpose only
|
||||
* @param args Main parameters
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
AlgorithmLauncherSPMF algorithmLauncherSPMF = new AlgorithmLauncherSPMF("ressource/sacha_chua_more_preprocessed.csv");
|
||||
|
||||
List<Pattern> listResult = algorithmLauncherSPMF.startAlgorithm(3);
|
||||
algorithmLauncherSPMF.exportMapIdLabel();
|
||||
|
||||
listResult.forEach(System.err::println);
|
||||
System.out.println("listResult.size() = " + listResult.size());
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
package fr.insa.ocm.model.wrapper.spmf;
|
||||
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
class CSVLoaderSPMF {
|
||||
|
||||
// Extension of the files used by the algorithm.
|
||||
private static final String DAT_EXT = ".spmfdat";
|
||||
private static final String MAP_EXT = ".spmfmap";
|
||||
|
||||
// The path of last files used.
|
||||
private String pathRawData;
|
||||
|
||||
// The informations about the current loaded data.
|
||||
private Map<String, Integer> mapLabelId;
|
||||
private Map<Integer, String> mapIdLabel;
|
||||
private String pathConvertedData;
|
||||
|
||||
|
||||
CSVLoaderSPMF(@NotNull String pathCSV){
|
||||
this.pathRawData = pathCSV;
|
||||
this.pathConvertedData = "";
|
||||
|
||||
this.mapLabelId = new HashMap<>();
|
||||
this.mapIdLabel = new HashMap<>();
|
||||
|
||||
this.convert();
|
||||
}
|
||||
|
||||
private void convert(){
|
||||
//Remove the extension of the file name.
|
||||
String fileName = pathRawData.substring(0, pathRawData.lastIndexOf("."));
|
||||
|
||||
File convertedFile = new File(fileName + DAT_EXT);
|
||||
File mapFile = new File(fileName + MAP_EXT);
|
||||
|
||||
pathConvertedData = convertedFile.getAbsolutePath();
|
||||
|
||||
BufferedWriter writerSPMFDAT = null;
|
||||
//BufferedWriter writerSPMFMAP = null;
|
||||
BufferedReader readerCSV = null;
|
||||
|
||||
try{
|
||||
readerCSV = new BufferedReader(new FileReader(pathRawData));
|
||||
writerSPMFDAT = new BufferedWriter(new FileWriter(fileName + DAT_EXT));
|
||||
//writerSPMFMAP = new BufferedWriter(new FileWriter(fileName + MAP_EXT));
|
||||
|
||||
String line;
|
||||
int id = 1;
|
||||
|
||||
while ((line = readerCSV.readLine()) != null){
|
||||
String[] lineSplit = line.split(";");
|
||||
String data;
|
||||
|
||||
if(!mapLabelId.containsKey(lineSplit[1])){
|
||||
mapLabelId.put(lineSplit[1], id);
|
||||
mapIdLabel.put(id, lineSplit[1]);
|
||||
|
||||
data = Integer.toString(id);
|
||||
id++;
|
||||
}else{
|
||||
data = mapLabelId.get(lineSplit[1]).toString();
|
||||
}
|
||||
|
||||
writerSPMFDAT.write(lineSplit[0] + ";" + data);
|
||||
writerSPMFDAT.newLine();
|
||||
}
|
||||
} catch (IOException e){
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(readerCSV != null){
|
||||
try {
|
||||
readerCSV.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(writerSPMFDAT != null){
|
||||
try {
|
||||
writerSPMFDAT.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
/*
|
||||
if(writerSPMFMAP != null){
|
||||
try {
|
||||
writerSPMFMAP.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
Map<Integer, String> getMapIdLabel(){
|
||||
return mapIdLabel;
|
||||
}
|
||||
|
||||
List<String> getListItem(){
|
||||
return new ArrayList<>(mapLabelId.keySet());
|
||||
}
|
||||
|
||||
String getPathConvertedData(){
|
||||
return pathConvertedData;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
package fr.insa.ocm.model.wrapper.spmf;
|
||||
|
||||
import fr.insa.ocm.model.utils.Vector;
|
||||
import fr.insa.ocm.model.wrapper.api.AbstractPattern;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.List;
|
||||
|
||||
public class PatternSPMF extends AbstractPattern {
|
||||
|
||||
//TODO Javadoc for serializer only
|
||||
public PatternSPMF(List<String> listAttributeNames,
|
||||
Vector attributeVector, double[] measures,
|
||||
String patternDescriptor, String algorithmType){
|
||||
|
||||
this.algorithmType = algorithmType;
|
||||
this.patternDescriptor = patternDescriptor;
|
||||
|
||||
this.attributeVector = attributeVector;
|
||||
this.listAttributeNames = listAttributeNames;
|
||||
|
||||
System.arraycopy(measures, 0, this.measures, 0, this.measures.length);
|
||||
|
||||
wrapperType = WrapperType.SPMF;
|
||||
}
|
||||
|
||||
public PatternSPMF(String patternDescriptor,
|
||||
List<String> listAttributeNames,
|
||||
AlgorithmLauncherSPMF algorithmLauncher,
|
||||
double[] interestingMeasures,
|
||||
String algorithmType){
|
||||
this.patternDescriptor = patternDescriptor;
|
||||
this.listAttributeNames = listAttributeNames;
|
||||
this.algorithmType = algorithmType;
|
||||
|
||||
wrapperType = WrapperType.SPMF;
|
||||
|
||||
initialize(algorithmLauncher, interestingMeasures);
|
||||
}
|
||||
|
||||
private PatternSPMF(PatternSPMF patternSPMF){
|
||||
super(patternSPMF);
|
||||
}
|
||||
|
||||
//********** Implemented Methods **********//
|
||||
|
||||
public Pattern copy(){
|
||||
return new PatternSPMF(this);
|
||||
}
|
||||
|
||||
//********** Internal Methods **********//
|
||||
|
||||
private void initialize(AlgorithmLauncherSPMF algorithmLauncher,
|
||||
double[] interestingMeasures){
|
||||
// The order of these operation is important.
|
||||
// computeAttributeVector uses the result of computeAttributeName
|
||||
|
||||
setInterestingValues(interestingMeasures);
|
||||
computeAttributeVector(algorithmLauncher);
|
||||
computeAttributeName(algorithmLauncher);
|
||||
}
|
||||
|
||||
private void setInterestingValues(double[] interestingMeasures){
|
||||
System.arraycopy(interestingMeasures, 0, measures, 0, measures.length);
|
||||
}
|
||||
|
||||
//********** Standard Methods **********//
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder stringBuilder = new StringBuilder("");
|
||||
NumberFormat formatter = new DecimalFormat("#0.00");
|
||||
|
||||
boolean needComma = false;
|
||||
|
||||
stringBuilder.append(patternDescriptor);
|
||||
stringBuilder.append("\n[");
|
||||
|
||||
for(MeasureType measureType : MeasureType.values()){
|
||||
if(AlgorithmLauncherSPMF.getMeasurePatternDescriptor(measureType.getIndex())) {
|
||||
if (needComma) {
|
||||
stringBuilder.append(", ");
|
||||
}
|
||||
|
||||
stringBuilder.append(measureType.toString());
|
||||
stringBuilder.append(": ");
|
||||
stringBuilder.append(formatter.format(measures[measureType.getIndex()]));
|
||||
|
||||
needComma = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(needComma){
|
||||
stringBuilder.append(", ");
|
||||
}
|
||||
|
||||
stringBuilder.append("Algorithm: ");
|
||||
stringBuilder.append(algorithmType);
|
||||
stringBuilder.append("]");
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
package fr.insa.ocm.model.wrapper.spmf.algorithm;
|
||||
|
||||
import ca.pfv.spmf.algorithms.sequentialpatterns.prefixspan.AlgoBIDEPlus;
|
||||
import ca.pfv.spmf.algorithms.sequentialpatterns.prefixspan.SequentialPattern;
|
||||
import ca.pfv.spmf.algorithms.sequentialpatterns.prefixspan.SequentialPatterns;
|
||||
import ca.pfv.spmf.patterns.itemset_list_integers_without_support.Itemset;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.model.wrapper.spmf.AlgorithmLauncherSPMF;
|
||||
import fr.insa.ocm.model.wrapper.spmf.PatternSPMF;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class BIDEPlusSPMF extends SequentialMiningAlgorithmSPMF {
|
||||
|
||||
// Name of this algorithm
|
||||
public static final String NAME = "BIDEPlus";
|
||||
|
||||
// Extension of the files used by the algorithm
|
||||
private static final String BIDEP_DAT_EXT = ".bidepdat";
|
||||
private static volatile boolean isAlreadyConverted = false;
|
||||
|
||||
// SPMF stuff
|
||||
private AlgoBIDEPlus algorithmBIDEPlus;
|
||||
private double minsup; // Required to launch BIDEPlus
|
||||
|
||||
// From which AlgorithmLauncher comes this algorithm, so Patterns could be easily made.
|
||||
private AlgorithmLauncherSPMF algorithmLauncher;
|
||||
private static int numberSequenceBIDEPlus = 0;
|
||||
|
||||
|
||||
public BIDEPlusSPMF(double minsup, Duration intervalItemset, Duration intervalSequence, AlgorithmLauncherSPMF algorithmLauncher){
|
||||
super(BIDEP_DAT_EXT, intervalItemset, intervalSequence);
|
||||
|
||||
this.minsup = minsup;
|
||||
this.algorithmLauncher = algorithmLauncher;
|
||||
|
||||
algorithmBIDEPlus = new AlgoBIDEPlus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(String csvPath) {
|
||||
if(!isAlreadyConverted) {
|
||||
isAlreadyConverted = true;
|
||||
super.loadData(csvPath);
|
||||
numberSequenceBIDEPlus = super.numberSequence;
|
||||
} else {
|
||||
// We need to get the already converted file.
|
||||
String fileName = csvPath.substring(0, csvPath.lastIndexOf("."));
|
||||
File convertedFile = new File(fileName + BIDEPlusSPMF.BIDEP_DAT_EXT);
|
||||
|
||||
pathDataConverted = convertedFile.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PatternSPMF> call() {
|
||||
List<PatternSPMF> resultPattern = new ArrayList<>();
|
||||
try {
|
||||
SequentialPatterns sequentialPatterns = algorithmBIDEPlus.runAlgorithm(pathDataConverted, minsup, null);
|
||||
|
||||
//sequentialPatterns.printFrequentPatterns(algorithmBIDEPlus.patternCount, false);
|
||||
//algorithmBIDEPlus.printStatistics();
|
||||
|
||||
resultPattern.addAll(computeResult(sequentialPatterns));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return resultPattern;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<PatternSPMF> computeResult(@NotNull SequentialPatterns sequentialPatterns){
|
||||
List<PatternSPMF> listPatternResult = new ArrayList<>();
|
||||
|
||||
sequentialPatterns.getLevels().forEach(sequentialPatternsSet -> sequentialPatternsSet.forEach(sequentialPattern -> {
|
||||
listPatternResult.add(computePattern(sequentialPattern));
|
||||
}));
|
||||
|
||||
return listPatternResult;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PatternSPMF computePattern(@NotNull SequentialPattern sequentialPattern){
|
||||
double[] interestingMeasures = new double[Pattern.MeasureType.values().length];
|
||||
StringBuilder patternDescriptorBuilder = new StringBuilder("[");
|
||||
Set<String> setAttributeName = new HashSet<>();
|
||||
|
||||
|
||||
for (Itemset itemset : sequentialPattern.getItemsets()) {
|
||||
|
||||
if(sequentialPattern.get(0).equals(itemset)) {
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append("(");
|
||||
} else {
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append("\n\t(");
|
||||
}
|
||||
|
||||
for(Integer id : itemset.getItems()){
|
||||
String label = algorithmLauncher.getLabel(id);
|
||||
setAttributeName.add(label);
|
||||
|
||||
if(itemset.get(0).equals(id)){
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append(label);
|
||||
} else {
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append(", ").append(label);
|
||||
}
|
||||
}
|
||||
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append(")");
|
||||
}
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append("]");
|
||||
|
||||
interestingMeasures[Pattern.MeasureType.FREQUENCY.getIndex()] = ((double) sequentialPattern.getAbsoluteSupport())/numberSequenceBIDEPlus;
|
||||
interestingMeasures[Pattern.MeasureType.RELATIVE_SHORTNESS.getIndex()] = ((double) setAttributeName.size())/algorithmLauncher.getNbAttributes();
|
||||
|
||||
return new PatternSPMF(patternDescriptorBuilder.toString(),
|
||||
new ArrayList<>(setAttributeName),
|
||||
algorithmLauncher,
|
||||
interestingMeasures,
|
||||
BIDEPlusSPMF.NAME);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
package fr.insa.ocm.model.wrapper.spmf.algorithm;
|
||||
|
||||
|
||||
import java.io.*;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ItemsetMiningAlgorithm implements MiningAlgorithmSPMF {
|
||||
|
||||
// Interval used to split a long sequence
|
||||
private Duration intervalItemset;
|
||||
|
||||
private String fileExtension;
|
||||
|
||||
String pathDataConverted;
|
||||
int numberItemset; // Be aware that this value is valid only if SequentialMiningAlgorithmSPMF.loadData is called
|
||||
|
||||
ItemsetMiningAlgorithm(String fileExtension, Duration intervalItemset){
|
||||
|
||||
this.fileExtension = fileExtension;
|
||||
this.intervalItemset = intervalItemset;
|
||||
|
||||
numberItemset = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(String csvPath) {
|
||||
//Remove the extension of the file name.
|
||||
String fileName = csvPath.substring(0, csvPath.lastIndexOf("."));
|
||||
|
||||
File convertedFile = new File(fileName + fileExtension);
|
||||
|
||||
pathDataConverted = convertedFile.getAbsolutePath();
|
||||
|
||||
BufferedWriter writerSPMFDAT = null;
|
||||
BufferedReader readerCSV = null;
|
||||
|
||||
try {
|
||||
writerSPMFDAT = new BufferedWriter(new FileWriter(convertedFile));
|
||||
readerCSV = new BufferedReader(new FileReader(csvPath));
|
||||
|
||||
String line;
|
||||
LocalDateTime thresholdDateTime = LocalDateTime.now();
|
||||
List<Integer> listAlreadyInItemSet = new ArrayList<>();
|
||||
|
||||
line = readerCSV.readLine();
|
||||
if (line != null) {
|
||||
String[] lineSplit = line.split(";");
|
||||
|
||||
LocalDateTime dateLine = LocalDateTime.parse(lineSplit[0]);
|
||||
thresholdDateTime = dateLine.plus(intervalItemset);
|
||||
|
||||
listAlreadyInItemSet.add(Integer.valueOf(lineSplit[1]));
|
||||
}
|
||||
|
||||
while ((line = readerCSV.readLine()) != null) {
|
||||
String[] lineSplit = line.split(";");
|
||||
|
||||
LocalDateTime dateLine = LocalDateTime.parse(lineSplit[0]);
|
||||
|
||||
// Each itemset should end with a newline. Here we are taking an itemset with all the items of the same day.
|
||||
// It assumes that the file has sorted records from the oldest to the newest.
|
||||
if (dateLine.isAfter(thresholdDateTime)) {
|
||||
// Set the new threshold as the next day if a day as already passed.
|
||||
thresholdDateTime = dateLine.plus(intervalItemset);
|
||||
|
||||
// Write the itemset all at once.
|
||||
Collections.sort(listAlreadyInItemSet);
|
||||
for (Integer idInt : listAlreadyInItemSet) {
|
||||
writerSPMFDAT.write(idInt + " ");
|
||||
}
|
||||
|
||||
writerSPMFDAT.newLine();
|
||||
|
||||
listAlreadyInItemSet.clear();
|
||||
numberItemset++;
|
||||
}
|
||||
|
||||
Integer item = Integer.valueOf(lineSplit[1]);
|
||||
|
||||
if (!listAlreadyInItemSet.contains(item)) {
|
||||
// An itemset should contain only one occurence of an item.
|
||||
listAlreadyInItemSet.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
// Write the last itemset.
|
||||
Collections.sort(listAlreadyInItemSet);
|
||||
for (Integer idInt : listAlreadyInItemSet) {
|
||||
writerSPMFDAT.write(idInt + " ");
|
||||
}
|
||||
writerSPMFDAT.newLine();
|
||||
numberItemset++;
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (writerSPMFDAT != null) {
|
||||
try {
|
||||
writerSPMFDAT.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (readerCSV != null) {
|
||||
try {
|
||||
readerCSV.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
package fr.insa.ocm.model.wrapper.spmf.algorithm;
|
||||
|
||||
import ca.pfv.spmf.algorithms.frequentpatterns.lcm.AlgoLCM;
|
||||
import ca.pfv.spmf.algorithms.frequentpatterns.lcm.Dataset;
|
||||
import ca.pfv.spmf.patterns.itemset_array_integers_with_count.Itemset;
|
||||
import ca.pfv.spmf.patterns.itemset_array_integers_with_count.Itemsets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.model.wrapper.spmf.AlgorithmLauncherSPMF;
|
||||
import fr.insa.ocm.model.wrapper.spmf.PatternSPMF;
|
||||
|
||||
import java.io.*;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
|
||||
public class LCMSPMF extends ItemsetMiningAlgorithm {
|
||||
|
||||
// Name of this algorithm
|
||||
public static final String NAME = "LCM";
|
||||
|
||||
// Extension of the files used by the algorithm
|
||||
private static final String LCM_DAT_EXT = ".lcmdat";
|
||||
private static volatile boolean isAlreadyConverted = false;
|
||||
|
||||
// SPMF stuff
|
||||
private AlgoLCM algorithmLCM;
|
||||
private double minsup; // Required to launch AlgoLCM
|
||||
|
||||
// From which AlgorithmLauncher comes this algorithm, so Patterns could be easily made.
|
||||
private AlgorithmLauncherSPMF algorithmLauncher;
|
||||
private static int numberItemSetLCM = 0;
|
||||
|
||||
public LCMSPMF(double minsup, Duration discretizeCriteron, AlgorithmLauncherSPMF algorithmLauncher){
|
||||
super(LCM_DAT_EXT, discretizeCriteron);
|
||||
this.minsup = minsup;
|
||||
this.algorithmLauncher = algorithmLauncher;
|
||||
|
||||
algorithmLCM = new AlgoLCM();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(String csvPath) {
|
||||
if(!isAlreadyConverted) {
|
||||
isAlreadyConverted = true;
|
||||
super.loadData(csvPath);
|
||||
|
||||
numberItemSetLCM = this.numberItemset;
|
||||
} else {
|
||||
// We need to get the already converted file.
|
||||
String fileName = csvPath.substring(0, csvPath.lastIndexOf("."));
|
||||
File convertedFile = new File(fileName + LCMSPMF.LCM_DAT_EXT);
|
||||
|
||||
pathDataConverted = convertedFile.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PatternSPMF> call() {
|
||||
List<PatternSPMF> resultPattern = new ArrayList<>();
|
||||
try {
|
||||
Dataset dataset = new Dataset(pathDataConverted);
|
||||
Itemsets itemsetsResult = algorithmLCM.runAlgorithm(minsup, dataset, null);
|
||||
|
||||
resultPattern.addAll(computeResult(itemsetsResult));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return resultPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all the Patterns to describe the results given by the algorithm. The resulting pattern are ready to use for OCM.
|
||||
* @param itemsets The itemsets which needs to be converted to Patterns.
|
||||
* @return Create a list of {@link PatternSPMF} to describe the result of the LCM algorithm.
|
||||
*/
|
||||
@NotNull
|
||||
private List<PatternSPMF> computeResult(@NotNull Itemsets itemsets){
|
||||
List<PatternSPMF> resultPattern = new ArrayList<>();
|
||||
|
||||
itemsets.getLevels().forEach(levelItemSet -> levelItemSet.forEach(itemset -> {
|
||||
resultPattern.add(computePattern(itemset));
|
||||
}));
|
||||
|
||||
return resultPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new pattern corresponding to the current itemset, for a OCM use.
|
||||
* @param itemset The itemset needed to be converted into a Pattern.
|
||||
* @return A new {@link PatternSPMF} which describe the sent itemset.
|
||||
*/
|
||||
@NotNull
|
||||
private PatternSPMF computePattern(@NotNull Itemset itemset){
|
||||
int[] items = itemset.getItems();
|
||||
double[] interestingMeasures = new double[Pattern.MeasureType.values().length];
|
||||
StringBuilder patternDescriptorBuilder = new StringBuilder("[");
|
||||
List<String> listAttributeName = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < interestingMeasures.length; i++) {
|
||||
interestingMeasures[i] = 0d;
|
||||
}
|
||||
|
||||
for(int id : items){
|
||||
String label = algorithmLauncher.getLabel(id);
|
||||
listAttributeName.add(label);
|
||||
|
||||
if(id != items[0]){
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append(", ").append(label);
|
||||
} else {
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append(label);
|
||||
}
|
||||
}
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append("]");
|
||||
|
||||
interestingMeasures[Pattern.MeasureType.FREQUENCY.getIndex()] = ((double) itemset.getAbsoluteSupport())/ numberItemSetLCM;
|
||||
interestingMeasures[Pattern.MeasureType.RELATIVE_SHORTNESS.getIndex()] = ((double) items.length)/algorithmLauncher.getNbAttributes();
|
||||
|
||||
return new PatternSPMF(patternDescriptorBuilder.toString(),
|
||||
listAttributeName,
|
||||
algorithmLauncher,
|
||||
interestingMeasures,
|
||||
LCMSPMF.NAME);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package fr.insa.ocm.model.wrapper.spmf.algorithm;
|
||||
|
||||
import fr.insa.ocm.model.wrapper.spmf.PatternSPMF;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface MiningAlgorithmSPMF {
|
||||
|
||||
void loadData(String csvPath);
|
||||
|
||||
List<PatternSPMF> call();
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
package fr.insa.ocm.model.wrapper.spmf.algorithm;
|
||||
|
||||
import ca.pfv.spmf.algorithms.frequentpatterns.pfpm.AlgoPFPM;
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.model.wrapper.spmf.AlgorithmLauncherSPMF;
|
||||
import fr.insa.ocm.model.wrapper.spmf.PatternSPMF;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class PFPMSPMF extends ItemsetMiningAlgorithm {
|
||||
|
||||
// Name of this algorithm
|
||||
public static final String NAME = "PFPM";
|
||||
|
||||
// Extension of the files used by the algorithm
|
||||
private static final String PFPM_DAT_EXT = ".pfpmdat";
|
||||
private static volatile boolean isAlreadyConverted = false;
|
||||
|
||||
// SPMF stuff
|
||||
private AlgoPFPM algorithmPFPM;
|
||||
private double minsup;
|
||||
private int minPeriodicity;
|
||||
private int maxPeriodicity;
|
||||
private int minAveragePeriodicity;
|
||||
private int maxAveragePeriodicity;
|
||||
|
||||
// From which AlgorithmLauncher comes this algorithm, so Patterns could be easily made.
|
||||
private AlgorithmLauncherSPMF algorithmLauncher;
|
||||
private static int numberItemSetPFPM = 0;
|
||||
|
||||
public PFPMSPMF(Duration intervalItemset,
|
||||
double minsup,
|
||||
int minPeriodicity, int maxPeriodicity,
|
||||
int minAveragePeriodicity, int maxAveragePeriodicity,
|
||||
AlgorithmLauncherSPMF algorithmLauncher) {
|
||||
super(PFPMSPMF.PFPM_DAT_EXT, intervalItemset);
|
||||
|
||||
this.minsup = minsup;
|
||||
this.minPeriodicity = minPeriodicity;
|
||||
this.maxPeriodicity = maxPeriodicity;
|
||||
this.minAveragePeriodicity = minAveragePeriodicity;
|
||||
this.maxAveragePeriodicity = maxAveragePeriodicity;
|
||||
|
||||
this.algorithmLauncher = algorithmLauncher;
|
||||
|
||||
algorithmPFPM = new AlgoPFPM(true);
|
||||
algorithmPFPM.setEnableESCP(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void loadData(String csvPath) {
|
||||
if(!isAlreadyConverted) {
|
||||
isAlreadyConverted = true;
|
||||
super.loadData(csvPath);
|
||||
|
||||
numberItemSetPFPM = this.numberItemset;
|
||||
} else {
|
||||
// We need to get the already converted file.
|
||||
String fileName = csvPath.substring(0, csvPath.lastIndexOf("."));
|
||||
File convertedFile = new File(fileName + PFPMSPMF.PFPM_DAT_EXT);
|
||||
|
||||
pathDataConverted = convertedFile.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PatternSPMF> call() {
|
||||
List<PatternSPMF> resultPattern = new ArrayList<>();
|
||||
|
||||
try {
|
||||
algorithmPFPM.runAlgorithm(pathDataConverted, DebugLogger.directoryLog +"junk.txt",
|
||||
minPeriodicity, maxPeriodicity, minAveragePeriodicity,
|
||||
maxAveragePeriodicity);
|
||||
|
||||
//System.out.println(algorithmPFPM.getResultAsString());
|
||||
resultPattern.addAll(computeResult(algorithmPFPM.getResultAsString()));
|
||||
//System.out.println("numberItemSetPFPM = " + numberItemSetPFPM);
|
||||
} catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return resultPattern;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<PatternSPMF> computeResult(@NotNull String results){
|
||||
List<PatternSPMF> resultPattern = new ArrayList<>();
|
||||
|
||||
List<String> listResult = Arrays.asList(results.split("\n"));
|
||||
|
||||
listResult.forEach(strPattern -> {
|
||||
if(strPattern != null){
|
||||
PatternSPMF pattern = computePattern(strPattern);
|
||||
if(pattern != null) {
|
||||
resultPattern.add(pattern);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return resultPattern;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PatternSPMF computePattern(@NotNull String strPattern){
|
||||
String[] patternParts = strPattern.split(";");
|
||||
double[] interestingMeasures = new double[Pattern.MeasureType.values().length];
|
||||
StringBuilder patternDescriptorBuilder = new StringBuilder("[");
|
||||
List<String> listAttributeName = new ArrayList<>();
|
||||
|
||||
// The pattern sent by the PFPM algorithm contains 5 items
|
||||
if(patternParts.length != 5){
|
||||
System.err.println("ERR: Impossible to retrieve information from this pattern: " + strPattern);
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < interestingMeasures.length; i++) {
|
||||
interestingMeasures[i] = 0d;
|
||||
}
|
||||
|
||||
int indexAttribute = 0;
|
||||
for(String strId : patternParts[0].split(" ")){
|
||||
Integer id = Integer.valueOf(strId);
|
||||
String label = algorithmLauncher.getLabel(id);
|
||||
listAttributeName.add(label);
|
||||
|
||||
if(indexAttribute != 0){
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append(", ").append(label);
|
||||
} else {
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append(label);
|
||||
}
|
||||
|
||||
indexAttribute++;
|
||||
}
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append("]");
|
||||
|
||||
Integer absoluteSupport = Integer.valueOf(patternParts[1]);
|
||||
Integer minPeriod = Integer.valueOf(patternParts[2]);
|
||||
Integer maxPeriod = Integer.valueOf(patternParts[3]);
|
||||
|
||||
interestingMeasures[Pattern.MeasureType.FREQUENCY.getIndex()] = ((double) absoluteSupport)/ numberItemSetPFPM;
|
||||
interestingMeasures[Pattern.MeasureType.RELATIVE_SHORTNESS.getIndex()] = ((double) indexAttribute)/algorithmLauncher.getNbAttributes();
|
||||
interestingMeasures[Pattern.MeasureType.RELATIVE_PERIODICITY.getIndex()] = minPeriod.doubleValue()/ maxPeriod.doubleValue();
|
||||
|
||||
if(interestingMeasures[Pattern.MeasureType.FREQUENCY.getIndex()] < minsup){
|
||||
// The created pattern should have a frequency at least higher then the minsup.
|
||||
return null;
|
||||
}
|
||||
|
||||
return new PatternSPMF(patternDescriptorBuilder.toString(),
|
||||
listAttributeName,
|
||||
algorithmLauncher,
|
||||
interestingMeasures,
|
||||
PFPMSPMF.NAME);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
package fr.insa.ocm.model.wrapper.spmf.algorithm;
|
||||
|
||||
import fr.insa.ocm.model.wrapper.spmf.PatternSPMF;
|
||||
|
||||
import java.io.*;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
abstract class SequentialMiningAlgorithmSPMF implements MiningAlgorithmSPMF {
|
||||
|
||||
|
||||
// Interval used to split a long sequence
|
||||
private Duration intervalItemset;
|
||||
private Duration intervalSequence;
|
||||
|
||||
private String fileExtension;
|
||||
|
||||
String pathDataConverted;
|
||||
int numberSequence; // Be aware that this value is valid only if SequentialMiningAlgorithmSPMF.loadData is called
|
||||
|
||||
SequentialMiningAlgorithmSPMF(String fileExtension, Duration intervalItemset, Duration intervalSequence){
|
||||
this.fileExtension = fileExtension;
|
||||
|
||||
this.intervalItemset = intervalItemset;
|
||||
this.intervalSequence = intervalSequence;
|
||||
|
||||
numberSequence = 0;
|
||||
}
|
||||
|
||||
public void loadData(String csvPath){
|
||||
//Remove the extension of the file name.
|
||||
String fileName = csvPath.substring(0, csvPath.lastIndexOf("."));
|
||||
|
||||
File convertedFile = new File(fileName + fileExtension);
|
||||
|
||||
pathDataConverted = convertedFile.getAbsolutePath();
|
||||
|
||||
BufferedWriter writerSPMFDAT = null;
|
||||
BufferedReader readerCSV = null;
|
||||
|
||||
try{
|
||||
readerCSV = new BufferedReader(new FileReader(new File(csvPath)));
|
||||
writerSPMFDAT = new BufferedWriter(new FileWriter(convertedFile));
|
||||
|
||||
String line;
|
||||
LocalDateTime thresholdItemset = LocalDateTime.now();
|
||||
LocalDateTime thresholdSequence = LocalDateTime.now();
|
||||
List<List<Integer>> listAlreadyInItemSet = new ArrayList<>();
|
||||
int indexList = 0;
|
||||
|
||||
line = readerCSV.readLine();
|
||||
if(line != null){
|
||||
String[] lineSplit = line.split(";");
|
||||
|
||||
LocalDateTime dateLine = LocalDateTime.parse(lineSplit[0]);
|
||||
|
||||
thresholdItemset = dateLine.plus(intervalItemset);
|
||||
thresholdSequence = dateLine.plus(intervalSequence);
|
||||
|
||||
listAlreadyInItemSet.add(new ArrayList<>());
|
||||
listAlreadyInItemSet.get(indexList).add(Integer.valueOf(lineSplit[1]));
|
||||
}
|
||||
|
||||
while ((line = readerCSV.readLine()) != null){
|
||||
String[] lineSplit = line.split(";");
|
||||
|
||||
LocalDateTime dateLine = LocalDateTime.parse(lineSplit[0]);
|
||||
|
||||
if(dateLine.isAfter(thresholdSequence)){
|
||||
// Write the sequence in the resulting file
|
||||
this.writeSequence(listAlreadyInItemSet, writerSPMFDAT);
|
||||
|
||||
// Initializing anew the list containing the sequence.
|
||||
indexList = 0;
|
||||
listAlreadyInItemSet.clear();
|
||||
listAlreadyInItemSet.add(new ArrayList<>());
|
||||
|
||||
// Set the new thresholds
|
||||
thresholdItemset = dateLine.plus(intervalItemset);
|
||||
thresholdSequence = dateLine.plus(intervalSequence);
|
||||
|
||||
// Increase the number of Sequence read.
|
||||
numberSequence++;
|
||||
|
||||
}else if(dateLine.isAfter(thresholdItemset)){
|
||||
thresholdItemset = dateLine.plus(intervalItemset);
|
||||
|
||||
if(!listAlreadyInItemSet.get(indexList).isEmpty()){
|
||||
listAlreadyInItemSet.add(new ArrayList<>());
|
||||
indexList++;
|
||||
}
|
||||
}
|
||||
|
||||
Integer item = Integer.valueOf(lineSplit[1]);
|
||||
|
||||
if(!listAlreadyInItemSet.get(indexList).contains(item)) {
|
||||
// An itemset should contain only one occurence of an item.
|
||||
listAlreadyInItemSet.get(indexList).add(item);
|
||||
}
|
||||
}
|
||||
|
||||
// Write the last sequence in the file
|
||||
this.writeSequence(listAlreadyInItemSet, writerSPMFDAT);
|
||||
numberSequence++;
|
||||
|
||||
} catch (IOException e){
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(writerSPMFDAT != null){
|
||||
try {
|
||||
writerSPMFDAT.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(readerCSV != null){
|
||||
try {
|
||||
readerCSV.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract List<PatternSPMF> call();
|
||||
|
||||
protected void writeSequence(List<List<Integer>> listItemsets, BufferedWriter fileWriter) throws IOException {
|
||||
for(List<Integer> listItemset : listItemsets){
|
||||
Collections.sort(listItemset);
|
||||
|
||||
for(Integer item : listItemset){
|
||||
fileWriter.write(item + " ");
|
||||
}
|
||||
|
||||
fileWriter.write("-1 ");
|
||||
}
|
||||
fileWriter.write("-2");
|
||||
fileWriter.newLine();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
package fr.insa.ocm.model.wrapper.spmf.algorithm;
|
||||
|
||||
import ca.pfv.spmf.algorithms.sequentialpatterns.spam.AlgoVMSP;
|
||||
import ca.pfv.spmf.algorithms.sequentialpatterns.spam.PatternVMSP;
|
||||
import ca.pfv.spmf.patterns.itemset_list_integers_without_support.Itemset;
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.model.wrapper.spmf.AlgorithmLauncherSPMF;
|
||||
import fr.insa.ocm.model.wrapper.spmf.PatternSPMF;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
|
||||
public class VMSPSPMF extends SequentialMiningAlgorithmSPMF {
|
||||
|
||||
// Name of this algorithm
|
||||
public static final String NAME = "VMSP";
|
||||
|
||||
// Extension of the files used by the algorithm
|
||||
private static final String VMSP_DAT_EXT = ".vmspdat";
|
||||
private static volatile boolean isAlreadyConverted = false;
|
||||
|
||||
// SPMF stuff
|
||||
private AlgoVMSP algorithmVMSP;
|
||||
private double minsup; // Required to launch VMSP
|
||||
|
||||
// From which AlgorithmLauncher comes this algorithm, so Patterns could be easily made.
|
||||
private AlgorithmLauncherSPMF algorithmLauncher;
|
||||
private static int numberSequenceVMSP = 0;
|
||||
|
||||
public VMSPSPMF(double minsup, int maxGap,
|
||||
Duration intervalItemset,
|
||||
Duration intervalSequence,
|
||||
AlgorithmLauncherSPMF algorithmLauncher) {
|
||||
super(VMSP_DAT_EXT, intervalItemset, intervalSequence);
|
||||
|
||||
this.minsup = minsup;
|
||||
this.algorithmLauncher = algorithmLauncher;
|
||||
|
||||
algorithmVMSP = new AlgoVMSP();
|
||||
algorithmVMSP.setMaxGap(maxGap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(String csvPath) {
|
||||
if(!isAlreadyConverted) {
|
||||
isAlreadyConverted = true;
|
||||
super.loadData(csvPath);
|
||||
|
||||
numberSequenceVMSP = super.numberSequence;
|
||||
} else {
|
||||
// We need to get the already converted file.
|
||||
String fileName = csvPath.substring(0, csvPath.lastIndexOf("."));
|
||||
File convertedFile = new File(fileName + VMSPSPMF.VMSP_DAT_EXT);
|
||||
|
||||
pathDataConverted = convertedFile.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PatternSPMF> call() {
|
||||
List<PatternSPMF> resultPattern = new ArrayList<>();
|
||||
|
||||
try {
|
||||
List<TreeSet<PatternVMSP>> maxPatterns = algorithmVMSP.runAlgorithm(pathDataConverted, DebugLogger.directoryLog +"junk.txt", minsup);
|
||||
|
||||
resultPattern.addAll(computeResult(maxPatterns));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return resultPattern;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<PatternSPMF> computeResult(@NotNull List<TreeSet<PatternVMSP>> listSetPatternVMSP){
|
||||
List<PatternSPMF> listPatternResult = new ArrayList<>();
|
||||
|
||||
listSetPatternVMSP.forEach(setPatternVMSP -> {
|
||||
if(setPatternVMSP != null) {
|
||||
setPatternVMSP.forEach(patternVMSP -> listPatternResult.add(computePattern(patternVMSP)));
|
||||
}
|
||||
});
|
||||
|
||||
return listPatternResult;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private PatternSPMF computePattern(@NotNull PatternVMSP patternVMSP) {
|
||||
double[] interestingMeasures = new double[Pattern.MeasureType.values().length];
|
||||
StringBuilder patternDescriptorBuilder = new StringBuilder("[");
|
||||
Set<String> setAttributeName = new HashSet<>();
|
||||
|
||||
for (Itemset itemset : patternVMSP.getPrefix().getItemsets()) {
|
||||
|
||||
if (patternVMSP.getPrefix().getItemsets().get(0).equals(itemset)) {
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append(" ... (");
|
||||
} else {
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append("\n\t... (");
|
||||
}
|
||||
|
||||
for (Integer id : itemset.getItems()) {
|
||||
String label = algorithmLauncher.getLabel(id);
|
||||
setAttributeName.add(label);
|
||||
|
||||
if (itemset.get(0).equals(id)) {
|
||||
patternDescriptorBuilder.append(" ... , ");
|
||||
patternDescriptorBuilder.append(label);
|
||||
patternDescriptorBuilder.append("");
|
||||
} else {
|
||||
patternDescriptorBuilder.append(", ... , ");
|
||||
patternDescriptorBuilder.append(label);
|
||||
patternDescriptorBuilder.append("");
|
||||
}
|
||||
}
|
||||
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append(", ... ) ...");
|
||||
}
|
||||
patternDescriptorBuilder = patternDescriptorBuilder.append("]");
|
||||
|
||||
interestingMeasures[Pattern.MeasureType.FREQUENCY.getIndex()] = ((double) patternVMSP.getSupport()) / numberSequenceVMSP;
|
||||
interestingMeasures[Pattern.MeasureType.RELATIVE_SHORTNESS.getIndex()] = ((double) setAttributeName.size()) / algorithmLauncher.getNbAttributes();
|
||||
|
||||
return new PatternSPMF(patternDescriptorBuilder.toString(),
|
||||
new ArrayList<>(setAttributeName),
|
||||
algorithmLauncher,
|
||||
interestingMeasures,
|
||||
VMSPSPMF.NAME);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package fr.insa.ocm.view;
|
||||
|
||||
import fr.insa.ocm.view.mainuis.MainView;
|
||||
import fr.insa.ocm.viewmodel.OCLController;
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class OCLApplication extends Application{
|
||||
|
||||
private static OCLApplication INSTANCE;
|
||||
|
||||
private static Stage mainStage;
|
||||
|
||||
public OCLApplication(){
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
mainStage = primaryStage;
|
||||
|
||||
new MainView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(){
|
||||
OCLController.requestStop();
|
||||
}
|
||||
|
||||
public static Stage getMainStage(){return mainStage;}
|
||||
|
||||
public static Application getInstance(){ return INSTANCE; }
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
package fr.insa.ocm.view.mainuis;
|
||||
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DataView {
|
||||
|
||||
@FXML private VBox mainVBox = null;
|
||||
|
||||
@FXML private GridPane gridPaneData = null;
|
||||
@FXML private Button buttonClose = null;
|
||||
|
||||
DataView(){
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/mainuis/dataView.fxml"));
|
||||
loader.setController(this);
|
||||
|
||||
try {
|
||||
loader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
//
|
||||
// buttonClose.setOnAction(event -> this.buttonClosePressed());
|
||||
//
|
||||
// List<List<String>> data = new ArrayList<>();
|
||||
//
|
||||
// String pathDataFile = OCLController.getInstance().getPathDataFile();
|
||||
// if(pathDataFile != null && !pathDataFile.equals("")){
|
||||
// CSVLoaderRealKD csvLoader = new CSVLoaderRealKD(pathDataFile);
|
||||
// data = csvLoader.loadCSV();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// int index = 0;
|
||||
// for(List<String> entry : data){
|
||||
// Label[] labels = new Label[entry.size()];
|
||||
//
|
||||
// for (int i = 0; i < labels.length; i++) {
|
||||
// if(index == 0){
|
||||
// Label label = new Label(entry.get(i));
|
||||
//
|
||||
// label.setFont(Font.font("Verdana", FontWeight.BOLD, 14));
|
||||
// label.setPadding(new Insets(5));
|
||||
// label.setStyle("" +
|
||||
// "-fx-border-color: black;" +
|
||||
// "-fx-border-width: 1px;");
|
||||
// label.setMaxWidth(1E300);
|
||||
// label.setMaxHeight(1E300);
|
||||
//
|
||||
// labels[i] = label;
|
||||
// }else {
|
||||
// Label label = new Label(entry.get(i));
|
||||
//
|
||||
// label.setFont(Font.font("Verdana", 14));
|
||||
// label.setPadding(new Insets(5));
|
||||
// label.setStyle("" +
|
||||
// "-fx-border-color: black;" +
|
||||
// "-fx-border-width: 1px;");
|
||||
// label.setMaxWidth(1E300);
|
||||
// label.setMaxHeight(1E300);
|
||||
//
|
||||
// labels[i] = label;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// gridPaneData.addRow(index, labels);
|
||||
// index++;
|
||||
// }
|
||||
//
|
||||
// Stage stage = new Stage();
|
||||
// stage.setScene(new Scene(mainVBox));
|
||||
// stage.setTitle("Data Viewer");
|
||||
// stage.show();
|
||||
//
|
||||
}
|
||||
|
||||
private void buttonClosePressed(){
|
||||
Stage stage = (Stage) buttonClose.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
package fr.insa.ocm.view.mainuis;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.utils.serialize.condition.ConditionsDeserializer;
|
||||
import fr.insa.ocm.model.utils.serialize.condition.ConditionsSerializer;
|
||||
import fr.insa.ocm.view.OCLApplication;
|
||||
import fr.insa.ocm.view.misc.FastForwardWaitingView;
|
||||
import fr.insa.ocm.view.misc.parts.fastforward.AddConditionView;
|
||||
import fr.insa.ocm.view.misc.parts.fastforward.ConditionView;
|
||||
import fr.insa.ocm.viewmodel.OCLController;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FastForwardView {
|
||||
|
||||
@FXML private VBox mainVBox = null;
|
||||
@FXML private ListView<HBox> listViewMeasure = null;
|
||||
@FXML private Button buttonLaunch = null;
|
||||
@FXML private TextField textFieldNumberRound = null;
|
||||
@FXML private TextField textFieldSecondPerRound = null;
|
||||
@FXML private ChoiceBox<Condition.ActionPatternChoice> choiceBoxKeepTrash = null;
|
||||
|
||||
// Menus to save or load a user list of conditions.
|
||||
@FXML private MenuItem menuItemSave = null;
|
||||
@FXML private MenuItem menuItemLoad = null;
|
||||
|
||||
private List<ConditionView> listConditionView;
|
||||
private AddConditionView addConditionView;
|
||||
|
||||
private ObservableList<HBox> listConditions;
|
||||
|
||||
FastForwardView(){
|
||||
listConditionView = new ArrayList<>();
|
||||
listConditions = FXCollections.observableArrayList();
|
||||
addConditionView = new AddConditionView(this);
|
||||
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/mainuis/fastForwardView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
Scene scene = new Scene(mainVBox);
|
||||
scene.getStylesheets().add(getClass().getResource("/css/button.css").toExternalForm());
|
||||
|
||||
buttonLaunch.setOnAction(event -> this.buttonLaunchPressed());
|
||||
|
||||
choiceBoxKeepTrash.getItems().addAll(Condition.ActionPatternChoice.KEEP, Condition.ActionPatternChoice.TRASH);
|
||||
choiceBoxKeepTrash.setValue(Condition.ActionPatternChoice.TRASH);
|
||||
|
||||
FXMLLoader loaderCondition = new FXMLLoader(getClass().getResource("/fxml/misc/parts/fastforward/addCondition.fxml"));
|
||||
loaderCondition.setController(addConditionView);
|
||||
HBox conditionHBox = new HBox();
|
||||
try {
|
||||
conditionHBox = loaderCondition.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
listConditions.add(conditionHBox);
|
||||
|
||||
listViewMeasure.setItems(listConditions);
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.setTitle("Choose your Patterns");
|
||||
stage.setScene(scene);
|
||||
stage.show();
|
||||
}
|
||||
|
||||
private void buttonLaunchPressed(){
|
||||
Stage stage = (Stage) mainVBox.getScene().getWindow();
|
||||
stage.close();
|
||||
|
||||
FastForwardWaitingView fastForwardWaitingView = new FastForwardWaitingView();
|
||||
|
||||
List<Condition> listCondition = new ArrayList<>();
|
||||
|
||||
for(ConditionView conditionMeasureStaticView : listConditionView){
|
||||
try{
|
||||
listCondition.add(conditionMeasureStaticView.getCondition());
|
||||
} catch (NumberFormatException e){
|
||||
System.err.println("ERR: No valid number was found to create a valid condition");
|
||||
}
|
||||
}
|
||||
|
||||
new Thread(new Task<Void>() {
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
OCLController.fastForward(Integer.valueOf(textFieldNumberRound.getText()),
|
||||
Double.valueOf(textFieldSecondPerRound.getText()),
|
||||
listCondition, fastForwardWaitingView, choiceBoxKeepTrash.getValue());
|
||||
return null;
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
public void buttonAddConditionPressed(){
|
||||
// Remove the last HBox which make possible the user to add a condition.
|
||||
listConditions.remove(listConditions.size() - 1);
|
||||
|
||||
// Add the condition required by the user.
|
||||
ConditionView conditionView = addConditionView.createConditionView();
|
||||
HBox conditionHBox = conditionView.getMainHBox();
|
||||
|
||||
listConditions.add(conditionHBox);
|
||||
listConditionView.add(conditionView);
|
||||
|
||||
// Add in the last position of the ListView the mean to add another condition.
|
||||
listConditions.add(addConditionView.getMainHBox());
|
||||
}
|
||||
|
||||
public void buttonRemoveConditionPressed(@NotNull HBox measure){
|
||||
listConditions.remove(measure);
|
||||
listConditionView.removeIf(conditionView -> conditionView.getMainHBox().equals(measure));
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void menuItemSaveSelected(){
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setInitialDirectory(new File(DebugLogger.directorySave));
|
||||
fileChooser.setTitle("Save your condition list");
|
||||
fileChooser.getExtensionFilters().addAll(
|
||||
new FileChooser.ExtensionFilter("Json", "*.json"));
|
||||
fileChooser.setSelectedExtensionFilter(fileChooser.getExtensionFilters().get(0));
|
||||
|
||||
File fileSelected = fileChooser.showSaveDialog(mainVBox.getScene().getWindow());
|
||||
if(fileSelected != null){
|
||||
final List<Condition> listConditions = new ArrayList<>();
|
||||
listConditionView.forEach(conditionView -> listConditions.add(conditionView.getCondition()));
|
||||
|
||||
ConditionsSerializer.saveConditions(fileSelected.getAbsolutePath(), listConditions);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void menuItemLoadSelected(){
|
||||
// Initialize the filechooser so the user can only choose Json files.
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setInitialDirectory(new File(DebugLogger.directorySave));
|
||||
fileChooser.setTitle("Load your condition list");
|
||||
fileChooser.getExtensionFilters().addAll(
|
||||
new FileChooser.ExtensionFilter("Json", "*.json"));
|
||||
fileChooser.setSelectedExtensionFilter(fileChooser.getExtensionFilters().get(0));
|
||||
|
||||
File fileSelected = fileChooser.showOpenDialog(mainVBox.getScene().getWindow());
|
||||
if(fileSelected != null){
|
||||
// When the file is selected, delete the conditions in the view to replace them with the loaded conditions.
|
||||
List<Condition> listDeserializedConditions = ConditionsDeserializer.loadConditions(fileSelected.getAbsolutePath());
|
||||
|
||||
listConditionView.clear();
|
||||
Platform.runLater(() -> listConditions.clear());
|
||||
|
||||
for(Condition condition : listDeserializedConditions){
|
||||
ConditionView conditionView = addConditionView.createViewFromCondition(condition);
|
||||
listConditionView.add(conditionView);
|
||||
Platform.runLater(() ->listConditions.add(conditionView.getMainHBox()));
|
||||
}
|
||||
Platform.runLater(() -> listConditions.add(addConditionView.getMainHBox()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,284 @@
|
|||
package fr.insa.ocm.view.mainuis;
|
||||
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.utils.serialize.OCMSerializer;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.view.OCLApplication;
|
||||
import fr.insa.ocm.view.misc.*;
|
||||
import fr.insa.ocm.view.misc.menus.AboutView;
|
||||
import fr.insa.ocm.view.misc.menus.MonitorView;
|
||||
import fr.insa.ocm.view.misc.menus.LoadStateView;
|
||||
import fr.insa.ocm.view.misc.menus.SettingsView;
|
||||
import fr.insa.ocm.viewmodel.InfoAlgorithm;
|
||||
import fr.insa.ocm.viewmodel.OCLController;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MainView {
|
||||
|
||||
@FXML private BorderPane mainPane = null;
|
||||
|
||||
@FXML private ListView<String> listKeptPatterns = null;
|
||||
private ObservableList<String> keptPatternsStrings = FXCollections.observableArrayList();
|
||||
|
||||
@FXML private Button buttonMining = null;
|
||||
@FXML private Button buttonData = null;
|
||||
@FXML private Button buttonPause = null;
|
||||
@FXML private Button buttonFastForward = null;
|
||||
|
||||
@FXML private Label labelInfo = null;
|
||||
|
||||
private static MainView currentMainView;
|
||||
private Stage mainStage = OCLApplication.getMainStage();
|
||||
|
||||
private boolean dataLoaded;
|
||||
|
||||
// Manage the file inputs of the user
|
||||
private final FileChooser fileChooser = new FileChooser();
|
||||
private boolean firstFile = true;
|
||||
|
||||
public MainView(){
|
||||
dataLoaded = false;
|
||||
|
||||
currentMainView = this;
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/mainuis/mainView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
listKeptPatterns.setItems(keptPatternsStrings);
|
||||
|
||||
MenuBar menuBar = new MenuBar();
|
||||
menuBar.prefWidthProperty().bind(mainStage.widthProperty());
|
||||
mainPane.setTop(menuBar);
|
||||
|
||||
// File menu
|
||||
Menu fileMenu = new Menu("File");
|
||||
MenuItem newDataMenuItem = new MenuItem("Import a new dataset");
|
||||
MenuItem savePatternMenuItem = new MenuItem("Export the patterns");
|
||||
MenuItem saveStateMenuItem = new MenuItem("Save the current search state");
|
||||
MenuItem loadStateMenuItem = new MenuItem("Load a search state");
|
||||
MenuItem exitMenuItem = new MenuItem("Quit");
|
||||
|
||||
Menu editMenu = new Menu("Edit");
|
||||
MenuItem menuItemSettings = new MenuItem("Settings");
|
||||
|
||||
Menu monitoringMenu = new Menu("Monitor");
|
||||
MenuItem menuItemNumberAlgorithmLaunched = new MenuItem("Algorithms Launched Stats");
|
||||
MenuItem menuItemBanditWeights = new MenuItem("Bandit Weights");
|
||||
MenuItem menuItemCoactiveWeights = new MenuItem("Coactive Learning Weights");
|
||||
|
||||
Menu helpMenu = new Menu("Help");
|
||||
MenuItem aboutMenuItem = new MenuItem("About");
|
||||
MenuItem helpMenuItem = new MenuItem("Help");
|
||||
|
||||
exitMenuItem.setOnAction(event -> Platform.exit());
|
||||
newDataMenuItem.setOnAction(event -> this.menuItemNewDataSelected());
|
||||
savePatternMenuItem.setOnAction(event -> this.menuItemSavePatternSelected());
|
||||
saveStateMenuItem.setOnAction(event -> this.menuItemSaveStateSelected());
|
||||
loadStateMenuItem.setOnAction(event -> this.menuItemLoadStateSelected());
|
||||
|
||||
menuItemSettings.setOnAction(event -> this.menuItemSettingsSelected());
|
||||
|
||||
menuItemNumberAlgorithmLaunched.setOnAction(event -> this.menuItemNumberAlgorithmLaunchedSelected());
|
||||
menuItemBanditWeights.setOnAction(event -> this.menuItemBanditWeightsSelected());
|
||||
menuItemCoactiveWeights.setOnAction(event -> this.menuItemCoactiveWeightsSelected());
|
||||
|
||||
aboutMenuItem.setOnAction(event -> this.menuItemAboutSelected());
|
||||
helpMenuItem.setOnAction(event -> this.menuItemHelpSelected());
|
||||
|
||||
|
||||
//add item to fileMenu
|
||||
fileMenu.getItems().addAll(newDataMenuItem, savePatternMenuItem, saveStateMenuItem, loadStateMenuItem,
|
||||
new SeparatorMenuItem(), exitMenuItem);
|
||||
editMenu.getItems().addAll(menuItemSettings);
|
||||
monitoringMenu.getItems().addAll(menuItemNumberAlgorithmLaunched, menuItemBanditWeights, menuItemCoactiveWeights);
|
||||
helpMenu.getItems().addAll(helpMenuItem, aboutMenuItem);
|
||||
//Add menus to menubar
|
||||
menuBar.getMenus().addAll(fileMenu, editMenu, monitoringMenu, helpMenu);
|
||||
|
||||
buttonMining.setOnAction(event -> this.buttonMiningClicked());
|
||||
buttonData.setOnAction(event -> this.buttonDataPressed());
|
||||
buttonPause.setOnAction(event -> this.buttonPausePressed());
|
||||
buttonPause.setText("Pause Mining");
|
||||
buttonFastForward.setOnAction(event -> this.buttonFastForwardPressed());
|
||||
|
||||
mainStage.setScene(new Scene(mainPane, 900, 600));
|
||||
mainStage.setTitle("OneClick Mining");
|
||||
mainStage.show();
|
||||
}
|
||||
|
||||
public static MainView getCurrentMainView(){
|
||||
return currentMainView;
|
||||
}
|
||||
|
||||
public void setDataLoaded(){
|
||||
dataLoaded = true;
|
||||
}
|
||||
|
||||
public Label getLabelInfo(){
|
||||
return labelInfo;
|
||||
}
|
||||
|
||||
public void refreshKeptPatternsList(){
|
||||
List<Pattern> patterns = OCMManager.patternWarehouseGetPatterns();
|
||||
Platform.runLater(() -> keptPatternsStrings.clear());
|
||||
|
||||
for(Pattern p : patterns){
|
||||
Platform.runLater(() -> keptPatternsStrings.add(p.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonMiningClicked(){
|
||||
if(dataLoaded && OCMManager.isInitialized() && OCMManager.algorithmManagerIsMining()){
|
||||
new MiningView(OCLController.getUserRank());
|
||||
} else if(dataLoaded && OCMManager.isInitialized()){
|
||||
new ErrorView("You can only request a knowledge gathering when the algorithms are running.");
|
||||
} else if(dataLoaded){
|
||||
new ErrorView("Please wait a few seconds for the initialization of the data handler.");
|
||||
} else {
|
||||
new ErrorView("No data has been found. Have you imported any data ?");
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonDataPressed(){
|
||||
new ErrorView("It's broken D:");
|
||||
}
|
||||
|
||||
private void buttonPausePressed(){
|
||||
if(OCMManager.algorithmManagerIsMining()){
|
||||
new Thread(OCMManager::algorithmManagerPauseMining).start();
|
||||
buttonPause.setText("Resume Mining");
|
||||
InfoAlgorithm.setPaused(true);
|
||||
}else{
|
||||
new Thread(OCMManager::algorithmManagerResumeMining).start();
|
||||
buttonPause.setText("Pause Mining");
|
||||
InfoAlgorithm.setPaused(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonFastForwardPressed(){
|
||||
if(dataLoaded && OCMManager.isInitialized() && OCMManager.algorithmManagerIsMining()){
|
||||
new FastForwardView();
|
||||
} else if(dataLoaded && OCMManager.isInitialized()){
|
||||
new ErrorView("You can only request a fast forward process when the algorithms are running.");
|
||||
} else if(dataLoaded){
|
||||
new ErrorView("Please wait a few seconds for the initialization of the data handler.");
|
||||
} else {
|
||||
new ErrorView("No data has been found. Have you imported any data ?");
|
||||
}
|
||||
}
|
||||
|
||||
//********** Menu Item Methods **********//
|
||||
|
||||
// Menu File //
|
||||
|
||||
private void menuItemNewDataSelected(){
|
||||
fileChooser.setTitle("Choose a file containing your data");
|
||||
File file = fileChooser.showOpenDialog(mainStage);
|
||||
if(file != null){
|
||||
if(firstFile) {
|
||||
new Thread(() -> OCLController.initialize(file.getAbsolutePath())).start();
|
||||
firstFile = false;
|
||||
} else {
|
||||
new Thread(() -> OCLController.reload(file.getAbsolutePath())).start();
|
||||
}
|
||||
dataLoaded = true;
|
||||
}else{
|
||||
new ErrorView("No file was selected !");
|
||||
}
|
||||
}
|
||||
|
||||
private void menuItemSavePatternSelected(){
|
||||
fileChooser.setTitle("Choose a file where to export your results");
|
||||
File file = fileChooser.showSaveDialog(mainStage);
|
||||
if (file != null){
|
||||
OCLController.exportInterestingPatterns(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
private void menuItemSaveStateSelected(){
|
||||
if(!OCMManager.algorithmManagerIsMining()) {
|
||||
fileChooser.setTitle("Choose a file where to serialize your current research");
|
||||
File file = fileChooser.showSaveDialog(mainStage);
|
||||
if (file != null) {
|
||||
InfoView infoView = new InfoView("Saving your state", "Currently saving your state.");
|
||||
infoView.setDisableContinue(true);
|
||||
|
||||
new Thread(new Task<Void>() {
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
new OCMSerializer(file.getAbsolutePath());
|
||||
Thread.sleep(500);
|
||||
|
||||
infoView.setProgress(1.);
|
||||
infoView.setDisableContinue(false);
|
||||
|
||||
return null;
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}else{
|
||||
new ErrorView("You should pause the mining algorithms before saving your current search state.");
|
||||
}
|
||||
}
|
||||
|
||||
private void menuItemLoadStateSelected(){
|
||||
if(!OCMManager.algorithmManagerIsMining()) {
|
||||
new LoadStateView();
|
||||
}else{
|
||||
new ErrorView("You should pause the mining algorithms before loading any search state.");
|
||||
}
|
||||
}
|
||||
|
||||
// Menu Edit //
|
||||
|
||||
private void menuItemSettingsSelected(){
|
||||
new SettingsView();
|
||||
}
|
||||
|
||||
// Menu Monitor //
|
||||
|
||||
private void menuItemNumberAlgorithmLaunchedSelected(){
|
||||
new MonitorView(MonitorView.MonitorType.ALGORITHM);
|
||||
}
|
||||
|
||||
private void menuItemBanditWeightsSelected(){
|
||||
new MonitorView(MonitorView.MonitorType.BANDIT);
|
||||
}
|
||||
|
||||
private void menuItemCoactiveWeightsSelected(){
|
||||
new MonitorView(MonitorView.MonitorType.COACTIVE);
|
||||
}
|
||||
|
||||
// Menu Help //
|
||||
|
||||
private void menuItemHelpSelected(){
|
||||
new ErrorView("This menu is currently unavailable :c"); //TODO -- Faire une fenêtre d'aide pour l'utilisateur.
|
||||
}
|
||||
|
||||
private void menuItemAboutSelected(){
|
||||
new AboutView();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
package fr.insa.ocm.view.mainuis;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.view.misc.parts.mining.PatternView;
|
||||
import fr.insa.ocm.viewmodel.OCLController;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MiningView {
|
||||
|
||||
@FXML private VBox mainVBox = null;
|
||||
@FXML private ListView<HBox> listProposedPatterns = null;
|
||||
@FXML private Button buttonConfirm = null;
|
||||
@FXML private Button buttonSetKeep = null;
|
||||
@FXML private Button buttonSetTrash = null;
|
||||
|
||||
@FXML private Label firstLabel = null;
|
||||
@FXML private Label labelRound = null;
|
||||
|
||||
private List<Pattern> patterns;
|
||||
|
||||
private List<PatternView> patternControllers;
|
||||
|
||||
MiningView(@NotNull List<Pattern> userRank){
|
||||
patternControllers = new ArrayList<>();
|
||||
patterns = userRank;
|
||||
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/mainuis/miningView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
Scene scene = new Scene(mainVBox);
|
||||
scene.getStylesheets().add(getClass().getResource("/css/button.css").toExternalForm());
|
||||
scene.getStylesheets().add(getClass().getResource("/css/hbox.css").toExternalForm());
|
||||
|
||||
buttonConfirm.setOnAction(event -> this.buttonConfirmPressed());
|
||||
buttonSetKeep.setOnAction(event -> this.buttonSetKeepPressed());
|
||||
buttonSetTrash.setOnAction(event -> this.buttonSetTrashPressed());
|
||||
|
||||
labelRound.setText("Round "+ OCMManager.coactiveGetNbRound());
|
||||
|
||||
ObservableList<HBox> hBoxes = FXCollections.observableArrayList();
|
||||
|
||||
patterns.forEach(pattern -> {
|
||||
PatternView patternView = new PatternView(pattern, patterns.indexOf(pattern));
|
||||
patternControllers.add(patternView);
|
||||
hBoxes.add(patternView.getMainHBox());
|
||||
});
|
||||
|
||||
listProposedPatterns.setItems(hBoxes);
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.setTitle("Choose your Patterns");
|
||||
stage.setScene(scene);
|
||||
stage.show();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void buttonConfirmPressed(){
|
||||
List<Pattern> keptPatterns = new ArrayList<>();
|
||||
List<Pattern> neutralPatterns = new ArrayList<>();
|
||||
List<Pattern> trashedPatterns = new ArrayList<>();
|
||||
|
||||
for(PatternView patternView : patternControllers){
|
||||
Pattern pattern = patterns.get(patternView.getIndex());
|
||||
|
||||
if(patternView.isKept()){
|
||||
keptPatterns.add(pattern);
|
||||
}else if(patternView.isTrashed()){
|
||||
trashedPatterns.add(pattern);
|
||||
}else{
|
||||
neutralPatterns.add(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
OCLController.setPatternList(keptPatterns, neutralPatterns, trashedPatterns);
|
||||
|
||||
MainView.getCurrentMainView().refreshKeptPatternsList();
|
||||
|
||||
Stage stage = (Stage) buttonConfirm.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
|
||||
private void buttonSetKeepPressed(){
|
||||
patternControllers.forEach(PatternView::setIsKept);
|
||||
}
|
||||
|
||||
private void buttonSetTrashPressed(){
|
||||
patternControllers.forEach(PatternView::setIsTrashed);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package fr.insa.ocm.view.misc;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
import jline.internal.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ErrorView {
|
||||
|
||||
@FXML private VBox mainVBox;
|
||||
@FXML private Button closeButton;
|
||||
@FXML private Label errorLabel;
|
||||
|
||||
private final static String defaultText = "Oh no ! An error has occured ! D:";
|
||||
private String errorText = "";
|
||||
|
||||
public ErrorView(@Nullable String errorTxt){
|
||||
this.errorText = errorTxt;
|
||||
if (errorTxt == null || errorTxt.equals("")){
|
||||
this.errorText = defaultText;
|
||||
}
|
||||
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/misc/errorView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
closeButton.setOnMouseClicked(event -> this.quit());
|
||||
errorLabel.setText(errorText);
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.setScene(new Scene(mainVBox));
|
||||
stage.setTitle("Error");
|
||||
stage.show();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void quit(){
|
||||
Stage stage = (Stage) mainVBox.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package fr.insa.ocm.view.misc;
|
||||
|
||||
import fr.insa.ocm.viewmodel.OCLController;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class FastForwardWaitingView {
|
||||
|
||||
@FXML private VBox mainVBox = null;
|
||||
@FXML private Label labelCurrentOperation = null;
|
||||
@FXML private Label labelTime = null;
|
||||
@FXML private ProgressBar progressBarMining = null;
|
||||
@FXML private ProgressBar progressBarRound = null;
|
||||
@FXML private Button buttonAbortFinish = null;
|
||||
|
||||
private boolean hasFinished;
|
||||
|
||||
public FastForwardWaitingView(){
|
||||
hasFinished = false;
|
||||
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/misc/fastForwardWaitingView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
labelCurrentOperation.setText("Current operation: Initializing the mining process.");
|
||||
labelTime.setText("Estimated time before completion: Unknown");
|
||||
buttonAbortFinish.setText("Abort");
|
||||
|
||||
progressBarMining.setProgress(0);
|
||||
progressBarRound.setProgress(0);
|
||||
|
||||
buttonAbortFinish.setOnAction(event -> this.buttonAbortFinishPressed());
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.setScene(new Scene(mainVBox));
|
||||
stage.setTitle("Fast Forward Mining");
|
||||
stage.show();
|
||||
}
|
||||
|
||||
public void setHasFinished(boolean b){
|
||||
hasFinished = b;
|
||||
if(hasFinished){
|
||||
Platform.runLater(() -> buttonAbortFinish.setText("Finished"));
|
||||
}
|
||||
}
|
||||
|
||||
public void bindCurrentOperation(StringProperty currentOpration){
|
||||
labelCurrentOperation.textProperty().bind(currentOpration);
|
||||
}
|
||||
|
||||
public void bindCurrentTime(StringProperty remainingTime){
|
||||
labelTime.textProperty().bind(remainingTime);
|
||||
}
|
||||
|
||||
public void bindProgressMining(DoubleProperty progressMining){
|
||||
progressBarMining.progressProperty().bind(progressMining);
|
||||
}
|
||||
|
||||
public void bindProgressLearning(DoubleProperty progressLearning) {
|
||||
progressBarRound.progressProperty().bind(progressLearning);
|
||||
}
|
||||
|
||||
private void buttonAbortFinishPressed(){
|
||||
if(!hasFinished){
|
||||
OCLController.requestFFStop();
|
||||
}
|
||||
Stage stage = (Stage) mainVBox.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package fr.insa.ocm.view.misc;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class InfoView {
|
||||
|
||||
@FXML private VBox mainVBox = null;
|
||||
@FXML private Label labelInfo = null;
|
||||
@FXML private ProgressBar progressBar = null;
|
||||
@FXML private Button buttonContinue = null;
|
||||
|
||||
private String title;
|
||||
private String mainText;
|
||||
|
||||
public InfoView(@NotNull String title, @NotNull String mainText){
|
||||
this.title = title;
|
||||
this.mainText = mainText;
|
||||
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/misc/infoView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
labelInfo.setText(mainText);
|
||||
|
||||
buttonContinue.setOnAction(event -> this.buttonContinuePressed());
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.setScene(new Scene(mainVBox));
|
||||
stage.setTitle(title);
|
||||
stage.show();
|
||||
}
|
||||
|
||||
public void setDisableContinue(boolean b){
|
||||
buttonContinue.setDisable(b);
|
||||
}
|
||||
|
||||
public void setProgress(double d){
|
||||
d = d > 1 ? 1 : d;
|
||||
d = d < 0 ? 0 : d;
|
||||
|
||||
progressBar.setProgress(d);
|
||||
}
|
||||
|
||||
private void buttonContinuePressed(){
|
||||
Stage stage = (Stage) mainVBox.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package fr.insa.ocm.view.misc.menus;
|
||||
|
||||
import fr.insa.ocm.viewmodel.OCLController;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class AboutView {
|
||||
|
||||
@FXML private VBox mainVBox = null;
|
||||
@FXML private Label versionLabel = null;
|
||||
@FXML private Button closeButton = null;
|
||||
|
||||
public AboutView(){
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/misc/menus/aboutView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
versionLabel.setText("OneClick Mining - Alpha v"+ OCLController.VERSION);
|
||||
|
||||
closeButton.setOnAction(event -> this.close());
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.setScene(new Scene(mainVBox));
|
||||
stage.setTitle("About OneClick Mining");
|
||||
stage.show();
|
||||
}
|
||||
|
||||
private void close(){
|
||||
Stage stage = (Stage) mainVBox.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
package fr.insa.ocm.view.misc.menus;
|
||||
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.utils.serialize.OCMDeserializer;
|
||||
import fr.insa.ocm.view.misc.ErrorView;
|
||||
import fr.insa.ocm.view.misc.InfoView;
|
||||
import fr.insa.ocm.view.mainuis.MainView;
|
||||
import fr.insa.ocm.viewmodel.OCLController;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class LoadStateView {
|
||||
|
||||
@FXML private VBox mainVBox = null;
|
||||
|
||||
@FXML private Button buttonSearch = null;
|
||||
@FXML private Button buttonData = null;
|
||||
@FXML private Button buttonLoad = null;
|
||||
|
||||
@FXML private Label labelSearch = null;
|
||||
@FXML private Label labelData = null;
|
||||
|
||||
private SimpleStringProperty msgSearch;
|
||||
private SimpleStringProperty msgData;
|
||||
|
||||
private File fileSearch;
|
||||
private File fileData;
|
||||
|
||||
private boolean isSearchFileSelected;
|
||||
private boolean isDataFileSelected;
|
||||
|
||||
public LoadStateView(){
|
||||
msgSearch = new SimpleStringProperty("Please select a search state file to load");
|
||||
msgData = new SimpleStringProperty("Please select a the corresponding data file to load");
|
||||
|
||||
isSearchFileSelected = false;
|
||||
isDataFileSelected = false;
|
||||
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/misc/menus/loadStateView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
labelSearch.textProperty().bind(msgSearch);
|
||||
labelData.textProperty().bind(msgData);
|
||||
|
||||
labelSearch.setWrapText(true);
|
||||
labelData.setWrapText(true);
|
||||
|
||||
buttonSearch.setOnAction(event -> this.buttonSearchPressed());
|
||||
buttonData.setOnAction(event -> this.buttonDataPressed());
|
||||
buttonLoad.setOnAction(event -> this.buttonLoadPressed());
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.setScene(new Scene(mainVBox));
|
||||
stage.setTitle("Load a saved state");
|
||||
stage.show();
|
||||
}
|
||||
|
||||
private void buttonSearchPressed(){
|
||||
Stage stage = (Stage) mainVBox.getScene().getWindow();
|
||||
FileChooser fileChooserSearch = new FileChooser();
|
||||
|
||||
fileChooserSearch.setTitle("Choose the file which contains the searching state");
|
||||
fileSearch = fileChooserSearch.showOpenDialog(stage);
|
||||
|
||||
if(fileSearch != null){
|
||||
msgSearch.set(fileSearch.getAbsolutePath());
|
||||
|
||||
buttonLoad.setDisable(!isDataFileSelected);
|
||||
isSearchFileSelected = true;
|
||||
}else{
|
||||
new ErrorView("No Search file were selected.");
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonDataPressed(){
|
||||
Stage stage = (Stage) mainVBox.getScene().getWindow();
|
||||
FileChooser fileChooserData = new FileChooser();
|
||||
|
||||
fileChooserData.setTitle("Choose the file which contains the data associated with the search state");
|
||||
fileData = fileChooserData.showOpenDialog(stage);
|
||||
|
||||
if(fileData != null) {
|
||||
msgData.set(fileData.getAbsolutePath());
|
||||
|
||||
buttonLoad.setDisable(!isSearchFileSelected);
|
||||
isDataFileSelected = true;
|
||||
}else{
|
||||
new ErrorView("No Data file were selected.");
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonLoadPressed(){
|
||||
Stage stage = (Stage) mainVBox.getScene().getWindow();
|
||||
stage.close();
|
||||
|
||||
InfoView infoView = new InfoView("Loading a state", "Currently loading the selected state.");
|
||||
infoView.setDisableContinue(true);
|
||||
|
||||
new Thread(new Task<Void>() {
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
OCMManager.algorithmManagerStopMining();
|
||||
|
||||
// Import the data
|
||||
OCLController.reload(fileData.getPath());
|
||||
Thread.sleep(250);
|
||||
Platform.runLater(() -> infoView.setProgress(0.5));
|
||||
|
||||
// Import the saveState
|
||||
new OCMDeserializer(fileSearch.getAbsolutePath());
|
||||
Thread.sleep(250);
|
||||
Platform.runLater(() -> infoView.setProgress(1.));
|
||||
|
||||
MainView.getCurrentMainView().setDataLoaded();
|
||||
Platform.runLater(() -> MainView.getCurrentMainView().refreshKeptPatternsList());
|
||||
|
||||
Platform.runLater(() -> infoView.setDisableContinue(false));
|
||||
|
||||
// OCMManager.getInstance().reloadData(fileData.getPath());
|
||||
// OCLController.getInstance().setFromLoadState();
|
||||
// Thread.sleep(500);
|
||||
// infoView.setProgress(0.5);
|
||||
//
|
||||
// // Import the saveState
|
||||
// new OCMDeserializer(fileSearch.getAbsolutePath());
|
||||
// Thread.sleep(500);
|
||||
// infoView.setProgress(1.);
|
||||
//
|
||||
// try{
|
||||
// OCMManager.getInstance().setInitialized(true);
|
||||
// } catch (Exception e){
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// MainView.getCurrentMainView().setDataLoaded();
|
||||
// Platform.runLater(() -> MainView.getCurrentMainView().refreshKeptPatternsList());
|
||||
//
|
||||
// infoView.setDisableContinue(false);
|
||||
|
||||
OCMManager.algorithmManagerStartMining();
|
||||
|
||||
return null;
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package fr.insa.ocm.view.misc.menus;
|
||||
|
||||
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.viewmodel.Monitor;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class MonitorView {
|
||||
|
||||
public enum MonitorType{
|
||||
ALGORITHM, BANDIT, COACTIVE;
|
||||
|
||||
public SimpleStringProperty getTextProperty(){
|
||||
switch (this){
|
||||
case ALGORITHM:
|
||||
return Monitor.getMonitorAlgorithmsLaunched();
|
||||
case BANDIT:
|
||||
return Monitor.getMonitorBanditWeights();
|
||||
case COACTIVE:
|
||||
return Monitor.getMonitorCoactiveWeights();
|
||||
default:
|
||||
DebugLogger.printDebug("MonitorView: Unable to retrieve the correct monitor type.", DebugLogger.MessageSeverity.MEDIUM);
|
||||
return new SimpleStringProperty("");
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getStageTitle(){
|
||||
switch (this){
|
||||
case ALGORITHM:
|
||||
return "Monitoring Launched Algorithms";
|
||||
case BANDIT:
|
||||
return "Monitoring Bandit Weights";
|
||||
case COACTIVE:
|
||||
return "Monitoring Coactive Weights";
|
||||
default:
|
||||
return "Monitor";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FXML private VBox mainVBox = null;
|
||||
@FXML private Label labelInfo = null;
|
||||
@FXML private Button buttonClose = null;
|
||||
|
||||
private MonitorType monitorType;
|
||||
|
||||
public MonitorView(MonitorType monitorType){
|
||||
this.monitorType = monitorType;
|
||||
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/misc/menus/monitor/monitorView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
buttonClose.setOnAction(event -> this.buttonClosePressed());
|
||||
|
||||
labelInfo.textProperty().bind(monitorType.getTextProperty());
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.setScene(new Scene(mainVBox));
|
||||
stage.setTitle(monitorType.getStageTitle());
|
||||
stage.show();
|
||||
}
|
||||
|
||||
private void buttonClosePressed(){
|
||||
Stage stage = (Stage) mainVBox.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
package fr.insa.ocm.view.misc.menus;
|
||||
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.set.CacheSet;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.view.misc.parts.settings.library.SettingsRealKDView;
|
||||
import fr.insa.ocm.view.misc.parts.settings.library.SettingsSPMFView;
|
||||
import fr.insa.ocm.view.misc.parts.settings.pattern.SettingsPatternView;
|
||||
import fr.insa.ocm.viewmodel.OCLController;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SettingsView {
|
||||
|
||||
@FXML private VBox mainVBox = null;
|
||||
@FXML private ChoiceBox<Pattern.WrapperType> choiceBoxWrapper = null;
|
||||
|
||||
// Library tab
|
||||
@FXML private ScrollPane paneSettings = null;
|
||||
|
||||
// Pattern tab
|
||||
@FXML private ListView<HBox> listViewPattern = null;
|
||||
@FXML private TextField textFieldNumberPattern = null;
|
||||
|
||||
// Main buttons
|
||||
@FXML private Button buttonConfirm = null;
|
||||
@FXML private Button buttonCancel = null;
|
||||
|
||||
private SettingsSPMFView settingsSPMFView;
|
||||
private SettingsRealKDView settingsRealKDView;
|
||||
private static Pattern.WrapperType previousValue = Pattern.WrapperType.SPMF;
|
||||
private List<SettingsPatternView> listSettingsPatternView;
|
||||
|
||||
public SettingsView(){
|
||||
settingsSPMFView = new SettingsSPMFView();
|
||||
settingsRealKDView = new SettingsRealKDView();
|
||||
listSettingsPatternView = new ArrayList<>();
|
||||
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/misc/menus/settingsView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//********** Initialization methods **********//
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
choiceBoxWrapper.getItems().setAll(Pattern.WrapperType.values());
|
||||
choiceBoxWrapper.setValue(previousValue);
|
||||
|
||||
this.choiceBoxWrapperModified();
|
||||
|
||||
choiceBoxWrapper.setOnAction(event -> this.choiceBoxWrapperModified());
|
||||
|
||||
// Pattern tab initialization
|
||||
ObservableList<HBox> observableSettings = FXCollections.observableArrayList();
|
||||
for(Pattern.MeasureType measureType : Pattern.MeasureType.values()){
|
||||
SettingsPatternView settingsPV = new SettingsPatternView(measureType);
|
||||
|
||||
listSettingsPatternView.add(settingsPV);
|
||||
observableSettings.add(settingsPV.getMainHBox());
|
||||
}
|
||||
listViewPattern.setItems(observableSettings);
|
||||
|
||||
textFieldNumberPattern.setText(OCMManager.cacheGetSizeListBestPatterns() + "");
|
||||
|
||||
// Buttons initialization
|
||||
buttonCancel.setOnAction(event -> this.buttonCancelPressed());
|
||||
buttonConfirm.setOnAction(event -> this.buttonConfirmPressed());
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.setScene(new Scene(mainVBox));
|
||||
stage.setTitle("Settings");
|
||||
stage.show();
|
||||
}
|
||||
|
||||
//********** Action methods **********//
|
||||
|
||||
private void choiceBoxWrapperModified(){
|
||||
|
||||
switch (choiceBoxWrapper.getValue()){
|
||||
case REALKD:
|
||||
paneSettings.setContent(settingsRealKDView.getMainVBox());
|
||||
break;
|
||||
case SPMF:
|
||||
paneSettings.setContent(settingsSPMFView.getMainVBox());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonCancelPressed(){
|
||||
Stage stage = (Stage) mainVBox.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
|
||||
private void buttonConfirmPressed(){
|
||||
OCLController.setWrapperType(choiceBoxWrapper.getValue());
|
||||
previousValue = choiceBoxWrapper.getValue();
|
||||
|
||||
switch (choiceBoxWrapper.getValue()){
|
||||
case REALKD:
|
||||
break;
|
||||
case SPMF:
|
||||
settingsSPMFView.setSettingsAlgorithmLauncher();
|
||||
listSettingsPatternView.forEach(SettingsPatternView::setMeasureChoice);
|
||||
break;
|
||||
}
|
||||
|
||||
try{
|
||||
OCMManager.cacheSetSizeListBestPatterns(Integer.valueOf(textFieldNumberPattern.getText()));
|
||||
} catch (NumberFormatException e){
|
||||
DebugLogger.printDebug("SettingsView: Wrong number given to the ranking size in the settings.", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
|
||||
Stage stage = (Stage) mainVBox.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package fr.insa.ocm.view.misc.parts.fastforward;
|
||||
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.view.mainuis.FastForwardView;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.layout.HBox;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class AddConditionView {
|
||||
|
||||
@FXML private HBox mainHBox = null;
|
||||
@FXML private ChoiceBox<Condition.ConditionType> choiceBoxCondition = null;
|
||||
@FXML private Button buttonAddCondition = null;
|
||||
|
||||
private FastForwardView parent;
|
||||
|
||||
public AddConditionView(@NotNull FastForwardView parent){
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
buttonAddCondition.setOnAction(event -> parent.buttonAddConditionPressed());
|
||||
|
||||
choiceBoxCondition.getItems().addAll(Condition.ConditionType.values());
|
||||
choiceBoxCondition.setValue(Condition.ConditionType.CONDITION_ATTRIBUTE);
|
||||
}
|
||||
|
||||
public HBox getMainHBox(){ return mainHBox; }
|
||||
|
||||
@Nullable
|
||||
public ConditionView createConditionView(){
|
||||
ConditionView conditionView = null;
|
||||
try {
|
||||
FXMLLoader loader = null;
|
||||
switch (choiceBoxCondition.getValue()) {
|
||||
case CONDITION_ATTRIBUTE:
|
||||
conditionView = new ConditionAttributeView(parent);
|
||||
loader = new FXMLLoader(getClass().getResource("/fxml/misc/parts/fastforward/conditionAttribute.fxml"));
|
||||
break;
|
||||
case CONDITION_ALGORITHM:
|
||||
conditionView = new ConditionAlgorithmView(parent);
|
||||
loader = new FXMLLoader(getClass().getResource("/fxml/misc/parts/fastforward/conditionAlgorithm.fxml"));
|
||||
break;
|
||||
case CONDITION_MEASURE_STATIC:
|
||||
conditionView = new ConditionMeasureStaticView(parent);
|
||||
loader = new FXMLLoader(getClass().getResource("/fxml/misc/parts/fastforward/conditionMeasureStatic.fxml"));
|
||||
break;
|
||||
case CONDITION_MEASURE_BETWEEN:
|
||||
conditionView = new ConditionMeasureBetweenView(parent);
|
||||
loader = new FXMLLoader(getClass().getResource("/fxml/misc/parts/fastforward/conditionMeasureBetween.fxml"));
|
||||
break;
|
||||
case CONDITION_MEASURE_DYNAMIC:
|
||||
conditionView = new ConditionMeasureDynamicView(parent);
|
||||
loader = new FXMLLoader(getClass().getResource("/fxml/misc/parts/fastforward/conditionMeasureDynamic.fxml"));
|
||||
break;
|
||||
}
|
||||
loader.setController(conditionView);
|
||||
loader.load();
|
||||
}catch (IOException | NullPointerException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return conditionView;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ConditionView createViewFromCondition(@NotNull Condition condition){
|
||||
ConditionView conditionView = null;
|
||||
choiceBoxCondition.setValue(condition.getConditionType());
|
||||
|
||||
conditionView = createConditionView();
|
||||
if (conditionView != null) {
|
||||
conditionView.importCondition(condition);
|
||||
}
|
||||
|
||||
return conditionView;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package fr.insa.ocm.view.misc.parts.fastforward;
|
||||
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.view.mainuis.FastForwardView;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.ConditionAlgorithm;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionAlgorithmView extends ConditionView {
|
||||
|
||||
@FXML private ChoiceBox<String> choiceBoxAlgorithmName = null;
|
||||
@FXML private ChoiceBox<ConditionAlgorithm.AlgorithmState> choiceBoxAlgorithmState = null;
|
||||
|
||||
public ConditionAlgorithmView(FastForwardView parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
public void initialize(){
|
||||
super.initialize();
|
||||
|
||||
choiceBoxAlgorithmState.getItems().addAll(ConditionAlgorithm.AlgorithmState.values());
|
||||
choiceBoxAlgorithmState.setValue(ConditionAlgorithm.AlgorithmState.CREATEDBY);
|
||||
|
||||
List<String> listAlgorithmName = OCMManager.algorithmLauncherGetListAlgorithmName();
|
||||
|
||||
choiceBoxAlgorithmName.getItems().addAll(listAlgorithmName);
|
||||
choiceBoxAlgorithmName.setValue(listAlgorithmName.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Condition getCondition() {
|
||||
return new ConditionAlgorithm(getActionPatternChoice(),
|
||||
getAlgorithmNameSelected(),
|
||||
getAlgorithmStateSelected());
|
||||
}
|
||||
|
||||
//********** Serialization Methods **********//
|
||||
|
||||
@Override
|
||||
public void importCondition(@NotNull Condition condition){
|
||||
super.importCondition(condition);
|
||||
if(condition instanceof ConditionAlgorithm) {
|
||||
ConditionAlgorithm conditionAlgorithm = (ConditionAlgorithm) condition;
|
||||
|
||||
choiceBoxAlgorithmName.setValue(conditionAlgorithm.getAlgorithmName());
|
||||
choiceBoxAlgorithmState.setValue(conditionAlgorithm.getAlgorithmState());
|
||||
}
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
private String getAlgorithmNameSelected(){
|
||||
return choiceBoxAlgorithmName.getValue();
|
||||
}
|
||||
|
||||
private ConditionAlgorithm.AlgorithmState getAlgorithmStateSelected(){
|
||||
return choiceBoxAlgorithmState.getValue();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package fr.insa.ocm.view.misc.parts.fastforward;
|
||||
|
||||
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.view.mainuis.FastForwardView;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.ConditionAttribute;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionAttributeView extends ConditionView {
|
||||
|
||||
@FXML private ChoiceBox<String> choiceBoxAttributeName = null;
|
||||
@FXML private ChoiceBox<ConditionAttribute.AttributeState> choiceBoxAttributeState = null;
|
||||
|
||||
public ConditionAttributeView(@NotNull FastForwardView parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(){
|
||||
super.initialize();
|
||||
|
||||
choiceBoxAttributeState.getItems().addAll(ConditionAttribute.AttributeState.values());
|
||||
choiceBoxAttributeState.setValue(ConditionAttribute.AttributeState.PRESENT);
|
||||
|
||||
List<String> listAttributeName = OCMManager.algorithmLauncherGetListAttributeName();
|
||||
|
||||
choiceBoxAttributeName.getItems().addAll(listAttributeName);
|
||||
choiceBoxAttributeName.setValue(listAttributeName.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Condition getCondition() {
|
||||
return new ConditionAttribute(getActionPatternChoice(), getAttributeNameSelected(), getAttributeStateSelected());
|
||||
}
|
||||
|
||||
//********** Serialization Methods **********//
|
||||
|
||||
@Override
|
||||
public void importCondition(@NotNull Condition condition){
|
||||
super.importCondition(condition);
|
||||
if(condition instanceof ConditionAttribute){
|
||||
ConditionAttribute conditionAttribute = (ConditionAttribute) condition;
|
||||
|
||||
choiceBoxAttributeName.setValue(conditionAttribute.getAttributeName());
|
||||
choiceBoxAttributeState.setValue(conditionAttribute.getAttributeState());
|
||||
}
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
private String getAttributeNameSelected(){ return choiceBoxAttributeName.getValue(); }
|
||||
|
||||
private ConditionAttribute.AttributeState getAttributeStateSelected(){ return choiceBoxAttributeState.getValue(); }
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package fr.insa.ocm.view.misc.parts.fastforward;
|
||||
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.view.mainuis.FastForwardView;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.ConditionMeasureBetween;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.TextField;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ConditionMeasureBetweenView extends ConditionView{
|
||||
|
||||
@FXML private ChoiceBox<Pattern.MeasureType> choiceBoxMeasure = null;
|
||||
@FXML private ChoiceBox<ConditionMeasureBetween.IntervalChoice> choiceBoxIncluded = null;
|
||||
@FXML private TextField textFieldLowValue = null;
|
||||
@FXML private TextField textFieldHighValue = null;
|
||||
|
||||
public ConditionMeasureBetweenView(@NotNull FastForwardView parent){
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
@FXML
|
||||
public void initialize(){
|
||||
super.initialize();
|
||||
|
||||
choiceBoxMeasure.getItems().addAll(Pattern.MeasureType.values());
|
||||
choiceBoxMeasure.setValue(Pattern.MeasureType.FREQUENCY);
|
||||
|
||||
choiceBoxIncluded.getItems().addAll(ConditionMeasureBetween.IntervalChoice.values());
|
||||
choiceBoxIncluded.setValue(ConditionMeasureBetween.IntervalChoice.INSIDE_IN_IN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Condition getCondition() {
|
||||
return new ConditionMeasureBetween(getActionPatternChoice(), getMeasureType(), getIntervalChoice(), getThresholdValueLowerBound(), getThresholdValueHigherBound());
|
||||
}
|
||||
|
||||
//********** Serialization Methods **********//
|
||||
|
||||
@Override
|
||||
public void importCondition(@NotNull Condition condition){
|
||||
super.importCondition(condition);
|
||||
if(condition instanceof ConditionMeasureBetween){
|
||||
ConditionMeasureBetween conditionMeBe = (ConditionMeasureBetween) condition;
|
||||
|
||||
choiceBoxMeasure.setValue(conditionMeBe.getMeasureType());
|
||||
choiceBoxIncluded.setValue(conditionMeBe.getIntervalChoice());
|
||||
textFieldLowValue.setText(Double.toString(conditionMeBe.getLowerBound().getThresholdValue()));
|
||||
textFieldHighValue.setText(Double.toString(conditionMeBe.getHigerBound().getThresholdValue()));
|
||||
}
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
private ConditionMeasureBetween.IntervalChoice getIntervalChoice(){
|
||||
return choiceBoxIncluded.getValue();
|
||||
}
|
||||
|
||||
private Pattern.MeasureType getMeasureType(){
|
||||
return choiceBoxMeasure.getValue();
|
||||
}
|
||||
|
||||
private double getThresholdValueLowerBound(){
|
||||
return Double.valueOf(textFieldLowValue.getText());
|
||||
}
|
||||
|
||||
private double getThresholdValueHigherBound(){
|
||||
return Double.valueOf(textFieldHighValue.getText());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package fr.insa.ocm.view.misc.parts.fastforward;
|
||||
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.view.mainuis.FastForwardView;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.ConditionMeasureDynamic;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.TextField;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ConditionMeasureDynamicView extends ConditionView {
|
||||
|
||||
@FXML private ChoiceBox<Pattern.MeasureType> choiceBoxMeasure = null;
|
||||
@FXML private TextField textFieldValue = null;
|
||||
@FXML private ChoiceBox<ConditionMeasureDynamic.CatogoryType> choiceCategory = null;
|
||||
|
||||
|
||||
public ConditionMeasureDynamicView(@NotNull FastForwardView parent){
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@FXML
|
||||
@Override
|
||||
public void initialize(){
|
||||
super.initialize();
|
||||
|
||||
choiceBoxMeasure.getItems().addAll(Pattern.MeasureType.values());
|
||||
choiceBoxMeasure.setValue(Pattern.MeasureType.FREQUENCY);
|
||||
|
||||
choiceCategory.getItems().addAll(ConditionMeasureDynamic.CatogoryType.values());
|
||||
choiceCategory.setValue(ConditionMeasureDynamic.CatogoryType.HIGHEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Condition getCondition() {
|
||||
return new ConditionMeasureDynamic(getActionPatternChoice(), getMeasureType(), getCategoryType(), getIndexValue());
|
||||
}
|
||||
|
||||
//********** Serialization Methods **********//
|
||||
|
||||
public void importCondition(@NotNull Condition condition){
|
||||
super.importCondition(condition);
|
||||
if(condition instanceof ConditionMeasureDynamic){
|
||||
ConditionMeasureDynamic conditionMeDy = (ConditionMeasureDynamic) condition;
|
||||
|
||||
choiceBoxMeasure.setValue(conditionMeDy.getMeasure());
|
||||
textFieldValue.setText(Integer.toString(conditionMeDy.getIndex()));
|
||||
choiceCategory.setValue(conditionMeDy.getCatogory());
|
||||
}
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
private Pattern.MeasureType getMeasureType(){
|
||||
return choiceBoxMeasure.getValue();
|
||||
}
|
||||
|
||||
private ConditionMeasureDynamic.CatogoryType getCategoryType(){
|
||||
return choiceCategory.getValue();
|
||||
}
|
||||
|
||||
private int getIndexValue(){
|
||||
return Integer.valueOf(textFieldValue.getText());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package fr.insa.ocm.view.misc.parts.fastforward;
|
||||
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.view.mainuis.FastForwardView;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.ConditionMeasureStatic;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ConditionMeasureStaticView extends ConditionView{
|
||||
|
||||
@FXML private ChoiceBox<Pattern.MeasureType> choiceBoxMeasure = null;
|
||||
@FXML private ChoiceBox<ConditionMeasureStatic.OperatorType> choiceBoxOperator = null;
|
||||
@FXML private TextField textFieldValue = null;
|
||||
|
||||
|
||||
public ConditionMeasureStaticView(@NotNull FastForwardView parent){
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@FXML
|
||||
@Override
|
||||
public void initialize(){
|
||||
super.initialize();
|
||||
|
||||
choiceBoxMeasure.getItems().addAll(Pattern.MeasureType.values());
|
||||
choiceBoxMeasure.setValue(Pattern.MeasureType.FREQUENCY);
|
||||
|
||||
choiceBoxOperator.getItems().addAll(ConditionMeasureStatic.OperatorType.values());
|
||||
choiceBoxOperator.setValue(ConditionMeasureStatic.OperatorType.EQL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Condition getCondition() {
|
||||
return new ConditionMeasureStatic(getActionPatternChoice(), getSelectedMeasureType(), getSelectedOperatorType(), getThresholdValue());
|
||||
}
|
||||
|
||||
//********** Serialization Methods **********//
|
||||
|
||||
public void importCondition(@NotNull Condition condition){
|
||||
super.importCondition(condition);
|
||||
if(condition instanceof ConditionMeasureStatic){
|
||||
ConditionMeasureStatic conditionMeSt = (ConditionMeasureStatic) condition;
|
||||
|
||||
choiceBoxMeasure.setValue(conditionMeSt.getMeasure());
|
||||
choiceBoxOperator.setValue(conditionMeSt.getOperator());
|
||||
textFieldValue.setText(Double.toString(conditionMeSt.getThresholdValue()));
|
||||
}
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
private ConditionMeasureStatic.OperatorType getSelectedOperatorType(){
|
||||
return choiceBoxOperator.getValue();
|
||||
}
|
||||
|
||||
private Pattern.MeasureType getSelectedMeasureType(){
|
||||
return choiceBoxMeasure.getValue();
|
||||
}
|
||||
|
||||
private double getThresholdValue(){
|
||||
return Double.valueOf(textFieldValue.getText());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package fr.insa.ocm.view.misc.parts.fastforward;
|
||||
|
||||
import fr.insa.ocm.view.mainuis.FastForwardView;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ToggleButton;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.layout.HBox;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class ConditionView {
|
||||
|
||||
@FXML protected HBox mainHBox = null;
|
||||
@FXML protected ToggleButton buttonAlwaysKeep = null;
|
||||
@FXML protected ToggleButton buttonAlwaysTrash = null;
|
||||
@FXML protected Button buttonRemoveCondition = null;
|
||||
|
||||
private FastForwardView parent;
|
||||
|
||||
ConditionView(@NotNull FastForwardView parent){
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public HBox getMainHBox(){ return mainHBox; }
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
ToggleGroup toggleGroup = new ToggleGroup();
|
||||
buttonAlwaysKeep.setToggleGroup(toggleGroup);
|
||||
buttonAlwaysTrash.setToggleGroup(toggleGroup);
|
||||
|
||||
buttonAlwaysKeep.getStyleClass().addAll("buttonKeep");
|
||||
buttonAlwaysTrash.getStyleClass().addAll("buttonTrash");
|
||||
|
||||
buttonRemoveCondition.setOnAction(event -> parent.buttonRemoveConditionPressed(mainHBox));
|
||||
}
|
||||
|
||||
Condition.ActionPatternChoice getActionPatternChoice(){
|
||||
Condition.ActionPatternChoice actionPatternChoice = Condition.ActionPatternChoice.NEUTRAL;
|
||||
if(buttonAlwaysKeep.isSelected()){
|
||||
actionPatternChoice = Condition.ActionPatternChoice.KEEP;
|
||||
}else if(buttonAlwaysTrash.isSelected()){
|
||||
actionPatternChoice = Condition.ActionPatternChoice.TRASH;
|
||||
}
|
||||
|
||||
return actionPatternChoice;
|
||||
}
|
||||
|
||||
public abstract Condition getCondition();
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
if(obj instanceof ConditionView){
|
||||
ConditionView conditionView = (ConditionView) obj;
|
||||
return conditionView.mainHBox.equals(this.mainHBox);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//********** Serialization Methods **********//
|
||||
|
||||
public void importCondition(@NotNull Condition condition){
|
||||
switch (condition.getActionPatternChoice()){
|
||||
case KEEP:
|
||||
buttonAlwaysKeep.setSelected(true);
|
||||
break;
|
||||
case TRASH:
|
||||
buttonAlwaysTrash.setSelected(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
package fr.insa.ocm.view.misc.parts.mining;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.utils.Vector;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ToggleButton;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.layout.HBox;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PatternView {
|
||||
|
||||
@FXML private HBox mainHBox = null;
|
||||
|
||||
@FXML private ToggleButton buttonKeep = null;
|
||||
@FXML private ToggleButton buttonTrash = null;
|
||||
|
||||
@FXML private Label labelPattern = null;
|
||||
@FXML private Label labelExploitation = null;
|
||||
@FXML private Label labelIndicator = null;
|
||||
|
||||
private Pattern pattern;
|
||||
private int index;
|
||||
|
||||
public PatternView(@NotNull Pattern pattern, int index){
|
||||
this.pattern = pattern;
|
||||
this.index = index;
|
||||
|
||||
FXMLLoader loaderPattern = new FXMLLoader(getClass().getResource("/fxml/misc/parts/mining/patternView.fxml"));
|
||||
loaderPattern.setController(this);
|
||||
|
||||
try {
|
||||
loaderPattern.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
ToggleGroup toggleGroup = new ToggleGroup();
|
||||
|
||||
// Set if it is exploitation or exploration pattern
|
||||
if(isExploitation()) {
|
||||
labelExploitation.setText("Exploitation");
|
||||
labelExploitation.getStyleClass().addAll("exploitation");
|
||||
|
||||
labelIndicator.getStyleClass().addAll("exploitation");
|
||||
} else {
|
||||
labelExploitation.setText("Exploration");
|
||||
labelExploitation.getStyleClass().addAll("exploration");
|
||||
|
||||
labelIndicator.getStyleClass().addAll("exploration");
|
||||
}
|
||||
|
||||
labelIndicator.setText(getMostUsefulWeightName());
|
||||
|
||||
// Set the style of the buttons
|
||||
buttonKeep.getStyleClass().addAll("buttonKeep");
|
||||
buttonTrash.getStyleClass().addAll("buttonTrash");
|
||||
|
||||
buttonKeep.setToggleGroup(toggleGroup);
|
||||
buttonTrash.setToggleGroup(toggleGroup);
|
||||
|
||||
labelPattern.setText(pattern.toString());
|
||||
}
|
||||
|
||||
private boolean isExploitation(){
|
||||
int indexAlgoName = OCMManager.algorithmLauncherGetListAlgorithmName().indexOf(pattern.getAlgorithmName());
|
||||
double[] weights = OCMManager.banditGetWeights();
|
||||
|
||||
// Determine if the pattern is from Exploitation or Exploration.
|
||||
boolean isExploitation = true;
|
||||
for(int i = 0; i < weights.length; ++i){
|
||||
if(i != indexAlgoName){
|
||||
isExploitation = isExploitation && (weights[indexAlgoName] > weights[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return isExploitation;
|
||||
}
|
||||
|
||||
private String getMostUsefulWeightName(){
|
||||
String weightName;
|
||||
double[] weightsCoactive = OCMManager.coactiveGetWeights();
|
||||
double[] weightsPattern = pattern.getAttributesVector().getValues();
|
||||
double[] weightsCartesian = new double[weightsCoactive.length];
|
||||
|
||||
if(weightsPattern.length == weightsCoactive.length){
|
||||
for(int i = 0; i < weightsCoactive.length; ++i){
|
||||
weightsCartesian[i] = (weightsPattern[i] != 0d) ? weightsCoactive[i] : 0d;
|
||||
}
|
||||
} else {
|
||||
DebugLogger.printDebug("PatternView: Unable to match the weights of the Coactive Learning and the weight of the Pattern", DebugLogger.MessageSeverity.HIGH);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
double max = weightsCartesian[index];
|
||||
for(int i = 1; i < weightsCartesian.length; ++i){
|
||||
if (weightsCartesian[i] > max){
|
||||
max = weightsCartesian[i];
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (index < Pattern.MeasureType.values().length){
|
||||
weightName = Pattern.MeasureType.getName(index).toString();
|
||||
} else {
|
||||
List<String> listWeightName = new ArrayList<>();
|
||||
for (Pattern.MeasureType measure : Pattern.MeasureType.values()) {
|
||||
listWeightName.add(measure.toString());
|
||||
}
|
||||
listWeightName.addAll(OCMManager.algorithmLauncherGetListAttributeName());
|
||||
listWeightName.addAll(OCMManager.algorithmLauncherGetListAlgorithmName());
|
||||
weightName = listWeightName.get(index);
|
||||
}
|
||||
|
||||
return weightName;
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
public HBox getMainHBox(){
|
||||
return mainHBox;
|
||||
}
|
||||
|
||||
public boolean isKept(){
|
||||
return buttonKeep.isSelected();
|
||||
}
|
||||
|
||||
public boolean isTrashed(){
|
||||
return buttonTrash.isSelected();
|
||||
}
|
||||
|
||||
public int getIndex(){
|
||||
return index;
|
||||
}
|
||||
|
||||
// Setters //
|
||||
|
||||
public void setIsKept(){
|
||||
buttonKeep.setSelected(true);
|
||||
}
|
||||
|
||||
public void setIsTrashed(){
|
||||
buttonTrash.setSelected(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package fr.insa.ocm.view.misc.parts.settings.library;
|
||||
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SettingsRealKDView {
|
||||
|
||||
@FXML private VBox mainVBox = null;
|
||||
|
||||
public SettingsRealKDView(){
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/misc/parts/settings/library/settingsRealKDView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//********** Getters/Setters methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
public VBox getMainVBox(){
|
||||
return mainVBox;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
package fr.insa.ocm.view.misc.parts.settings.library;
|
||||
|
||||
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.wrapper.spmf.AlgorithmLauncherSPMF;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SettingsSPMFView {
|
||||
|
||||
@FXML private VBox mainVBox = null;
|
||||
|
||||
@FXML private TextField minsupLCM = null;
|
||||
@FXML private TextField minsupBIDEPlus = null;
|
||||
@FXML private TextField minsupVMSP = null;
|
||||
@FXML private TextField maxgapVMSP = null;
|
||||
@FXML private TextField minsupPFPM = null;
|
||||
@FXML private TextField minPeriodicity = null;
|
||||
@FXML private TextField maxPeriodicity = null;
|
||||
|
||||
public SettingsSPMFView(){
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/misc/parts/settings/library/settingsSPMFView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//********** Initialization methods **********//
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
minsupLCM.setText(AlgorithmLauncherSPMF.getMinsupLCM() + "");
|
||||
minsupBIDEPlus.setText(AlgorithmLauncherSPMF.getMinsupBIDEPlus() + "");
|
||||
minsupVMSP.setText(AlgorithmLauncherSPMF.getMinsupVMSP() + "");
|
||||
maxgapVMSP.setText(AlgorithmLauncherSPMF.getMaxgapVMSP() + "");
|
||||
minsupPFPM.setText(AlgorithmLauncherSPMF.getMinsupPFPM() + "");
|
||||
minPeriodicity.setText(AlgorithmLauncherSPMF.getMinPeriodicityPFPM() + "");
|
||||
maxPeriodicity.setText(AlgorithmLauncherSPMF.getMaxPeriodicityPFPM() + "");
|
||||
}
|
||||
|
||||
//********** Getters/Setters methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
public VBox getMainVBox(){
|
||||
return mainVBox;
|
||||
}
|
||||
|
||||
public void setSettingsAlgorithmLauncher(){
|
||||
this.setMinsupLCMValue();
|
||||
this.setMinsupBIDEPlusValue();
|
||||
this.setMinsupVMSPValue();
|
||||
this.setMaxgapVMSPValue();
|
||||
this.setMinsupPFPMValue();
|
||||
this.setMinPeriodicityValue();
|
||||
this.setMaxPeriodicityValue();
|
||||
}
|
||||
|
||||
//********** Internal methods **********//
|
||||
|
||||
private void setMinsupLCMValue(){
|
||||
try{
|
||||
AlgorithmLauncherSPMF.setMinsupLCM(Double.valueOf(minsupLCM.getText()));
|
||||
} catch (NumberFormatException e){
|
||||
DebugLogger.printDebug("SettingsSPMFView: Impossible to get the value for the minsupLSM setting", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMinsupBIDEPlusValue(){
|
||||
try{
|
||||
AlgorithmLauncherSPMF.setMinsupBIDEPlus(Double.valueOf(minsupBIDEPlus.getText()));
|
||||
} catch (NumberFormatException e){
|
||||
DebugLogger.printDebug("SettingsSPMFView: Impossible to get the value for the minsupBIDEPlus setting", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMinsupVMSPValue(){
|
||||
try{
|
||||
AlgorithmLauncherSPMF.setMinsupVMSP(Double.valueOf(minsupVMSP.getText()));
|
||||
} catch (NumberFormatException e){
|
||||
DebugLogger.printDebug("SettingsSPMFView: Impossible to get the value for the minsupVMSP setting", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMaxgapVMSPValue(){
|
||||
try{
|
||||
AlgorithmLauncherSPMF.setMaxgapVMSP(Integer.valueOf(maxgapVMSP.getText()));
|
||||
} catch (NumberFormatException e){
|
||||
DebugLogger.printDebug("SettingsSPMFView: Impossible to get the value for the maxgapVMSP setting", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMinsupPFPMValue(){
|
||||
try{
|
||||
AlgorithmLauncherSPMF.setMinsupPFPM(Double.valueOf(minsupPFPM.getText()));
|
||||
} catch (NumberFormatException e){
|
||||
DebugLogger.printDebug("SettingsSPMFView: Impossible to get the value for the minsupPFPM setting", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMinPeriodicityValue(){
|
||||
try{
|
||||
AlgorithmLauncherSPMF.setMinPeriodicityPFPM(Integer.valueOf(minPeriodicity.getText()));
|
||||
} catch (NumberFormatException e){
|
||||
DebugLogger.printDebug("SettingsSPMFView: Impossible to get the value for the minPeriodicity setting", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMaxPeriodicityValue(){
|
||||
try{
|
||||
AlgorithmLauncherSPMF.setMaxPeriodicityPFPM(Integer.valueOf(maxPeriodicity.getText()));
|
||||
} catch (NumberFormatException e){
|
||||
DebugLogger.printDebug("SettingsSPMFView: Impossible to get the value for the maxPeriodicity setting", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package fr.insa.ocm.view.misc.parts.settings.pattern;
|
||||
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.model.wrapper.spmf.AlgorithmLauncherSPMF;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.layout.HBox;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SettingsPatternView {
|
||||
|
||||
@FXML private HBox mainHBox = null;
|
||||
@FXML private CheckBox checkBox = null;
|
||||
|
||||
private Pattern.MeasureType measure;
|
||||
|
||||
public SettingsPatternView(Pattern.MeasureType measure){
|
||||
this.measure = measure;
|
||||
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/misc/parts/settings/pattern/settingsPatternView.fxml"));
|
||||
fxmlLoader.setController(this);
|
||||
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//********** Initialization methods **********//
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
checkBox.setText(measure.toString());
|
||||
|
||||
checkBox.setSelected(AlgorithmLauncherSPMF.getMeasurePatternDescriptor(measure.getIndex()));
|
||||
}
|
||||
|
||||
//********** Getters/Setters methods **********//
|
||||
|
||||
// Getters //
|
||||
|
||||
public HBox getMainHBox(){
|
||||
return mainHBox;
|
||||
}
|
||||
|
||||
public void setMeasureChoice(){
|
||||
AlgorithmLauncherSPMF.setMeasuresPatternDescriptor(checkBox.isSelected(), measure.getIndex());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package fr.insa.ocm.viewmodel;
|
||||
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.wrapper.api.AbstractAlgorithmLauncher;
|
||||
import fr.insa.ocm.view.mainuis.MainView;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class InfoAlgorithm extends Thread {
|
||||
|
||||
private static InfoAlgorithm INSTANCE = new InfoAlgorithm();
|
||||
|
||||
private volatile boolean stopRequested;
|
||||
private volatile boolean paused;
|
||||
|
||||
private InfoAlgorithm(){
|
||||
INSTANCE = this;
|
||||
|
||||
|
||||
stopRequested = false;
|
||||
paused = true;
|
||||
|
||||
INSTANCE.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(){
|
||||
Thread.currentThread().setName("Information Gatherer");
|
||||
|
||||
try {
|
||||
DebugLogger.initializeBanditLog();
|
||||
DebugLogger.initializeCoactiveLog();
|
||||
DebugLogger.initializeAlgorithmLog();
|
||||
DebugLogger.initializeSelectionDistributionLog();
|
||||
} catch (NullPointerException e){
|
||||
DebugLogger.printDebug("InfoAlgorithm: Unable to initialize the bandit or the coactive logger.", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
|
||||
while(!stopRequested){
|
||||
try {
|
||||
changeInfoLabel();
|
||||
DebugLogger.logBandit();
|
||||
DebugLogger.logCoactive();
|
||||
DebugLogger.logAlgorithm();
|
||||
} catch (NullPointerException exception){
|
||||
DebugLogger.printDebug("InfoAlgorithm: Unable to have the informations on the Algorithm Launcher.", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void changeInfoLabel(){
|
||||
MainView mainView = MainView.getCurrentMainView();
|
||||
|
||||
int nbAlgoLaunched = OCMManager.algorithmManagerGetNbAlgoLaunched();
|
||||
int nbPatternFound = OCMManager.algorithmManagerGetNbPatternFound();
|
||||
String status = paused ? "Paused" : "Mining";
|
||||
|
||||
Platform.runLater(() -> mainView.getLabelInfo().setText(
|
||||
"Mining Algorithm status : "+ status + "\n\n" +
|
||||
"Since the last mining round :\n "+
|
||||
nbAlgoLaunched+" algorithms have been launched\n "+
|
||||
nbPatternFound+" patterns have been found"));
|
||||
}
|
||||
|
||||
|
||||
static void requestStop(){
|
||||
INSTANCE.stopRequested = true;
|
||||
}
|
||||
|
||||
public static void setPaused(boolean isPaused){
|
||||
INSTANCE.paused = isPaused;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
package fr.insa.ocm.viewmodel;
|
||||
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.wrapper.api.AbstractAlgorithmLauncher;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Monitor extends Thread {
|
||||
|
||||
private static Monitor INSTANCE;
|
||||
|
||||
// Monitor some stats about the launched algorithms
|
||||
private SimpleStringProperty monitorAlgorithmsLaunched;
|
||||
private SimpleStringProperty monitorBanditWeight;
|
||||
private SimpleStringProperty monitorCoactiveWeight;
|
||||
|
||||
private static boolean stopRequested = false;
|
||||
private static boolean paused = false;
|
||||
|
||||
private Monitor() {
|
||||
monitorAlgorithmsLaunched = new SimpleStringProperty("");
|
||||
monitorBanditWeight = new SimpleStringProperty("");
|
||||
monitorCoactiveWeight = new SimpleStringProperty("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (!stopRequested) {
|
||||
if(!paused) {
|
||||
monitorAlgorithmCalls();
|
||||
monitorBanditWeight();
|
||||
monitorCoactiveWeights();
|
||||
}
|
||||
|
||||
DebugLogger.printDebug("Monitor: Stats refreshed.");
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
} catch (InterruptedException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void monitorAlgorithmCalls() {
|
||||
final Map<String, Integer> mapStatsAlgorithmsLaunched = AbstractAlgorithmLauncher.getStatsAlgorithmsLaunched();
|
||||
List<String> listAlgorithmUsed = OCMManager.algorithmLauncherGetListAlgorithmName();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for(String algorithmName : mapStatsAlgorithmsLaunched.keySet()){
|
||||
if(listAlgorithmUsed.contains(algorithmName)) {
|
||||
stringBuilder.append("The algorithm named: ");
|
||||
stringBuilder.append(algorithmName);
|
||||
stringBuilder.append(" has been launched ");
|
||||
stringBuilder.append(mapStatsAlgorithmsLaunched.get(algorithmName));
|
||||
stringBuilder.append(" times.\n");
|
||||
}
|
||||
}
|
||||
|
||||
Platform.runLater(() -> monitorAlgorithmsLaunched.set(stringBuilder.toString()));
|
||||
}
|
||||
|
||||
private void monitorBanditWeight() {
|
||||
double[] banditWeights = OCMManager.banditGetWeights();
|
||||
List<String> algorithmNames = OCMManager.algorithmLauncherGetListAlgorithmName();
|
||||
|
||||
if (banditWeights.length == algorithmNames.size()) {
|
||||
Platform.runLater(() -> monitorBanditWeight.set(makeText(banditWeights, algorithmNames)));
|
||||
} else {
|
||||
DebugLogger.printDebug("Monitor: Unable to match the size of the bandit weights with the number of algorithms", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
private void monitorCoactiveWeights() {
|
||||
double[] coactiveWeights = OCMManager.coactiveGetWeights();
|
||||
List<String> names = new ArrayList<>();
|
||||
|
||||
for(Pattern.MeasureType measure : Pattern.MeasureType.values()){
|
||||
names.add(measure.toString());
|
||||
}
|
||||
names.addAll(OCMManager.algorithmLauncherGetListAttributeName());
|
||||
names.addAll(OCMManager.algorithmLauncherGetListAlgorithmName());
|
||||
|
||||
if(coactiveWeights.length == names.size()){
|
||||
Platform.runLater(() -> monitorCoactiveWeight.set(makeText(coactiveWeights, names)));
|
||||
} else {
|
||||
DebugLogger.printDebug("Monitor: Unable to match the size of the coactive weights and the names associated", DebugLogger.MessageSeverity.MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String makeText(double[] weights, List<String> names){
|
||||
StringBuilder strBuild = new StringBuilder("");
|
||||
DecimalFormat decimalFormat = new DecimalFormat("#0.0000");
|
||||
|
||||
for(int i = 0; i < weights.length; ++i){
|
||||
strBuild.append(names.get(i));
|
||||
strBuild.append(" has a coefficient of ");
|
||||
strBuild.append(decimalFormat.format(weights[i]));
|
||||
strBuild.append(".\n");
|
||||
}
|
||||
|
||||
return strBuild.toString();
|
||||
}
|
||||
|
||||
public static void startMonitoring(){
|
||||
INSTANCE = new Monitor();
|
||||
INSTANCE.setDaemon(true);
|
||||
INSTANCE.setName("Monitor");
|
||||
INSTANCE.start();
|
||||
}
|
||||
|
||||
public static void pauseMonitoring(){
|
||||
paused = true;
|
||||
}
|
||||
|
||||
public static void resumeMonitoring(){
|
||||
paused = false;
|
||||
}
|
||||
|
||||
public static void requestStop(){
|
||||
stopRequested = true;
|
||||
}
|
||||
|
||||
public static SimpleStringProperty getMonitorAlgorithmsLaunched(){
|
||||
return INSTANCE.monitorAlgorithmsLaunched;
|
||||
}
|
||||
|
||||
public static SimpleStringProperty getMonitorBanditWeights(){
|
||||
return INSTANCE.monitorBanditWeight;
|
||||
}
|
||||
|
||||
public static SimpleStringProperty getMonitorCoactiveWeights(){
|
||||
return INSTANCE.monitorCoactiveWeight;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,320 @@
|
|||
package fr.insa.ocm.viewmodel;
|
||||
|
||||
import fr.insa.ocm.model.DebugLogger;
|
||||
import fr.insa.ocm.model.OCMManager;
|
||||
import fr.insa.ocm.model.oneclicklearning.cache.api.Cache;
|
||||
import fr.insa.ocm.model.oneclicklearning.coactivelearning.api.CoactiveLearning;
|
||||
import fr.insa.ocm.model.utils.fastforward.FastForward;
|
||||
import fr.insa.ocm.model.wrapper.api.Pattern;
|
||||
import fr.insa.ocm.view.misc.FastForwardWaitingView;
|
||||
import fr.insa.ocm.model.utils.fastforward.condition.Condition;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OCLController {
|
||||
|
||||
public static final String VERSION = "0.5.0.1";
|
||||
|
||||
private static OCLController INSTANCE = new OCLController();
|
||||
|
||||
private volatile boolean stopRequested = false;
|
||||
|
||||
private List<Pattern> interestingPattern;
|
||||
private List<Pattern> neutralPattern;
|
||||
private List<Pattern> trashedPattern;
|
||||
|
||||
private String pathDataFile = null;
|
||||
|
||||
// Keeps a track of the last fastforward done.
|
||||
private FastForward fastForward;
|
||||
|
||||
// Settings of the controller
|
||||
private Pattern.WrapperType wrapperTypeSelected;
|
||||
private CoactiveLearning.CoactiveType coactiveLearningSelected;
|
||||
private Cache.CacheType cacheTypeSelected;
|
||||
|
||||
//This constructor is valid only if used by the Application launcher
|
||||
private OCLController(){
|
||||
INSTANCE = this;
|
||||
|
||||
interestingPattern = new ArrayList<>();
|
||||
neutralPattern = new ArrayList<>();
|
||||
trashedPattern = new ArrayList<>();
|
||||
|
||||
// Initializing default settings
|
||||
wrapperTypeSelected = Pattern.WrapperType.SPMF;
|
||||
coactiveLearningSelected = CoactiveLearning.CoactiveType.SET;
|
||||
cacheTypeSelected = Cache.CacheType.SET;
|
||||
}
|
||||
|
||||
//********** Initializing Methods **********//
|
||||
|
||||
public static void initialize(String pathDataFile){
|
||||
DebugLogger.printDebug("OCLController: Initializing.");
|
||||
OCMManager.initialize(INSTANCE.wrapperTypeSelected, pathDataFile);
|
||||
OCMManager.algorithmManagerStartMining();
|
||||
|
||||
INSTANCE.pathDataFile = pathDataFile;
|
||||
|
||||
InfoAlgorithm.setPaused(false);
|
||||
Monitor.startMonitoring();
|
||||
|
||||
INSTANCE.waitForOCMResults();
|
||||
|
||||
DebugLogger.printDebug("OCLController: initialized correctly.");
|
||||
}
|
||||
|
||||
public static void reload(String pathDataFile){
|
||||
DebugLogger.printDebug("OCLController: Reloading OCLController.");
|
||||
Monitor.pauseMonitoring();
|
||||
OCMManager.requestStop();
|
||||
|
||||
INSTANCE.stopRequested = false;
|
||||
|
||||
INSTANCE.interestingPattern = new ArrayList<>();
|
||||
INSTANCE.neutralPattern = new ArrayList<>();
|
||||
INSTANCE.trashedPattern = new ArrayList<>();
|
||||
|
||||
INSTANCE.pathDataFile = pathDataFile;
|
||||
|
||||
DebugLogger.printDebug("OCLController: Reloading OCMManager.");
|
||||
OCMManager.reload(INSTANCE.wrapperTypeSelected, INSTANCE.cacheTypeSelected, INSTANCE.coactiveLearningSelected, pathDataFile);
|
||||
OCMManager.algorithmManagerStartMining();
|
||||
|
||||
Monitor.resumeMonitoring();
|
||||
|
||||
INSTANCE.waitForOCMResults();
|
||||
|
||||
DebugLogger.printDebug("OCLController: Reloaded correctly.");
|
||||
}
|
||||
|
||||
//********** Public Methods **********//
|
||||
|
||||
public static void exportInterestingPatterns(String pathFile){
|
||||
List<Pattern> patterns = OCMManager.patternWarehouseGetPatterns();
|
||||
|
||||
BufferedWriter writerTXT = null;
|
||||
try {
|
||||
writerTXT = new BufferedWriter(new FileWriter(new File(pathFile)));
|
||||
writerTXT.write("Interesting patterns:");
|
||||
writerTXT.newLine();
|
||||
writerTXT.write("---------------------");
|
||||
writerTXT.newLine();
|
||||
|
||||
for(Pattern p : patterns){
|
||||
String toWrite = p.toString();
|
||||
writerTXT.write(toWrite);
|
||||
writerTXT.newLine();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(writerTXT != null){
|
||||
try {
|
||||
writerTXT.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//********** Fast Forward Methods **********//
|
||||
|
||||
public static void fastForward(int numberRounds, double numberSecPerRound, List<Condition> listConditions,
|
||||
FastForwardWaitingView fastForwardWaitingView,
|
||||
Condition.ActionPatternChoice conditionPriority){
|
||||
|
||||
FastForward fastForward = new FastForward(numberRounds, numberSecPerRound,
|
||||
listConditions,
|
||||
conditionPriority,
|
||||
INSTANCE.interestingPattern,
|
||||
INSTANCE.neutralPattern,
|
||||
INSTANCE.trashedPattern);
|
||||
|
||||
INSTANCE.fastForward = fastForward;
|
||||
|
||||
final StringProperty currentOperation = new SimpleStringProperty("");
|
||||
final StringProperty remainingTime = new SimpleStringProperty("");
|
||||
final DoubleProperty progressLearning = new SimpleDoubleProperty(0d);
|
||||
final DoubleProperty progressMining = new SimpleDoubleProperty(0d);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
fastForwardWaitingView.bindCurrentOperation(currentOperation);
|
||||
fastForwardWaitingView.bindCurrentTime(remainingTime);
|
||||
fastForwardWaitingView.bindProgressLearning(progressLearning);
|
||||
fastForwardWaitingView.bindProgressMining(progressMining);
|
||||
});
|
||||
|
||||
Thread threadFF = new Thread(fastForward);
|
||||
threadFF.setName("FastForward");
|
||||
threadFF.setDaemon(true);
|
||||
threadFF.start();
|
||||
|
||||
try {
|
||||
while (!fastForward.isFinished()) {
|
||||
String strCurrentOperation = fastForward.getCurrentOperation();
|
||||
String strRemainingTime = fastForward.getRemainingTime();
|
||||
Double dProgressLearning = fastForward.getProgressLearning();
|
||||
Double dProgressMining = fastForward.getProgressMining();
|
||||
|
||||
Platform.runLater(() -> {
|
||||
currentOperation.setValue("Current Operation: "+ strCurrentOperation + ".");
|
||||
remainingTime.setValue("Estimated time before completion: "+ strRemainingTime);
|
||||
progressLearning.setValue(dProgressLearning);
|
||||
progressMining.setValue(dProgressMining);
|
||||
});
|
||||
Thread.sleep(100);
|
||||
}
|
||||
} catch (InterruptedException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// final int nbIter = 100;
|
||||
// try {
|
||||
// for (int i = 0; i < nbRound && !INSTANCE.stopRequested && !INSTANCE.ffStopRequested; ++i) {
|
||||
// fastForwardWaitingView.setCurrentOperation("Mining");
|
||||
// for (int j = 0; j < nbIter && !INSTANCE.stopRequested && !INSTANCE.ffStopRequested; ++j) {
|
||||
// Thread.sleep((long)secPerRound*1000/nbIter);
|
||||
// double pbm = (j+1.)/nbIter;
|
||||
// fastForwardWaitingView.setProgressBarMining(pbm);
|
||||
//
|
||||
// int remainingTimeSec = (int)((nbRound-i) * secPerRound - (secPerRound/nbIter) * j);
|
||||
// fastForwardWaitingView.setCurrentTime(remainingTimeSec/60 + " min " + remainingTimeSec%60 + " sec");
|
||||
// }
|
||||
//
|
||||
// // We process the data gathered by the mining algorithms.
|
||||
// fastForwardWaitingView.setCurrentOperation("Processing data");
|
||||
//
|
||||
//
|
||||
//
|
||||
// Rank<Pattern> rank = OCMManager.getNewRanking(INSTANCE.interestingPattern, INSTANCE.neutralPattern, INSTANCE.trashedPattern);
|
||||
// Rank<Pattern> rawRank = new Rank<>(rank);
|
||||
//
|
||||
// if(mainPriority.equals(Condition.ActionPatternChoice.TRASH)){
|
||||
// INSTANCE.trashedPattern = computeListPattern(rank, rawRank, listCondition, Condition.ActionPatternChoice.TRASH);
|
||||
// rank.removeAll(INSTANCE.trashedPattern);
|
||||
// INSTANCE.interestingPattern = computeListPattern(rank, rawRank, listCondition, Condition.ActionPatternChoice.KEEP);
|
||||
// rank.removeAll(INSTANCE.interestingPattern);
|
||||
// INSTANCE.neutralPattern = new ArrayList<>(rank);
|
||||
// }else{
|
||||
// INSTANCE.interestingPattern = computeListPattern(rank, rawRank, listCondition, Condition.ActionPatternChoice.KEEP);
|
||||
// rank.removeAll(INSTANCE.interestingPattern);
|
||||
// INSTANCE.trashedPattern = computeListPattern(rank, rawRank, listCondition, Condition.ActionPatternChoice.TRASH);
|
||||
// rank.removeAll(INSTANCE.trashedPattern);
|
||||
// INSTANCE.neutralPattern = new ArrayList<>(rank);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// // Print in the error channel the results of the automated selection.
|
||||
//
|
||||
// System.err.println("Kept Patterns :");
|
||||
// INSTANCE.interestingPattern.forEach(System.err::println);
|
||||
// System.err.println("Neutral Patterns :");
|
||||
// INSTANCE.neutralPattern.forEach(System.err::println);
|
||||
// System.err.println("Trashed Patterns :");
|
||||
// INSTANCE.trashedPattern.forEach(System.err::println);
|
||||
// System.err.println("");
|
||||
//
|
||||
// int nbPatternRank = rawRank.size();
|
||||
// double nbQuality = INSTANCE.interestingPattern.size() - INSTANCE.trashedPattern.size();
|
||||
// DebugLogger.printQuality(i +";"+ ((nbQuality/nbPatternRank)+1)/2);
|
||||
//
|
||||
// double pbr = (i+1.)/nbRound;
|
||||
// fastForwardWaitingView.setProgressBarRound(pbr);
|
||||
// }
|
||||
// fastForwardWaitingView.setCurrentOperation("Finished");
|
||||
// fastForwardWaitingView.setCurrentTime("Finished");
|
||||
// MainView.getCurrentMainView().refreshKeptPatternsList();
|
||||
// }catch(InterruptedException e){
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
fastForwardWaitingView.setHasFinished(true);
|
||||
}
|
||||
|
||||
//********** Internal Methods **********//
|
||||
|
||||
private void waitForOCMInitialization(){
|
||||
try {
|
||||
while(!OCMManager.isInitialized() || !OCMManager.algorithmManagerIsMining()){
|
||||
Thread.sleep(500);
|
||||
if(stopRequested){
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void waitForOCMResults(){
|
||||
// try{
|
||||
// DebugLogger.printDebug("OCLController: Trying to find better result.");
|
||||
// Rank<Pattern> rank = OCMManager.getNewRanking(interestingPattern, neutralPattern, trashedPattern);
|
||||
// while (rank.size() <= 0){
|
||||
// Thread.sleep(250);
|
||||
// DebugLogger.printDebug("OCLController: Trying to find better result.");
|
||||
// rank = OCMManager.getNewRanking(interestingPattern, neutralPattern, trashedPattern);
|
||||
// if(stopRequested){
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// synchronized (OCLController.class) {
|
||||
// userRank.clear();
|
||||
// userRank.addAll(rank);
|
||||
// }
|
||||
// } catch (InterruptedException e){
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
}
|
||||
|
||||
//********** Getters/Setters Methods **********//
|
||||
|
||||
// Getters //
|
||||
public static String getPathDataFile(){
|
||||
return INSTANCE.pathDataFile;
|
||||
}
|
||||
|
||||
// Setters //
|
||||
public static void setPatternList(List<Pattern> interestingPattern, List<Pattern> neutralPattern, List<Pattern> trashedPattern){
|
||||
INSTANCE.interestingPattern = interestingPattern;
|
||||
INSTANCE.neutralPattern = neutralPattern;
|
||||
INSTANCE.trashedPattern = trashedPattern;
|
||||
}
|
||||
|
||||
public static void setWrapperType(Pattern.WrapperType wrapperType){
|
||||
INSTANCE.wrapperTypeSelected = wrapperType;
|
||||
}
|
||||
|
||||
//********** Request From View Methods **********//
|
||||
|
||||
public static List<Pattern> getUserRank(){
|
||||
return OCMManager.getNewRanking(INSTANCE.interestingPattern, INSTANCE.neutralPattern, INSTANCE.trashedPattern);
|
||||
}
|
||||
|
||||
public static void requestStop(){
|
||||
INSTANCE.stopRequested = true;
|
||||
DebugLogger.printDebug("OCLController: Stopping the controller.");
|
||||
OCMManager.requestStop();
|
||||
InfoAlgorithm.requestStop();
|
||||
Monitor.requestStop();
|
||||
}
|
||||
|
||||
public static void requestFFStop(){
|
||||
DebugLogger.printDebug("OCLController: Stopping the Fast Forward.");
|
||||
INSTANCE.fastForward.setStopRequested();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*noinspection CssUnusedSymbol*/
|
||||
.buttonKeep:pressed{
|
||||
-fx-base: lightgreen;
|
||||
}
|
||||
|
||||
/*noinspection CssUnusedSymbol*/
|
||||
.buttonKeep:selected{
|
||||
-fx-base: lightgreen;
|
||||
}
|
||||
|
||||
/*noinspection CssUnusedSymbol*/
|
||||
.buttonTrash:pressed{
|
||||
-fx-base: salmon;
|
||||
}
|
||||
|
||||
/*noinspection CssUnusedSymbol*/
|
||||
.buttonTrash:selected{
|
||||
-fx-base: salmon;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
.exploitation{
|
||||
-fx-background-color: #92d623;
|
||||
-fx-border-color: black
|
||||
}
|
||||
|
||||
.exploration{
|
||||
-fx-background-color: #58cde0;
|
||||
-fx-border-color: black
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<VBox fx:id="mainVBox" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
|
||||
prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<ScrollPane fx:id="scrollPaneData" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
|
||||
VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0"/>
|
||||
</VBox.margin>
|
||||
<GridPane fx:id="gridPaneData">
|
||||
</GridPane>
|
||||
</ScrollPane>
|
||||
<Separator maxWidth="1.7976931348623157E308" prefWidth="200.0">
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" top="10.0"/>
|
||||
</VBox.margin>
|
||||
</Separator>
|
||||
<Button fx:id="buttonClose" cancelButton="true" defaultButton="true" maxWidth="1.7976931348623157E308"
|
||||
mnemonicParsing="false" text="Close">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
</VBox>
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ChoiceBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.Menu?>
|
||||
<?import javafx.scene.control.MenuBar?>
|
||||
<?import javafx.scene.control.MenuItem?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox fx:id="mainVBox" alignment="CENTER" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<MenuBar>
|
||||
<menus>
|
||||
<Menu mnemonicParsing="false" text="Save/Load Conditions">
|
||||
<items>
|
||||
<MenuItem fx:id="menuItemSave" mnemonicParsing="false" onAction="#menuItemSaveSelected" text="Save Conditions" />
|
||||
<MenuItem fx:id="menuItemLoad" mnemonicParsing="false" onAction="#menuItemLoadSelected" text="Load Conditions" />
|
||||
</items>
|
||||
</Menu>
|
||||
</menus>
|
||||
</MenuBar>
|
||||
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" text="Launch a series of mining round all at once with specific settings. First, tell if you want to always keep or trash a pattern if it has a specific attribute. Then, tell if you want to keep or trash automatically according to any pattern measurement." wrapText="true" VBox.vgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<HBox alignment="CENTER" maxWidth="1.7976931348623157E308" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
<Label maxHeight="1.7976931348623157E308" text="When the fast forward encounter a conflit between keep and trash, the priority is : " wrapText="true" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<ChoiceBox fx:id="choiceBoxKeepTrash" maxHeight="1.7976931348623157E308" prefWidth="150.0" HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
</ChoiceBox>
|
||||
</HBox>
|
||||
<ListView fx:id="listViewMeasure" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</VBox.margin>
|
||||
</ListView>
|
||||
<HBox alignment="CENTER" maxWidth="1.7976931348623157E308" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
<Label maxHeight="1.7976931348623157E308" text="Number of round to launch automatically : " wrapText="true" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<TextField fx:id="textFieldNumberRound" maxHeight="1.7976931348623157E308" promptText="Any Value">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
</TextField>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER" maxWidth="1.7976931348623157E308" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
<Label maxHeight="1.7976931348623157E308" text="Number of seconds between each learning round : " wrapText="true" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<TextField fx:id="textFieldSecondPerRound" maxHeight="1.7976931348623157E308" promptText="Any Value">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
</TextField>
|
||||
</HBox>
|
||||
<Button fx:id="buttonLaunch" maxHeight="1.7976931348623157E308" mnemonicParsing="false" text="Launch" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</VBox.margin>
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0" />
|
||||
</font>
|
||||
</Button>
|
||||
</VBox>
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<BorderPane fx:id="mainPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<center>
|
||||
<GridPane BorderPane.alignment="CENTER">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="40.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="60.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<VBox maxHeight="1.7976931348623157E308" prefWidth="100.0">
|
||||
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="Kept patterns" textAlignment="CENTER">
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<ListView fx:id="listKeptPatterns" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</ListView>
|
||||
</VBox>
|
||||
<VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" GridPane.columnIndex="1">
|
||||
<GridPane.margin>
|
||||
<Insets />
|
||||
</GridPane.margin>
|
||||
<HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
<Button fx:id="buttonMining" alignment="CENTER" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Gather Knowledge" textAlignment="CENTER" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0" />
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
<Button fx:id="buttonPause" maxHeight="1.7976931348623157E308" mnemonicParsing="false" text="{RESUME/PAUSE}" HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0" />
|
||||
</font>
|
||||
</Button>
|
||||
</HBox>
|
||||
<Button fx:id="buttonFastForward" maxHeight="1.7976931348623157E308" mnemonicParsing="false" text="Fast Forward" VBox.vgrow="ALWAYS">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
<Separator maxHeight="1.7976931348623157E308" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Separator>
|
||||
<Label fx:id="labelInfo" maxHeight="1.7976931348623157E308" text="Waiting for the data... Please go to File and Import a CSV file to start the mining process. Then you can gather knowledge." wrapText="true" VBox.vgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<Separator maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" VBox.vgrow="ALWAYS" />
|
||||
<Button fx:id="buttonData" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="View data" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
</VBox>
|
||||
|
||||
</GridPane>
|
||||
</center>
|
||||
</BorderPane>
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox fx:id="mainVBox" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
|
||||
prefHeight="550.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8.0.112"
|
||||
xmlns:fx="http://javafx.com/fxml/1">
|
||||
<Label fx:id="labelRound" alignment="CENTER" contentDisplay="CENTER" maxWidth="1.7976931348623157E308"
|
||||
text="{ROUND N}">
|
||||
<font>
|
||||
<Font name="System Bold" size="24.0"/>
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<Separator maxWidth="1.7976931348623157E308">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Separator>
|
||||
<!--
|
||||
<GridPane fx:id="patternGrid" gridLinesVisible="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="10.0" prefWidth="440.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="75.0" minWidth="75.0" prefWidth="75.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="75.0" minWidth="10.0" prefWidth="75.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
<children>
|
||||
|
||||
</children>
|
||||
</GridPane>
|
||||
-->
|
||||
<ListView fx:id="listProposedPatterns" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
|
||||
VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="5.0" right="5.0" top="10.0"/>
|
||||
</VBox.margin>
|
||||
</ListView>
|
||||
<Separator maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="15.0" prefWidth="600.0"
|
||||
VBox.vgrow="ALWAYS"/>
|
||||
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</VBox.margin>
|
||||
<Button fx:id="buttonSetKeep" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Set Keep"
|
||||
HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets left="10.0" right="10.0"/>
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
<Separator maxWidth="1.7976931348623157E308" orientation="VERTICAL" HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets left="5.0" right="5.0"/>
|
||||
</HBox.margin>
|
||||
</Separator>
|
||||
<Button fx:id="buttonConfirm" alignment="CENTER" contentDisplay="CENTER" maxWidth="1.7976931348623157E308"
|
||||
mnemonicParsing="false" nodeOrientation="LEFT_TO_RIGHT" text="Confirm" textAlignment="CENTER"
|
||||
HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets left="10.0" right="10.0"/>
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
<Separator maxWidth="1.7976931348623157E308" orientation="VERTICAL" HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets left="5.0" right="5.0"/>
|
||||
</HBox.margin>
|
||||
</Separator>
|
||||
<Button fx:id="buttonSetTrash" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Set Trash"
|
||||
HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets left="10.0" right="10.0"/>
|
||||
</HBox.margin>
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0"/>
|
||||
</font>
|
||||
</Button>
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<VBox fx:id="mainVBox" alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="100.0" prefWidth="300.0" spacing="15.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<Label fx:id="errorLabel" text="Error" wrapText="true" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets left="10.0" right="10.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<Button fx:id="closeButton" maxHeight="1.7976931348623157E308" mnemonicParsing="false" text="OK" textAlignment="CENTER">
|
||||
<VBox.margin>
|
||||
<Insets left="10.0" right="10.0" />
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
</VBox>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ProgressBar?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox fx:id="mainVBox" alignment="CENTER" prefHeight="300.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="Please wait while the software is currently mining." VBox.vgrow="ALWAYS">
|
||||
<font>
|
||||
<Font name="System Bold" size="16.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<Separator maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Separator>
|
||||
<Label fx:id="labelCurrentOperation" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="{CURRENT OPERATION}" VBox.vgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<ProgressBar fx:id="progressBarMining" maxWidth="1.7976931348623157E308" progress="0.0">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="20.0" right="20.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</ProgressBar>
|
||||
<Label fx:id="labelTime" alignment="CENTER" contentDisplay="CENTER" maxWidth="1.7976931348623157E308" text="{REMAINING TIME}" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<ProgressBar fx:id="progressBarRound" maxWidth="1.7976931348623157E308" progress="0.0">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="20.0" right="20.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</ProgressBar>
|
||||
<Separator prefWidth="200.0" />
|
||||
<Button fx:id="buttonAbortFinish" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" text="{ABORT/FINISHED}" textAlignment="CENTER" VBox.vgrow="ALWAYS">
|
||||
<font>
|
||||
<Font name="System Bold" size="15.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
</VBox>
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ProgressBar?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
|
||||
<VBox fx:id="mainVBox" prefHeight="100.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/8.0.112"
|
||||
xmlns:fx="http://javafx.com/fxml/1">
|
||||
<Label fx:id="labelInfo" alignment="CENTER" maxWidth="1.7976931348623157E308" text="{MANY INFO HERE}"
|
||||
wrapText="true" VBox.vgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="14.0"/>
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</VBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<ProgressBar fx:id="progressBar" maxWidth="1.7976931348623157E308" progress="0.0">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</VBox.margin>
|
||||
</ProgressBar>
|
||||
<Button fx:id="buttonContinue" defaultButton="true" maxWidth="1.7976931348623157E308" mnemonicParsing="false"
|
||||
text="Continue">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</VBox.margin>
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0"/>
|
||||
</font>
|
||||
</Button>
|
||||
</VBox>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox fx:id="mainVBox" alignment="CENTER" prefHeight="300.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<Label alignment="TOP_CENTER" text="OneClick Mining" VBox.vgrow="ALWAYS">
|
||||
<font>
|
||||
<Font name="Serif Bold" size="36.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="20.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<Separator prefWidth="200.0">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Separator>
|
||||
<Label fx:id="versionLabel" text="VERSION">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<Label fx:id="presentationLabel" text="The software OneClick Mining is a project of the team LACODAM located in the reseach laboratory IRISA. Contributors: Violaine Fabry, Gregory Martin" textOverrun="CLIP" wrapText="true">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<Separator maxHeight="1.7976931348623157E308" prefWidth="200.0" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Separator>
|
||||
<Button fx:id="closeButton" alignment="CENTER" cancelButton="true" contentDisplay="CENTER" defaultButton="true" mnemonicParsing="false" nodeOrientation="LEFT_TO_RIGHT" text="Close">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
</VBox>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox fx:id="mainVBox" alignment="TOP_CENTER" prefHeight="300.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<Button fx:id="buttonSearch" mnemonicParsing="false" text="Import Previous Search" textAlignment="CENTER" wrapText="true">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
<Label fx:id="labelSearch" text="{PATH TO PREVIOUS SEARCH}" wrapText="true">
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<Separator maxHeight="1.7976931348623157E308" prefWidth="200.0" VBox.vgrow="ALWAYS" />
|
||||
<Button fx:id="buttonData" mnemonicParsing="false" text="Import Previous Data" textAlignment="CENTER" wrapText="true">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
<Label fx:id="labelData" text="{PATH TO PREVIOUS DATA}" wrapText="true">
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<Separator maxHeight="1.7976931348623157E308" prefWidth="200.0" VBox.vgrow="ALWAYS" />
|
||||
<Button fx:id="buttonLoad" defaultButton="true" disable="true" mnemonicParsing="false" text="Load Files" VBox.vgrow="ALWAYS">
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
</VBox>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox fx:id="mainVBox" alignment="CENTER" prefHeight="200.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<ScrollPane VBox.vgrow="ALWAYS">
|
||||
<content>
|
||||
<VBox alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
|
||||
<children>
|
||||
<Label fx:id="labelInfo" alignment="CENTER_RIGHT" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="{ALGORITHM INFORMATIONS}" wrapText="true">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
</content>
|
||||
</ScrollPane>
|
||||
<Button fx:id="buttonClose" alignment="CENTER" cancelButton="true" contentDisplay="CENTER" defaultButton="true" mnemonicParsing="false" text="Close" textAlignment="CENTER" VBox.vgrow="ALWAYS">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
<font>
|
||||
<Font name="System Bold" size="15.0" />
|
||||
</font>
|
||||
</Button>
|
||||
</VBox>
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ChoiceBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.control.Tab?>
|
||||
<?import javafx.scene.control.TabPane?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox fx:id="mainVBox" alignment="TOP_CENTER" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Label text="Settings">
|
||||
<font>
|
||||
<Font name="System Bold" size="24.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<Separator prefWidth="200.0">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Separator>
|
||||
<HBox alignment="CENTER" prefWidth="200.0">
|
||||
<children>
|
||||
<Label text="Choose the library you want to use :">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<ChoiceBox fx:id="choiceBoxWrapper">
|
||||
<HBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</HBox.margin>
|
||||
</ChoiceBox>
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</HBox>
|
||||
<TabPane prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" VBox.vgrow="ALWAYS">
|
||||
<tabs>
|
||||
<Tab text="Library">
|
||||
<content>
|
||||
<ScrollPane fx:id="paneSettings" maxWidth="1.7976931348623157E308" />
|
||||
</content>
|
||||
</Tab>
|
||||
<Tab text="Pattern">
|
||||
<content>
|
||||
<VBox prefHeight="200.0" prefWidth="100.0">
|
||||
<children>
|
||||
<HBox maxWidth="1.7976931348623157E308">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
<children>
|
||||
<Label maxHeight="1.7976931348623157E308" text="Number of Patterns per ranking :">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<TextField fx:id="textFieldNumberPattern" promptText="Any Positive Value" text="10" />
|
||||
</children>
|
||||
</HBox>
|
||||
<Separator prefWidth="200.0">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Separator>
|
||||
<ListView fx:id="listViewPattern" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" />
|
||||
</children>
|
||||
</VBox>
|
||||
</content>
|
||||
</Tab>
|
||||
</tabs>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</TabPane>
|
||||
<HBox alignment="CENTER" maxWidth="1.7976931348623157E308">
|
||||
<children>
|
||||
<Button fx:id="buttonConfirm" defaultButton="true" mnemonicParsing="false" text="Confirm">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
<Button fx:id="buttonCancel" cancelButton="true" mnemonicParsing="false" text="Cancel">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</HBox>
|
||||
</children>
|
||||
</VBox>
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<?import javafx.scene.control.ChoiceBox?>
|
||||
<HBox fx:id="mainHBox" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<ChoiceBox fx:id="choiceBoxCondition" maxHeight="1.7976931348623157E308" HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</ChoiceBox>
|
||||
<Button fx:id="buttonAddCondition" mnemonicParsing="false" text="Add Condition" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="14.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
</HBox>
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ChoiceBox?>
|
||||
<?import javafx.scene.control.ToggleButton?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
|
||||
<HBox fx:id="mainHBox" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" text="If the pattern"
|
||||
HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="18.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<ChoiceBox fx:id="choiceBoxAlgorithmState" maxHeight="1.7976931348623157E308" HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</ChoiceBox>
|
||||
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" text="by" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="18.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<ChoiceBox fx:id="choiceBoxAlgorithmName" maxHeight="1.7976931348623157E308" HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</ChoiceBox>
|
||||
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" text="then"
|
||||
HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="18.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<ToggleButton fx:id="buttonAlwaysKeep" mnemonicParsing="false" text="Always Keep">
|
||||
<font>
|
||||
<Font size="14.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</ToggleButton>
|
||||
<ToggleButton fx:id="buttonAlwaysTrash" mnemonicParsing="false" text="Always Trash">
|
||||
<font>
|
||||
<Font size="14.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</ToggleButton>
|
||||
<Separator maxHeight="1.7976931348623157E308" orientation="VERTICAL" HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets left="10.0" right="10.0"/>
|
||||
</HBox.margin>
|
||||
</Separator>
|
||||
<Button fx:id="buttonRemoveCondition" mnemonicParsing="false" text="Remove Condition" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="14.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
</HBox>
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.control.ToggleButton?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
|
||||
<?import javafx.scene.control.ChoiceBox?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<HBox fx:id="mainHBox" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" text="If" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="18.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<ChoiceBox fx:id="choiceBoxAttributeName" maxHeight="1.7976931348623157E308" HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</ChoiceBox>
|
||||
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" text="is" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="18.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<ChoiceBox fx:id="choiceBoxAttributeState" maxHeight="1.7976931348623157E308" HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</ChoiceBox>
|
||||
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" text="then"
|
||||
HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="18.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<ToggleButton fx:id="buttonAlwaysKeep" mnemonicParsing="false" text="Always Keep">
|
||||
<font>
|
||||
<Font size="14.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</ToggleButton>
|
||||
<ToggleButton fx:id="buttonAlwaysTrash" mnemonicParsing="false" text="Always Trash">
|
||||
<font>
|
||||
<Font size="14.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</ToggleButton>
|
||||
<Separator maxHeight="1.7976931348623157E308" orientation="VERTICAL" HBox.hgrow="ALWAYS">
|
||||
<HBox.margin>
|
||||
<Insets left="10.0" right="10.0"/>
|
||||
</HBox.margin>
|
||||
</Separator>
|
||||
<Button fx:id="buttonRemoveCondition" mnemonicParsing="false" text="Remove Condition" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="14.0"/>
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
</HBox>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue