AlgoDatSoSe26/praktika/06_hashtable/aufgabe4_kapazitaet.py
2026-06-01 11:51:33 +02:00

71 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sys, os
_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
_l07 = os.path.join(_root, 'vorlesung', 'L07_hashtable')
_p06 = os.path.dirname(__file__)
if _l07 not in sys.path: sys.path.insert(0, _l07)
if _root not in sys.path: sys.path.insert(0, _root)
if _p06 not in sys.path: sys.path.insert(0, _p06)
from utils.algo_context import AlgoContext
from utils.algo_array import Array
from hashtable import HashTableOpenAddressing
from analyze_hashtable import h, f
from aufgabe1_chaining import HashTableChaining
ctx = AlgoContext()
values = Array.from_file('data/seq1.txt', ctx)
n = len(values)
# ── a) Größe 90 ───────────────────────────────────────────────────────────────
ht90 = HashTableOpenAddressing(90, f, ctx)
inserted90 = sum(1 for cell in values if ht90.insert(cell))
rejected90 = n - inserted90
print("=== a) HashTableOpenAddressing m=90, seq1.txt (100 Werte) ===")
print(f"Eingefügt: {inserted90}, Abgewiesen: {rejected90}, "
f"Freie Slots: {90 - inserted90}")
print(
"Ursache: Die quadratische Sondierungsfunktion f(x,i) = (h(x)+i+5i²) mod m\n"
"erzeugt für m=90 (keine Primzahl) zyklische Sondierungssequenzen, die nicht\n"
"alle 90 Slots abdecken. Sobald alle erreichbaren Slots belegt sind, schlägt\n"
"insert fehl auch wenn noch andere Slots frei sind."
)
# ── b) Größe 89 ───────────────────────────────────────────────────────────────
ctx2 = AlgoContext()
values2 = Array.from_file('data/seq1.txt', ctx2)
ht89 = HashTableOpenAddressing(89, f, ctx2)
inserted89 = sum(1 for cell in values2 if ht89.insert(cell))
rejected89 = n - inserted89
print(f"\n=== b) HashTableOpenAddressing m=89 (Primzahl), seq1.txt ===")
print(f"Eingefügt: {inserted89}, Abgewiesen: {rejected89}")
print(
"Bei Primzahlgröße garantiert die quadratische Sondierung, dass mindestens\n"
"m/2 verschiedene Slots erreicht werden (bei geeigneten Konstanten c1, c2\n"
"sogar alle m). Für m=89 ist die Sondierungssequenz deutlich länger, bevor\n"
"sie sich wiederholt dadurch können mehr Werte platziert werden."
)
# ── c) HashTableChaining m=20, seq1.txt ───────────────────────────────────────
ctx3 = AlgoContext()
values3 = Array.from_file('data/seq1.txt', ctx3)
htc = HashTableChaining(20, h, ctx3)
for cell in values3:
htc.insert(cell)
print(f"\n=== c) HashTableChaining m=20, seq1.txt ===")
unique = len(set(int(str(c)) for c in values3))
print(f"Eingefügt: {htc._n} (seq1.txt hat {n} Werte, davon {unique} eindeutig; "
f"Duplikate werden nicht doppelt gespeichert)")
print(f"Belegungsfaktor α = {htc._n}/{int(htc.m)} = {htc.alpha():.2f}")
print("Verkettung hat keine Kapazitätsgrenze die Ketten wachsen unbegrenzt.")
# ── d) Theoretische Sondierungsanzahl ─────────────────────────────────────────
print("\n=== d) Mittlere Sondierungsanzahl 1/(1-α) ===")
for alpha in [0.5, 0.9]:
probes = 1 / (1 - alpha)
print(f" α = {alpha}: 1/(1{alpha}) = {probes:.1f} Sondierungen")
print(
"Bis α ≈ 0,7 bleibt die offene Adressierung praktikabel (≈ 3,3 Sondierungen).\n"
"Für α > 0,8 steigen die Kosten rapide; α = 0,9 bedeutet bereits 10 Sondierungen\n"
"im Schnitt. Als Faustregel gilt: Tabelle vergrößern (Rehashing), wenn α > 0,75."
)