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:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user