add QTableFrame and clickable states that display a gui

- remove org.javaTuple in favour of org.apache.common for tuples and circleQueue
- remove ViewListener from non-GUI Controller
- stateActionTable saves the last 10 states that changed. They will get displayed in QTable Frame
in JTextAreas
This commit is contained in:
2020-01-01 23:54:18 +01:00
parent a8f8af1102
commit f4f1f7bd37
16 changed files with 334 additions and 136 deletions
+45 -60
View File
@@ -15,10 +15,9 @@ import lombok.Setter;
import javax.swing.*;
import java.io.*;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class RLController<A extends Enum> implements ViewListener, LearningListener {
public class RLController<A extends Enum> implements LearningListener {
protected final String folderPrefix = "learningStates" + File.separator;
protected Environment<A> environment;
protected DiscreteActionSpace<A> discreteActionSpace;
@@ -37,15 +36,15 @@ public class RLController<A extends Enum> implements ViewListener, LearningListe
protected int prevDelay;
protected volatile boolean printNextEpisode;
public RLController(Environment<A> env, Method method, A... actions){
public RLController(Environment<A> env, Method method, A... actions) {
setEnvironment(env);
setMethod(method);
setAllowedActions(actions);
printNextEpisode = true;
}
public void start(){
switch (method){
public void start() {
switch(method) {
case MC_ONPOLICY_EGREEDY:
learning = new MonteCarloOnPolicyEGreedy<>(environment, discreteActionSpace, discountFactor, epsilon, delay);
break;
@@ -60,13 +59,13 @@ public class RLController<A extends Enum> implements ViewListener, LearningListe
initLearning();
}
protected void initListeners(){
protected void initListeners() {
learning.addListener(this);
new Thread(() -> {
while (true){
while(true) {
printNextEpisode = true;
try {
Thread.sleep(30*1000);
Thread.sleep(30 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
@@ -74,35 +73,42 @@ public class RLController<A extends Enum> implements ViewListener, LearningListe
}).start();
}
private void initLearning(){
if(learning instanceof EpisodicLearning){
private void initLearning() {
if(learning instanceof EpisodicLearning) {
System.out.println("Starting learning of <" + nrOfEpisodes + "> episodes");
((EpisodicLearning) learning).learn(nrOfEpisodes);
}else{
((EpisodicLearning) learning).learn(nrOfEpisodes);
} else {
learning.learn();
}
}
/*************************************************
** VIEW LISTENERS **
*************************************************/
@Override
public void onLearnMoreEpisodes(int nrOfEpisodes){
if(learning instanceof EpisodicLearning){
protected void changeLearningDelay(int delay) {
learning.setDelay(delay);
}
protected void learnMoreEpisodes(int nrOfEpisodes) {
if(learning instanceof EpisodicLearning) {
((EpisodicLearning) learning).learn(nrOfEpisodes);
}else{
} else {
throw new RuntimeException("Triggering onLearnMoreEpisodes on non-episodic learning!");
}
}
@Override
public void onLoadState(String fileName) {
protected void changeEpsilon(float epsilon) {
if(learning.getPolicy() instanceof EpsilonPolicy) {
((EpsilonPolicy<A>) learning.getPolicy()).setEpsilon(epsilon);
} else {
System.out.println("Trying to call inEpsilonChange on non-epsilon policy");
}
}
protected void saveState(String fileName) {
FileInputStream fis;
ObjectInputStream in;
try {
fis = new FileInputStream(fileName);
in = new ObjectInputStream(fis);
System.out.println("interrupt" + Thread.currentThread().getId());
System.out.println("interrup" + Thread.currentThread().getId());
learning.interruptLearning();
learning.load(in);
in.close();
@@ -111,46 +117,26 @@ public class RLController<A extends Enum> implements ViewListener, LearningListe
}
}
@Override
public void onSaveState(String fileName) {
protected void loadState(String fileName) {
FileOutputStream fos;
ObjectOutputStream out;
try{
fos = new FileOutputStream(folderPrefix + fileName);
try {
fos = new FileOutputStream(folderPrefix + fileName);
out = new ObjectOutputStream(fos);
learning.interruptLearning();
learning.save(out);
out.close();
}catch (IOException e){
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onEpsilonChange(float epsilon) {
if(learning.getPolicy() instanceof EpsilonPolicy){
((EpsilonPolicy<A>) learning.getPolicy()).setEpsilon(epsilon);
}else{
System.out.println("Trying to call inEpsilonChange on non-epsilon policy");
}
}
@Override
public void onDelayChange(int delay) {
changeLearningDelay(delay);
}
protected void changeLearningDelay(int delay){
learning.setDelay(delay);
}
@Override
public void onFastLearnChange(boolean fastLearn) {
protected void changeFastLearning(boolean fastLearn) {
this.fastLearning = fastLearn;
if(fastLearn){
if(fastLearn) {
prevDelay = learning.getDelay();
changeLearningDelay(0);
}else{
} else {
changeLearningDelay(prevDelay);
}
}
@@ -165,7 +151,6 @@ public class RLController<A extends Enum> implements ViewListener, LearningListe
@Override
public void onLearningEnd() {
System.out.println("Learning finished");
onSaveState( method.toString() + System.currentTimeMillis()/1000 + (learning instanceof EpisodicLearning ? "e" + ((EpisodicLearning) learning).getCurrentEpisode() : ""));
}
@Override
@@ -176,9 +161,9 @@ public class RLController<A extends Enum> implements ViewListener, LearningListe
@Override
public void onEpisodeEnd(List<Double> rewardHistory) {
latestRewardsHistory = rewardHistory;
if(printNextEpisode){
System.out.println("Episode " + ((EpisodicLearning) learning).getCurrentEpisode() + " Latest Reward: " + rewardHistory.get(rewardHistory.size()-1));
System.out.println("Eps/sec: " + ((EpisodicLearning) learning).getEpisodePerSecond());
if(printNextEpisode) {
System.out.println("Episode " + ((EpisodicLearning) learning).getCurrentEpisode() + " Latest Reward: " + rewardHistory.get(rewardHistory.size() - 1));
System.out.println("Eps/sec: " + ((EpisodicLearning) learning).getEpisodePerSecond());
printNextEpisode = false;
}
}
@@ -192,22 +177,22 @@ public class RLController<A extends Enum> implements ViewListener, LearningListe
** SETTERS **
*************************************************/
private void setEnvironment(Environment<A> environment){
if(environment == null){
private void setEnvironment(Environment<A> environment) {
if(environment == null) {
throw new IllegalArgumentException("Environment cannot be null");
}
this.environment = environment;
}
private void setMethod(Method method){
if(method == null){
private void setMethod(Method method) {
if(method == null) {
throw new IllegalArgumentException("Method cannot be null");
}
this.method = method;
}
private void setAllowedActions(A[] actions){
if(actions == null || actions.length == 0){
private void setAllowedActions(A[] actions) {
if(actions == null || actions.length == 0) {
throw new IllegalArgumentException("There has to be at least one action");
}
this.discreteActionSpace = new ListDiscreteActionSpace<>(actions);
@@ -1,14 +1,16 @@
package core.controller;
import core.Environment;
import core.algo.EpisodicLearning;
import core.algo.Method;
import core.gui.LearningView;
import core.gui.View;
import core.listener.ViewListener;
import javax.swing.*;
import java.util.List;
public class RLControllerGUI<A extends Enum> extends RLController<A> {
public class RLControllerGUI<A extends Enum> extends RLController<A> implements ViewListener {
private LearningView learningView;
public RLControllerGUI(Environment<A> env, Method method, A... actions) {
@@ -23,21 +25,41 @@ public class RLControllerGUI<A extends Enum> extends RLController<A> {
});
}
@Override
public void onLearnMoreEpisodes(int nrOfEpisodes) {
super.onLearnMoreEpisodes(nrOfEpisodes);
learningView.updateLearningInfoPanel();
}
/*************************************************
** View LISTENERS **
*************************************************/
@Override
public void onLoadState(String fileName) {
super.onLoadState(fileName);
super.loadState(fileName);
SwingUtilities.invokeLater(() -> learningView.updateLearningInfoPanel());
}
@Override
public void onSaveState(String fileName) {
super.saveState(fileName);
}
@Override
public void onShowQTable() {
learningView.showQTableFrame();
}
@Override
public void onEpsilonChange(float epsilon) {
super.onEpsilonChange(epsilon);
super.changeEpsilon(epsilon);
SwingUtilities.invokeLater(() -> learningView.updateLearningInfoPanel());
}
@Override
public void onDelayChange(int delay) {
super.changeLearningDelay(delay);
SwingUtilities.invokeLater(() -> learningView.updateLearningInfoPanel());
}
@Override
public void onFastLearnChange(boolean isFastLearn) {
super.changeFastLearning(isFastLearn);
SwingUtilities.invokeLater(() -> learningView.updateLearningInfoPanel());
}
@@ -48,17 +70,23 @@ public class RLControllerGUI<A extends Enum> extends RLController<A> {
}
@Override
public void onLearningEnd() {
super.onLearningEnd();
SwingUtilities.invokeLater(() -> learningView.updateRewardGraph(latestRewardsHistory));
public void onLearnMoreEpisodes(int nrOfEpisodes) {
super.learnMoreEpisodes(nrOfEpisodes);
learningView.updateLearningInfoPanel();
}
/*************************************************
** LEARNING LISTENERS **
*************************************************/
@Override
public void onEpisodeEnd(List<Double> rewardHistory) {
super.onEpisodeEnd(rewardHistory);
SwingUtilities.invokeLater(() -> {
if (!fastLearning) {
if(!fastLearning) {
learningView.updateRewardGraph(latestRewardsHistory);
learningView.updateQTable();
}
learningView.updateLearningInfoPanel();
});
@@ -66,8 +94,15 @@ public class RLControllerGUI<A extends Enum> extends RLController<A> {
@Override
public void onStepEnd() {
if (!fastLearning) {
if(!fastLearning) {
SwingUtilities.invokeLater(() -> learningView.repaintEnvironment());
}
}
@Override
public void onLearningEnd() {
super.onLearningEnd();
onSaveState(method.toString() + System.currentTimeMillis() / 1000 + (learning instanceof EpisodicLearning ? "e" + ((EpisodicLearning) learning).getCurrentEpisode() : ""));
SwingUtilities.invokeLater(() -> learningView.updateRewardGraph(latestRewardsHistory));
}
}