From c9d5a7a84c7677dbc13d44d1ca1101c93dba4b44 Mon Sep 17 00:00:00 2001 From: Samuel Oberhofer Date: Sun, 26 Jun 2022 15:29:55 +0200 Subject: [PATCH] Initial 5_3 --- Uebung 5/Uebung5_3/Makefile | 52 ++++++++++++++++++++++++ Uebung 5/Uebung5_3/backpack.cpp | 72 +++++++++++++++++++++++++++++++++ Uebung 5/Uebung5_3/backpack.h | 31 ++++++++++++++ Uebung 5/Uebung5_3/item.cpp | 5 +++ Uebung 5/Uebung5_3/item.h | 17 ++++++++ Uebung 5/Uebung5_3/main.cpp | 14 +++++++ 6 files changed, 191 insertions(+) create mode 100644 Uebung 5/Uebung5_3/Makefile create mode 100644 Uebung 5/Uebung5_3/backpack.cpp create mode 100644 Uebung 5/Uebung5_3/backpack.h create mode 100644 Uebung 5/Uebung5_3/item.cpp create mode 100644 Uebung 5/Uebung5_3/item.h create mode 100644 Uebung 5/Uebung5_3/main.cpp diff --git a/Uebung 5/Uebung5_3/Makefile b/Uebung 5/Uebung5_3/Makefile new file mode 100644 index 0000000..ab88379 --- /dev/null +++ b/Uebung 5/Uebung5_3/Makefile @@ -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 diff --git a/Uebung 5/Uebung5_3/backpack.cpp b/Uebung 5/Uebung5_3/backpack.cpp new file mode 100644 index 0000000..26ca08d --- /dev/null +++ b/Uebung 5/Uebung5_3/backpack.cpp @@ -0,0 +1,72 @@ +#include "backpack.h" + +/* 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() { + 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! + + std::cout << "Backpack has been packed:\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 + } + 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 << "\t" + << this->getValuePacked() << "\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"; + } +} \ No newline at end of file diff --git a/Uebung 5/Uebung5_3/backpack.h b/Uebung 5/Uebung5_3/backpack.h new file mode 100644 index 0000000..0e35d48 --- /dev/null +++ b/Uebung 5/Uebung5_3/backpack.h @@ -0,0 +1,31 @@ +#include +#include +#include + +#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 availableItems; + int currentWeight; + std::vector packedItems; + + Backpack(float maxWeight, std::vector availableItems) + : maxWeight(maxWeight), availableItems(availableItems), + currentWeight(0){}; + void sortAvailableItems(); + void greedyPack(); + int getValuePacked(); + void printItems(); +}; \ No newline at end of file diff --git a/Uebung 5/Uebung5_3/item.cpp b/Uebung 5/Uebung5_3/item.cpp new file mode 100644 index 0000000..36c8133 --- /dev/null +++ b/Uebung 5/Uebung5_3/item.cpp @@ -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); }; diff --git a/Uebung 5/Uebung5_3/item.h b/Uebung 5/Uebung5_3/item.h new file mode 100644 index 0000000..5471b4e --- /dev/null +++ b/Uebung 5/Uebung5_3/item.h @@ -0,0 +1,17 @@ +#include + +#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(); +}; \ No newline at end of file diff --git a/Uebung 5/Uebung5_3/main.cpp b/Uebung 5/Uebung5_3/main.cpp new file mode 100644 index 0000000..239bea7 --- /dev/null +++ b/Uebung 5/Uebung5_3/main.cpp @@ -0,0 +1,14 @@ +#include "backpack.h" +#include "item.h" +#include + +int main() { + std::vector 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)20, + items); // creation of the backpack, utilizing the constructor + bp.greedyPack(); // greedily pack backpack +} \ No newline at end of file