wip: Evaluation

master
Armin Wolf 7 years ago
parent e31a9258a7
commit 528bc7651f

@ -3,6 +3,7 @@ package Presenter.Evaluation;
import Model.Interval;
import Model.Line;
import Model.LineModel;
import Model.Point;
import Presenter.Algorithms.*;
import Presenter.Generator.DatasetGenerator;
@ -10,6 +11,8 @@ import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Observable;
import javax.swing.JOptionPane;
import sun.awt.image.ImageWatched.Link;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -25,6 +28,14 @@ public class EvaluateAlgorithms extends Observable {
private Integer iterationCount;
private LineModel arrangement;
private LinkedList<Line> lms;
private LinkedList<Line> rm;
private LinkedList<Line> ts;
private LinkedList<Point> nodeLms;
private LinkedList<Point> nodeTs;
private String[] lmsResult;
private String[] rmResult;
private String[] tsResult;
@ -63,7 +74,7 @@ public class EvaluateAlgorithms extends Observable {
public void run() throws InterruptedException {
for (int i = 0; i < iterationCount; i++) {
this.arrangement = new LineModel();
DatasetGenerator generator;
@ -75,15 +86,24 @@ public class EvaluateAlgorithms extends Observable {
}
arrangement.setLines(generator.generateDataset());
setChanged();
String[] msg = {"eval-dataset-generated"};
notifyObservers(msg);
IntersectionCounter counter = new IntersectionCounter();
counter.run(arrangement.getLines(), new Interval(-99999, 99999));
counter.calculateIntersectionAbscissas(arrangement);
lms = new LinkedList<>(arrangement.getLines());
rm = new LinkedList<>(arrangement.getLines());
ts = new LinkedList<>(arrangement.getLines());
nodeLms = new LinkedList<>(arrangement.getNodes());
nodeTs = new LinkedList<>(arrangement.getNodes());
lmsThread = new Thread(() -> {
LeastMedianOfSquaresEstimator lmsAlg = new LeastMedianOfSquaresEstimator(arrangement.getLines()
, arrangement.getNodes());
LeastMedianOfSquaresEstimator lmsAlg = new LeastMedianOfSquaresEstimator(lms, nodeLms);
lmsAlg.run();
lmsAlg.getResult();
List<Double> errors = sampsonError(arrangement.getLines(), lmsAlg.getSlope(), lmsAlg.getyInterception());
@ -95,7 +115,7 @@ public class EvaluateAlgorithms extends Observable {
});
rmThread = new Thread(() -> {
RepeatedMedianEstimator rmAlg = new RepeatedMedianEstimator(arrangement.getLines());
RepeatedMedianEstimator rmAlg = new RepeatedMedianEstimator(rm);
rmAlg.run();
rmAlg.getResult();
List<Double> errors = sampsonError(arrangement.getLines(), rmAlg.getSlope(), rmAlg.getyInterception());
@ -106,7 +126,7 @@ public class EvaluateAlgorithms extends Observable {
rmResult = getResults(errors,perrors);
});
tsThread = new Thread(() -> {
TheilSenEstimator tsAlg = new TheilSenEstimator(arrangement.getLines(), arrangement.getNodes());
TheilSenEstimator tsAlg = new TheilSenEstimator(ts, nodeTs);
tsAlg.run();
tsAlg.getResult();
List<Double> errors = sampsonError(arrangement.getLines(), tsAlg.getSlope(), tsAlg.getyInterception());
@ -125,7 +145,7 @@ public class EvaluateAlgorithms extends Observable {
tsThread.join();
createGlobalResult();
}
}
public void createGlobalResult(){
@ -145,7 +165,24 @@ public class EvaluateAlgorithms extends Observable {
setChanged();
notifyObservers(separator);
//visualisiere m,b
ArrayList<String> lines = new ArrayList<>();
lines.add("lines-res");
//lms res
lines.add(lmsRes[0]+"");
lines.add(lmsRes[1]+"");
//rm res
lines.add(rmRes[0]+"");
lines.add(rmRes[1]+"");
//ts res
lines.add(tsRes[0]+"");
lines.add(tsRes[1]+"");
setChanged();
notifyObservers(lines.stream().toArray(String[]::new));
}
@ -247,4 +284,8 @@ public class EvaluateAlgorithms extends Observable {
return sampsonerror;
}
public LinkedList<Line> getData(){
return arrangement.getLines();
}
}

@ -28,15 +28,13 @@ public class DatasetGenerator extends Observable{
public DatasetGenerator(){
random = new Random();
random.setSeed(9999);
m = 1 + random.nextDouble();
b = random.nextDouble();
}
public LinkedList<Line> generateDataset(){
LinkedList<Line> lines = new LinkedList<>();
m = 1 + random.nextDouble();
b = random.nextDouble();
for (int i=1;i<101;i++){

@ -62,7 +62,7 @@ public class DataImporter extends Observable{
setChanged();
counter++;
result[2] = counter + "";
Thread.sleep(20);
Thread.sleep(1);
notifyObservers(result);
}
@ -72,7 +72,6 @@ public class DataImporter extends Observable{
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

@ -53,10 +53,16 @@ public class Presenter implements Observer {
public void update(Observable o, Object arg) {
String[] result = ((String[]) arg);
if (result[0] == "eval-dataset-generated"){
SwingUtilities.invokeLater(() -> getView().addEvalDataset(eval.getData()));
}
if (result[0] == "eval"){
SwingUtilities.invokeLater(() -> {
getView().appendEvalResult(result);
});
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result));
}
if (result[0] == "lines-res"){
SwingUtilities.invokeLater(() -> getView().drawLineResult(result));
}
if (result[0] == "lms"){
@ -301,26 +307,12 @@ public class Presenter implements Observer {
}
}
public void startEvaluation(String[] args){
public void startEvaluation(){
if (evalThread == null || !evalThread.isAlive()){
evalThread = new Thread(() ->{
Double m = null;
Double b = null;
Integer i = null;
if (!(args[0].isEmpty() && args[1].isEmpty() && args[2].isEmpty())) {
m = Double.parseDouble(args[0]);
b = Double.parseDouble(args[1]);
i = Integer.parseInt(args[2]);
}
try {
if (m != null && b!= null && i != null) {
eval = new EvaluateAlgorithms(m, b, i);
}else {
eval = new EvaluateAlgorithms();
}
eval = new EvaluateAlgorithms();
eval.addObserver(this);
eval.run();
} catch (InterruptedException e) {
@ -330,11 +322,6 @@ public class Presenter implements Observer {
evalThread.start();
}
}
public void stopEvaluation(){
if (!evalThread.isInterrupted())
evalThread.interrupt();
}
/***************************************************************************************************************************
* Getter und Setter Methoden
***************************************************************************************************************************/

@ -1,9 +1,11 @@
package View;
import Model.Line;
import Presenter.Presenter;
import View.Panels.*;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
@ -105,26 +107,26 @@ public class MainFrame extends JFrame {
public void visualizeLMS(double m, double b) {
plotLMS = new PlotDialog();
lmsPanel.setPlotDialog(plotLMS);
createPlot(m,b,plotLMS,lmsPanel);
createPlot(m,b,plotLMS,lmsPanel, "LMS");
}
public void visualizeRM(double m, double b) {
plotRM = new PlotDialog();
rmPanel.setPlotDialog(plotRM);
createPlot(m,b,plotRM,rmPanel);
createPlot(m,b,plotRM,rmPanel, "RM");
}
public void visualizeTS(double m, double b){
plotTS = new PlotDialog();
tsPanel.setPlotDialog(plotTS);
createPlot(m,b,plotTS, tsPanel);
createPlot(m,b,plotTS, tsPanel, "TS");
}
public void createPlot(double m, double b, PlotDialog plot, JPanel panel){
public void createPlot(double m, double b, PlotDialog plot, JPanel panel, String name){
SwingUtilities.invokeLater(() -> {
plot.clear();
plot.createPlot(getPresenter().getLines());
plot.addLineToPlot(m, b);
plot.addLineToPlot(m, b, name);
panel.revalidate();
});
}
@ -141,7 +143,7 @@ public class MainFrame extends JFrame {
evaluationDialog = new JDialog();
evaluationDialog.setTitle("Evaluation");
evaluationDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
evaluationDialog.setSize(800,500);
evaluationDialog.setSize(1600,800);
evaluationDialog.setLocationRelativeTo(null);
evaluationPanel = new EvaluationPanel(this);
@ -165,6 +167,24 @@ public class MainFrame extends JFrame {
});
}
public void drawLineResult(Object[] res){
SwingUtilities.invokeLater(() -> {
Object[] result = Arrays.asList(res).subList(1,res.length).toArray();
evaluationPanel.drawLines(result);
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
public void addEvalDataset(LinkedList<Line> lines){
SwingUtilities.invokeLater(() -> {
evaluationPanel.setDualPoints(lines);
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
/*******************************************************************************************************************
* init GUI
******************************************************************************************************************/

@ -1,7 +1,11 @@
package View.Panels;
import Model.Line;
import View.MainFrame;
import View.PlotDialog;
import java.util.Arrays;
import java.util.LinkedList;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
@ -15,83 +19,161 @@ public class EvaluationPanel extends JPanel{
private final MainFrame view;
private JTable table;
private JButton start;
private JButton stop;
private JRadioButton evalTypeOne; //1: Alg - N: Data
private JRadioButton evalTypeTwo; //N: Alg - 1: Data
private ButtonGroup radiobuttonGroup;
private ButtonGroup checkboxGroup;
private JCheckBox lms; //1: Alg - N: Data
private JCheckBox rm; //N: Alg - 1: Data
private JCheckBox ts; //1: Alg - N: Data
private JPanel comp;
private JTextField iIteration;
private JTextField iSlope;
private JTextField iYinterception;
private JLabel lIteration;
private JLabel lSlope;
private JLabel lYinterception;
private JPanel algorithmPanel;
private JPanel leftSidePanel;
private JPanel datasetCount;
private JComboBox<Integer> datasetCountChoice;
private JLabel datasetCountLabel;
private JSplitPane splitPane;
private DefaultTableModel model;
private JPanel buttonPanel;
private PlotDialog plotDialog;
public EvaluationPanel(MainFrame view){
super();
this.view = view;
this.setLayout(new BorderLayout());
this.setBorder(new TitledBorder("Evaluation der Algorithmen"));
init();
addComponents();
}
private void addComponents(){
lIteration = new JLabel("Interationen");
lSlope = new JLabel("Steigung");
lYinterception = new JLabel("y-Achsenabschnitt");
private void init(){
datasetCountLabel = new JLabel("Anzahl der Datensätze");
Integer[] choice = {1,2,3,4,5,6,7,8,9,10};
datasetCountChoice = new JComboBox(choice);
iIteration = new JTextField();
iSlope = new JTextField();
iYinterception = new JTextField();
start = new JButton("Start");
stop = new JButton("Stop");
evalTypeOne = new JRadioButton("1 Algorithmus - N Datensätze");
evalTypeTwo = new JRadioButton("N Algorithmen - 1 Datensatz");
lms = new JCheckBox ("Least Median of Squares");
rm = new JCheckBox ("Repeated Median");
ts = new JCheckBox ("Theil-Sen");
radiobuttonGroup = new ButtonGroup();
checkboxGroup = new ButtonGroup();
buttonPanel = new JPanel(new FlowLayout());
leftSidePanel = new JPanel(new BorderLayout());
comp = new JPanel(new GridLayout(0,1));
plotDialog = new PlotDialog();
model = new DefaultTableModel(){
@Override
public boolean isCellEditable(int row, int column) {
//all cells false
return false;
}
};
table = new JTable(model);
splitPane = new JSplitPane();
algorithmPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
datasetCount = new JPanel(new FlowLayout(FlowLayout.LEFT));
}
private void addComponents(){
evalTypeOne.setSelected(true);
checkboxGroup.add(lms);
checkboxGroup.add(rm);
checkboxGroup.add(ts);
evalTypeOne.addActionListener(e -> {
checkboxGroup.add(lms);
checkboxGroup.add(rm);
checkboxGroup.add(ts);
});
evalTypeTwo.addActionListener(e -> {
checkboxGroup.remove(lms);
checkboxGroup.remove(rm);
checkboxGroup.remove(ts);
});
radiobuttonGroup.add(evalTypeOne);
radiobuttonGroup.add(evalTypeTwo);
buttonPanel.add(start);
//buttonPanel.add(stop);
comp = new JPanel();
comp.setLayout(new GridLayout(0,2));
comp.add(lIteration);
comp.add(iIteration);
comp.add(lSlope);
comp.add(iSlope);
comp.add(lYinterception);
comp.add(iYinterception);
algorithmPanel.add(lms);
algorithmPanel.add(rm);
algorithmPanel.add(ts);
datasetCount.add(datasetCountLabel);
datasetCount.add(datasetCountChoice);
comp.add(evalTypeOne);
comp.add(evalTypeTwo);
comp.add(algorithmPanel);
comp.add(datasetCount);
start.addActionListener(e -> {
String[] params = {iSlope.getText(), iYinterception.getText(), iIteration.getText() };
view.getPresenter().startEvaluation(params);
view.getPresenter().startEvaluation();
});
stop.addActionListener(e -> {
view.getPresenter().stopEvaluation();
});
comp.setBorder(new TitledBorder("Konfiguration"));
//Tabelle
String[] selections = { "Approximationsgüte","Theil-Sen", "Repeated-Median", "Least Median of Squares"};
model = new DefaultTableModel(){
@Override
public boolean isCellEditable(int row, int column) {
//all cells false
return false;
}
};
model.setColumnIdentifiers(selections);
table = new JTable(model);
table.setDragEnabled(true);
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setWheelScrollingEnabled(true);
this.add(scrollPane, BorderLayout.CENTER);
this.add(comp, BorderLayout.NORTH);
scrollPane.setBorder(new TitledBorder("Ergebnisse"));
//Plot
plotDialog.createPlot(new LinkedList<>());
plotDialog.setBorder(new TitledBorder("Plot"));
leftSidePanel.add(comp, BorderLayout.NORTH);
leftSidePanel.add(scrollPane, BorderLayout.CENTER);
//Splitpane
splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setResizeWeight(.5d);
splitPane.setContinuousLayout(true);
splitPane.setLeftComponent(leftSidePanel);
splitPane.setRightComponent(plotDialog);
this.add(splitPane, BorderLayout.CENTER);
this.add(buttonPanel, BorderLayout.SOUTH);
}
public void appendData(Object[] row){
model.addRow(row);
this.repaint();
this.revalidate();
}
public void drawLines(Object[] results){
String[] castedResults = Arrays.copyOf(results, results.length, String[].class);
Paint[] color = {Color.ORANGE,Color.ORANGE, Color.RED,Color.RED, Color.MAGENTA,Color.MAGENTA};
String[] name = {"LMS","", "RM","", "TS"};
for (int i=0;i<6;i=i+2){
Double m = Double.parseDouble(castedResults[i]);
Double b = Double.parseDouble(castedResults[i+1]);
plotDialog.addLineToPlot(m,b,color[i],name[i]);
}
}
public void setDualPoints(LinkedList<Line> points){
plotDialog = new PlotDialog();
plotDialog.setBorder(new TitledBorder("Plot"));
splitPane.setRightComponent(plotDialog);
plotDialog.createPlot(points);
plotDialog.repaint();
plotDialog.revalidate();
}
}

@ -30,58 +30,56 @@ public class PlotDialog extends JPanel {
private ChartPanel panel;
private XYSeriesCollection datapoints;
private XYSeries series;
private XYSeries linesA, linesB;
private Double min;
private Double max;
private XYPlot xyPlot;
private int seriesCount;
private XYLineAndShapeRenderer renderer;
private Shape diamond;
public PlotDialog() {
super();
this.setPreferredSize(new Dimension(1000, 1000));
this.setMinimumSize(new Dimension(1000, 800));
// this.setPreferredSize(new Dimension(1000, 1000));
// this.setMinimumSize(new Dimension(1000, 800));
this.setLayout(new BorderLayout());
seriesCount = 1;
}
public void createPlot(LinkedList<Line> points) {
try {
Thread thread = new Thread(() -> convertData(points));
thread.start();
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
if (!points.isEmpty()) {
try {
Thread thread = new Thread(() -> convertData(points));
thread.start();
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//createScatterPlot
chart = ChartFactory.createXYLineChart("",
"X", "Y", datapoints, PlotOrientation.VERTICAL, false, true, false);
Shape diamond = ShapeUtilities.createDiamond(2f);
"X", "Y", datapoints, PlotOrientation.VERTICAL, true, true, false);
diamond = ShapeUtilities.createDiamond(2f);
chart.setBorderVisible(false);
chart.setAntiAlias(true);
chart.getPlot().setBackgroundPaint(Color.WHITE);
chart.setBorderVisible(false);
XYPlot xyPlot = (XYPlot) chart.getPlot();
xyPlot = (XYPlot) chart.getPlot();
xyPlot.setDomainCrosshairVisible(true);
xyPlot.setRangeCrosshairVisible(true);
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer();
renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer();
renderer.setSeriesLinesVisible(0, false);
renderer.setSeriesShapesVisible(0, true);
renderer.setSeriesLinesVisible(1, true);
renderer.setSeriesLinesVisible(2, true);
renderer.setSeriesLinesVisible(1, true);
renderer.setSeriesPaint(0, Color.blue);
renderer.setSeriesShape(0, diamond);
renderer.setSeriesPaint(1, Color.red);
renderer.setSeriesShape(1, diamond);
renderer.setSeriesStroke(1, new BasicStroke(2.0f));
renderer.setBaseSeriesVisible(true);
renderer.setSeriesPaint(2, Color.GREEN);
renderer.setSeriesShape(2, diamond);
renderer.setSeriesStroke(2, new BasicStroke(2.0f));
renderer.setBaseSeriesVisible(true);
xyPlot.setDomainCrosshairVisible(true);
xyPlot.setRangeCrosshairVisible(true);
@ -96,12 +94,35 @@ public class PlotDialog extends JPanel {
datapoints.removeAllSeries();
}
public void addLineToPlot(double m, double b) {
linesA = new XYSeries("linesA");
linesA.add(min.intValue(), min.intValue() * m + b);
linesA.add(max.intValue(), max.intValue() * m + b);
public void addLineToPlot(double m, double b, Paint color, String name) {
XYSeries linesA = new XYSeries(name);
linesA.add(min.doubleValue()-10, min.doubleValue() * m + b);
linesA.add(max.doubleValue()+10, max.doubleValue() * m + b);
datapoints.addSeries(linesA);
renderer.setSeriesPaint(seriesCount, color);
renderer.setSeriesStroke(seriesCount, new BasicStroke(2.0f));
renderer.setBaseSeriesVisible(true);
renderer.setSeriesLinesVisible(seriesCount, true);
seriesCount++;
}
public void addLineToPlot(double m, double b, String name) {
XYSeries linesA = new XYSeries(name);
linesA.add(min.intValue()-10, min.intValue() * m + b);
linesA.add(max.intValue()+10, max.intValue() * m + b);
datapoints.addSeries(linesA);
seriesCount = xyPlot.getSeriesCount();
renderer.setSeriesPaint(seriesCount, Color.red);
renderer.setSeriesStroke(seriesCount, new BasicStroke(2.0f));
renderer.setBaseSeriesVisible(true);
renderer.setSeriesLinesVisible(seriesCount, true);
}
private void convertData(LinkedList<Line> points) {
@ -114,8 +135,8 @@ public class PlotDialog extends JPanel {
coordinates.add(p.getM());
}
this.max = Collections.max(coordinates) + 1;
this.min = Collections.min(coordinates) - 1;
this.max = series.getMaxX();
this.min = series.getMinX();
datapoints.addSeries(series);
}

Binary file not shown.
Loading…
Cancel
Save