Compare commits

..

24 Commits

Author SHA1 Message Date
Selebrator 14a9b248c8 12.2 war falsch 7 years ago
Selebrator 869243e424 12.2 7 years ago
Selebrator 0164050f66 2 new algorithms and renaming old ones to better describe them 7 years ago
Selebrator 8d213feecb forbid negafibonacci numbers 7 years ago
Selebrator 04699c95fa Lukas Vorschlag für 12.1
Ich halte mich nicht genau an die Aufgabenstellung um nicht ganz so schlimme verbrechen zu begehen.
Alles was ich anderes gemacht habe ist als Verbesserungsvorschlag zu verstehen.
7 years ago
Selebrator 0d444ad4af Move test to test package so gradle can manage our dependencies 7 years ago
Selebrator 54488df98d tell gradle to use java 12 7 years ago
Lisa feba60b41e Initial commit 12.1 7 years ago
Selebrator 6063ca4b76 Greedy : Selection not immutable -> calculate order when needed.
improve readability
7 years ago
SirTeruki c1e409d82c Initial commit for 11.3 7 years ago
SirTeruki f9288aa4d5 Commit of the provided classed for task number 3 7 years ago
Selebrator de32d5fd23 Wozu eigentlich Atmoic? 7 years ago
Selebrator 81be577d01 Alternative für 11.2 7 years ago
Lisa 2f4251ad53 Initial commit 11.1 and 11.2 7 years ago
Selebrator df3264d284 Weniger Narcismus 7 years ago
Selebrator 8577edd5e7 Ein paar alternative Lösungen für 10.4 7 years ago
Lisa 51328f56cb Initial commit 10.3 7 years ago
Lisa 27fb4e14c5 Initial commit 10.4 7 years ago
Lisa fc0d86554b Initial commit 10.2 7 years ago
Lisa 988047eca0 Initial commit 10.1 7 years ago
Lisa 8e6b4e5a7b Correction ship direction 7 years ago
Selebrator 5a98026252 Merge branch 'master' of github.com:Selebrator/omp-ha-2019 7 years ago
Selebrator 66905d4f0e Merge branch 'master' of github.com:Selebrator/omp-ha-2019 7 years ago
Selebrator 62ad650537 More documentation 7 years ago

@ -11,7 +11,7 @@ project.ext.junitVersion = '5.3.1'
mainClassName = '_9._2.Lights' mainClassName = '_9._2.Lights'
sourceCompatibility = 1.8 sourceCompatibility = 12
repositories { repositories {
mavenCentral() mavenCentral()

@ -0,0 +1,59 @@
package _10._1;
public class SearchThread extends Thread {
private int[] array;
private int value;
private int from;
private int to;
private boolean found = false;
public SearchThread(int[] array, int value, int from, int to) {
this.array = array;
this.value = value;
this.from = from;
this.to = to;
}
public void run() {
for (int i = this.from; i < this.to; i++) {
if (this.array[i] == this.value) {
this.found = true;
System.out.println(this.getName() + ": found");
return;
}
}
System.out.println(this.getName() + ": not found");
}
public boolean getFound() {
return found;
}
public static void main(String[] args) {
int[] array = { 2, 7, 3, 9, 23 };
arraySearch(array,7);
}
private static void arraySearch(int[] array, int value) {
SearchThread thread1 = new SearchThread(array, value, 0, array.length/2);
SearchThread thread2 = new SearchThread(array, value, array.length/2, array.length);
thread1.setName("Thread 1");
thread2.setName("Thread 2");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
if (thread1.getFound() || thread2.getFound()) {
System.out.println("Found: true");
} else {
System.out.println("Found: false");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,53 @@
package _10._2;
import provided._10._2.*;
public class QuickSortThreaded extends QuickSort implements Runnable {
private int[] numbers;
private int leftIndex;
private int rightIndex;
public QuickSortThreaded() {
}
public QuickSortThreaded(int[] numbers, int leftIndex, int rightIndex) {
this.numbers = numbers;
this.leftIndex = leftIndex;
this.rightIndex = rightIndex;
}
@Override
public void run() {
quickSort(numbers, leftIndex, rightIndex);
}
/**
* sortiert das uebergebene Array in aufsteigender Reihenfolge
* gemaess dem QuickSort-Algorithmus (parallel!)
*/
public static void sort(int[] numbers) {
new QuickSortThreaded().quickSort(numbers, 0, numbers.length - 1);
}
/**
* der Quicksort-Algorithmus wird auf dem Array zwischen den
* angegebenen Indizes ausgefuehrt
*/
protected void quickSort(int[] numbers, int leftIndex, int rightIndex) {
if (leftIndex < rightIndex) {
int pivotIndex = divide(numbers, leftIndex, rightIndex);
Thread threadLeft = new Thread(new QuickSortThreaded(numbers, leftIndex, pivotIndex - 1));
Thread threadRight = new Thread(new QuickSortThreaded(numbers, pivotIndex + 1, rightIndex));
threadLeft.start();
threadRight.start();
try {
threadLeft.join(); // Wait for first thread.
threadRight.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

@ -0,0 +1,59 @@
package _10._3;
import java.awt.*;
import provided._10._3.ImageFilter;
public class ImageFilterThreaded extends ImageFilter {
class FilterThread implements Runnable {
private int x1;
private int x2;
private int y1;
private int y2;
private Color[][] result;
private float[][] filter;
private FilterThread(int x1, int x2, int y1, int y2, Color[][] result, float[][] filter) {
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
this.result = result;
this.filter = filter;
}
@Override
public void run() {
for (int x = x1; x < x2; x++) {
for (int y = y1; y < y2; y++) {
filterPixel(result, x, y, filter);
}
}
}
}
@Override
protected Color[][] filterMatrix(float[][] filter) {
Color[][] result = new Color[matrix.length][matrix[0].length];
Thread threadLB = new Thread(new FilterThread(0, matrix.length/2, matrix[0].length/2, matrix[0].length,result,filter));
Thread threadRB = new Thread(new FilterThread(matrix.length/2, matrix.length, matrix[0].length/2, matrix[0].length,result,filter));
Thread threadLT = new Thread(new FilterThread(0, matrix.length/2, 0, matrix[0].length/2,result,filter));
Thread threadRT = new Thread(new FilterThread(matrix.length/2, matrix.length, 0, matrix[0].length/2,result,filter));
threadLB.start();
threadRB.start();
threadLT.start();
threadRT.start();
try {
threadLB.join();
threadRB.join();
threadLT.join();
threadRT.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
}

@ -0,0 +1,55 @@
package _10._4;
public class NameOutput extends Thread {
private NumberData currentNumber;
private int threadNumber;
public NameOutput(int threadNumber, NumberData currentNumber) {
this.threadNumber = threadNumber;
this.currentNumber = currentNumber;
}
@Override
public void run() {
while (true) {
synchronized (currentNumber) {
while (currentNumber.getNumber() != threadNumber) {
try {
currentNumber.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.getName());
currentNumber.increaseNumber();
}
}
}
public static void main(String[] args) {
int numberOfThreads = 3;
NumberData currentNumber = new NumberData(numberOfThreads);
for (int i = 0; i < numberOfThreads; i++) {
Thread thread = new NameOutput(i, currentNumber);
thread.start();
}
}
}
class NumberData {
private int number = 0;
private int modulo;
public NumberData(int modulo) {
this.modulo = modulo;
}
public int getNumber() {
return number;
}
public void increaseNumber() {
this.number = (this.number + 1) % this.modulo;
notifyAll();
}
}

@ -0,0 +1,14 @@
package _10._4.alternative;
public abstract class NameOutput {
private NameOutput() {
}
public static void main(String[] args) {
final int n = 3;
for(int i = 0; i < n; i++) {
new NameOutputFairLock().start();
}
}
}

@ -0,0 +1,31 @@
package _10._4.alternative;
// ordered by creation time, deadlocks if any thread in the chain is interrupted.
public class NameOutputBusyWaiting extends Thread {
private static final Object LOCK = new Object();
private static int counter = 0;
private static int total = 0;
private final int number;
public NameOutputBusyWaiting() {
synchronized(LOCK) {
this.number = total;
total++;
}
}
@Override
public void run() {
while(!this.isInterrupted()) {
synchronized(LOCK) {
if(this.number == counter) {
System.out.println(this.getName());
counter = (counter + 1) % total;
}
}
}
}
}

@ -0,0 +1,22 @@
package _10._4.alternative;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
// ordered by least recent access since creation
public class NameOutputFairLock extends Thread {
private static final Lock LOCK = new ReentrantLock(true);
@Override
public void run() {
while(!this.isInterrupted()) {
LOCK.lock();
try {
System.out.println(this.getName());
} finally {
LOCK.unlock();
}
}
}
}

@ -0,0 +1,37 @@
package _10._4.alternative;
// ordered by creation time, deadlocks if any thread in the chain is interrupted.
public class NameOutputWaitNotify extends Thread {
private static final Object LOCK = new Object();
private static int counter = 0;
private static int total = 0;
private final int number;
public NameOutputWaitNotify() {
synchronized(LOCK) {
this.number = total;
total++;
}
}
@Override
public void run() {
while(!this.isInterrupted()) {
synchronized(LOCK) {
while(this.number != counter) {
try {
LOCK.wait();
} catch(InterruptedException e) {
System.out.println(this.getName() + " was interrupted");
}
}
System.out.println(this.getName());
counter = (counter + 1) % total;
LOCK.notifyAll();
}
}
}
}

@ -0,0 +1,46 @@
package _11._1;
import provided.IO;
import java.util.concurrent.Semaphore;
class Output extends Thread {
public void run() {
try {
InOut.getSemaphore().acquire();
System.out.println(InOut.getValue() * InOut.getValue());
} catch (InterruptedException e) {
}
}
}
class Input extends Thread {
public void run() {
InOut.setValue(IO.readInt("Value: "));
InOut.getSemaphore().release();
}
}
public class InOut {
private static Semaphore semaphore = new Semaphore(0);
private static int value = 0;
public static Semaphore getSemaphore() { return semaphore; }
public static int getValue() {
return value;
}
public static void setValue(int value) {
InOut.value = value;
}
public static void main(String[] args) {
new Output().start();
new Input().start();
}
}

@ -0,0 +1,101 @@
package _11._2;
public class Barriers {
private final static int NUMBER = 3;
public static void main(String[] args) {
Counter obj = new Counter(NUMBER);
NumberRunner[] runner = new NumberRunner[NUMBER];
for (int i = 0; i < NUMBER; i++) {
runner[i] = new NumberRunner(i, obj);
}
for (int i = 0; i < NUMBER; i++) {
runner[i].start();
}
}
}
class Counter {
private final int numb; // Anzahl Threads
private int numberIn = 0; // Anzahl der Threads an Sperre
private int numberOut; // Anzahl der laufenden Threads
public Counter(int number) {
this.numb = number;
this.numberOut = number;
}
public int getMax() { return this.numb; }
public int getIn() {
return this.numberIn;
}
public int getOut() { return this.numberOut; }
public void resetIn() { this.numberIn = 0; }
public void resetOut() { this.numberOut = 0; }
public void incrementIn() { this.numberIn++; }
public void incrementOut() { this.numberOut++; }
}
class NumberRunner extends Thread {
private int number;
private final Counter obj;
public NumberRunner(int n, Counter obj) {
this.number = n;
this.obj = obj;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("Thread " + number + ": " + i);
if (i%10 == 0 && i != 0) {
synchronized (obj) {
try {
// warte, falls andere Threads von vorheriger Sperre noch nicht wieder gestartet sind
while (obj.getOut() < obj.getMax()) {
obj.wait();
}
// Thread kommt an aktueller Sperre an
obj.incrementIn();
// letzter Thread, der ankommt, benachrichtigt alle, dass es weiter gehen kann
if (obj.getIn() >= obj.getMax()) {
obj.resetOut();
obj.notifyAll();
}
// Threads warten, bis alle angekommen sind
while (obj.getIn() < obj.getMax()) {
obj.wait();
}
// Thread startet wieder
obj.incrementOut();
// der letzte Thread, der startet, benachrichtigt alle, dass die naechste Sperre freigegeben ist
if (obj.getOut() == obj.getMax()) {
obj.resetIn();
obj.notifyAll();
}
} catch (InterruptedException e) {
}
}
}
}
}
}

@ -0,0 +1,16 @@
package _11._2.alternative;
public class Barriers {
public static final int NUMBER_OF_RUNNERS = 3;
public static void main(String[] args) {
NumberRunner[] runners = new NumberRunner[NUMBER_OF_RUNNERS];
for(int i = 0; i < NUMBER_OF_RUNNERS; i++) {
runners[i] = new NumberRunner(i);
}
for(int i = 0; i < NUMBER_OF_RUNNERS; i++) {
runners[i].start();
}
}
}

@ -0,0 +1,28 @@
package _11._2.alternative;
public class Checkpoint {
private final Object lock = new Object();
private int groupSize;
private int gathered = 0;
public Checkpoint(int groupSize) {
this.groupSize = groupSize;
}
/**
* Blocks until called by {@link #groupSize} different Threads,
* then wakes all of them up again.
*/
public void gather() throws InterruptedException {
synchronized(this.lock) {
if(++this.gathered != this.groupSize) {
this.lock.wait();
} else {
this.gathered = 0;
System.out.println("Group gathered");
this.lock.notifyAll();
}
}
}
}

@ -0,0 +1,27 @@
package _11._2.alternative;
public class NumberRunner extends Thread {
private static final Checkpoint CHECKPOINT = new Checkpoint(Barriers.NUMBER_OF_RUNNERS);
private final int id;
public NumberRunner(int id) {
this.id = id;
}
@Override
public void run() {
for(int i = 0; i < 1000; i++) {
if(i % 10 == 0) {
try {
CHECKPOINT.gather();
} catch(InterruptedException e) {
throw new IllegalStateException("Group can never be complete again, because one of the members got lost", e);
}
}
System.out.println("Thread " + this.id + ": " + i);
}
}
}

@ -0,0 +1,35 @@
package _11._3;
import provided._11._3.Item;
import provided._11._3.Knapsack;
import provided._11._3.Selection;
import java.util.*;
public class KnapsackDynamic extends Knapsack {
public KnapsackDynamic(int capacity, Collection<Item> candidates) {
super(capacity, candidates);
}
@Override
public Selection pack() {
return this.pack(new Selection(), new HashMap<>());
}
private Selection pack(Selection parent, Map<Integer, Selection> memory) {
return memory.computeIfAbsent(parent.getWeight(), weight -> {
final Collection<Selection> children = new ArrayList<>();
for(Item candidate : this.candidates) {
if(parent.getWeight() + candidate.getWeight() <= this.capacity) {
children.add(pack(new Selection(parent, candidate), memory));
}
}
return children.stream()
.max(Comparator.comparingDouble(Selection::getValue))
.orElse(parent);
});
}
}

@ -0,0 +1,43 @@
package _11._3;
import provided._11._3.Item;
import provided._11._3.Knapsack;
import provided._11._3.Selection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
public class KnapsackGreedy extends Knapsack {
private static final Comparator<Item> DESCENDING_ITEM_VALUE_COMPARATOR
= Comparator.comparing(Item::getValue).reversed();
public KnapsackGreedy(int capacity, Collection<Item> candidates) {
super(capacity, candidates);
}
@Override
public Selection pack() {
final List<Item> orderedCandidates = new ArrayList<>(this.candidates);
orderedCandidates.sort(DESCENDING_ITEM_VALUE_COMPARATOR);
/*
* Fügt das wertvollste Item hinzu, solange es noch passt, geht
* dann zum nächst wertvolleren Item über und wiederholt den Vorgang
* so lange bis kein Item mehr passt.
*/
Selection selection = new Selection();
for(Item candidate : orderedCandidates) {
while(selection.getWeight() + candidate.getWeight() <= this.capacity) {
selection = new Selection(selection, candidate);
/*
* Der Speicher leidet hier sehr,
* weil Selection#add(Item) private ist.
*/
}
}
return selection;
}
}

@ -0,0 +1,35 @@
package _11._3;
import provided._11._3.Item;
import provided._11._3.Knapsack;
import provided._11._3.Selection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
public class KnapsackRecursive extends Knapsack {
public KnapsackRecursive(int capacity, Collection<Item> candidates) {
super(capacity, candidates);
}
@Override
public Selection pack() {
return this.pack(new Selection());
}
private Selection pack(Selection parent) {
final Collection<Selection> children = new ArrayList<>();
for(Item candidate : this.candidates) {
if(parent.getWeight() + candidate.getWeight() <= this.capacity) {
children.add(pack(new Selection(parent, candidate)));
}
}
return children.stream()
.max(Comparator.comparingDouble(Selection::getValue))
.orElse(parent);
}
}

@ -0,0 +1,26 @@
package _12._1;
import provided._12._1.Fibonacci;
import java.util.HashMap;
import java.util.Map;
public class FibonacciDynamic extends Fibonacci {
protected Map<Integer, Long> map = new HashMap<>();
public FibonacciDynamic() {
this.map.put(0, (long) 0);
this.map.put(1, (long) 1);
}
@Override
public long calculate(int n) {
if (this.map.containsKey(n)) {
return this.map.get(n);
} else {
long result = calculate(n-1) + calculate(n-2);
this.map.put(n, result);
return result;
}
}
}

@ -0,0 +1,47 @@
package _12._1;
public class FibonacciDynamicParallel extends FibonacciDynamic {
@Override
public long calculate(int n) {
if (this.map.containsKey(n)) {
return this.map.get(n);
} else {
FibonacciThread thread1 = new FibonacciThread(n-1);
FibonacciThread thread2 = new FibonacciThread(n-2);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
long result = thread1.getResult() + thread2.getResult();
this.map.put(n, result);
return result;
}
}
class FibonacciThread extends Thread {
private int n;
private long result;
public FibonacciThread(int n) {
this.n = n;
}
@Override
public void run() {
result = calculate(n);
}
public long getResult() {
return result;
}
}
}

@ -0,0 +1,50 @@
package _12._1;
import provided._12._1.Fibonacci;
public class FibonacciParallel extends Fibonacci {
@Override
public long calculate(int n) {
if (n == 0) {
return 0;
} else if (n == 1) {
return 1;
} else {
FibonacciThread thread1 = new FibonacciThread(n-1);
FibonacciThread thread2 = new FibonacciThread(n-2);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return thread1.getResult() + thread2.getResult();
}
}
class FibonacciThread extends Thread {
private int n;
private long result;
public FibonacciThread(int n) {
this.n = n;
}
@Override
public void run() {
result = calculate(n);
}
public long getResult() {
return result;
}
}
}

@ -0,0 +1,17 @@
package _12._1;
import provided._12._1.Fibonacci;
public class FibonacciRecursive extends Fibonacci {
@Override
public long calculate(int n) {
if (n == 0) {
return 0;
} else if (n == 1) {
return 1;
} else {
return calculate(n-1) + calculate(n-2);
}
}
}

@ -0,0 +1,33 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
/*
* F(2n) = F(n) * (2*F(n+1) - F(n)).
* F(2n+1) = F(n+1)^2 + F(n)^2.
*
* O(log(n))
*/
public class FibonacciDoubling extends Fibonacci {
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
long a = 0L;
long b = 1L;
for(int bit = Integer.highestOneBit(n); bit != 0; bit >>>= 1) {
long aTemp = a * ((2 * b) - a);
long bTemp = a * a + b * b;
a = aTemp;
b = bTemp;
if((n & bit) != 0) {
long c = a + b;
a = b;
b = c;
}
}
return a;
}
}

@ -0,0 +1,20 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
// iterative, dynamic programing with minimal memory usage
public class FibonacciDynamicIterative extends Fibonacci {
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
long a = 0L, b = 1L, c;
for(int i = 0; i < n; i++) {
c = a + b;
a = b;
b = c;
}
return a;
}
}

@ -0,0 +1,31 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
import java.util.HashMap;
import java.util.Map;
// uses recursion and dynamic programing with persistent memory
public class FibonacciDynamicRecursivePersistent extends Fibonacci {
private final Map<Integer, Long> memory = new HashMap<>();
{
this.memory.put(0, 0L);
this.memory.put(1, 1L);
}
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
if(this.memory.containsKey(n)) {
return this.memory.get(n);
}
long result = calculate(n - 1) + calculate(n - 2);
this.memory.put(n, result);
return result;
}
}

@ -0,0 +1,46 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
import java.util.HashMap;
import java.util.Map;
// eats up the heap
public class FibonacciDynamicRecursivePersistentParallel extends Fibonacci {
private final Map<Integer, Long> memory = new HashMap<>();
{
this.memory.put(0, 0L);
this.memory.put(1, 1L);
}
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
if(this.memory.containsKey(n)) {
return this.memory.get(n);
}
final long result;
{
final long[] parts = new long[2];
Thread big = new Thread(() -> parts[0] = calculate(n - 1));
Thread small = new Thread(() -> parts[1] = calculate(n - 2));
big.start();
small.start();
try {
big.join();
small.join();
result = parts[0] + parts[1];
} catch(InterruptedException e) {
throw new IllegalStateException(e);
}
}
this.memory.put(n, result);
return result;
}
}

@ -0,0 +1,16 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
public class FibonacciRecursive extends Fibonacci {
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
if(n == 0 || n == 1) {
return n;
}
return calculate(n - 1) + calculate(n - 2);
}
}

@ -0,0 +1,30 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
// rest in peace ram
public class FibonacciRecursiveParallel extends Fibonacci {
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
if(n == 0 || n == 1) {
return n;
}
final long[] parts = new long[2];
Thread big = new Thread(() -> parts[0] = calculate(n - 1));
Thread small = new Thread(() -> parts[1] = calculate(n - 2));
big.start();
small.start();
try {
big.join();
small.join();
return parts[0] + parts[1];
} catch(InterruptedException e) {
throw new IllegalStateException(e);
}
}
}

@ -0,0 +1,70 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
public class FibonacciTiming {
private static final int[] NUMBERS = new int[]{ 3, 5, 8, 12, 9, 18, 15, 10, 7, 11, 20 };
private static final Fibonacci RECURSIVE = new FibonacciRecursive();
private static final Fibonacci PARALLEL_RECURSIVE = new FibonacciRecursiveParallel();
private static final Fibonacci DYNAMIC = new FibonacciDynamicRecursivePersistent();
private static final Fibonacci PARALLEL_DYNAMIC = new FibonacciDynamicRecursivePersistentParallel();
private static final Fibonacci ITERATIVE = new FibonacciDynamicIterative();
// can take a few minutes
public static void main(String[] args) {
System.out.println("# Sequential");
System.out.println("FibonacciRecursive (first): " + formatTime(
Timing.measureNanos(() -> generateHeat(RECURSIVE))
));
System.out.println("FibonacciDynamicRecursivePersistent (first): " + formatTime(
Timing.measureNanos(() -> generateHeat(DYNAMIC))
));
System.out.println("FibonacciDynamicIterative (first): " + formatTime(
Timing.measureNanos(() -> generateHeat(ITERATIVE))
));
System.out.println("FibonacciRecursive (1M iteration average): " + formatTime(
Timing.measureAverageNanos(1_000_000, () -> generateHeat(RECURSIVE))
));
System.out.println("FibonacciDynamicRecursivePersistent (1M iteration average): " + formatTime(
Timing.measureAverageNanos(1_000_000, () -> generateHeat(DYNAMIC))
));
System.out.println("FibonacciDynamicIterative (1M iteration average): " + formatTime(
Timing.measureAverageNanos(1_000_000, () -> generateHeat(ITERATIVE))
));
System.out.println("# Parallel");
System.out.println("FibonacciRecursiveParallel (first): " + formatTime(
Timing.measureNanos(() -> generateHeat(PARALLEL_RECURSIVE))
));
System.out.println("FibonacciDynamicRecursivePersistentParallel (first): " + formatTime(
Timing.measureNanos(() -> generateHeat(PARALLEL_DYNAMIC))
));
System.out.println("FibonacciRecursiveParallel (10 iteration average): " + formatTime(
Timing.measureAverageNanos(10, () -> generateHeat(PARALLEL_RECURSIVE))
));
System.out.println("FibonacciDynamicRecursivePersistentParallel (1M iteration average): " + formatTime(
Timing.measureAverageNanos(1_000_000, () -> generateHeat(PARALLEL_DYNAMIC))
));
}
private static void generateHeat(Fibonacci calculator) {
for(int n : NUMBERS) {
calculator.calculate(n);
}
}
private static String formatTime(double nanos) {
double digits = Math.log10(nanos);
if(digits > 9) {
return Math.round(nanos / 1e7) / 1e2 + " seconds";
} else if(digits > 6) {
return Math.round(nanos / 1e4) / 1e2 + " milliseconds";
} else if(digits > 3) {
return Math.round(nanos / 1e1) / 1e2 + " microseconds";
} else {
return Math.round(nanos) + " nanoseconds";
}
}
}

@ -0,0 +1,18 @@
package _12._1.lukas;
public class Timing {
public static long measureNanos(Runnable runnable) {
long start = System.nanoTime();
runnable.run();
return System.nanoTime() - start;
}
public static double measureAverageNanos(int iterations, Runnable runnable) {
long start = System.nanoTime();
for(int i = 0; i < iterations; i++) {
runnable.run();
}
return (System.nanoTime() - start) / (double) iterations;
}
}

@ -184,6 +184,18 @@ public class Lecture {
Files.write(file, lines); Files.write(file, lines);
} }
/*
* Bitte um Feedback, untere lösung (loadText2)
* macht weniger Annahmen.
*
* Zeilenumbrüche zwischen name-value Paaren.
* Whitespace weglassen macht probleme. Ist kompatibel mit
* dem outout von saveText.
* Nur eine Lecture pro Datei.
*
*
*
*/
public static Lecture loadText(String filename) throws IOException { public static Lecture loadText(String filename) throws IOException {
Path file = Paths.get(filename); Path file = Paths.get(filename);
List<String> data = Files.readAllLines(file); List<String> data = Files.readAllLines(file);

@ -56,6 +56,7 @@ public class SonReader implements Closeable {
} }
} }
/* true untill the current inner most array or object is out of elements */
public boolean hasNext() throws IOException { public boolean hasNext() throws IOException {
int c = this.nextNonWhitespace(); int c = this.nextNonWhitespace();
this.rememberChar(c); this.rememberChar(c);
@ -93,6 +94,7 @@ public class SonReader implements Closeable {
return name.toString().trim(); return name.toString().trim();
} }
/* put the reder in a state where it can accept a name */
private void prepareName() throws IOException { private void prepareName() throws IOException {
SonState state = this.peekState(); SonState state = this.peekState();
if(state == NONEMPTY_OBJECT) { // not first in an object if(state == NONEMPTY_OBJECT) { // not first in an object
@ -104,6 +106,8 @@ public class SonReader implements Closeable {
this.replaceTopState(DANGLING_NAME); this.replaceTopState(DANGLING_NAME);
} }
/* put the reder in a state where it can accept a value
*/
private void prepareValue() throws IOException { private void prepareValue() throws IOException {
SonState state = this.peekState(); SonState state = this.peekState();
switch(state) { switch(state) {
@ -136,6 +140,8 @@ public class SonReader implements Closeable {
return value.toString().trim(); return value.toString().trim();
} }
/* should recursively skip a value */
//TODO funktioniert nicht so wie es soll
public void skipValue() throws IOException { public void skipValue() throws IOException {
this.prepareValue(); this.prepareValue();
int count = 0; int count = 0;

@ -1,17 +1,19 @@
package _9._3.observer; package _9._3;
import provided._9.Observer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public abstract class Observable<Who extends Observable<Who, What>, What> { public abstract class Observable {
private List<Observer<Who, What>> observers = new ArrayList<>(); private List<Observer> observers = new ArrayList<>();
private boolean changed = false; private boolean changed = false;
public void addObserver(Observer<Who, What> o) { public void addObserver(Observer o) {
this.observers.add(o); this.observers.add(o);
} }
public void removeObserver(Observer<Who, What> o) { public void removeObserver(Observer o) {
this.observers.remove(o); this.observers.remove(o);
} }
@ -27,10 +29,10 @@ public abstract class Observable<Who extends Observable<Who, What>, What> {
return changed; return changed;
} }
public void notifyObservers(What what) { public void notifyObservers(ShipEvent what) {
if (this.isChanged()) { if (this.isChanged()) {
for (Observer<Who, What> observer : observers) { for (Observer observer : observers) {
observer.update((Who) this, what); observer.update(this, what);
} }
this.clearChanged(); this.clearChanged();
} }

@ -1,8 +1,6 @@
package _9._3; package _9._3;
import _9._3.observer.Observable; public class Ship extends Observable {
public class Ship extends Observable<Ship, ShipEvent> {
private boolean sailsSet = false; private boolean sailsSet = false;
private boolean cannonsLoaded = false; private boolean cannonsLoaded = false;
private int heading = 0; private int heading = 0;
@ -15,10 +13,6 @@ public class Ship extends Observable<Ship, ShipEvent> {
} }
} }
public boolean isSailsSet() {
return this.sailsSet;
}
public void strikeSails() { public void strikeSails() {
if (sailsSet) { if (sailsSet) {
sailsSet = false; sailsSet = false;
@ -43,12 +37,12 @@ public class Ship extends Observable<Ship, ShipEvent> {
} }
} }
public boolean isCannonsLoaded() {
return this.cannonsLoaded;
}
public void turnLeft() { public void turnLeft() {
heading = (heading - 90) % 180; if (heading - 90 < 0) {
heading = 360 + ((heading - 90) % 360);
} else {
heading = (heading - 90) % 360;
}
this.setChanged(); this.setChanged();
notifyObservers(ShipEvent.TURN_LEFT); notifyObservers(ShipEvent.TURN_LEFT);
} }
@ -58,8 +52,4 @@ public class Ship extends Observable<Ship, ShipEvent> {
this.setChanged(); this.setChanged();
notifyObservers(ShipEvent.TURN_RIGHT); notifyObservers(ShipEvent.TURN_RIGHT);
} }
public int getHeading() {
return this.heading;
}
} }

@ -1,6 +1,6 @@
package _9._3; package _9._3;
import java.util.concurrent.ThreadLocalRandom; import java.util.Random;
public enum ShipEvent { public enum ShipEvent {
@ -13,6 +13,7 @@ public enum ShipEvent {
TURN_RIGHT; TURN_RIGHT;
public static ShipEvent getRandomShipEvent() { public static ShipEvent getRandomShipEvent() {
return values()[ThreadLocalRandom.current().nextInt(values().length)]; Random random = new Random();
return values()[random.nextInt(values().length)];
} }
} }

@ -1,10 +1,11 @@
package _9._3; package _9._3;
import _9._3.observer.Observer; import provided._9.Observer;
public class ShipLog implements Observer<Ship, ShipEvent> { public class ShipLog implements Observer {
private int heading = 0;
@Override @Override
public void update(Ship who, ShipEvent what) { public void update(Observable who, ShipEvent what) {
switch (what) { switch (what) {
case SET_SAILS: case SET_SAILS:
System.out.println("Sails set."); System.out.println("Sails set.");
@ -19,10 +20,16 @@ public class ShipLog implements Observer<Ship, ShipEvent> {
System.out.println("Cannons fired."); System.out.println("Cannons fired.");
break; break;
case TURN_LEFT: case TURN_LEFT:
System.out.println("Turned left. New heading " + who.getHeading() + " degrees."); if (heading - 90 < 0) {
heading = 360 + ((heading - 90) % 360);
} else {
heading = (heading - 90) % 360;
}
System.out.println("Turned left. New heading " + heading + " degrees.");
break; break;
case TURN_RIGHT: case TURN_RIGHT:
System.out.println("Turned right. New heading " + who.getHeading() + " degrees."); heading = (heading + 90) % 360;
System.out.println("Turned right. New heading " + heading + " degrees.");
break; break;
} }
} }

@ -1,5 +0,0 @@
package _9._3.observer;
public interface Observer<Who extends Observable<Who, What>, What> {
void update(Who who, What what);
}

@ -0,0 +1,80 @@
package provided._10._2;
public class QuickSort {
/**
* sortiert das uebergebene Array in aufsteigender Reihenfolge
* gemaess dem QuickSort-Algorithmus
*/
public static void sort(int[] numbers) {
new QuickSort().quickSort(numbers, 0, numbers.length - 1);
}
/**
* der Quicksort-Algorithmus wird auf dem Array zwischen den
* angegebenen Indizes ausgefuehrt
*/
protected void quickSort(int[] numbers, int leftIndex, int rightIndex) {
if (leftIndex < rightIndex) {
int pivotIndex = divide(numbers, leftIndex, rightIndex);
quickSort(numbers, leftIndex, pivotIndex - 1);
quickSort(numbers, pivotIndex + 1, rightIndex);
}
}
/**
* liefert den Index des Pivot-Elementes und ordnet das Array innerhalb
* der angegebenen Indizes so um, dass alle Zahlen links vom Index
* kleiner oder gleich und alle Zahlen rechts vom Index groesser
* oder gleich dem Pivot-Element sind
*/
protected int divide(int[] numbers, int leftIndex, int rightIndex) {
int pivotIndex = choosePivotIndex(numbers, leftIndex, rightIndex);
int pivotValue = numbers[pivotIndex];
// das Pivot-Element kommt nach ganz rechts im Array
swap(numbers, pivotIndex, rightIndex);
int left = leftIndex - 1;
int right = rightIndex;
// ordne das Array so um, dass jeweils alle Elemente links vom
// Zeiger left kleiner und alle Elemente rechts vom Zeiger right
// groesser als das Pivot-Element sind
do {
left++;
while (left <= rightIndex && numbers[left] <= pivotValue)
left++;
right--;
while (right >= leftIndex && numbers[right] >= pivotValue)
right--;
if (left < right) {
swap(numbers, left, right);
}
} while (left < right);
// platziere das Pivot-Element an seine korrekte Position
if (left < rightIndex) {
swap(numbers, left, rightIndex);
return left;
} else {
return rightIndex;
}
}
/**
* waehlt einen beliebigen Index zwischen den angegebenen Indizes
*/
protected int choosePivotIndex(int[] numbers, int leftIndex, int rightIndex) {
// in diesem Fall einfach der mittleren Index
return (leftIndex + rightIndex) / 2;
}
/**
* tauscht die Elemente des Arrays an den angegebenen Indizes
*/
protected void swap(int[] numbers, int index1, int index2) {
if (index1 != index2) {
int tmp = numbers[index1];
numbers[index1] = numbers[index2];
numbers[index2] = tmp;
}
}
}

@ -0,0 +1,26 @@
package provided._10._2;
import _10._2.QuickSortThreaded;
public class QuickSortTest {
public static void main(String[] args) {
int[] numbers = {2, 3, 9, 33, -2, 4, 55, 66, -234};
print(numbers);
QuickSort.sort(numbers);
print(numbers);
int[] numbers2 = {2, 3, 9, 33, -2, 4, 55, 66, -234};
print(numbers2);
QuickSortThreaded.sort(numbers2);
print(numbers2);
}
private static void print(int[] numbers) {
for (int number : numbers) {
System.out.print(number + " ");
}
System.out.println();
}
}

@ -0,0 +1,113 @@
package provided._10._3;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImageFilter {
private static final int FILTER_SIZE = 3;
private static final int OFFSET = FILTER_SIZE / 2;
public static final float[][] FILTER_BLUR = new float[][] {
{ 0.111f, 0.111f, 0.111f },
{ 0.111f, 0.111f, 0.111f },
{ 0.111f, 0.111f, 0.111f }
};
public static final float[][] FILTER_SHARPEN = new float[][] {
{ 0.f, -1f, 0.f },
{ -1f, 5f, -1f },
{ 0.f, -1f, 0.f }
};
public static final float[][] FILTER_LINES = new float[][] {
{ -1f, -1f, -1f },
{ -1f, 8f, -1f },
{ -1f, -1f, -1f }
};
protected Color[][] matrix = new Color[0][0];
public void setImage(File input) throws IOException {
BufferedImage img = ImageIO.read(input);
getMatrix(img);
}
public void applyFilter(float[][] filter, File output) throws IOException, InvalidFilterException {
if (filter == null || filter.length != FILTER_SIZE || filter[0].length != FILTER_SIZE) {
throw new InvalidFilterException();
}
Color[][] result = filterMatrix(filter);
BufferedImage img = new BufferedImage(result.length, result[0].length, BufferedImage.TYPE_INT_ARGB);
setMatrix(img, result);
ImageIO.write(img, "jpg", output);
}
protected Color[][] filterMatrix(float[][] filter) {
Color[][] result = new Color[matrix.length][matrix[0].length];
for (int x = 0; x < matrix.length; x++) {
for (int y = 0; y < matrix[x].length; y++) {
filterPixel(result, x, y, filter);
}
}
return result;
}
protected void filterPixel(Color[][] result, int x, int y, float[][] filter) {
Color[][] colors = getColorMatrix(x, y);
float red = 0;
float green = 0;
float blue = 0;
for (int i = 0; i < FILTER_SIZE; i++) {
for (int j = 0; j < FILTER_SIZE; j++) {
red += (float) colors[i][j].getRed() * filter[i][j];
green += (float) colors[i][j].getGreen() * filter[i][j];
blue += (float) colors[i][j].getBlue() * filter[i][j];
}
}
red = Math.min(red, 255);
red = Math.max(red, 0);
green = Math.min(green, 255);
green = Math.max(green, 0);
blue = Math.min(blue, 255);
blue = Math.max(blue, 0);
result[x][y] = new Color(Math.round(red), Math.round(green), Math.round(blue));
}
protected Color[][] getColorMatrix(int x, int y) {
Color[][] result = new Color[FILTER_SIZE][FILTER_SIZE];
for (int i = 0; i < FILTER_SIZE; i++) {
for (int j = 0; j < FILTER_SIZE; j++) {
result[i][j] = getColor(x + (i - OFFSET), y + (j - OFFSET));
}
}
return result;
}
protected Color getColor(int x, int y) {
x = Math.min(x, matrix.length - 1);
x = Math.max(x, 0);
y = Math.min(y, matrix[0].length - 1);
y = Math.max(y, 0);
return matrix[x][y];
}
private void setMatrix(BufferedImage img, Color[][] matrix) {
for (int x=0;x<matrix.length;x++) {
for (int y=0;y<matrix[x].length;y++) {
img.setRGB(x, y, matrix[x][y].getRGB());
}
}
}
private void getMatrix(BufferedImage img) {
matrix = new Color[img.getWidth()][img.getHeight()];
for (int x=0;x<img.getWidth();x++) {
for (int y=0;y<img.getHeight();y++) {
matrix[x][y] = new Color(img.getRGB(x, y));
}
}
}
}

@ -0,0 +1,51 @@
package provided._10._3;
import _10._3.ImageFilterThreaded;
import java.io.File;
import java.io.IOException;
public class ImageFilterTest {
private static final int REPETITIONS = 5;
public static void main(String[] args) {
ImageFilter filterSequential = new ImageFilter();
ImageFilter filterThreaded = new ImageFilterThreaded();
try {
filterSequential.setImage(new File("./university_of_oldenburg.jpg"));
filterThreaded.setImage(new File("./university_of_oldenburg.jpg"));
} catch (IOException e) {
e.printStackTrace();
return;
}
long start;
long stop;
long time;
start = System.nanoTime();
for (int i = 0; i < REPETITIONS; i++) {
runFilters(filterSequential);
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Sequential runtime: " + time + " ms");
start = System.nanoTime();
for (int i = 0; i < REPETITIONS; i++) {
runFilters(filterThreaded);
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Threaded runtime: " + time + " ms");
}
private static void runFilters(ImageFilter filter) {
try {
filter.applyFilter(ImageFilter.FILTER_BLUR, new File("./university_of_oldenburg_blur.jpg"));
filter.applyFilter(ImageFilter.FILTER_SHARPEN, new File("./university_of_oldenburg_sharpen.jpg"));
filter.applyFilter(ImageFilter.FILTER_LINES, new File("./university_of_oldenburg_lines.jpg"));
} catch (IOException | InvalidFilterException e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,7 @@
package provided._10._3;
public class InvalidFilterException extends Exception {
private static final long serialVersionUID = 1L;
}

@ -0,0 +1,76 @@
package provided._11._3;
public class Item {
private String name;
private int value;
private int weight;
public Item(String name, int value, int weight) {
super();
this.name = name;
this.value = value;
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@Override
public String toString() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + value;
result = prime * result + weight;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Item other = (Item) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (value != other.value)
return false;
if (weight != other.weight)
return false;
return true;
}
}

@ -0,0 +1,67 @@
package provided._11._3;
import _11._3.KnapsackDynamic;
import _11._3.KnapsackGreedy;
import _11._3.KnapsackRecursive;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public abstract class Knapsack {
protected List<Item> candidates = new ArrayList<>();
protected int capacity;
public Knapsack(int capacity, Collection<Item> candidates) {
super();
this.capacity = capacity;
this.candidates.addAll(candidates);
}
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
public List<Item> getCandidates() {
return candidates;
}
public abstract Selection pack();
private static final int REPETITIONS = 5;
private static final int CAPACITY = 49;
public static void main(String[] args) {
List<Item> items = new ArrayList<>();
items.add(new Item("Banknote", 100, 1));
items.add(new Item("Goldbar", 1000, 30));
items.add(new Item("Diamond", 750, 5));
test("Recursive", new KnapsackRecursive(CAPACITY, items));
test("Greedy", new KnapsackGreedy(CAPACITY, items));
test("Dynamic Programming", new KnapsackDynamic(CAPACITY, items));
}
private static void test(String title, Knapsack knapsack) {
System.out.print(title);
Selection result = null;
long totalNs = 0;
for (int i = 0; i < REPETITIONS; i++) {
long start = System.nanoTime();
result = knapsack.pack();
long stop = System.nanoTime();
totalNs += stop - start;
System.out.print(".");
}
System.out.println("\n\t" + result);
totalNs /= REPETITIONS;
long totalMs = totalNs / 1000000L;
System.out.println("\tTime required: " + totalNs + " ns (~ " + totalMs + " ms)");
System.out.println();
}
}

@ -0,0 +1,114 @@
package provided._11._3;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Selection {
private Map<Item, Integer> items = new HashMap<>();
private int value;
private int weight;
public Selection() {
super();
}
public Selection(Selection previous) {
super();
items.putAll(previous.items);
value = previous.value;
weight = previous.weight;
}
public Selection(Selection previous, Item item) {
super();
items.putAll(previous.items);
value = previous.value;
weight = previous.weight;
add(item);
}
private void add(Item item) {
items.put(item, getCount(item) + 1);
value += item.getValue();
weight += item.getWeight();
}
public int getCount(Item item) {
Integer result = items.get(item);
if (result == null) {
result = 0;
}
return result;
}
public Collection<Item> getItems() {
return items.keySet();
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append("Value: ");
b.append(value);
b.append(", weight: ");
b.append(weight);
b.append(", items: ");
List<Item> list = new ArrayList<>(items.keySet());
list.sort((i1, i2) -> i1.getName().compareTo(i2.getName()));
for (int i = 0; i < list.size(); i++) {
b.append(items.get(list.get(i)));
b.append("x ");
b.append(list.get(i).getName());
if (i < list.size() - 1) {
b.append(", ");
}
}
return b.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((items == null) ? 0 : items.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Selection other = (Selection) obj;
if (items == null) {
if (other.items != null)
return false;
} else if (!items.equals(other.items))
return false;
return true;
}
}

@ -0,0 +1,7 @@
package provided._12._1;
public abstract class Fibonacci {
public abstract long calculate(int n);
}

@ -0,0 +1,10 @@
package provided._9;
import _9._3.Observable;
import _9._3.ShipEvent;
public interface Observer {
void update(Observable who, ShipEvent what);
}

@ -0,0 +1,81 @@
package _12._1;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class FibonacciTest {
private static final int[] NUMBERS = new int[] { 3, 5, 8, 12, 9, 18, 15, 10, 7, 11, 20 };
@Test
void test() {
int count = 0;
long start;
long stop;
long time;
start = System.nanoTime();
FibonacciRecursive r = new FibonacciRecursive();
long[] rResult = new long[NUMBERS.length];
for (int i : NUMBERS) {
rResult[count] = r.calculate(i);
count++;
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Rekursiv runtime: " + time + " ms");
count = 0;
start = System.nanoTime();
FibonacciParallel p = new FibonacciParallel();
long[] pResult = new long[NUMBERS.length];
for (int i : NUMBERS) {
pResult[count] = p.calculate(i);
count++;
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Parallel runtime: " + time + " ms");
count = 0;
start = System.nanoTime();
FibonacciDynamic d = new FibonacciDynamic();
long[] dResult = new long[NUMBERS.length];
for (int i : NUMBERS) {
dResult[count] = d.calculate(i);
count++;
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Dynamic runtime: " + time + " ms");
count = 0;
start = System.nanoTime();
FibonacciDynamicParallel dp = new FibonacciDynamicParallel();
long[] dpResult = new long[NUMBERS.length];
for (int i : NUMBERS) {
dpResult[count] = dp.calculate(i);
count++;
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Dynamic Parallel runtime: " + time + " ms");
for (int i = 0; i < NUMBERS.length; i++) {
assertEquals(rResult[i], pResult[i]);
assertEquals(rResult[i], dResult[i]);
assertEquals(rResult[i], dpResult[i]);
assertEquals(pResult[i], dResult[i]);
assertEquals(pResult[i], dpResult[i]);
assertEquals(dResult[i], dpResult[i]);
}
}
}

@ -0,0 +1,59 @@
package _12._1.lukas;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import provided._12._1.Fibonacci;
import java.util.Map;
public class FibonacciTest {
private static final Map<Integer, Long> NUMBERS = Map.ofEntries(
Map.entry(3, 2L),
Map.entry(5, 5L),
Map.entry(8, 21L),
Map.entry(12, 144L),
Map.entry(9, 34L),
Map.entry(18, 2584L),
Map.entry(15, 610L),
Map.entry(10, 55L),
Map.entry(7, 13L),
Map.entry(11, 89L),
Map.entry(20, 6765L)
);
@Test
void recursive() {
Fibonacci calculator = new FibonacciRecursive();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
@Test
void recursiveParallel() {
Fibonacci calculator = new FibonacciRecursiveParallel();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
@Test
void dynamicRecursivePersistent() {
Fibonacci calculator = new FibonacciDynamicRecursivePersistent();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
@Test
void dynamicRecursivePersistentParallel() {
Fibonacci calculator = new FibonacciDynamicRecursivePersistentParallel();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
@Test
void dynamicIterative() {
Fibonacci calculator = new FibonacciDynamicIterative();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
@Test
void doubling() {
Fibonacci calculator = new FibonacciDoubling();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
}
Loading…
Cancel
Save