diff --git a/Uebung 6/Uebung6_1/Makefile b/Uebung 6/Uebung6_1/Makefile new file mode 100644 index 0000000..e0ef2d8 --- /dev/null +++ b/Uebung 6/Uebung6_1/Makefile @@ -0,0 +1,52 @@ + +# Name of the binary for Development +BINARY = main +# Name of the binary for Release +FINAL = prototyp +# Object files +OBJS = mergeSortRand.o helperFunctions.o main.o +# Compiler flags +CFLAGS = -Werror -Wall -std=c++17 -g#-fsanitize=address,undefined -g +# Linker flags +LFLAGS = #-fsanitize=address,undefined +#Which Compiler to use +COMPILER = g++ + + +# all target: builds all important targets +all: binary + +final : ${OBJS} + ${COMPILER} ${LFLAGS} -o ${FINAL} ${OBJS} + rm ${OBJS} + +binary : ${OBJS} + ${COMPILER} ${LFLAGS} -o ${BINARY} ${OBJS} + +# Links the binary +${BINARY} : ${OBJS} + ${COMPILER} ${LFLAGS} -o ${BINARY} ${OBJS} + + +# Compiles a source-file (any file with file extension .c) into an object-file +# +# "%" is a wildcard which matches every file-name (similar to * in regular expressions) +# Such a rule is called a pattern rule (because it matches a pattern, see https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html), +# which are a form of so called implicit rules (see https://www.gnu.org/software/make/manual/html_node/Implicit-Rules.html) +# "$@" and "$<" are so called automatic variables (see https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html) +%.o : %.cpp + ${COMPILER} -c ${CFLAGS} -o $@ $< + + +# Rules can not only be used for compiling a program but also for executing a program +run: ${BINARY} + ./${BINARY} + + +# Delete all build artifacts +clean : + rm -rf ${BINARY} ${OBJS} + + +# all and clean are a "phony" targets, meaning they are no files +.PHONY : all clean diff --git a/Uebung 6/Uebung6_1/helperFunctions.cpp b/Uebung 6/Uebung6_1/helperFunctions.cpp new file mode 100644 index 0000000..3c3ce5c --- /dev/null +++ b/Uebung 6/Uebung6_1/helperFunctions.cpp @@ -0,0 +1,20 @@ +#include "helperFunctions.h" +#include + +void printArray(int* array, int arrayLength, std::string heading) { + std::cout << "========== " << heading << " ==========" << std::endl; + for(int i = 0; i < arrayLength; i++) { + if(i > 0) { + std::cout << " - "; + } + std::cout << array[i]; + } + std::cout << std::endl << "==============================================" << std::endl; +} + +void generateRandomIntArray(int* array, int arrayLength) { + std::srand(std::time(NULL)); + for(int i = 0; i < arrayLength; i++) { + array[i] = rand() % 100000 + 1; + } +} \ No newline at end of file diff --git a/Uebung 6/Uebung6_1/helperFunctions.h b/Uebung 6/Uebung6_1/helperFunctions.h new file mode 100644 index 0000000..9513b3d --- /dev/null +++ b/Uebung 6/Uebung6_1/helperFunctions.h @@ -0,0 +1,7 @@ +#include +#include + +#pragma once + +void generateRandomIntArray(int* array, int arrayLength); +void printArray(int* array, int arrayLength, std::string heading); \ No newline at end of file diff --git a/Uebung 6/Uebung6_1/main.cpp b/Uebung 6/Uebung6_1/main.cpp new file mode 100644 index 0000000..7517679 --- /dev/null +++ b/Uebung 6/Uebung6_1/main.cpp @@ -0,0 +1,157 @@ +#include +#include + +#include "helperFunctions.h" +#include "mergeSortRand.h" +#include + +#define ARRAY_LENGTH 10 + +class PerformanceTest { +private: + double minExecutionTime; + double maxExecutionTime; + double totalExecutionTime; + std::string algorithmName; + +public: + PerformanceTest() { + this->minExecutionTime = 1000; + this->maxExecutionTime = 0; + this->totalExecutionTime = 0; + this->algorithmName = ""; + }; + + double getMinExecutionTime() { return this->minExecutionTime; } + + double getMaxExecutionTime() { return this->maxExecutionTime; } + + double getTotalExecutionTime() { return this->totalExecutionTime; } + + const std::string &getAlgorithmName() { return this->algorithmName; } + + void setAlgorithmName(std::string name) { this->algorithmName = name; } + + void processResult(std::chrono::high_resolution_clock::time_point startTime, + std::chrono::high_resolution_clock::time_point endTime) { + std::chrono::duration duration = (endTime - startTime); + double execTime = duration.count(); + this->totalExecutionTime += execTime; + if (execTime < this->minExecutionTime) { + this->minExecutionTime = execTime; + return; + } else if (execTime > this->maxExecutionTime) { + this->maxExecutionTime = execTime; + return; + } + } +}; + +class PerformanceComparison { +private: + int *baseArray; + int arrayLength; + int testsetSize; + std::vector testResults; + +public: + PerformanceComparison(int arrayLength, int testsetSize) { + this->arrayLength = arrayLength; + this->testsetSize = testsetSize; + this->baseArray = + (int *)malloc(sizeof(int) * this->arrayLength * this->testsetSize); + generateRandomIntArray(this->baseArray, + this->arrayLength * this->testsetSize); + } + + ~PerformanceComparison() { + free(this->baseArray); + for (int i = 0; i < this->testResults.size(); i++) { + free(testResults[i]); + } + } + + void runTest(int algorithm) { + PerformanceTest *pt = new PerformanceTest(); + if (algorithm == 1) { + pt->setAlgorithmName("MergeSort"); + for (int i = 0; i < this->testsetSize; i++) { + int testArray[this->arrayLength]; + std::memcpy(testArray, this->baseArray + (this->arrayLength * i), + this->arrayLength * sizeof(int)); + auto startTime = std::chrono::high_resolution_clock::now(); + mergeSort(testArray, 0, arrayLength - 1); + auto endTime = std::chrono::high_resolution_clock::now(); + pt->processResult(startTime, endTime); + } + + } else if (algorithm == 2) { + pt->setAlgorithmName("MergeSortRand"); + for (int i = 0; i < this->testsetSize; i++) { + int testArray[this->arrayLength]; + std::memcpy(testArray, this->baseArray + (this->arrayLength * i), + this->arrayLength * sizeof(int)); + auto startTime = std::chrono::high_resolution_clock::now(); + mergeSortRand(testArray, 0, arrayLength - 1); + auto endTime = std::chrono::high_resolution_clock::now(); + pt->processResult(startTime, endTime); + } + } else { + std::cerr << "Algorithm not recognized!" << std::endl; + exit(1); + } + + this->testResults.push_back(pt); + }; + + void printComparison(int mode) { + if (mode == 1) { + std::cout << "Algorithm\t\tMIN\t\t\tMAX\t\t\tAVG\t\t\tTOTAL" << std::endl; + for (int i = 0; i < this->testResults.size(); i++) { + std::cout << this->testResults[i]->getAlgorithmName() << "\t\t" + << this->testResults[i]->getMinExecutionTime() << "\t\t" + << this->testResults[i]->getMaxExecutionTime() << "\t\t" + << this->testResults[i]->getTotalExecutionTime() / + this->testsetSize + << "\t\t" << this->testResults[i]->getTotalExecutionTime() + << std::endl; + } + } else if (mode == 2) { + std::cout << "Algorithm\tTOTAL\t\tAVG" << std::endl; + for (int i = 0; i < this->testResults.size(); i++) { + std::cout << this->testResults[i]->getAlgorithmName() << "\t\t" + << this->testResults[i]->getTotalExecutionTime() << " \t\t" + << this->testResults[i]->getTotalExecutionTime() / + this->testsetSize + << std::endl; + } + } else { + std::cerr << "Mode not recognized!" << std::endl; + exit(1); + } + } +}; + +int main() { + srand(time(0)); + int array[ARRAY_LENGTH]; + int array2[ARRAY_LENGTH]; + generateRandomIntArray(array, ARRAY_LENGTH); + memcpy(array2, array, ARRAY_LENGTH * sizeof(int)); + printArray(array, ARRAY_LENGTH, "Unsortiertes Array"); + mergeSort(array, 0, ARRAY_LENGTH - 1); + printArray(array, ARRAY_LENGTH, "Array nach MergeSort"); + mergeSortRand(array2, 0, ARRAY_LENGTH - 1); + printArray(array2, ARRAY_LENGTH, "Array nach MergeSortRand"); + for (int i = 0; i < ARRAY_LENGTH; i++) { + if (array[i] != array2[i]) { + std::cout << "ERROR" << std::endl; + exit(0); + } + } + + PerformanceComparison pc(10, 10000); + pc.runTest(1); + pc.runTest(2); + pc.printComparison(1); +} \ No newline at end of file diff --git a/Uebung 6/Uebung6_1/mergeSortRand.cpp b/Uebung 6/Uebung6_1/mergeSortRand.cpp new file mode 100644 index 0000000..babfc83 --- /dev/null +++ b/Uebung 6/Uebung6_1/mergeSortRand.cpp @@ -0,0 +1,62 @@ +#include "mergeSortRand.h" +//#include +#include + +void merge(int array[], int left, int middle, int right) { + int n1 = middle - left + 1; + int n2 = right - middle; + + int leftArray[n1]; + int rightArray[n2]; + + for (int i = 0; i < n1; i++) { + leftArray[i] = array[left + i]; + } + for (int j = 0; j < n2; j++) { + rightArray[j] = array[middle + j + 1]; + } + + int k = 0, l = 0, m = left; + while (k < n1 && l < n2) { + if (leftArray[k] <= rightArray[l]) { + array[m] = leftArray[k]; + k++; + } else { + array[m] = rightArray[l]; + l++; + } + m++; + } + + while (k < n1) { + array[m] = leftArray[k]; + k++; + m++; + } + + while (l < n2) { + array[m] = rightArray[l]; + l++; + m++; + } +} + +void mergeSortRand(int array[], int left, int right) { + if (left < right) { + int middle = (rand() % (right - left + 1)) + left; + if (middle < left || middle > right) { + std::cout << "ERROR2" << std::endl; + } + mergeSortRand(array, left, middle); + mergeSortRand(array, middle + 1, right); + merge(array, left, middle, right); + } +} +void mergeSort(int array[], int left, int right) { + if (left < right) { + int middle = left + (right - left) / 2; + mergeSort(array, left, middle); + mergeSort(array, middle + 1, right); + merge(array, left, middle, right); + } +} \ No newline at end of file diff --git a/Uebung 6/Uebung6_1/mergeSortRand.h b/Uebung 6/Uebung6_1/mergeSortRand.h new file mode 100644 index 0000000..de1ba1b --- /dev/null +++ b/Uebung 6/Uebung6_1/mergeSortRand.h @@ -0,0 +1,5 @@ +#pragma once + +void merge(int array[], int left, int middle, int right); +void mergeSort(int array[], int left, int right); +void mergeSortRand(int array[], int left, int right); \ No newline at end of file