71 lines
3.6 KiB
Python
71 lines
3.6 KiB
Python
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."
|
||
)
|