WIP: RM Estimator

This commit is contained in:
Armin Wolf 2017-06-20 16:59:24 +02:00
parent 04bcaa0f24
commit 6b99966b5e
29 changed files with 2399 additions and 2170 deletions

View File

@ -1,8 +1,7 @@
import Model.Arrangement;
import Presenter.Presenter;
import View.MainFrame;
import javax.swing.*;
import javax.swing.SwingUtilities;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.

View File

@ -2,7 +2,6 @@ package Model.DCEL;
import Model.Point;
import java.util.LinkedList;
/**

View File

@ -49,7 +49,8 @@ public class Face {
public Face insertEdge(Edge edgeWithSameDestination, Edge edgeToMySource) {
if (edgeWithSameDestination.getIncidentFace().equals(this) || edgeToMySource.getIncidentFace().equals(this)) {
if (edgeWithSameDestination.getIncidentFace().equals(this) || edgeToMySource.getIncidentFace()
.equals(this)) {
LinkedList<Edge> components = new LinkedList<Edge>();
for (Edge e : innerComponents) {
components.add(e);
@ -108,7 +109,8 @@ public class Face {
}
return face;
} else {
throw new IllegalArgumentException("Die angegebenen Kanten haben keinen zusammenhang mit der Fläche!");
throw new IllegalArgumentException(
"Die angegebenen Kanten haben keinen zusammenhang mit der Fläche!");
}
}

View File

@ -24,9 +24,9 @@ public class Line {
this.b = b;
this.x1 = Double.MIN_VALUE;
this.y1 = (Double.MIN_VALUE * m ) + b;
this.y1 = (Double.MIN_VALUE * m) + b;
this.x2 = Double.MAX_VALUE * 0.5;
this.y2 = ((Double.MAX_VALUE * 0.5) * m ) + b;
this.y2 = ((Double.MAX_VALUE * 0.5) * m) + b;
this.id = id;
}
@ -36,9 +36,9 @@ public class Line {
this.b = b;
this.x1 = Double.MIN_VALUE;
this.y1 = (Double.MIN_VALUE * m ) + b;
this.y1 = (Double.MIN_VALUE * m) + b;
this.x2 = Double.MAX_VALUE * 0.5;
this.y2 = ((Double.MAX_VALUE * 0.5) * m ) + b;
this.y2 = ((Double.MAX_VALUE * 0.5) * m) + b;
}
public Line(double x1, double x2, double y1, double y2) {
@ -47,7 +47,7 @@ public class Line {
this.y1 = y1;
this.y2 = y2;
this.m = (y2 -y1)/(x2-x1);
this.m = (y2 - y1) / (x2 - x1);
this.b = y2 - (x2 * m);
}
@ -92,7 +92,7 @@ public class Line {
return y2;
}
public void setEndPoints(double x1, double y1, double x2, double y2){
public void setEndPoints(double x1, double y1, double x2, double y2) {
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;

View File

@ -8,8 +8,10 @@ package Model;
* @Date: 19.06.2017.
*/
public class Pair {
private Integer p1;
private Integer p2;
public Pair(Integer p1, Integer p2) {
this.p1 = p1;
this.p2 = p2;

View File

@ -8,6 +8,7 @@ package Model;
* @Date: 16.06.2017.
*/
public class Slab {
private double upper;
private double lower;
private Boolean activity;
@ -42,7 +43,7 @@ public class Slab {
this.lower = lower;
}
public Double getDistance(){
public Double getDistance() {
return Math.abs(this.upper - this.lower);
}

View File

@ -1,7 +1,5 @@
package Presenter.Algorithms;
import java.util.Observable;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*

View File

@ -1,165 +0,0 @@
package Presenter.Algorithms;
import Model.Line;
import Model.Pair;
import Model.Point;
import Model.Slab;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 18.06.2017.
*/
public class InversionCounter {
private HashMap<Integer, Integer> dictionaryTO;
private HashMap<Integer, Integer> dictionaryBACK;
private ArrayList<Integer> substituted;
private ArrayList<Pair> inversions;
//indexieren der Punkte damit die schnittpunkte berechnet werden können
private HashMap<Integer, Integer> secondaryIndex;
private ArrayList<Point> umin;
private ArrayList<Point> umax;
public int run(List<Integer> a, List<Integer> b){
dictionaryTO = new HashMap<>();
dictionaryBACK = new HashMap<>();
substituted = new ArrayList<>();
inversions = new ArrayList<>();
ArrayList<Integer> temp = new ArrayList<>();
temp.addAll(a);
for (int i=0;i<a.size();i++){
dictionaryTO.put(a.get(i), i+1 );
dictionaryBACK.put(i+1 , a.get(i));
}
for (int j=0;j<b.size();j++){
substituted.add(dictionaryTO.get(b.get(j)));
}
int ret = countInversions(substituted, 0, substituted.size()-1, temp);
dictionaryTO = null;
substituted = null;
inversions = null;
return ret;
}
public int run(List<Line> set, Slab slab){
ArrayList<Integer> listA = new ArrayList<>();
ArrayList<Integer> listB = new ArrayList<>();
prepareData(set, slab, listA, listB);
return run(listA, listB);
}
private void prepareData(List<Line> set, Slab slab, ArrayList<Integer> listA, ArrayList<Integer> listB){
secondaryIndex = new HashMap<>();
umin = new ArrayList<>();
umax = new ArrayList<>();
int counter = 0;
for (Line p : set) {
//vertauscht das Point standardmäßig die x lexikografische Ordnung betrachtet
umin.add(new Point(slab.getLower() * p.getM() + p.getB(),p.getM(), counter+""));
umax.add(new Point(slab.getUpper() * p.getM() + p.getB(),p.getM() ,counter+""));
counter++;
}
for (int i=0; i<umin.size();i++){
int id = Integer.parseInt(umin.get(i).getId());
secondaryIndex.put(id, i);
}
Collections.sort(umin);
Collections.sort(umax);
for (Point p : umax){
int x = Integer.parseInt(p.getId());
listB.add(secondaryIndex.get(x));
}
for (Point q : umin){
int x = Integer.parseInt(q.getId());
listA.add(secondaryIndex.get(x));
}
}
/**
* Angepasster Merge-Sort Algorithmus.
* Die Funktion bekommt neben den standard Parametern zusätzlich eine Liste mit Elementen
* die als Groundtruth dienen.
* @param a Eingabefeld mit den Elementen die überprüft werden sollen.
* @param start Startpunkt des Eingabefeldes.
* @param end Endpunkt des Eingabefeldes.
* @param aux Groundtruth Ordnung um die Anzahl der Inversionen zu bestimmen.
* @return Anzahl der inversionen zwischen a und aux.
*/
public int countInversions(List<Integer> a, int start, int end, List<Integer> aux) {
if (start >= end) {
return 0;
}
int invCount = 0;
int mid = start + (end - start) / 2;
int invCountLeft = countInversions(a, start, mid, aux); // divide and conquer
int invCountRight = countInversions(a, mid + 1, end, aux); // divide and conquer
invCount += (invCountLeft + invCountRight);
for (int i = start; i <= end; i++) {
aux.set(i, a.get(i));
}
int left = start;
int right = mid + 1;
int index = start;
while (left <= mid && right <= end) {
if (aux.get(left) < aux.get(right)) {
a.set(index++, aux.get(left++));
} else {
for (int i=left; i<=mid;i++){
// System.out.println(aux.get(i)+" -- "+ aux.get(right));
inversions.add(new Pair(aux.get(i), aux.get(right)));
}
a.set(index++, aux.get(right++));
invCount += mid - left + 1; // number of inversions for aux[right]
}
}
while (left <= mid) {
a.set(index++, aux.get(left++));
}
// no need to copy over remaining aux[right++] because they are already inside a
return invCount;
}
public ArrayList<Pair> getInversionPairs(){
ArrayList<Pair> result = new ArrayList<>();
for (int i=0;i<inversions.size();i++){
result.add(new Pair(dictionaryBACK.get(inversions.get(i).getP1()), dictionaryBACK.get(inversions.get(i).getP2())));
}
//for (Pair p : result){
// System.out.println(p.getP1() + " <==> " + p.getP2());
//}
return result;
}
}

View File

@ -3,10 +3,15 @@ package Presenter.Algorithms;
import Model.Line;
import Model.Point;
import Model.Slab;
import Presenter.InversionCounter;
import Presenter.Presenter;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Observable;
import java.util.PriorityQueue;
import java.util.Random;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -35,7 +40,8 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
private Double intersectionsPoint;
private Double constant;
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections, Presenter presenter) {
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections,
Presenter presenter) {
this.set = set;
this.intersections = intersections;
@ -59,18 +65,19 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
*/
public void run() {
//(2.) Let U <- (-inf, inf) be the initial active slabs...
Comparator<Slab> comparator = new Comparator<Slab>() {
@Override
public int compare(Slab o1, Slab o2) {
if (o1.getDistance() < o2.getDistance())
if (o1.getDistance() < o2.getDistance()) {
return -1;
if (o1.getDistance() > o2.getDistance())
}
if (o1.getDistance() > o2.getDistance()) {
return 1;
else
} else {
return 0;
}
}
};
slabs = new PriorityQueue<>(comparator);
slabs.add(new Slab(-100000, 100000));
@ -82,7 +89,7 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
Slab slab;
while (!this.slabs.isEmpty()) {
slab = this.slabs.peek();
if (slab.getActivity()){
if (slab.getActivity()) {
//(a.) Select any active Slab and calc. the inversions
int numberOfIntersections = countInversions(slab);
@ -93,8 +100,9 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
//(c.) otherwise....
// get random intersections point...
Collections.shuffle(tmpIntersections, new Random());
for (int i=0;i<tmpIntersections.size();i++) {
if (tmpIntersections.get(i).getX() > slab.getLower() && tmpIntersections.get(i).getX() < slab.getUpper()) {
for (int i = 0; i < tmpIntersections.size(); i++) {
if (tmpIntersections.get(i).getX() > slab.getLower()
&& tmpIntersections.get(i).getX() < slab.getUpper()) {
intersectionsPoint = tmpIntersections.get(i).getX();
break;
} else {
@ -102,7 +110,7 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
}
}
if (intersectionsPoint != null){
if (intersectionsPoint != null) {
splitActiveSlab(intersectionsPoint, slab);
//(d.) this may update sigma min
upperBound(intersectionsPoint);
@ -110,10 +118,10 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
lowerBound(subSlabU1);
lowerBound(subSlabU2);
if (subSlabU1.getActivity()){
if (subSlabU1.getActivity()) {
this.slabs.add(subSlabU1);
}
if (subSlabU2.getActivity()){
if (subSlabU2.getActivity()) {
this.slabs.add(subSlabU2);
}
@ -127,11 +135,11 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
this.slabs.remove(slab);
}
}
if (presenter != null){
if (presenter != null) {
setChanged();
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * -0.5;
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * 0.5;
notifyObservers(new Line(m,b));
notifyObservers(new Line(m, b));
}
}
@ -146,13 +154,12 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
//for (int i=0;i<listA.size();i++){
// System.out.println(listA.get(i)+", "+listB.get(i));
//}
numberOfInversions = invCounter.run(set,slab);
numberOfInversions = invCounter.run(set, slab);
return numberOfInversions;
}
/**
* @param slab
* @return
@ -168,16 +175,15 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
}
Collections.sort(xQueue);
Line bracelet = sigmaMin;
double heightOfBracelet = heightsigmaMin;
for (Point current : xQueue){
for (Point current : xQueue) {
Double[] currentBracelet = calcKMinusBracelet(current, kMinus);
if (currentBracelet == null){
if (currentBracelet == null) {
continue;
} else if (currentBracelet[0] < heightOfBracelet){
} else if (currentBracelet[0] < heightOfBracelet) {
heightOfBracelet = currentBracelet[0];
bracelet = new Line(current.getX(), current.getX(), currentBracelet[1], currentBracelet[2]);
}
@ -188,11 +194,13 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
}
/**
* Diese Methode spaltet den aktiven Slab an der x Koordinate point. Es werden zwei neue Slabs erzeugt.
* Diese Methode spaltet den aktiven Slab an der x Koordinate point. Es werden zwei neue Slabs
* erzeugt.
*
* @param point x Koordinate an der, der Split geschieht.
*/
public void splitActiveSlab(double point, Slab active) {
subSlabU1 = new Slab(active.getLower()+0.01, point);
subSlabU1 = new Slab(active.getLower() + 0.01, point);
subSlabU2 = new Slab(point, active.getUpper());
this.slabs.remove(active);
@ -208,21 +216,21 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
double tmpHeight;
ArrayList<Double> sortedLineSequence = getEjValues(point);
int itnbr = ((n - kMinus) + 1);
for (int i = 0; i < itnbr; i++) {
tmpHeight = sortedLineSequence.get((i + kMinus) - 1) - sortedLineSequence.get(i);
if (tmpHeight < height){
if (tmpHeight < height) {
height = tmpHeight;
}
if (height < heightsigmaMin) {
heightsigmaMin = height;
if (sigmaMin != null){
if (sigmaMin != null) {
sigmaMin.setEndPoints(point, sortedLineSequence.get(i)
,point, sortedLineSequence.get((i + kMinus) - 1));
, point, sortedLineSequence.get((i + kMinus) - 1));
} else {
sigmaMin = new Line(point, point, sortedLineSequence.get(i), sortedLineSequence.get((i + kMinus) - 1));
sigmaMin = new Line(point, point, sortedLineSequence.get(i),
sortedLineSequence.get((i + kMinus) - 1));
}
}
}
@ -246,14 +254,16 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
//y koordinaten der Schnittpunkte
ArrayList<Line> lines = new ArrayList<>();
for (Line p : set) {
lines.add(new Line(pslab.getLower(), pslab.getUpper(),((pslab.getLower() * p.getM()) + p.getB()), ((pslab.getUpper() * p.getM()) + p.getB())));
lines.add(
new Line(pslab.getLower(), pslab.getUpper(), ((pslab.getLower() * p.getM()) + p.getB()),
((pslab.getUpper() * p.getM()) + p.getB())));
}
umaxList = getEjValues(pslab.getUpper());
uminList = getEjValues(pslab.getLower());
for (int i = 0; i < n; i++) {
Line level = new Line(pslab.getLower(),pslab.getUpper(),uminList.get(i), umaxList.get(i));
Line level = new Line(pslab.getLower(), pslab.getUpper(), uminList.get(i), umaxList.get(i));
for (Line line : lines) {
if ((line.getY1() < level.getY1()) && (line.getY2() < level.getY2())) {
alpha[i]++;
@ -277,7 +287,7 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
double h;
pslab.setActivity(false);
for (int j = 0; j < n; j++) {
while ((i < n && (Math.abs(beta[i] - alpha[j]) < kPlus))){
while ((i < n && (Math.abs(beta[i] - alpha[j]) < kPlus))) {
i++;
}
//test
@ -289,7 +299,8 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
pslab.setActivity(false);
break;
} else {
h = Math.min(Math.abs(uminList.get(j) - uminList.get(i)), Math.abs(umaxList.get(j) - umaxList.get(i)));
h = Math.min(Math.abs(uminList.get(j) - uminList.get(i)),
Math.abs(umaxList.get(j) - umaxList.get(i)));
double error = 0.01;
if (((1 + error) * h) < heightsigmaMin) {
//System.out.println("h: "+ h +" ist kleiner als height(sigmaMin): "+heightsigmaMin);
@ -303,8 +314,8 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
}
/**
* Berechnet die Schnittpunkte der Geraden und der vertikalen Gerade u. Im paper sind diese Werte als e_j Werte
* bekannt.
* Berechnet die Schnittpunkte der Geraden und der vertikalen Gerade u. Im paper sind diese Werte
* als e_j Werte bekannt.
*
* @param u vertikale Gerade
* @return Liste der Schnittpunkte (da u bekannt werden nur die y Werte zurück gegeben)
@ -323,9 +334,10 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
}
/**
* Die Funktion berechnet anhand einer vertikalen Gerade x = px das sogenannte kleinste kMinus Bracelet.
* Mit anderen Worten es wird eine vertikale Teilgerade berechnet die mindestens kMinus Geraden schneidet
* und dabei minimal ist.
* Die Funktion berechnet anhand einer vertikalen Gerade x = px das sogenannte kleinste kMinus
* Bracelet. Mit anderen Worten es wird eine vertikale Teilgerade berechnet die mindestens kMinus
* Geraden schneidet und dabei minimal ist.
*
* @param px Koordinate um die "vertikale Gerade" zu simulieren.
* @return Das Array enthält höhe des Bracelet, e_j und e_(j + kMinus - 1)
*/
@ -334,9 +346,9 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
//y Koordinaten für das kMinus brecalet
LinkedList<Double> intersections = new LinkedList<>();
for (Line line : set) {
intersections.add((px.getX() * line.getM())+line.getB());
intersections.add((px.getX() * line.getM()) + line.getB());
}
if (intersections.size() >= kMinusValue){
if (intersections.size() >= kMinusValue) {
Collections.sort(intersections);
double height = Math.abs(intersections.get(0) - intersections.get(0 + kMinusValue - 1));
Double[] ret = {height, intersections.get(0), intersections.get(0 + kMinusValue - 1)};
@ -348,7 +360,8 @@ public class LeastMedianOfSquaresEstimator extends Observable implements Algorit
}
/**
* Im Allgemeinen werden keine Getter und Setter Methoden benötigt aber sie sind nützlich bei den JUnit Testfällen.
* Im Allgemeinen werden keine Getter und Setter Methoden benötigt aber sie sind nützlich bei den
* JUnit Testfällen.
*/
public LinkedList<Line> getSet() {

View File

@ -1,13 +1,14 @@
package Presenter.Algorithms;
import Model.Line;
import Model.Pair;
import Model.Slab;
import Presenter.InversionCounter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -19,13 +20,13 @@ import java.util.Random;
public class RepeatedMedianEstimator implements Algorithm {
private LinkedList<Line> set;
private HashMap<Line, ArrayList<Line>> linePairs;
private Slab interval;
private InversionCounter invCounter = new InversionCounter();
//in der Literatur als L_i, C_i, und R_i bekannt
private Integer countLeftSlab;
private Integer countCenterSlab;
private Integer countRightSlab;
private ArrayList<Integer> countLeftSlab;
private ArrayList<Integer> countCenterSlab;
private ArrayList<Integer> countRightSlab;
//die Mengen L,C und R
private ArrayList<Line> linesInLeftSlab;
@ -39,106 +40,204 @@ public class RepeatedMedianEstimator implements Algorithm {
private Double kHigh;
private Double beta;
private Line thetaLow;
private Line thetaHigh;
private Double thetaLow;
private Double thetaHigh;
public RepeatedMedianEstimator(LinkedList<Line> set) {
this.set = set;
interval = new Slab(-10000,10000);
interval = new Slab(-10000, 10000);
n = set.size();
beta = 1.0;
countLeftSlab = 0;
countCenterSlab = n - 1;
countRightSlab = 0;
beta = 0.5;
countLeftSlab = new ArrayList<>();
countCenterSlab = new ArrayList<>();
countRightSlab = new ArrayList<>();
for (int i = 0; i < n; i++) {
countLeftSlab.add(0);
countRightSlab.add(0);
countCenterSlab.add(n - 1);
}
linesInLeftSlab = new ArrayList<>();
linesInCenterSlab = new ArrayList<>(set);
linesInRightSlab = new ArrayList<>();
linePairs = new HashMap<>();
}
public void run(){
while (linesInCenterSlab.size() != 1){
public void run() {
while (linesInCenterSlab.size() != 1) {
r = Math.floor(Math.pow(n, beta));
ArrayList<Line> lines = sampleLines(linesInCenterSlab, r);
//TODO: hier kommt der neue Ansatz vom zweiten Algorithmus hin
estimateMedianIntersectionAbscissas(lines);
InversionCounter invCounter = new InversionCounter();
invCounter.run(lines, interval);
HashMap<Line, ArrayList<Line>> tmpMap;
tmpMap = invCounter.getIntersectionAbscissas();
linePairs.putAll(tmpMap);
if (tmpMap.size() > 0){
ArrayList<Double> medianIntersections = new ArrayList<>();
for (Line l : lines) {
medianIntersections.add(estimateMedianIntersectionAbscissas(l));
}
k = (Math.floor(n * 0.5) - linesInLeftSlab.size());
computeSlabBorders();
thetaLow = randomizedSelect(linesInCenterSlab,0,linesInCenterSlab.size()-1,kLow);
thetaHigh = randomizedSelect(linesInCenterSlab,0,linesInCenterSlab.size()-1,kHigh);
countNumberOfIntersectionsAbscissas();
thetaLow = randomizedSelect(medianIntersections, 0, medianIntersections.size() - 1, kLow);
thetaHigh = randomizedSelect(medianIntersections, 0, medianIntersections.size() - 1, kHigh);
for (Line l : linesInCenterSlab) {
countNumberOfIntersectionsAbscissas(l);
}
contractIntervals();
}
}
public void computeSlabBorders(){
kLow = Math.max(1, Math.ceil(((r * k)/(linesInCenterSlab.size()))-((3 * Math.sqrt(r))/(2))));
kHigh = Math.min(1, Math.ceil(((r * k)/(linesInCenterSlab.size()))+((3 * Math.sqrt(r))/(2))));
System.out.println(
"Ergebnis: " + linesInCenterSlab.get(0).getM() + " * x + " + linesInCenterSlab.get(0)
.getB());
}
public ArrayList<Line> sampleLines(ArrayList<Line> set, Double r){
public void computeSlabBorders() {
kLow = Math
.max(1, Math.ceil(((r * k) / (linesInCenterSlab.size())) - ((3 * Math.sqrt(r)) / (2))));
kHigh = Math
.min(r, Math.ceil(((r * k) / (linesInCenterSlab.size())) + ((3 * Math.sqrt(r)) / (2))));
}
public ArrayList<Line> sampleLines(ArrayList<Line> set, Double r) {
ArrayList<Line> sampledLines = new ArrayList<>();
Random random = new Random(n);
for (int i=0; i<n; i++){
sampledLines.add(set.get(random.nextInt()));
for (int i = 0; i < r; i++) {
sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, n)));
}
return sampledLines;
}
public Line randomizedSelect(ArrayList<Line> a, int start, int end, double i){
if (start == end)
public Double randomizedSelect(ArrayList<Double> a, int start, int end, double i) {
if (start == end) {
return a.get(start);
}
int q = randomizedPartition(a, start, end);
int tmpPivot = q - start + 1;
if ( i == tmpPivot ){
if (i == tmpPivot) {
return a.get(q);
} else if ( i < tmpPivot ) {
return randomizedSelect(a, start, q-1, i);
} else if (i < tmpPivot) {
return randomizedSelect(a, start, q - 1, i);
} else {
return randomizedSelect(a, q+1, end, i-tmpPivot);
return randomizedSelect(a, q + 1, end, i - tmpPivot);
}
}
public int randomizedPartition(ArrayList<Line> a, int start, int end){
public int randomizedPartition(ArrayList<Double> a, int start, int end) {
int delta = Math.abs(end - start);
Random random = new Random(delta);
int i = start + random.nextInt();
int i = start + ThreadLocalRandom.current().nextInt(0, delta);
Collections.swap(a, end, i);
return partition(a, start, end);
}
public int partition(ArrayList<Line> a, int start, int end){
Line x = a.get(end);
public int partition(ArrayList<Double> a, int start, int end) {
Double x = a.get(end);
int i = start - 1;
for (int j=start; j<end; j++){
if (a.get(j).getM() <= x.getM()){
for (int j = start; j < end; j++) {
if (a.get(j) <= x) {
i++;
Collections.swap(a, i, j);
}
}
Collections.swap(a, i+1, end);
return i+1;
Collections.swap(a, i + 1, end);
return i + 1;
}
public void countNumberOfIntersectionsAbscissas(){
public void countNumberOfIntersectionsAbscissas(Line sampledLine) {
if (linePairs.get(sampledLine) != null){
double intersection;
Integer index = Integer.parseInt(sampledLine.getId());
for (Line line : linePairs.get(sampledLine)) {
intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
int tmpVal;
if (intersection <= thetaLow) {
tmpVal = countLeftSlab.get(index) + 1;
countLeftSlab.set(index, tmpVal);
tmpVal = countCenterSlab.get(index) - 1;
countCenterSlab.set(index, tmpVal);
} else if (intersection > thetaHigh) {
tmpVal = countRightSlab.get(index) + 1;
countRightSlab.set(index, tmpVal);
tmpVal = countCenterSlab.get(index) - 1;
countCenterSlab.set(index, tmpVal);
}
public void estimateMedianIntersectionAbscissas(ArrayList<Line> sampledLines){
int inversions = invCounter.run(sampledLines, interval);
countCenterSlab
.set(index, Math.abs((n - 1) - (countLeftSlab.get(index) + countRightSlab.get(index))));
}
}
}
public Double estimateMedianIntersectionAbscissas(Line sampledLine) {
Integer index = Integer.parseInt(sampledLine.getId());
ArrayList<Double> intersections = new ArrayList<>();
double intersection;
for (Line line : linePairs.get(sampledLine)) {
if (line != sampledLine){
intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
intersections.add(intersection);
}
}
Collections.sort(intersections);
double ki = Math.floor((n - 1) / 2) - countLeftSlab.get(index);
int accessIndex = ((int) Math.floor((Math.sqrt(n) * ki) / countCenterSlab.get(index)))-1;
System.out.println(accessIndex);
return intersections.get(accessIndex);
}
public void contractIntervals() {
if (linesInLeftSlab.size() < Math.floor(n / 2) && Math.floor(n / 2) <= (linesInLeftSlab.size()
+ linesInCenterSlab.size())) {
for (int i = 0; i < linesInCenterSlab.size(); i++) {
int maxVal = Math
.max(countLeftSlab.get(i), Math.max(countCenterSlab.get(i), countRightSlab.get(i)));
if (countLeftSlab.get(i) == maxVal) {
linesInLeftSlab.add(linesInCenterSlab.get(i));
linesInCenterSlab.remove(i);
}
if (countRightSlab.get(i) == maxVal) {
linesInRightSlab.add(linesInCenterSlab.get(i));
linesInCenterSlab.remove(i);
}
}
for (int i = 0; i < n; i++) {
countLeftSlab.set(i,0);
countRightSlab.set(i,0);
countCenterSlab.set(i,n - 1);
}
interval.setLower(thetaLow - 0.01);
interval.setUpper(thetaHigh);
}
}
}

View File

@ -8,4 +8,5 @@ package Presenter.Algorithms;
* @Date: 28.05.2017.
*/
public class TheilSenEstimator implements Algorithm {
}

View File

@ -0,0 +1,29 @@
package Presenter.Comparators;
import Model.Line;
import java.util.Comparator;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 19.06.2017.
*/
public class YOrderLineComparatorBegin implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
if (o1.getY1() == o2.getY1()) {
if (o1.getX1() <= o2.getX1()) {
return -1;
} else {
return 1;
}
} else if (o1.getY1() < o2.getY1()) {
return -1;
} else {
return 1;
}
}
}

View File

@ -0,0 +1,29 @@
package Presenter.Comparators;
import Model.Line;
import java.util.Comparator;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 19.06.2017.
*/
public class YOrderLineComparatorEnd implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
if (o1.getY2() == o2.getY2()) {
if (o1.getX2() <= o2.getX2()) {
return -1;
} else {
return 1;
}
} else if (o1.getY2() < o2.getY2()) {
return -1;
} else {
return 1;
}
}
}

View File

@ -0,0 +1,195 @@
package Presenter;
import Model.Line;
import Model.Pair;
import Model.Slab;
import Presenter.Comparators.YOrderLineComparatorBegin;
import Presenter.Comparators.YOrderLineComparatorEnd;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 18.06.2017.
*/
public class InversionCounter {
private HashMap<Integer, Integer> dictionaryTO;
private HashMap<Integer, Integer> dictionaryBACK;
private ArrayList<Integer> substituted;
private ArrayList<Pair> inversions;
private List<Line> set;
//indexieren der Punkte damit die schnittpunkte berechnet werden können
private HashMap<Line, Integer> secondaryDictionaryTO;
private HashMap<Integer, Line> secondaryDictionaryBACK;
private ArrayList<Line> umin;
public int run(List<Integer> a, List<Integer> b) {
dictionaryTO = new HashMap<>();
dictionaryBACK = new HashMap<>();
substituted = new ArrayList<>();
inversions = new ArrayList<>();
ArrayList<Integer> temp = new ArrayList<>();
temp.addAll(a);
for (int i = 0; i < a.size(); i++) {
dictionaryTO.put(a.get(i), i + 1);
dictionaryBACK.put(i + 1, a.get(i));
}
for (int j = 0; j < b.size(); j++) {
substituted.add(dictionaryTO.get(b.get(j)));
}
int ret = countInversions(substituted, 0, substituted.size() - 1, temp);
getIntersectionAbscissas();
return ret;
}
public int run(List<Line> set, Slab slab) {
ArrayList<Integer> listA = new ArrayList<>();
ArrayList<Integer> listB = new ArrayList<>();
prepareData(set, slab, listA, listB);
return run(listA, listB);
}
private void prepareData(List<Line> set, Slab slab, ArrayList<Integer> listA,
ArrayList<Integer> listB) {
secondaryDictionaryTO = new HashMap<>();
secondaryDictionaryBACK = new HashMap<>();
this.set = set;
umin = new ArrayList<>();
Line tmpLine;
for (Line p : set) {
//vertauscht das Point standardmäßig die x lexikografische Ordnung betrachtet
tmpLine = new Line(p.getM(), p.getM(), slab.getLower() * p.getM() + p.getB(),
slab.getUpper() * p.getM() + p.getB());
//wird benötigt um späer die Schnittpunkte ermitteln zu können
tmpLine.setB(p.getB());
tmpLine.setM(p.getM());
umin.add(tmpLine);
}
for (int i = 0; i < umin.size(); i++) {
secondaryDictionaryTO.put(umin.get(i), i);
secondaryDictionaryBACK.put(i, this.set.get(i));
}
Collections.sort(umin, new YOrderLineComparatorBegin());
for (Line q : umin) {
listA.add(secondaryDictionaryTO.get(q));
}
Collections.sort(umin, new YOrderLineComparatorEnd());
for (Line q : umin) {
listB.add(secondaryDictionaryTO.get(q));
}
}
/**
* Angepasster Merge-Sort Algorithmus.
* Die Funktion bekommt neben den standard Parametern zusätzlich eine Liste mit Elementen
* die als Groundtruth dienen.
*
* @param a Eingabefeld mit den Elementen die überprüft werden sollen.
* @param start Startpunkt des Eingabefeldes.
* @param end Endpunkt des Eingabefeldes.
* @param aux Groundtruth Ordnung um die Anzahl der Inversionen zu bestimmen.
* @return Anzahl der inversionen zwischen a und aux.
*/
public int countInversions(List<Integer> a, int start, int end, List<Integer> aux) {
if (start >= end) {
return 0;
}
int invCount = 0;
int mid = start + (end - start) / 2;
int invCountLeft = countInversions(a, start, mid, aux); // divide and conquer
int invCountRight = countInversions(a, mid + 1, end, aux); // divide and conquer
invCount += (invCountLeft + invCountRight);
for (int i = start; i <= end; i++) {
aux.set(i, a.get(i));
}
int left = start;
int right = mid + 1;
int index = start;
while (left <= mid && right <= end) {
if (aux.get(left) < aux.get(right)) {
a.set(index++, aux.get(left++));
} else {
for (int i = left; i <= mid; i++) {
// System.out.println(aux.get(i)+" -- "+ aux.get(right));
inversions.add(new Pair(aux.get(i), aux.get(right)));
}
a.set(index++, aux.get(right++));
invCount += mid - left + 1; // number of inversions for aux[right]
}
}
while (left <= mid) {
a.set(index++, aux.get(left++));
}
// no need to copy over remaining aux[right++] because they are already inside a
return invCount;
}
public HashMap<Line, ArrayList<Line>> getIntersectionAbscissas() {
ArrayList<Pair> result = new ArrayList<>();
HashMap<Line, ArrayList<Line>> ret = new HashMap<>();
for (int i = 0; i < inversions.size(); i++) {
result.add(new Pair(dictionaryBACK.get(inversions.get(i).getP1()),
dictionaryBACK.get(inversions.get(i).getP2())));
}
ArrayList<Line> linePairs;
for (Pair p : result) {
Line l1 = secondaryDictionaryBACK.get(p.getP1());
Line l2 = secondaryDictionaryBACK.get(p.getP2());
if (ret.get(l2) == null){
linePairs = new ArrayList<>();
} else {
linePairs = ret.get(l2);
}
linePairs.add(l1);
ret.put(l2, linePairs);
//Symetrie
if (ret.get(l1) == null){
linePairs = new ArrayList<>();
} else {
linePairs = ret.get(l1);
}
linePairs.add(l2);
ret.put(l1, linePairs);
}
// System.out.println("----------------------------------------------------------");
// for (Line outerLine : ret.keySet()){
// System.out.println("Linie: "+outerLine);
// for (Line innerLine : ret.get(outerLine)){
// System.out.println("\t\t -> "+innerLine);
// }
// }
// System.out.println("----------------------------------------------------------");
return ret;
}
}

View File

@ -4,13 +4,13 @@ import Model.Arrangement;
import Model.Line;
import Model.Point;
import Presenter.Algorithms.LeastMedianOfSquaresEstimator;
import Presenter.Algorithms.RepeatedMedianEstimator;
import View.MainFrame;
import javax.swing.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import javax.swing.SwingUtilities;
/**
@ -35,13 +35,14 @@ public class Presenter implements Observer {
this.view = view;
// Double[] x = {1d, 2d, 3d, 4d, 10d, 12d, 18d};
// Double[] y = {9d, 15d, 19d, 20d, 45d, 55d, 78d};
Double[] x = {18d,24d,30d,34d,38d};
Double[] y = {18d,26d,30d,40d,70d};
Double[] x = {18d, 24d, 30d, 34d, 38d};
Double[] y = {18d, 26d, 30d, 40d, 70d};
// Double[] x = {1d,3d,4d,5d,8d};
// Double[] y = {4d,2d,1d,0d,0d};
view.logHeading("Duale Darstellung der Punkte als Geraden:");
for (int j = 0; j < x.length; j++) {
Line p = new Line(x[j], y[j]);
p.setId(j+"");
view.log("f(x) = " + p.getM() + "x + " + p.getB());
this.model.addLine(p);
}
@ -62,6 +63,11 @@ public class Presenter implements Observer {
view.createTable(heading, rows);
Thread t = new Thread(() -> {
RepeatedMedianEstimator rm = new RepeatedMedianEstimator(this.getLines());
rm.run();
});
t.start();
}
@ -69,11 +75,11 @@ public class Presenter implements Observer {
@Override
public void update(Observable o, Object arg) {
Line result = ((Line) arg);
SwingUtilities.invokeLater(()->{
SwingUtilities.invokeLater(() -> {
getView().createPlot(result.getM(), result.getB());
getView().setLmsIsComplete(true);
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt");
getView().log("m: "+result.getM()+"\t b: "+result.getB());
getView().log("m: " + result.getM() + "\t b: " + result.getB());
});
}
@ -109,7 +115,7 @@ public class Presenter implements Observer {
Thread thread = new Thread(() -> {
for (int i = 0; i < getLines().size(); i++) {
for (int j = i; j < getLines().size(); j++) {
if (i != j){
if (i != j) {
model.addNode(calcIntersection(getLines().get(j), getLines().get(i)));
}
}
@ -123,23 +129,23 @@ public class Presenter implements Observer {
}
public LinkedList<LinkedList<Point>> calcArrangementLines(){
public LinkedList<LinkedList<Point>> calcArrangementLines() {
LinkedList<LinkedList<Point>> lineCoordinates = new LinkedList<>();
double x1 = -1000;
double x2 = 1000;
for (Line point : model.getLines()) {
LinkedList line = new LinkedList();
double y1 = (point.getM() * x1 + point.getB());
double y2 = (point.getM() * x2 + point.getB());
line.add(new Point(x1,y1));
line.add(new Point(x2,y2));
line.add(new Point(x1, y1));
line.add(new Point(x2, y2));
lineCoordinates.add(line);
}
return lineCoordinates;
}
/***************************************************************************************************************************
* Getter und Setter Methoden
***************************************************************************************************************************/

View File

@ -1,7 +1,15 @@
package View;
import Model.Line;
import Model.Point;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.util.LinkedList;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
@ -13,12 +21,6 @@ import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
@ -46,8 +48,8 @@ public class ArrangementDialog extends JPanel {
this.setPreferredSize(new Dimension(800, 800));
this.setMinimumSize(new Dimension(800, 800));
this.setLayout(new BorderLayout());
this.vslider = new JSlider(SwingConstants.VERTICAL,1,100,50);
this.hslider = new JSlider(SwingConstants.HORIZONTAL,10,1000,500);
this.vslider = new JSlider(SwingConstants.VERTICAL, 1, 100, 50);
this.hslider = new JSlider(SwingConstants.HORIZONTAL, 10, 1000, 500);
}
public void setPrameters(LinkedList<LinkedList<Point>> lines, LinkedList<Point> points) {
@ -82,7 +84,8 @@ public class ArrangementDialog extends JPanel {
chart = ChartFactory.createXYLineChart(
null, null, null, dataset,
PlotOrientation.HORIZONTAL, false, false, false);
chart.setRenderingHints( new RenderingHints( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ) );
chart.setRenderingHints(
new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
chart.setAntiAlias(true);
final XYPlot plot = chart.getXYPlot();
@ -96,19 +99,17 @@ public class ArrangementDialog extends JPanel {
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
renderer.setSeriesLinesVisible(dataset.indexOf(intersections), false);
plot.setRenderer(renderer);
for (int i=0;i<lines.size();i++){
for (int i = 0; i < lines.size(); i++) {
// Setze die Shapes für die Schnittpunkte
renderer.setSeriesPaint(i, Color.BLUE);
renderer.setBaseSeriesVisible(true);
}
Shape shape = ShapeUtilities.createDiagonalCross(4,1);
Shape shape = ShapeUtilities.createDiagonalCross(4, 1);
renderer.setSeriesPaint(lines.size(), Color.BLACK);
renderer.setSeriesShape(lines.size(), shape);
@ -122,11 +123,11 @@ public class ArrangementDialog extends JPanel {
this.add(vslider, BorderLayout.EAST);
}
private void addListener(){
private void addListener() {
this.vslider.addChangeListener(e -> {
JSlider slider = (JSlider) e.getSource();
double delta = Math.abs(slider.getValue() - 50) * 0.1;
if (slider.getValue() < 50){
if (slider.getValue() < 50) {
domain.setRange(domainMin - delta, domainMax - delta);
} else {
domain.setRange(domainMin + delta, domainMax + delta);
@ -137,7 +138,7 @@ public class ArrangementDialog extends JPanel {
JSlider slider = (JSlider) e.getSource();
double delta = Math.abs(slider.getValue() - 500);
if (slider.getValue() < 500){
if (slider.getValue() < 500) {
range.setRange(rangeMin - delta, rangeMax - delta);
} else {
range.setRange(rangeMin + delta, rangeMax + delta);

View File

@ -1,11 +1,16 @@
package View;
import Model.Point;
import javax.swing.*;
import java.awt.*;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
import java.util.LinkedList;
import javax.swing.JPanel;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -18,7 +23,7 @@ public class ArrangementDialog2 extends JPanel {
private int min = 0;
private int max = 800;
private int zero = max/2;
private int zero = max / 2;
private double scale = 1.0;
private int pointThicknes = 5;
@ -29,9 +34,9 @@ public class ArrangementDialog2 extends JPanel {
private LinkedList<Line2D.Double> line2Ds;
public ArrangementDialog2(){
public ArrangementDialog2() {
super();
this.dimension = new Dimension(max,max);
this.dimension = new Dimension(max, max);
this.setPreferredSize(dimension);
this.setLayout(new BorderLayout());
@ -60,20 +65,22 @@ public class ArrangementDialog2 extends JPanel {
}
@Override
public void paintComponent(Graphics g){
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
line2Ds = new LinkedList<>();
g2.translate(zero, zero);
g2.scale(scale, scale);
g2.translate(-1 * zero, -1 *zero);
g2.translate(-1 * zero, -1 * zero);
//draw the lines
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(5f / (float) scale));
for (LinkedList<Point> line : lines){
line2Ds.add(new Line2D.Double(zero +line.getFirst().getX().intValue(), zero +line.getFirst().getY().intValue(), zero +line.getLast().getX().intValue(), zero +line.getLast().getY().intValue()));
for (LinkedList<Point> line : lines) {
line2Ds.add(new Line2D.Double(zero + line.getFirst().getX().intValue(),
zero + line.getFirst().getY().intValue(), zero + line.getLast().getX().intValue(),
zero + line.getLast().getY().intValue()));
}
for (Line2D.Double line : line2Ds) {
g2.draw(line);
@ -82,7 +89,8 @@ public class ArrangementDialog2 extends JPanel {
//draw intersections of the lines
g2.setColor(Color.RED);
for (Point point : points) {
g2.fillOval(zero +point.getX().intValue(),zero +point.getY().intValue(), pointThicknes, pointThicknes);
g2.fillOval(zero + point.getX().intValue(), zero + point.getY().intValue(), pointThicknes,
pointThicknes);
}
}
}

View File

@ -1,21 +1,20 @@
package View;
import Model.Line;
import Presenter.Algorithms.LeastMedianOfSquaresEstimator;
import Presenter.Presenter;
import com.sun.org.apache.xpath.internal.operations.Bool;
import jdk.nashorn.internal.scripts.JO;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -24,7 +23,7 @@ import java.util.Observer;
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class MainFrame extends JFrame{
public class MainFrame extends JFrame {
private Presenter presenter;
private Boolean lmsIsComplete = false;
@ -73,7 +72,8 @@ public class MainFrame extends JFrame{
public void createArrangement() {
if (arrangement == null) {
arrangement = new ArrangementDialog();
arrangement.setPrameters(getPresenter().calcArrangementLines(), getPresenter().getModel().getNodes());
arrangement.setPrameters(getPresenter().calcArrangementLines(),
getPresenter().getModel().getNodes());
arrangement.createArrangement();
SwingUtilities.invokeLater(() -> {
arrangementDialog.add(arrangement, BorderLayout.CENTER);
@ -95,24 +95,23 @@ public class MainFrame extends JFrame{
}
/*******************************************************************************************************************
* init GUI
******************************************************************************************************************/
private void setTitles(){
private void setTitles() {
this.setTitle("MainFrame");
arrangementDialog.setTitle("Dual Representation - Dialog");
button3.setText("Import");
arrangementButton.setText("Dualraum");
}
private void setupTabbedPane(){
tabbedPane.add("LMS", sidepanel);
tabbedPane.add("RM", new JPanel());
tabbedPane.add("TS", new JPanel());
private void setupTabbedPane() {
tabbedPane.add("Least Median of Squares", sidepanel);
tabbedPane.add("Repeated Median", new JPanel());
tabbedPane.add("Theil-Sen", new JPanel());
}
private void addComponents(){
private void addComponents() {
pane.add(arrangementButton);
pane.add(button3);
@ -124,7 +123,7 @@ public class MainFrame extends JFrame{
this.add(menupanel, BorderLayout.NORTH);
}
private void setupSplitPane(){
private void setupSplitPane() {
splitpane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitpane.setResizeWeight(.5d);
splitpane.setContinuousLayout(true);
@ -132,24 +131,24 @@ public class MainFrame extends JFrame{
splitpane.setRightComponent(tabbedPane);
}
private void setCloseOperations(){
private void setCloseOperations() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
arrangementDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
}
private void setDimensions(){
private void setDimensions() {
this.setSize(1900, 1000);
sidepanel.setMinimumSize(new Dimension(400,500));
sidepanel.setMinimumSize(new Dimension(400, 500));
arrangementDialog.setSize(new Dimension(800, 800));
output.setMinimumSize(new Dimension(400,500));
output.setMinimumSize(new Dimension(400, 500));
}
private void setLayouts(){
private void setLayouts() {
this.setLayout(new BorderLayout());
pane.setLayout(new FlowLayout());
}
private void initializeComponents(){
private void initializeComponents() {
//Panels
pane = new JPanel();
sidepanel = new SidePanel();
@ -168,14 +167,15 @@ public class MainFrame extends JFrame{
button3 = new JButton();
}
private void setActionListeners(){
private void setActionListeners() {
arrangementButton.addActionListener((ActionEvent e) -> {
Thread t = new Thread(() -> getPresenter().startArrangementVisualization());
t.start();
});
sidepanel.getStartButton().addActionListener((ActionEvent e) -> {
Thread t = new Thread(() -> this.getPresenter().startScatterPlotVisualization(sidepanel.getInput()));
Thread t = new Thread(
() -> this.getPresenter().startScatterPlotVisualization(sidepanel.getInput()));
t.start();
});
}
@ -188,21 +188,22 @@ public class MainFrame extends JFrame{
SwingUtilities.invokeLater(() -> output.appendParagraph(s));
}
public void logError(String s){
public void logError(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphRed(s));
}
public void logSuccess(String s){
public void logSuccess(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphGreen(s));
}
public void logHeading(String s){
public void logHeading(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphWithHeading(s));
}
public void createTable(List<String> heading, List<List<String>> rows){
public void createTable(List<String> heading, List<List<String>> rows) {
SwingUtilities.invokeLater(() -> output.logTable(heading, rows));
}
/*******************************************************************************************************************
* Getter und Setter Methoden
******************************************************************************************************************/

View File

@ -1,9 +1,12 @@
package View;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.BorderLayout;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -24,7 +27,9 @@ public class MenuPanel extends JPanel {
this.menu = new JMenu("File");
this.item = new JMenuItem("Exit");
this.item.addActionListener(e -> { System.exit(0);});
this.item.addActionListener(e -> {
System.exit(0);
});
menu.add(item);
menuBar.add(menu);

View File

@ -1,9 +1,12 @@
package View;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.BorderLayout;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.border.TitledBorder;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
@ -17,7 +20,7 @@ public class OutputPanel extends JPanel {
private JScrollPane scrollPane;
private StringBuilder content;
public OutputPanel(){
public OutputPanel() {
this.setBorder(new TitledBorder("Ausgabekanal"));
this.setLayout(new BorderLayout());
output = new JTextPane();
@ -26,7 +29,6 @@ public class OutputPanel extends JPanel {
content = new StringBuilder();
scrollPane = new JScrollPane(output);
scrollPane.setWheelScrollingEnabled(true);
this.add(scrollPane, BorderLayout.CENTER);
@ -41,9 +43,9 @@ public class OutputPanel extends JPanel {
output.setText(content.toString());
}
public void appendParagraphWithHeading(String h1){
public void appendParagraphWithHeading(String h1) {
content.append("<h1>"+ h1 + "</h1></br>");
content.append("<h1>" + h1 + "</h1></br>");
output.setText(content.toString());
}
@ -54,6 +56,7 @@ public class OutputPanel extends JPanel {
output.setText(content.toString());
}
public void appendParagraphGreen(String p) {
content.append("<p style=\" color:green \"><em><strong>" + p + "</strong></em></p></br>");
@ -61,7 +64,7 @@ public class OutputPanel extends JPanel {
output.setText(content.toString());
}
public void logTable(List<String> heading, List<List<String>> rows){
public void logTable(List<String> heading, List<List<String>> rows) {
content.append("<center>");
content.append("<table style=\" width:80%; border: 1px solid black; \">");
content.append("<tr>");
@ -72,7 +75,7 @@ public class OutputPanel extends JPanel {
for (List<String> row : rows) {
content.append("<tr>");
for (String entry : row) {
content.append("<td style=\" border: 1px solid black; \">"+entry+"</td>");
content.append("<td style=\" border: 1px solid black; \">" + entry + "</td>");
}
content.append("</tr>");
}

View File

@ -1,24 +1,25 @@
package View;
import Model.Line;
import Model.Point;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Shape;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
@ -66,23 +67,22 @@ public class PlotDialog extends JPanel {
xyPlot.setRangeCrosshairVisible(true);
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer();
renderer.setSeriesLinesVisible(0,false);
renderer.setSeriesLinesVisible(0, false);
renderer.setSeriesShapesVisible(0, true);
renderer.setSeriesLinesVisible(1,true);
renderer.setSeriesLinesVisible(2,true);
renderer.setSeriesLinesVisible(1, true);
renderer.setSeriesLinesVisible(2, 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.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.setSeriesStroke(2, new BasicStroke(2.0f));
renderer.setBaseSeriesVisible(true);
xyPlot.setDomainCrosshairVisible(true);
@ -94,8 +94,8 @@ public class PlotDialog extends JPanel {
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 );
linesA.add(min.intValue(), min.intValue() * m + b);
linesA.add(max.intValue(), max.intValue() * m + b);
datapoints.addSeries(linesA);
}

View File

@ -1,8 +1,14 @@
package View;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import java.awt.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -32,7 +38,6 @@ public class SidePanel extends JPanel {
this.northPanel.setBorder(new TitledBorder("Konfiguration"));
this.centerPanel.setBorder(new TitledBorder("Visualisierung"));
this.continer = new JPanel();
this.continer.setLayout(new GridBagLayout());

View File

@ -1,17 +1,16 @@
package Model;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import Model.DCEL.DoublyConnectedEdgeList;
import Model.DCEL.Edge;
import Model.DCEL.Face;
import Model.DCEL.Node;
import java.util.LinkedList;
import org.junit.Before;
import org.junit.Test;
import java.util.LinkedList;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*

View File

@ -1,16 +1,18 @@
package Presenter.Algorithms;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import Model.Line;
import Model.Point;
import Model.Slab;
import org.junit.Before;
import org.junit.Test;
import Presenter.InversionCounter;
import java.util.ArrayList;
import java.util.LinkedList;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -26,17 +28,15 @@ public class LeastMedianOfSquaresEstimatorTest {
@Before
public void setUp() throws Exception {
Double[] x = {18d,24d,30d,34d,38d};
Double[] y = {18d,26d,30d,40d,70d};
Double[] x = {18d, 24d, 30d, 34d, 38d};
Double[] y = {18d, 26d, 30d, 40d, 70d};
LinkedList<Line> lines = new LinkedList<>();
LinkedList<Point> intersections = new LinkedList<>();
for (int i=0; i<5; i++)
for (int i = 0; i < 5; i++) {
lines.add(new Line(x[i], y[i]));
}
lms = new LeastMedianOfSquaresEstimator(lines, intersections);
}
@ -51,16 +51,16 @@ public class LeastMedianOfSquaresEstimatorTest {
public void mergeSort() throws Exception {
// double[] umin = {6,3,4,1,2,5};
// double[] umax = {3,5,2,6,1,4};
double[] umin = {1,2,3,4};
double[] umax = {2,3,4,1};
double[] umin = {1, 2, 3, 4};
double[] umax = {2, 3, 4, 1};
ArrayList<Integer> a = new ArrayList<>();
ArrayList<Integer> b = new ArrayList<>();
for (double d :umin) {
for (double d : umin) {
a.add((int) d);
}
for (double d :umax) {
for (double d : umax) {
b.add((int) d);
}
InversionCounter invCounter = new InversionCounter();
@ -72,7 +72,7 @@ public class LeastMedianOfSquaresEstimatorTest {
@Test
public void geEjValues() throws Exception {
Double[] expected = {36d,50d,60d,74d,108d};
Double[] expected = {36d, 50d, 60d, 74d, 108d};
ArrayList<Double> actual = lms.getEjValues(1d);
assertArrayEquals(expected, actual.toArray());
}
@ -92,29 +92,28 @@ public class LeastMedianOfSquaresEstimatorTest {
public void upperBound() throws Exception {
lms.setkMinus(3);
lms.setHeightsigmaMin(500);
lms.setSigmaMin(new Line(0,0,0,0));
lms.setSigmaMin(new Line(0, 0, 0, 0));
lms.setN(5);
Line expected = new Line(5,5,146,210);
Line expected = new Line(5, 5, 146, 210);
lms.upperBound(5d);
assertEquals(expected.getX1(), lms.getSigmaMin().getX1(),0.01);
assertEquals(expected.getX2(), lms.getSigmaMin().getX2(),0.01);
assertEquals(expected.getY1(), lms.getSigmaMin().getY1(),0.01);
assertEquals(expected.getY2(), lms.getSigmaMin().getY2(),0.01);
assertEquals(expected.getX1(), lms.getSigmaMin().getX1(), 0.01);
assertEquals(expected.getX2(), lms.getSigmaMin().getX2(), 0.01);
assertEquals(expected.getY1(), lms.getSigmaMin().getY1(), 0.01);
assertEquals(expected.getY2(), lms.getSigmaMin().getY2(), 0.01);
}
@Test
public void lowerBound() throws Exception {
//kann nur über sout geprüft werden test passt aber
Double[] expectedAlpha = {0d,0d,0d,2d,4d};
Double[] expectedBeta = {2d,4d,4d,2d,1d};
Double[] expectedAlpha = {0d, 0d, 0d, 2d, 4d};
Double[] expectedBeta = {2d, 4d, 4d, 2d, 1d};
lms.setHeightsigmaMin(500);
Slab slab = new Slab(-2,0);
Slab slab = new Slab(-2, 0);
lms.lowerBound(slab);
assertTrue(slab.getActivity());
}
}