Compare commits
11 Commits
d5cb71c477
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| b35d52e60d | |||
| 6a4a468adf | |||
| eb2d62b9e7 | |||
| b8c7e44846 | |||
| 80f6c741d2 | |||
| 8ad105ef56 | |||
| a5563a4103 | |||
| cf6edcdff6 | |||
| 7dc503ca13 | |||
| 8a95eb668b | |||
| c9d5a7a84c |
@@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
# Name of the binary for Development
|
||||||
|
BINARY = main
|
||||||
|
# Name of the binary for Release
|
||||||
|
FINAL = prototyp
|
||||||
|
# Object files
|
||||||
|
OBJS = backpack.o item.o main.o
|
||||||
|
# Compiler flags
|
||||||
|
CFLAGS = -Werror -Wall -std=c++17 -fsanitize=address,undefined -g
|
||||||
|
# Linker flags
|
||||||
|
LFLAGS = -fsanitize=address,undefined
|
||||||
|
#Which Compiler to use
|
||||||
|
COMPILER = c++
|
||||||
|
|
||||||
|
|
||||||
|
# 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
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
#include "backpack.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
/* Optimized insertion sort algorithm utilizing the Item's getRatio() function
|
||||||
|
*/
|
||||||
|
void Backpack::sortAvailableItems() {
|
||||||
|
int i = 0;
|
||||||
|
while (i < (int)this->availableItems.size()) {
|
||||||
|
Item x = this->availableItems[i];
|
||||||
|
int j = i - 1;
|
||||||
|
while (j >= 0 && this->availableItems[j].getRatio() < x.getRatio()) {
|
||||||
|
this->availableItems[j + 1] = this->availableItems[j];
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
this->availableItems[j + 1] = x;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterates through all packed items and returns the total value */
|
||||||
|
int Backpack::getValuePacked() {
|
||||||
|
int total = 0;
|
||||||
|
for (int i = 0; i < (int)this->packedItems.size(); i++) {
|
||||||
|
total += this->packedItems[i].value;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the algorithm to pack the backpack */
|
||||||
|
void Backpack::greedyPack(bool continuous) {
|
||||||
|
this->packedItems
|
||||||
|
.clear(); /* resets the packedItems -> removes all elements! */
|
||||||
|
this->currentWeight = 0; /* ...and also sets the current weight to 0.0 */
|
||||||
|
|
||||||
|
this->sortAvailableItems(); // sort the available items first!
|
||||||
|
const char *text = "";
|
||||||
|
float partialValue = 0.0f;
|
||||||
|
float partialWeight = 0.0f;
|
||||||
|
if (!continuous) {
|
||||||
|
text = "non-";
|
||||||
|
}
|
||||||
|
std::cout << "Backpack has been packed " << text
|
||||||
|
<< "continuously:\n"; // output
|
||||||
|
std::cout << "\t\tWeight\tValue\n"; // output
|
||||||
|
std::cout << "---------------------------------------------\n"; // output
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)this->availableItems.size();
|
||||||
|
i++) { // iterate through all available items
|
||||||
|
if (this->currentWeight + (float)this->availableItems[i].weight <=
|
||||||
|
this->maxWeight) { // check if the item still fits in the backpack
|
||||||
|
this->packedItems.push_back(
|
||||||
|
this->availableItems[i]); // and if so, put it in there (by adding it
|
||||||
|
// to this->packedItems)
|
||||||
|
currentWeight +=
|
||||||
|
this->availableItems[i].weight; // adjust currentWeight accordingly
|
||||||
|
std::cout << "\t" << this->availableItems[i].name << ":\t"
|
||||||
|
<< this->availableItems[i].weight << "\t"
|
||||||
|
<< this->availableItems[i].value
|
||||||
|
<< "\t Factor: 1.00\n"; // output
|
||||||
|
} else if (continuous) {
|
||||||
|
float factor = (float)(this->maxWeight - this->currentWeight) /
|
||||||
|
this->availableItems[i].weight;
|
||||||
|
factor = std::round(factor * 100) / 100;
|
||||||
|
std::cout << "\t" << this->availableItems[i].name << ":\t"
|
||||||
|
<< this->availableItems[i].weight << "\t"
|
||||||
|
<< this->availableItems[i].value << "\t Factor: " << factor
|
||||||
|
<< std::endl;
|
||||||
|
partialWeight = this->availableItems[i].weight * factor;
|
||||||
|
partialValue = this->availableItems[i].value * factor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((this->currentWeight - this->maxWeight) ==
|
||||||
|
0) { // if the backpack is completely full, the loop can be exited -
|
||||||
|
// small optimization
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "---------------------------------------------\n"; // output
|
||||||
|
std::cout << "\tTotal:\t" << this->currentWeight + partialWeight << "\t"
|
||||||
|
<< this->getValuePacked() + partialValue << "\n"; // output
|
||||||
|
}
|
||||||
|
|
||||||
|
void Backpack::printItems() {
|
||||||
|
for (int i = 0; i < (int)this->availableItems.size(); i++) {
|
||||||
|
std::cout << this->availableItems[i].name << "\t"
|
||||||
|
<< this->availableItems[i].weight << "\t"
|
||||||
|
<< this->availableItems[i].value << "\t"
|
||||||
|
<< this->availableItems[i].getRatio() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "item.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* Class for Backpack, consisting of a maxWeight that can be put into a
|
||||||
|
backpack, one that shows the weight that is currently in the backpack, a
|
||||||
|
vector representing all available items and a vector for the items that have
|
||||||
|
been placed in the backpack. There is also a constructor to increase the
|
||||||
|
ease/convenience of use, as well as functions to:
|
||||||
|
* sort the available Items based on their getRatio()
|
||||||
|
* greedily pack the backpack
|
||||||
|
* get the value of all packed items
|
||||||
|
*/
|
||||||
|
struct Backpack {
|
||||||
|
int maxWeight;
|
||||||
|
std::vector<Item> availableItems;
|
||||||
|
int currentWeight;
|
||||||
|
std::vector<Item> packedItems;
|
||||||
|
|
||||||
|
Backpack(float maxWeight, std::vector<Item> availableItems)
|
||||||
|
: maxWeight(maxWeight), availableItems(availableItems),
|
||||||
|
currentWeight(0){};
|
||||||
|
void sortAvailableItems();
|
||||||
|
void greedyPack(bool continuous);
|
||||||
|
int getValuePacked();
|
||||||
|
void printItems();
|
||||||
|
};
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#include "item.h"
|
||||||
|
|
||||||
|
/* function that returns the value/weight ratio of an item as float; used to
|
||||||
|
* sort items */
|
||||||
|
float Item::getRatio() { return ((float)this->value / (float)this->weight); };
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#include <string>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* Class for Item, containing name (string), value (int) and weight (int).
|
||||||
|
There is also a constructor that can be called with all member variables to
|
||||||
|
increase convenience. The getRatio() function returns the value/weight ratio
|
||||||
|
*/
|
||||||
|
class Item {
|
||||||
|
public:
|
||||||
|
std::string name;
|
||||||
|
int weight;
|
||||||
|
int value;
|
||||||
|
Item(std::string name, int weight, int value)
|
||||||
|
: name(name), weight(weight), value(value){};
|
||||||
|
float getRatio();
|
||||||
|
};
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#include "backpack.h"
|
||||||
|
#include "item.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::vector<Item> items = {// creation of the availableItems
|
||||||
|
{"1", 5, 8}, {"2", 5, 8}, {"3", 6, 6},
|
||||||
|
{"4", 8, 5}, {"5", 10, 10}, {"6", 11, 5},
|
||||||
|
{"7", 12, 10}, {"8", 15, 17}, {"9", 15, 20},
|
||||||
|
{"10", 30, 20}};
|
||||||
|
Backpack bp((float)24,
|
||||||
|
items); // creation of the backpack, utilizing the constructor
|
||||||
|
bp.greedyPack(false); // greedily pack Backpack non-continuously
|
||||||
|
bp.greedyPack(true); // greedily pack Backpack continuously
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#include "helperFunctions.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void generateRandomIntArray(int* array, int arrayLength);
|
||||||
|
void printArray(int* array, int arrayLength, std::string heading);
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "helperFunctions.h"
|
||||||
|
#include "mergeSortRand.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#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<double, std::milli> 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<PerformanceTest *> 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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#include "mergeSortRand.h"
|
||||||
|
//#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
#include "ExtendedBinaryTree.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
ExtendedBinaryTree::ExtendedBinaryTree(Ware *rootNodeKey, int priority) {
|
||||||
|
ExtendedBinaryTreeNode *root =
|
||||||
|
new ExtendedBinaryTreeNode(rootNodeKey, priority);
|
||||||
|
this->rootNode = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode *ExtendedBinaryTree::insert(Ware *key, int priority) {
|
||||||
|
return this->rootNode->insert(key, priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode *ExtendedBinaryTree::search(int value) {
|
||||||
|
ExtendedBinaryTreeNode *node = this->rootNode;
|
||||||
|
while (value != node->key->getVerkaufspreis() && node != nullptr) {
|
||||||
|
if (value > node->key->getVerkaufspreis()) {
|
||||||
|
node = node->right;
|
||||||
|
} else {
|
||||||
|
node = node->left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode *ExtendedBinaryTree::deleteItem(Ware *key) {
|
||||||
|
return this->rootNode->deleteItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode *
|
||||||
|
ExtendedBinaryTree::findMin(ExtendedBinaryTreeNode *node) {
|
||||||
|
while (node->left != nullptr) {
|
||||||
|
node = node->left;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode *
|
||||||
|
ExtendedBinaryTree::findMax(ExtendedBinaryTreeNode *node) {
|
||||||
|
while (node->right != nullptr) {
|
||||||
|
node = node->right;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// function to print a tree in pre-order: (sub)root, left (sub)tree, right
|
||||||
|
// (sub)tree
|
||||||
|
std::string ExtendedBinaryTree::printPreorder(ExtendedBinaryTreeNode *node) {
|
||||||
|
std::stringstream output;
|
||||||
|
output << *(node->key) << " " << node->priority << std::endl;
|
||||||
|
|
||||||
|
if (node->left != nullptr) {
|
||||||
|
output << this->printPreorder(node->left);
|
||||||
|
}
|
||||||
|
if (node->right != nullptr) {
|
||||||
|
output << this->printPreorder(node->right);
|
||||||
|
}
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ExtendedBinaryTree::printPreorder() {
|
||||||
|
return this->printPreorder(this->rootNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ExtendedBinaryTree::printPostorder() {
|
||||||
|
return this->printPostorder(this->rootNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ExtendedBinaryTree::printPostorder(ExtendedBinaryTreeNode *node) {
|
||||||
|
std::stringstream output;
|
||||||
|
|
||||||
|
if (node->left != nullptr) {
|
||||||
|
output << this->printPreorder(node->left);
|
||||||
|
}
|
||||||
|
if (node->right != nullptr) {
|
||||||
|
output << this->printPreorder(node->right);
|
||||||
|
}
|
||||||
|
output << *(node->key) << std::endl;
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ExtendedBinaryTree::printInorder() {
|
||||||
|
return this->printInorder(this->rootNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ExtendedBinaryTree::printInorder(ExtendedBinaryTreeNode *node) {
|
||||||
|
std::stringstream output;
|
||||||
|
|
||||||
|
if (node->left != nullptr) {
|
||||||
|
output << this->printPreorder(node->left);
|
||||||
|
}
|
||||||
|
output << *(node->key) << std::endl;
|
||||||
|
|
||||||
|
if (node->right != nullptr) {
|
||||||
|
output << this->printPreorder(node->right);
|
||||||
|
}
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ExtendedBinaryTree::printPriority() {
|
||||||
|
return this->printPriority(this->rootNode, INT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ExtendedBinaryTree::printPriority(ExtendedBinaryTreeNode *node,
|
||||||
|
int max) {
|
||||||
|
std::stringstream output;
|
||||||
|
|
||||||
|
// Print the node
|
||||||
|
if (node->priority < max) {
|
||||||
|
output << *(node->key) << " Priority: " << node->priority << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find out which of the children has lower priority
|
||||||
|
ExtendedBinaryTreeNode *bigger = nullptr;
|
||||||
|
ExtendedBinaryTreeNode *smaller = nullptr;
|
||||||
|
|
||||||
|
if (node->left != nullptr) {
|
||||||
|
if (node->right != nullptr) {
|
||||||
|
smaller = node->left->priority < node->right->priority ? node->left
|
||||||
|
: node->right;
|
||||||
|
bigger = node->left->priority > node->right->priority ? node->left
|
||||||
|
: node->right;
|
||||||
|
} else {
|
||||||
|
smaller = node->left;
|
||||||
|
}
|
||||||
|
} else if (node->right != nullptr) {
|
||||||
|
smaller = node->right;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smaller != nullptr) {
|
||||||
|
int prio;
|
||||||
|
if (bigger != nullptr) {
|
||||||
|
if (bigger->priority < max) {
|
||||||
|
|
||||||
|
prio = bigger->priority;
|
||||||
|
} else {
|
||||||
|
prio = max;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prio = INT_MAX;
|
||||||
|
}
|
||||||
|
output << printPriority(smaller, prio);
|
||||||
|
}
|
||||||
|
if (bigger != nullptr) {
|
||||||
|
output << printPriority(bigger, INT_MAX);
|
||||||
|
}
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
std::string ExtendedBinaryTree::printPriorityBruteForce() {
|
||||||
|
// return ExtendedBinaryTree::printPriorityBruteForce(this->rootNode,
|
||||||
|
// INT_MAX);
|
||||||
|
int maxprinted = 0;
|
||||||
|
ExtendedBinaryTreeNode *maxprintedNode = nullptr;
|
||||||
|
while (true) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
ExtendedBinaryTree::printPriorityBruteForce(ExtendedBinaryTreeNode *key,
|
||||||
|
int max) {
|
||||||
|
int currentMin = max;
|
||||||
|
while (true) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#include "ExtendedBinaryTreeNode.h"
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class ExtendedBinaryTree {
|
||||||
|
public:
|
||||||
|
ExtendedBinaryTreeNode *rootNode;
|
||||||
|
|
||||||
|
ExtendedBinaryTree(Ware *rootNodeKey, int priority);
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode *search(int value);
|
||||||
|
ExtendedBinaryTreeNode *insert(Ware *key, int priority);
|
||||||
|
ExtendedBinaryTreeNode *deleteItem(Ware *key);
|
||||||
|
ExtendedBinaryTreeNode *findMin(ExtendedBinaryTreeNode *node);
|
||||||
|
ExtendedBinaryTreeNode *findMax(ExtendedBinaryTreeNode *node);
|
||||||
|
std::string printPreorder(ExtendedBinaryTreeNode *node);
|
||||||
|
std::string printPreorder();
|
||||||
|
std::string printPostorder(ExtendedBinaryTreeNode *node);
|
||||||
|
std::string printPostorder();
|
||||||
|
std::string printInorder(ExtendedBinaryTreeNode *node);
|
||||||
|
std::string printInorder();
|
||||||
|
std::string printPriority();
|
||||||
|
std::string printPriority(ExtendedBinaryTreeNode *node, int max);
|
||||||
|
std::string printPriorityBruteForce();
|
||||||
|
std::string printPriorityBruteForce(ExtendedBinaryTreeNode *node, int max);
|
||||||
|
};
|
||||||
|
|
||||||
|
// std::string printPreorder(BinaryTreeNode* node);
|
||||||
|
// /* -- Your TODO -- */
|
||||||
|
// std::string printPostorder(BinaryTreeNode* node);
|
||||||
|
// std::string printInorder(BinaryTreeNode* node);
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
#include "ExtendedBinaryTreeNode.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode::ExtendedBinaryTreeNode(Ware *key, int priority) {
|
||||||
|
this->key = key;
|
||||||
|
this->left = nullptr;
|
||||||
|
this->right = nullptr;
|
||||||
|
this->priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode *ExtendedBinaryTreeNode::insert(Ware *key,
|
||||||
|
int priority) {
|
||||||
|
if (key->getVerkaufspreis() > this->key->getVerkaufspreis()) {
|
||||||
|
if (this->right == nullptr) {
|
||||||
|
ExtendedBinaryTreeNode *temp = new ExtendedBinaryTreeNode(key, priority);
|
||||||
|
this->right = temp;
|
||||||
|
return this->right;
|
||||||
|
}
|
||||||
|
this->right->insert(key, priority);
|
||||||
|
} else {
|
||||||
|
if (this->left == nullptr) {
|
||||||
|
ExtendedBinaryTreeNode *temp = new ExtendedBinaryTreeNode(key, priority);
|
||||||
|
this->left = temp;
|
||||||
|
return this->left;
|
||||||
|
}
|
||||||
|
this->left->insert(key, priority);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode *ExtendedBinaryTreeNode::deleteItem(Ware *key) {
|
||||||
|
ExtendedBinaryTreeNode *node = this;
|
||||||
|
|
||||||
|
if (node == nullptr) {
|
||||||
|
return this;
|
||||||
|
} else if (key->getVerkaufspreis() < node->key->getVerkaufspreis()) {
|
||||||
|
node->left = node->left->deleteItem(key);
|
||||||
|
} else if (key->getVerkaufspreis() > node->key->getVerkaufspreis()) {
|
||||||
|
node->right = node->right->deleteItem(key);
|
||||||
|
} else {
|
||||||
|
if (node->left == nullptr && node->right == nullptr) {
|
||||||
|
delete node;
|
||||||
|
node = nullptr;
|
||||||
|
} else if (node->left == nullptr) { // only children in right subtree
|
||||||
|
ExtendedBinaryTreeNode *temp = node;
|
||||||
|
node = node->right;
|
||||||
|
delete temp;
|
||||||
|
} else if (this->right == nullptr) { // only children in left subtree
|
||||||
|
ExtendedBinaryTreeNode *temp = node;
|
||||||
|
node = node->left;
|
||||||
|
delete temp;
|
||||||
|
} else { // we have to keep the BST structure, here, we look for the minimum
|
||||||
|
// in the right subtree (see lecture)
|
||||||
|
ExtendedBinaryTreeNode *temp = node->right;
|
||||||
|
while (temp->left != nullptr) {
|
||||||
|
temp = temp->left;
|
||||||
|
}
|
||||||
|
node->key = temp->key;
|
||||||
|
node->right = node->right->deleteItem(temp->key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode *ExtendedBinaryTreeNode::leftRotation() {
|
||||||
|
// std::cout << "Do a left rotation on node " << this->key << "\n";
|
||||||
|
ExtendedBinaryTreeNode *rightNode = this->right;
|
||||||
|
ExtendedBinaryTreeNode *leftOfRightNode = rightNode->left;
|
||||||
|
|
||||||
|
rightNode->left = this;
|
||||||
|
this->right = leftOfRightNode;
|
||||||
|
return rightNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform a right rotation (see lecture)
|
||||||
|
ExtendedBinaryTreeNode *ExtendedBinaryTreeNode::rightRotation() {
|
||||||
|
// std::cout << "Do a right rotation on node " << this->key << "\n";
|
||||||
|
ExtendedBinaryTreeNode *leftNode = this->left;
|
||||||
|
ExtendedBinaryTreeNode *rightOfLeftNode = leftNode->right;
|
||||||
|
|
||||||
|
leftNode->right = this;
|
||||||
|
this->left = rightOfLeftNode;
|
||||||
|
|
||||||
|
return leftNode;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Ware.h"
|
||||||
|
|
||||||
|
class ExtendedBinaryTreeNode {
|
||||||
|
public:
|
||||||
|
Ware *key;
|
||||||
|
int priority;
|
||||||
|
ExtendedBinaryTreeNode *left;
|
||||||
|
ExtendedBinaryTreeNode *right;
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode(Ware *key, int priority);
|
||||||
|
|
||||||
|
ExtendedBinaryTreeNode *insert(Ware *key, int priority);
|
||||||
|
ExtendedBinaryTreeNode *deleteItem(Ware *key);
|
||||||
|
ExtendedBinaryTreeNode *leftRotation();
|
||||||
|
ExtendedBinaryTreeNode *rightRotation();
|
||||||
|
};
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
|
||||||
|
# Name of the binary for Development
|
||||||
|
BINARY = main
|
||||||
|
# Name of the binary for Release
|
||||||
|
FINAL = prototyp
|
||||||
|
# Object files
|
||||||
|
OBJS = Ware.o ExtendedBinaryTreeNode.o ExtendedBinaryTree.o main.o
|
||||||
|
# Compiler flags
|
||||||
|
CFLAGS = -Werror -Wall -std=c++17 -g -fsanitize=address,undefined
|
||||||
|
# Linker flags
|
||||||
|
LFLAGS = -fsanitize=address,undefined
|
||||||
|
#Which Compiler to use
|
||||||
|
COMPILER = c++
|
||||||
|
|
||||||
|
|
||||||
|
# all target: builds all important targets
|
||||||
|
all: binary
|
||||||
|
|
||||||
|
final : ${OBJS}
|
||||||
|
${COMPILER} ${LFLAGS} -o ${FINAL} ${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
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#include "Ware.h"
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Ware &ware) {
|
||||||
|
out << "Name: " << ware.getBezeichnung() << ", SN: " << ware.getSeriennummer()
|
||||||
|
<< ", Gewicht: " << ware.getGewicht()
|
||||||
|
<< ", EK: " << ware.getEinkaufspreis()
|
||||||
|
<< ", VK: " << ware.getVerkaufspreis();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Ware {
|
||||||
|
private:
|
||||||
|
std::string bezeichnung;
|
||||||
|
int seriennummer;
|
||||||
|
double gewicht;
|
||||||
|
double einkaufspreis;
|
||||||
|
double verkaufspreis;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string getBezeichnung() const { return this->bezeichnung; }
|
||||||
|
|
||||||
|
void setBezeichnung(std::string bezeichnung) {
|
||||||
|
this->bezeichnung = bezeichnung;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSeriennummer() const { return this->seriennummer; }
|
||||||
|
|
||||||
|
void setSeriennummer(int seriennummer) { this->seriennummer = seriennummer; }
|
||||||
|
|
||||||
|
double getGewicht() const { return this->gewicht; }
|
||||||
|
|
||||||
|
void setGewicht(double gewicht) { this->gewicht = gewicht; }
|
||||||
|
|
||||||
|
double getEinkaufspreis() const { return this->einkaufspreis; }
|
||||||
|
|
||||||
|
void setEinkaufspreis(double einkaufspreis) {
|
||||||
|
this->einkaufspreis = einkaufspreis;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getVerkaufspreis() const { return this->verkaufspreis; }
|
||||||
|
|
||||||
|
void setVerkaufspreis(double verkaufspreis) {
|
||||||
|
this->verkaufspreis = verkaufspreis;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ware(std::string bezeichnung, int seriennummer, double gewicht,
|
||||||
|
double einkaufspreis, double verkaufspreis)
|
||||||
|
: bezeichnung(bezeichnung), seriennummer(seriennummer), gewicht(gewicht),
|
||||||
|
einkaufspreis(einkaufspreis), verkaufspreis(verkaufspreis) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Ware &ware);
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#include "ExtendedBinaryTree.h"
|
||||||
|
#include "ExtendedBinaryTreeNode.h"
|
||||||
|
#include "Ware.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void generateRandomIntArray(int *array, int arrayLength) {
|
||||||
|
std::srand(time(NULL));
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
array[i] = rand() % 100000 + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
// bez, sn, gw, ek, vk
|
||||||
|
Ware ware1("S", 1, 5.12, 10.37, 13.0);
|
||||||
|
Ware ware2("L", 2, 6.12, 1.37, 29.0);
|
||||||
|
Ware ware3("A", 3, 4.12, 9.37, 10.0);
|
||||||
|
Ware ware4("Z", 12, 1.12, 18.37, 19.0);
|
||||||
|
Ware ware5("LA", 27, 0.12, 13.37, 17.0);
|
||||||
|
Ware ware6("LC", 13, 13.12, 15.37, 16.0);
|
||||||
|
Ware ware7("ABC", 4, 7.12, 27.37, 35.0);
|
||||||
|
Ware ware8("C", 123, 9.12, 2.37, 4.0);
|
||||||
|
|
||||||
|
int randInts[8];
|
||||||
|
generateRandomIntArray(randInts, 8);
|
||||||
|
|
||||||
|
// Händisch sortierte Prioritäten, um die Waren ihren Prioritäten entsprechend
|
||||||
|
// einzusortieren, damit die Heapbedingung nicht verletzt werden kann.
|
||||||
|
std::sort(randInts, randInts + 8);
|
||||||
|
|
||||||
|
ExtendedBinaryTree tree(&ware1, randInts[0]);
|
||||||
|
// std::cout << tree.printPreorder() << std::endl << std::flush;
|
||||||
|
tree.insert(&ware2, randInts[1]);
|
||||||
|
// std::cout << tree.printPreorder() << std::endl << std::flush;
|
||||||
|
tree.insert(&ware3, randInts[2]);
|
||||||
|
// std::cout << tree.printPreorder() << std::endl << std::flush;
|
||||||
|
tree.insert(&ware4, randInts[3]);
|
||||||
|
// std::cout << tree.printPreorder() << std::endl << std::flush;
|
||||||
|
tree.insert(&ware5, randInts[4]);
|
||||||
|
// std::cout << tree.printPreorder() << std::endl << std::flush;
|
||||||
|
tree.insert(&ware6, randInts[5]);
|
||||||
|
// std::cout << tree.printInorder() << std::endl << std::flush;
|
||||||
|
tree.insert(&ware7, randInts[6]);
|
||||||
|
// std::cout << tree.printInorder() << std::endl << std::flush;
|
||||||
|
tree.insert(&ware8, randInts[7]);
|
||||||
|
std::cout << tree.printPreorder() << std::endl << std::flush;
|
||||||
|
|
||||||
|
// std::cout << ware1 << std::endl;
|
||||||
|
// std::cout << tree.printPreorder() << std::endl;
|
||||||
|
// std::cout << tree.printPostorder() << std::endl;
|
||||||
|
// std::cout << tree.printPreorder() << "\n" << std::endl;
|
||||||
|
// std::cout << tree.printPostorder() << "\n" << std::endl;
|
||||||
|
// std::cout << tree.printInorder();
|
||||||
|
std::cout << tree.printPriority() << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
# Name of the binary for Development
|
||||||
|
BINARY = main
|
||||||
|
# Name of the binary for Release
|
||||||
|
FINAL = prototyp
|
||||||
|
# Object files
|
||||||
|
OBJS = 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
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// Konstanten aus der Angabe
|
||||||
|
#define n 12
|
||||||
|
#define k 6
|
||||||
|
#define L 15
|
||||||
|
|
||||||
|
// Liste der Primzahlen. Durch die oben angeführten Konstanten ist
|
||||||
|
// sichergestellt dass diese eindeutig sind
|
||||||
|
uint16_t listofPrimes[L];
|
||||||
|
|
||||||
|
// Random n-bits Zahl generieren. MSB ist immer 1
|
||||||
|
uint16_t createRandomNumber(uint8_t bits) {
|
||||||
|
|
||||||
|
// äquivalent zu:
|
||||||
|
// return rand() % pow(2,bits-1) + pow(2,bits-1);
|
||||||
|
|
||||||
|
uint16_t result = 1;
|
||||||
|
for (uint8_t i = 0; i < bits - 1; i++) {
|
||||||
|
result <<= 1;
|
||||||
|
result |= rand() % 2;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check ob eine Zahl Prim ist
|
||||||
|
bool checkPrime(int number) {
|
||||||
|
for (int i = 2; i < sqrt(number); i++) {
|
||||||
|
if (number % i == 0) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schreibe "length" primzahlen größer als "start" in "array"
|
||||||
|
void findPrimesBiggerThan(uint16_t *array, int length, int start) {
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
while (!checkPrime(start)) {
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
array[i] = start;
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// die zwei Zahlen die Alice und Bob aussuchen werden
|
||||||
|
int xAlice;
|
||||||
|
int xBob;
|
||||||
|
|
||||||
|
// Daten die an Bob übermittelt werden. j = x_A mod p_i. Bob antwortet mit Bool
|
||||||
|
bool transmitToBob(int i, int j) {
|
||||||
|
|
||||||
|
if (j != (xBob % listofPrimes[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// rand() mit timestamp seeden
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
// Primzahlen für Alice und Bob initialisieren
|
||||||
|
findPrimesBiggerThan(listofPrimes, L, pow(2, k));
|
||||||
|
|
||||||
|
// Alice sucht ein i zw. 1 und L aus
|
||||||
|
int iAlice = rand() % (L - 1) + 1;
|
||||||
|
|
||||||
|
// Counter für false positives
|
||||||
|
int falseCounter = 0;
|
||||||
|
|
||||||
|
long long iterations = 1000000;
|
||||||
|
for (int i = 0; i < iterations; i++) {
|
||||||
|
// Alice und Bob suchen 2 Zahlen aus
|
||||||
|
xAlice = createRandomNumber(n);
|
||||||
|
xBob = createRandomNumber(n);
|
||||||
|
|
||||||
|
// false positive, wenn Bob behauptet die Zahlen wären gleich, sie es aber
|
||||||
|
// nicht sind
|
||||||
|
if (transmitToBob(iAlice, xAlice % listofPrimes[iAlice]) &&
|
||||||
|
xAlice != xBob) {
|
||||||
|
falseCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// false-positive rate in Prozent. Empirisch: ca. 1%
|
||||||
|
std::cout << "False positivity rate: "
|
||||||
|
<< 100 * (float)(falseCounter) / iterations << "%" << std::endl;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
da ein L = 10^6 * n/k eine false Positive Wahrscheinlichkeit von 10^-6 ergibt, nehme ich stark an, dass man eine false Positive Wahrscheinlichkeit von 10^-15 duch ein L = 10^15 * n/k erreichen kann.
|
||||||
|
|
||||||
|
Ich schätze in der Angabe ist ein Tippfehler drinnen.
|
||||||
|
Da jede Wahrscheinlichkeit per Definition kleiner oder gleich 1 ist, ist auch die Wahrscheinlichkeit eines falschen Ergebnisses zwangsläufig kleiner als 10^15.
|
||||||
Reference in New Issue
Block a user