From b8a2972b6bd21fd31e5727ebc1d42ef797342099 Mon Sep 17 00:00:00 2001 From: Jan-Niclas Loosen Date: Mon, 26 Jan 2026 22:40:07 +0100 Subject: [PATCH] Task 10 exercise a --- Uebung-02/dice.py | 2 +- Uebung-03/find.py | 59 ++++++++++++ Uebung-10/BitVector.hpp | 126 ++++++++++++++++++++++++ Uebung-10/main | Bin 0 -> 59016 bytes Uebung-10/main.cpp | 206 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 Uebung-03/find.py create mode 100644 Uebung-10/BitVector.hpp create mode 100755 Uebung-10/main create mode 100644 Uebung-10/main.cpp diff --git a/Uebung-02/dice.py b/Uebung-02/dice.py index 4db4e73..52ac636 100644 --- a/Uebung-02/dice.py +++ b/Uebung-02/dice.py @@ -17,7 +17,7 @@ dice_props = [0.1, 0.1, 0.1, 0.1, 0.1, 0.5] coin_sides = ['Head', 'Number'] coin_head = [0.1, 0.5] -rep = 100000 +rep = 100 # --- Dice test --- res_cpp, acc_dice, rej_dice = throw_dice_cpp(rep, dice_sides, dice_props) diff --git a/Uebung-03/find.py b/Uebung-03/find.py new file mode 100644 index 0000000..675b0e5 --- /dev/null +++ b/Uebung-03/find.py @@ -0,0 +1,59 @@ +import math +import random +from multiprocessing import Pool +from typing import Optional, Iterable, Tuple + +def gen_nums(n: int) -> list[int]: + assert n > 0 + nums = list(range(2 ** n)) + random.shuffle(nums) + return nums + +def chunks(n: int, p: int) -> Iterable[Tuple[int, int]]: + base, rem = divmod(n, p) + start = 0 + for i in range(p): + size = base + (1 if i < rem else 0) + end = start + size + yield start, end + start = end + +def t_find(args: Tuple[int, int, list[int], int]) -> Optional[int]: + s, e, haystack, needle = args + for i in range(s, e): + if haystack[i] == needle: + return i + return None + +def find(needle: int, haystack: list[int]) -> Optional[int]: + size = len(haystack) + assert size >= 1 + + procs = int(math.log2(size)) + ranges = list(chunks(size, procs)) + with Pool(processes=procs) as pool: + res = pool.map(t_find, [(s, e, haystack, needle) for (s, e) in ranges]) + + for idx in res: + if idx is not None: + return idx + return None + +def fuzz_test(trials: int = 200, max_n: int = 16, seed: Optional[int] = None) -> None: + if seed is not None: + random.seed(seed) + + for t in range(1, trials + 1): + n = random.randint(1, max_n) + arr = gen_nums(n) + + idx_true = random.randrange(len(arr)) + needle = arr[idx_true] + expected = idx_true + + got = find(needle, arr) + assert got == expected, f"[t={t}] Expected {expected}, got {got}; n={n}" + + print(f"Fuzz OK: {trials} trials, max_n={max_n}") + +fuzz_test(trials=1000, max_n=16) \ No newline at end of file diff --git a/Uebung-10/BitVector.hpp b/Uebung-10/BitVector.hpp new file mode 100644 index 0000000..36ba40d --- /dev/null +++ b/Uebung-10/BitVector.hpp @@ -0,0 +1,126 @@ +#pragma once +#include +#include +#include +#include + +class BitVector { + std::vector data; + std::vector rankIndex; + uint64_t numBits; + bool isBuilt = false; + static constexpr uint64_t BLOCK_SIZE_BITS = 512; + static constexpr uint64_t WORDS_PER_BLOCK = BLOCK_SIZE_BITS / 64; + + static uint64_t countSetBits(uint64_t n) { + return std::popcount(n); + } + +public: + explicit BitVector(uint64_t n) : numBits(n) { + data.resize((n + 63) / 64, 0); + } + + // Bit setzen, nur während der Initialisierung erlaubt + void setBit(uint64_t index) { + if (isBuilt) throw std::runtime_error("BitVector is already built (read-only)."); + if (index >= numBits) throw std::out_of_range("Bit index out of range."); + data[index / 64] |= 1ULL << (index % 64); + } + + // Index aufbauen, muss nach dem Setzen aller Bits und vor der ersten Abfrage gerufen werden + void buildIndex() { + if (isBuilt) return; + rankIndex.clear(); + rankIndex.reserve(data.size() / WORDS_PER_BLOCK + 2); + + uint32_t currentRank = 0; + for (size_t i = 0; i < data.size(); ++i) { + if (i % WORDS_PER_BLOCK == 0) { + rankIndex.push_back(currentRank); + } + currentRank += countSetBits(data[i]); + } + rankIndex.push_back(currentRank); + isBuilt = true; + } + + // Anzahl der Einsen im Bereich [0, index) + uint64_t rank1(uint64_t index) const { + if (!isBuilt) throw std::runtime_error("Index not built."); + if (index > numBits) index = numBits; + + uint64_t blockIdx = index / BLOCK_SIZE_BITS; + uint64_t result = rankIndex[blockIdx]; + uint64_t startWord = blockIdx * WORDS_PER_BLOCK; + uint64_t endWord = index / 64; + + for (uint64_t i = startWord; i < endWord; ++i) { + result += countSetBits(data[i]); + } + + uint64_t bitsInLastWord = index % 64; + if (bitsInLastWord > 0) { + result += countSetBits(data[endWord] & ((1ULL << bitsInLastWord) - 1)); + } + return result; + } + + uint64_t rank0(uint64_t index) const { + return index - rank1(index); + } + + // Gibt den Index der k-ten Eins zurück (k ist 1-basiert) + uint64_t select1(uint64_t k) const { + if (!isBuilt) throw std::runtime_error("Index not built."); + if (k == 0) return -1; + + auto it = std::upper_bound(rankIndex.begin(), rankIndex.end(), k); + uint64_t blockIdx = std::distance(rankIndex.begin(), it) - 1; + uint64_t currentRank = rankIndex[blockIdx]; + uint64_t wordIdx = blockIdx * WORDS_PER_BLOCK; + + while (wordIdx < data.size()) { + uint64_t count = countSetBits(data[wordIdx]); + if (currentRank + count >= k) { + uint64_t temp = data[wordIdx]; + for (int bit = 0; bit < 64; ++bit) { + if ((temp >> bit) & 1) { + currentRank++; + if (currentRank == k) return wordIdx * 64 + bit; + } + } + } + currentRank += count; + wordIdx++; + } + return -1; // Nicht gefunden + } + + // Gibt den Index der k-ten Null zurück (k ist 1-basiert) + uint64_t select0(uint64_t k) const { + if (!isBuilt) throw std::runtime_error("Index not built."); + // Binäre Suche über rank0 + uint64_t low = 0, high = numBits; + uint64_t ans = -1; + while (low <= high) { + uint64_t mid = low + (high - low) / 2; + if (rank0(mid + 1) >= k) { + ans = mid; + high = mid - 1; + } else { + low = mid + 1; + } + } + return ans; + } + + // Speicherverbrauch in Bytes (inkl. Overhead) + uint64_t sizeInBytes() const { + return (data.capacity() * sizeof(uint64_t)) + + (rankIndex.capacity() * sizeof(uint32_t)) + + sizeof(*this); + } + + uint64_t length() const { return numBits; } +}; diff --git a/Uebung-10/main b/Uebung-10/main new file mode 100755 index 0000000000000000000000000000000000000000..453fada5556d6452f31e0a27af02314553706615 GIT binary patch literal 59016 zcmeHw3w)ea(f5-yfkImnN{az1Y_agRr4896P175smn|D;+L#MgZre?=ZBlY$vuRTV z38clYA($6Is-Q+hty-lbVqb)kwm<@+rid8sk+i~rpa7`qN+0Kh;{{J>s`r4<-Ef-lX{a?MNc9q3Gt(4BLnB?4sa`65m9iUt z)vx$8)O54Gb&77d;I0`8uc5sj*`}pK(ObUigvHYDF5MZ?D;aE5uS@E6Nj(kIi2;{} z+MXnaK3c9D7Jx=q0sl1&cfC&0#|@=>hKAGzT?FZK%T_9lgdWBkhK9Oc>F*;|^xdtW zE*D5W4Yi)dQg3{=}ATsmrnqWu4E}|I`K}yhlYddzuK5xbk;RTYEM1Gd!+iFdrn*M_4#j{ zUt3d=mwSF~)!f>e`sS9oE%|wK^Kvtr8ZxsXPuZO0seVtPwv#+4(=}zs#O0@)>G_%} zjr_X_sL3PI#*ZN+9)5BH{CNrR-+_W>$C2NfpxqS-3K&2{1+0)e=q_6 zk_7y3CBV;4Ag3yU{=ZFtzb=8CtOWQg6X?^CfZv}0e{BLeKTDwJaS8ZoUU~3wUv&xE zg_yYfG2r8kZ*2nnoCI<%K)WX!XBfsezi>n3sEftYM(CC8)G#jlA=9Un+u-TwB{v37O1P0n5|}Dua>AYOqqr zguqOHVyNw4~HD~D6ijK1D29d6NU

5HL#=-S3{P%Hbjh-jav+GHASi_&pVISh&(FR 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 If~#o!AI>`382|tP literal 0 HcmV?d00001 diff --git a/Uebung-10/main.cpp b/Uebung-10/main.cpp new file mode 100644 index 0000000..e81e7a2 --- /dev/null +++ b/Uebung-10/main.cpp @@ -0,0 +1,206 @@ +#include +#include +#include +#include +#include +#include + +#include "BitVector.hpp" + +// ========================================== +// Aufgabenteil a) Baseline-Implementierung +// ========================================== + +class BaselineTree { +public: + struct Node { + uint32_t parent = 0; // 0 = Root + std::vector children; + }; + +private: + std::vector nodes; + +public: + BaselineTree() { + nodes.emplace_back(); + nodes.emplace_back(); + } + + static int32_t root() { + return 1; + } + + [[nodiscard]] uint64_t nodeCount() const { + return nodes.size() - 1; + } + + [[nodiscard]] const std::vector& children(const uint32_t id) const { + return nodes[id].children; + } + + [[nodiscard]] uint32_t parent(const uint32_t id) const { + return nodes[id].parent; + } + + [[nodiscard]] bool exists(const uint32_t id) const { + return id > 0 && id < nodes.size(); + } + + uint32_t add(const uint32_t parentId) { + if (!exists(parentId)) { + throw std::invalid_argument("parentId does not exist"); + } + + nodes.emplace_back(); + const uint32_t id = nodes.size() - 1; + + nodes[id].parent = parentId; + nodes[parentId].children.push_back(id); + + return id; + } + + // BFS traversing with lambda for increased reusability + template + void bfs(Fn&& fn) const { + std::queue q; + q.push(root()); + + while (!q.empty()) { + uint32_t u = q.front(); + q.pop(); + + fn(u, nodes[u]); + + for (uint32_t v : nodes[u].children) { + q.push(v); + } + } + } + + [[nodiscard]] uint64_t sizeInBytes() const { + uint64_t total = 0; + + // Size of data in the tree instance + total += sizeof(BaselineTree); + total += nodes.capacity() * sizeof(Node); + + // Size of data in node instances + bfs([&](uint32_t, const Node& n) { + total += n.children.capacity() * sizeof(uint32_t); + }); + + return total; + } + + static BaselineTree randomTree(const uint64_t N, const uint32_t seed = 03062001) { + BaselineTree t; + t.nodes.reserve(N + 1); + + std::mt19937 gen(seed); + for (uint32_t i = 2; i <= N; ++i) { + std::uniform_int_distribution dist(1, i - 1); + t.add(dist(gen)); + } + + return t; + } +}; + + + +// ========================================== +// Aufgabenteil b) LOUDS-Implementierung +// ========================================== + +class LOUDSTree { + // Der BitVector ist der einzige Datenspeicher! Keine Knoten-Objekte. + BitVector bv; + +public: + // TODO: Passen Sie den Konstruktor an Ihre BaselineTree-Klasse an. + // Der Konstruktor soll den übergebenen Baum in Level-Order traversieren + // und die LOUDS-Bits in 'bv' setzen. + explicit LOUDSTree(const BaselineTree &tree) : bv(1 /* TODO: Richtige Größe berechnen! */) { + // TODO: Implementierung der LOUDS-Erstellung (BFS Traversierung) + // TODO: bfs can be used here! Comment by JNLOOS + + // WICHTIG: Am Ende muss der Index gebaut werden: + bv.buildIndex(); + } + + uint64_t sizeInBytes() const { + return bv.sizeInBytes(); + } + + // --- LOUDS-Operationen (Ausschließlich via rank/select implementieren!) --- + + uint64_t parent(uint64_t i) { + // TODO + return 0; + } + + bool isRoot(uint64_t i) { + // TODO + return false; + } + + bool isLeaf(uint64_t i) { + // TODO + return false; + } + + uint64_t outDegree(uint64_t i) { + // TODO + return 0; + } + + uint64_t childNum(uint64_t i, uint64_t j) { + // TODO: Geben Sie das j-te Kind von nodeId zurück (j ist 1-basiert) + return 0; + } +}; + + +int main() { + // Parameter für den Benchmark, 1 Million Knoten + const uint64_t N = 1000000; + + std::cout << "--- Start der Uebung: LOUDS (N=" << N << ") ---" << std::endl; + + // 1. Baseline Tree erstellen + std::cout << "[Init] Erstelle Baseline Tree..." << std::endl; + // Nutzen Sie std::mt19937 für reproduzierbare Zufallszahlen. + const BaselineTree baseline = BaselineTree::randomTree(N); + + // 2. LOUDS Tree erstellen + // std::cout << "[Init] Konvertiere zu LOUDS..." << std::endl; + // const LOUDSTree louds(baseline); + + // 3. Speichermessung + const uint64_t bytesBaseline = baseline.sizeInBytes(); + // uint64_t bytesLouds = louds.sizeInBytes(); + + std::cout << "Speicher Baseline: " << bytesBaseline / (1024.0 * 1024.0) << " MB" << std::endl; + // std::cout << "Speicher LOUDS: " << bytesLouds / (1024.0 * 1024.0) << " MB" << std::endl; + // if (bytesLouds > 0) { + // std::cout << "Faktor: " << (double) bytesBaseline / bytesLouds << "x" << std::endl; + // } + + // 4. Laufzeitmessung (Parent Operation) + // std::cout << "[Benchmark] Starte 1.000.000 Parent-Abfragen..." << std::endl; + // uint64_t checksum = 0; + + // auto start = std::chrono::high_resolution_clock::now(); + // for (uint64_t i = 2; i <= N; ++i) { + // checksum += louds.parent(i); + // } + // auto end = std::chrono::high_resolution_clock::now(); + + // auto duration = std::chrono::duration_cast(end - start).count(); + // std::cout << "Zeit LOUDS: " << duration << " ms" << std::endl; + // std::cout << "Checksum: " << checksum << std::endl; + + return 0; +}