This commit is contained in:
team3
2026-06-18 14:30:21 +02:00
parent d8932c90d6
commit 9c0f622e0c
30 changed files with 45808 additions and 217 deletions

View File

@@ -24,11 +24,11 @@ from jsonio import read_json_file as _json_datei
from paths import arbeit_dir, bausteine_path, project_dir, subbausteine_path, quelle_path, quelle_crawl_dir, safe_ordner
from crawl import crawl
from pipeline import (
CANCELLED, FAILED, GenContext, _extra, _log, _prompt, _race, _rest_schema,
CANCELLED, FAILED, GenContext, _extra, _log, _prompt, _race, _relevanz_schema, _rest_schema,
_runde_schema, _semaphore, _str_liste, _stufen_schema, _timeout, run_single_slot,
)
from textkit import (
_eindeutige_titel, _norm_titel, _parse_auswahl, _parse_subbausteine, _titel,
_eindeutige_titel, _lade_bausteine, _norm_titel, _parse_auswahl, _parse_subbausteine, _titel,
_titel_aufloesen, _titel_index, _vormerge,
)
@@ -50,6 +50,7 @@ BAUSTEINE_STEPS = (
"Recherche", "Konsolidierung", "Klärung",
"Subbausteine finden", "Subbausteine wählen", "Subbausteine klären",
"Stufen finden", "Stufen wählen", "Stufen klären",
"Relevanz finden", "Relevanz wählen", "Relevanz klären",
)
@@ -78,6 +79,36 @@ def _crawl_fertig(topic: str) -> bool:
return (quelle_crawl_dir(topic) / ".done").exists() # Marker erst bei sauberem Abschluss
_STUFEN = ("einfach", "mittel", "schwer")
def lade_uebersicht(topic: str) -> list[dict]:
"""Strukturierte Baustein-Liste für die Übersicht: Titel + Beschreibung + Subbausteine/Stufen.
Verbindet bausteine.md (Nummer/Titel/Beschreibung) mit der Sidecar subbausteine.json
(Key = Titel). Fehlt die Sidecar, sind die Subbaustein-Listen leer.
"""
entries = _lade_bausteine(_read(bausteine_path(topic)))
sidecar = _json_datei(subbausteine_path(topic))
sidecar = sidecar if isinstance(sidecar, dict) else {}
out = []
for num, entry in entries.items():
titel = _titel(entry)
teile = entry.split("", 1)
beschreibung = teile[1].strip() if len(teile) == 2 else ""
subbausteine = [
{
"titel": t,
"stufe": s.get("stufe") if s.get("stufe") in _STUFEN else "mittel",
"relevanz": s.get("relevanz") if s.get("relevanz") in ("relevant", "rand") else None,
}
for s in (sidecar.get(titel) or [])
if isinstance(s, dict) and (t := str(s.get("titel", "")).strip())
]
out.append({"num": num, "titel": titel, "beschreibung": beschreibung, "subbausteine": subbausteine})
return out
def _bausteine_steps(topic: str) -> tuple:
"""Schritte je Quelle: link bekommt vorne „Quelle laden", projekt zusätzlich „Ergänzung".
@@ -89,6 +120,7 @@ def _bausteine_steps(topic: str) -> tuple:
rest = (
"Subbausteine finden", "Subbausteine wählen", "Subbausteine klären",
"Stufen finden", "Stufen wählen", "Stufen klären",
"Relevanz finden", "Relevanz wählen", "Relevanz klären",
)
mitte = base + (("Ergänzung",) if q["type"] == "projekt" else ()) + rest
return (("Quelle laden",) if q["type"] == "link" else ()) + mitte
@@ -117,7 +149,7 @@ def _bausteine_files(topic: str) -> dict:
def _alle_slot_dateien(files: dict) -> list[Path]:
arbeit = files["arbeit"]
# Subbaustein-/Stufen-Slots sind pro Chunk dynamisch — per Glob einsammeln.
dyn = (list(arbeit.glob("subbaustein-*")) + list(arbeit.glob("stufe-*"))) if arbeit.is_dir() else []
dyn = (list(arbeit.glob("subbaustein-*")) + list(arbeit.glob("stufe-*")) + list(arbeit.glob("relevanz-*"))) if arbeit.is_dir() else []
return [
*files["recherche"], files["recherche_mapping"],
*(p for slots in files["auswahl"].values() for p in slots),
@@ -153,8 +185,12 @@ def _resume_step(topic: str) -> int:
return _step_idx(topic, "Klärung")
if q["type"] == "projekt" and not files["ergaenzung"].exists():
return _step_idx(topic, "Ergänzung")
if _sidecar_schema(_json_datei(files["sidecar"])) is not None:
sidecar = _json_datei(files["sidecar"])
if _sidecar_schema(sidecar) is not None:
# Stufen fertig; nur noch Relevanz offen?
if _relevanz_komplett(sidecar):
return len(_bausteine_steps(topic))
return _step_idx(topic, "Relevanz finden")
if _sub_roh_schema(_json_datei(files["sub_roh"])) is None:
return _step_idx(topic, "Subbausteine finden")
return _step_idx(topic, "Stufen finden")
@@ -287,7 +323,7 @@ def _sub_roh_schema(data):
def _sidecar_schema(data):
"""{Baustein-Titel: [{titel, stufe}, …]} → dict · sonst None (finale Sidecar)."""
"""{Baustein-Titel: [{titel, stufe}, …]} → dict · sonst None (Sidecar mit Stufen)."""
if not isinstance(data, dict) or not data:
return None
for v in data.values():
@@ -299,6 +335,17 @@ def _sidecar_schema(data):
return data
def _relevanz_komplett(data) -> bool:
"""Jeder Subbaustein der Sidecar trägt eine gültige Relevanz (relevant/rand)?"""
if not isinstance(data, dict) or not data:
return False
return all(
isinstance(s, dict) and s.get("relevanz") in ("relevant", "rand")
for v in data.values() if isinstance(v, list)
for s in v
)
def _read(p: Path) -> str:
return p.read_text(encoding="utf-8") if p.exists() else ""
@@ -574,6 +621,115 @@ async def _stufen_block(ctx: GenContext, set_p, files: dict, roh: dict, instruct
return sidecar
async def _relevanz_block(ctx: GenContext, set_p, files: dict, sidecar: dict, instructions: str) -> dict | None:
"""Block D: drei Phasen mit Barriere — Finden (relevant/rand), Wählen (Vote), Klären.
Items aus der Sidecar; lokale IDs 1..n pro Paket → globale gid.
{gid: relevanz} oder None bei Abbruch/Recherche-Fehler. Default bei Lücke/Streit: 'relevant'."""
topic, provider, is_cancelled = ctx.topic, ctx.provider, ctx.is_cancelled
arbeit = files["arbeit"]
items = [(titel, sub["titel"]) for titel, subs in sidecar.items() for sub in subs] # globale id = index+1
if not items:
return {}
chunks = _chunk_nums(list(range(len(items))), _n_chunks(len(items), STUFE_CHUNK))
n = len(chunks)
def rater_paths(c):
return [arbeit / f"relevanz-c{c}-{i}.json" for i in (1, 2, 3)]
def lset(item_idxs):
return set(range(1, len(item_idxs) + 1))
# Phase „Relevanz finden": pro Paket 3 Rater (min. 2), lokale IDs.
async def _rate(c, item_idxs):
local_set = lset(item_idxs)
paths = rater_paths(c)
vorhanden = sum(1 for p in paths if _relevanz_schema(_json_datei(p), local_set))
if vorhanden >= 2:
return True
enum = "\n".join(f"{k}. [{items[j][0]}] {items[j][1]}" for k, j in enumerate(item_idxs, 1))
offen = [(i, p) for i, p in enumerate(paths, 1) if not _relevanz_schema(_json_datei(p), local_set)]
slots = [{
"key": f"bausteine-{topic}-relevanz-c{c}-{i}",
"prompt": _prompt("Relevanz-Recherche", topic=topic, subbausteine=enum, out_path=p, extra=_extra(instructions)),
"role": "fast", "capabilities": "files",
"payload": (lambda result, p=p, ids=local_set: _relevanz_schema(_json_datei(p), ids)),
} for i, p in offen]
neu = await _race(topic, f"Relevanz Paket {c}", slots, 2 - vorhanden, _timeout("relevanz", len(item_idxs)), provider, cancelled=is_cancelled, grace=KONSENS_GRACE)
return not is_cancelled() and neu is not None
set_p(f"Relevanz finden ({n} Pakete)…", step=_step_idx(topic, "Relevanz finden"))
oks = await asyncio.gather(*[_rate(c, idxs) for c, idxs in enumerate(chunks, 1)], return_exceptions=True)
if is_cancelled():
return None
if not all(ok is True for ok in oks):
_bausteine_errors[topic] = "Relevanz fehlgeschlagen (Recherche)"
return None
# Phase „Relevanz wählen": Code-Vote je Paket → (ergebnis, strittig).
set_p(f"Relevanz wählen ({n} Pakete)…", step=_step_idx(topic, "Relevanz wählen"))
vote_by_c = {}
for c, item_idxs in enumerate(chunks, 1):
local_set = lset(item_idxs)
rater = [d for p in rater_paths(c) if (d := _relevanz_schema(_json_datei(p), local_set))]
ergebnis: dict[int, str] = {}
strittig: dict[int, list[str]] = {}
for k in range(1, len(item_idxs) + 1):
stimmen = [d[k] for d in rater if k in d]
zaehler: dict[str, int] = {}
for s in stimmen:
zaehler[s] = zaehler.get(s, 0) + 1
best = max(zaehler.values(), default=0)
gewinner = [s for s, v in zaehler.items() if v == best]
if len(gewinner) == 1 and best >= 2:
ergebnis[k] = gewinner[0]
else:
strittig[k] = stimmen
vote_by_c[c] = (ergebnis, strittig)
# Phase „Relevanz klären": Judge je Paket mit Strittigem, alle parallel.
async def _klaere(c, item_idxs):
ergebnis, strittig = vote_by_c[c]
if strittig:
judge_path = arbeit / f"relevanz-final-c{c}.json"
entsch = _relevanz_schema(_json_datei(judge_path), set(strittig))
if entsch is None:
strittig_block = "\n".join(
f"{k}. [{items[item_idxs[k - 1]][0]}] {items[item_idxs[k - 1]][1]} — Stimmen: {', '.join(stimmen) or 'keine'}"
for k, stimmen in strittig.items()
)
status, entsch = await run_single_slot(
ctx, f"Relevanz-Klärung {c}",
key=f"bausteine-{topic}-relevanz-final-c{c}",
prompt=_prompt("Relevanz-Mapping", topic=topic, strittig=strittig_block, out_path=judge_path, extra=_extra(instructions)),
role="judge", capabilities="files",
payload=lambda result, p=judge_path, ids=set(strittig): _relevanz_schema(_json_datei(p), ids),
timeout=_timeout("relevanz_check", len(strittig)),
)
if status == FAILED:
_log(topic, f"Relevanz-Klärung Paket {c} fehlgeschlagen — Default 'relevant'")
entsch = entsch if isinstance(entsch, dict) else {}
# Strittige ohne Entscheid → 'relevant' (nie versehentlich ausschließen).
ergebnis = {**{k: "relevant" for k in strittig}, **ergebnis, **entsch}
return {item_idxs[k - 1] + 1: rel for k, rel in ergebnis.items()}
set_p(f"Relevanz klären ({n} Pakete)…", step=_step_idx(topic, "Relevanz klären"))
parts = await asyncio.gather(*[_klaere(c, idxs) for c, idxs in enumerate(chunks, 1)], return_exceptions=True)
if is_cancelled():
return None
relevanz_by_id: dict[int, str] = {}
for c, part in enumerate(parts, 1):
if not isinstance(part, dict):
# Klärung ist nicht fatal: Vote-Ergebnis + Default 'relevant' für Strittige.
if isinstance(part, BaseException):
_log(topic, f"Relevanz-Klärung Paket {c}: {type(part).__name__}: {part}")
ergebnis, strittig = vote_by_c[c]
item_idxs = chunks[c - 1]
merged = {**{k: "relevant" for k in strittig}, **ergebnis}
part = {item_idxs[k - 1] + 1: s for k, s in merged.items()}
relevanz_by_id.update(part)
return relevanz_by_id
async def generate_bausteine(topic: str, instructions: str = "", provider: str = DEFAULT_PROVIDER) -> None:
if topic in _bausteine_progress:
return
@@ -834,6 +990,24 @@ async def generate_bausteine(topic: str, instructions: str = "", provider: str =
if sidecar is None:
return
atomic_write_json(files["sidecar"], sidecar, indent=1)
# Block D: Relevanz je Subbaustein (relevant/rand) → in die Sidecar mergen.
# Eigene Phase nach den Stufen; treibt das ProGuide-Format (alle Bausteine
# mit ≥1 relevantem Subbaustein) und filtert Rand-Subs aus den Guides.
sidecar = _json_datei(files["sidecar"])
if _sidecar_schema(sidecar) is not None and not _relevanz_komplett(sidecar):
relevanz_by_id = await _relevanz_block(ctx, set_p, files, sidecar, instructions)
if is_cancelled():
abgebrochen()
return
if relevanz_by_id is None:
return # Fehler ist gesetzt
gid = 0
for subs in sidecar.values():
for sub in subs:
gid += 1
sub["relevanz"] = relevanz_by_id.get(gid, "relevant")
atomic_write_json(files["sidecar"], sidecar, indent=1)
except Exception as e:
log.exception("[%s] Bausteine-Generierung fehlgeschlagen", topic)
_bausteine_errors[topic] = str(e)[:2000]

View File

@@ -6,6 +6,7 @@ STORAGE_DIR = PROJECT_ROOT / "storage"
FRONTEND_DIST = PROJECT_ROOT / "frontend" / "dist"
DB_PATH = STORAGE_DIR / "creator.db"
PROJECTS_DIR = PROJECT_ROOT / "projects"
UNI_DIR = PROJECT_ROOT / "uni"
MAX_CONCURRENT_GENERATIONS = 10
@@ -42,6 +43,8 @@ TIMEOUTS = {
"subbaustein_check": (300, 15), # Judge entscheidet strittige Subbausteine im Chunk
"stufe": (300, 10), # Subbausteine einstufen je Chunk
"stufe_check": (300, 10), # Judge entscheidet strittige Stufen im Chunk
"relevanz": (300, 10), # Subbausteine relevant/rand je Chunk
"relevanz_check": (300, 10), # Judge entscheidet strittige Relevanz im Chunk
"writer": (600, 120), # pro Section im Chunk
"lese_check": (300, 10), # pro Section im Paket
"onepager_recherche": (900, 0),
@@ -55,6 +58,7 @@ TIMEOUTS = {
FORMAT_ANTEIL = {
"MiniGuide": (0.05, 0.10, 8, "einen kompakten Anfänger-Guide — der schnelle Einstieg ins Thema"),
"Guide": (0.25, 0.35, 20, "einen ausführlichen Anfänger-Guide — ein solides Fundament im Thema"),
"ProGuide": (0.0, 1.0, 0, "einen fokussierten Guide — alles Relevante ohne Randthemen"),
"FullGuide": (0.90, 1.00, 0, "einen Komplett-Guide — das ganze Thema"),
}

View File

@@ -71,7 +71,7 @@ def _topic_context(topic: str, limit: int = 12000) -> str:
bp = bausteine_path(topic)
if bp.exists():
parts.append(bp.read_text(encoding="utf-8"))
for fmt in ("FullGuide", "Guide", "MiniGuide", "OnePager"):
for fmt in ("FullGuide", "ProGuide", "Guide", "MiniGuide", "OnePager"):
content = _json_datei(guide_content_path(topic, fmt))
if content:
for ch in content.get("chapters", []):

View File

@@ -407,7 +407,20 @@ async def _generate_sections(
"Wähle, was diesem Zweck dient — lass weg, was dafür nicht nötig ist."
)
# Schritt 0: Auswahl-Konsens (5 Agenten → Voting → Mapping → Klärungs-Loop)
# Subbausteine je Baustein (Sidecar) — früh geladen: ProGuide wählt darüber aus,
# Nicht-FullGuide filtert später Rand-Subbausteine. Fehlt sie → {} (Fallback).
subs_raw = _load_subbausteine(topic)
# Schritt 0: Auswahl. ProGuide ist deterministisch — alle Bausteine mit ≥1
# relevantem Subbaustein. Fallback (keine Relevanz-Daten): alle Bausteine.
if format_name == "ProGuide":
auswahl = [num for num in entries
if any(s.get("relevanz") == "relevant" for s in subs_raw.get(_titel(entries[num]), []))]
if not auswahl:
_log(topic, "ProGuide: keine Relevanz-Daten — alle Bausteine genommen")
auswahl = list(entries)
else:
# Auswahl-Konsens (5 Agenten → Voting → Mapping → Klärungs-Loop)
auswahl = await _konsens_auswahl(
ctx, files, entries, k_min, k_max, auswahl_auftrag, format_name,
bausteine_liste, instructions,
@@ -487,9 +500,16 @@ async def _generate_sections(
# dieselbe Aufteilung: 1 Agent je ~30 Bausteine (gedeckelt).
total_sections = sum(len(c["nums"]) for c in plan)
chunks = _split_chunks(plan, min(WRITER_MAX, max(1, math.ceil(total_sections / WRITER_SECTIONS))))
# Subbausteine je Baustein (Sidecar). Fehlt sie → leer → Inhalte/Writer laufen
# auf Baustein-Granularität weiter (Fallback für Alt-Themen ohne Sidecar).
subs_by_titel = _load_subbausteine(topic)
# Subbausteine je Baustein. Rand-Subbausteine fliegen aus allen Guides AUSSER
# FullGuide (Fokus). Subs ohne Relevanz-Feld (Alt-Themen) bleiben erhalten.
# Fehlt die Sidecar → leer → Inhalte/Writer laufen auf Baustein-Granularität.
subs_by_titel = subs_raw
if format_name != "FullGuide":
subs_by_titel = {
t: [s for s in subs if s.get("relevanz") != "rand"]
for t, subs in subs_raw.items()
}
subs_by_titel = {t: subs for t, subs in subs_by_titel.items() if subs}
zuteilungen = [_zuteilung_subs(chunk, entries, subs_by_titel) for chunk in chunks]
chunk_sizes = [sum(len(c["nums"]) for c in chunk) for chunk in chunks]
writer_count = len(chunks)

View File

@@ -5,6 +5,7 @@ FormatType = Literal[
"OnePager",
"MiniGuide",
"Guide",
"ProGuide",
"FullGuide",
]
@@ -50,6 +51,37 @@ class ProjectResponse(BaseModel):
name: str
class FolderResponse(BaseModel):
name: str
ort: str # relativer Pfad ab Repo-Root (z.B. "projects/foo")
class BausteineQuelleUpdate(BaseModel):
topic: str = Field(min_length=1, max_length=100)
type: SourceType = "thema"
ort: str = Field(default="", max_length=2000)
spec: str = Field(default="", max_length=2000)
class BausteineQuelleResponse(BaseModel):
type: SourceType
ort: str
spec: str
class SubbausteinInfo(BaseModel):
titel: str
stufe: Literal["einfach", "mittel", "schwer"]
relevanz: Literal["relevant", "rand"] | None = None
class BausteinUebersicht(BaseModel):
num: int
titel: str
beschreibung: str = ""
subbausteine: list[SubbausteinInfo] = []
class ProviderInfo(BaseModel):
id: str
available: bool

View File

@@ -158,6 +158,32 @@ def _stufen_schema(data, ids: set[int] | None = None):
return out
_RELEVANZ = ("relevant", "rand")
def _relevanz_schema(data, ids: set[int] | None = None):
"""{"relevanz": {"1": "relevant", …}} → {id: relevanz} · sonst None.
Relevanz ∈ {relevant, rand} (binär). Wie `_stufen_schema`: sind `ids` gegeben,
müssen mindestens diese abgedeckt sein (Extras erlaubt).
"""
if not isinstance(data, dict) or not isinstance(data.get("relevanz"), dict) or not data["relevanz"]:
return None
out: dict[int, str] = {}
for k, v in data["relevanz"].items():
try:
num = int(k)
except (ValueError, TypeError):
return None
wert = str(v).strip().casefold()
if wert not in _RELEVANZ:
return None
out[num] = wert
if ids is not None and not ids <= set(out):
return None
return out
_MAX_RESTARTS = 2

View File

@@ -18,10 +18,11 @@ from paths import bausteine_path, guide_content_path
from textkit import _norm_titel
MAX_OFFENE_GUIDES = 3
VORSTUFE = {"Guide": "MiniGuide", "FullGuide": "Guide"}
VORSTUFE = {"Guide": "MiniGuide", "ProGuide": "Guide", "FullGuide": "Guide"}
# Welches Niveau die Vorstufe erreichen muss, um das Format freizuschalten.
FREISCHALT_LEVEL = {"Guide": "absolviert", "FullGuide": "verstanden"}
FORMATE = ("MiniGuide", "Guide", "FullGuide")
# ProGuide hängt parallel zu FullGuide an „Guide absolviert" — kein Pflicht-Gate vor FullGuide.
FREISCHALT_LEVEL = {"Guide": "absolviert", "ProGuide": "absolviert", "FullGuide": "verstanden"}
FORMATE = ("MiniGuide", "Guide", "ProGuide", "FullGuide")
async def lade_lernstand() -> tuple[list[dict], dict[str, set[str]], dict[str, dict[str, set[str]]]]:

View File

@@ -7,7 +7,7 @@ from fastapi import APIRouter, HTTPException
from fastapi.responses import FileResponse
from agents import provider_available
from config import PROJECTS_DIR, PROVIDERS
from config import PROJECTS_DIR, UNI_DIR, PROVIDERS
from database import (
create_guide, delete_guide, get_guide, list_guides,
create_topic, list_topics as db_list_topics, delete_topic,
@@ -16,7 +16,7 @@ from database import (
get_vertiefung, set_vertiefung, list_vertiefungen,
list_baustein_progress, set_baustein_score, set_baustein_streak, set_baustein_absolviert, set_baustein_verstanden, set_baustein_gemeistert, delete_baustein_daten,
)
from bausteine import generate_bausteine, cancel_bausteine, bausteine_status, active_bausteine, reset_bausteine
from bausteine import generate_bausteine, cancel_bausteine, bausteine_status, active_bausteine, reset_bausteine, lade_quelle, lade_uebersicht
from elements import generate_element, chat_with_guide, chat_with_element, check_element, style_element, refine_suggestion
from lernen import NOETIG, MASTERY, MEISTERN, baustein_chat, baustein_diskussion, baustein_element_anlegen, pruefung_bewertung, pruefung_bewertung_schnell, pruefung_frage, score_berechnen, streak_berechnen, vertiefung_generieren
from guide import generate_guide, guide_slot_dateien
@@ -31,6 +31,7 @@ from models import (
ElementUpdateRequest, ElementCheckRequest, ElementCheckResponse, ElementStyleResponse,
ElementRefineRequest, ElementRefineResponse,
ProgressUpdate, ProgressResponse, ProjectResponse, ProviderInfo,
FolderResponse, BausteineQuelleUpdate, BausteineQuelleResponse, BausteinUebersicht,
VertiefungRequest, VertiefungResponse,
BausteinChatRequest, BausteinChatResponse,
BausteinPruefungRequest, BausteinPruefungResponse, BausteinLernstandResponse,
@@ -113,6 +114,18 @@ async def remove_project(name: str):
return {"ok": True}
@router.get("/folders", response_model=list[FolderResponse])
async def list_folders(kind: str):
"""Ordner für die Quellen-Auswahl: kind=projekt → projects/, kind=uni → uni/."""
base = {"projekt": (PROJECTS_DIR, "projects"), "uni": (UNI_DIR, "uni")}.get(kind)
if base is None:
raise HTTPException(400, "kind muss 'projekt' oder 'uni' sein")
root, prefix = base
if not root.is_dir():
return []
return [{"name": e.name, "ort": f"{prefix}/{e.name}"} for e in sorted(root.iterdir()) if e.is_dir()]
# --- Bausteine ---
@router.get("/bausteine/status", response_model=BausteineStatusResponse)
@@ -161,6 +174,39 @@ async def remove_bausteine(topic: str):
return {"ok": True}
def _validate_quelle(typ: str, ort: str) -> None:
"""Quellen-Eingabe prüfen (gleiche Regeln wie beim Erstellen)."""
if typ in ("projekt", "uni"):
ordner = safe_ordner(ort)
if ordner is None or not ordner.is_dir():
raise HTTPException(400, "Ordner ungültig oder nicht gefunden (Pfad relativ zum Projekt-Root, kein ../).")
elif typ == "link":
if not ort.lower().startswith(("http://", "https://")):
raise HTTPException(400, "Link muss mit http:// oder https:// beginnen.")
@router.get("/bausteine/quelle", response_model=BausteineQuelleResponse)
async def get_bausteine_quelle(topic: str):
return lade_quelle(topic)
@router.put("/bausteine/quelle", response_model=BausteineQuelleResponse)
async def update_bausteine_quelle(req: BausteineQuelleUpdate):
"""Nur speichern — KEINE Neugenerierung. Quellen-/Spec-Wahl überschreiben."""
topic, typ, ort = req.topic.strip(), req.type, req.ort.strip()
_validate_quelle(typ, ort)
qp = quelle_path(topic)
qp.parent.mkdir(parents=True, exist_ok=True)
daten = {"type": typ, "ort": ort, "spec": req.spec.strip()}
atomic_write_json(qp, daten)
return daten
@router.get("/bausteine/uebersicht", response_model=list[BausteinUebersicht])
async def get_bausteine_uebersicht(topic: str):
return lade_uebersicht(topic)
# --- Baustein-Lernen: Vertiefung, Chat, Prüfung ---
async def _bester_text(topic: str, baustein: str) -> str | None:

View File

@@ -1,14 +1,14 @@
<script setup>
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import { fetchGuides, fetchTopics, createTopic as apiCreateTopic, deleteTopic as apiDeleteTopic, createGuide as apiCreate, deleteGuide, cancelGuide as apiCancel, fetchBausteineStatus, fetchActiveBausteine, createBausteine as apiCreateBausteine, cancelBausteine as apiCancelBausteine, deleteBausteine as apiDeleteBausteine, fetchProjects, deleteProject as apiDeleteProject, fetchProviders, fetchStats, fetchTopicFortschritt, fetchGuideLocks } from './api.js'
import { fetchGuides, fetchTopics, createTopic as apiCreateTopic, deleteTopic as apiDeleteTopic, createGuide as apiCreate, deleteGuide, cancelGuide as apiCancel, fetchBausteineStatus, fetchActiveBausteine, createBausteine as apiCreateBausteine, cancelBausteine as apiCancelBausteine, deleteBausteine as apiDeleteBausteine, fetchProviders, fetchStats, fetchTopicFortschritt, fetchGuideLocks, fetchFolders, updateQuelle as apiUpdateQuelle } from './api.js'
import { usePolling } from './composables/usePolling.js'
import TopicSidebar from './components/TopicSidebar.vue'
import TopicDetail from './components/TopicDetail.vue'
import BausteineUebersicht from './components/BausteineUebersicht.vue'
import ElementsSidebar from './components/elements/ElementsSidebar.vue'
import ElementsOverview from './components/ElementsOverview.vue'
const guides = ref([])
const projects = ref([])
const backendTopics = ref([])
const selectedTopic = ref(null)
const previewGuide = ref(null)
@@ -24,6 +24,8 @@ const bausteine = ref({ ...EMPTY_BAUSTEINE })
const activeBausteine = ref([])
const provider = ref(localStorage.getItem('provider') || 'claude')
const providers = ref([])
const folders = ref({ projekt: [], uni: [] }) // Ordner für die Quellen-Auswahl
const bausteineView = ref(false) // Bausteine-Übersicht im Hauptbereich
const stats = ref(null)
const fortschritt = ref({})
const locks = ref({}) // Sperr-Gründe pro Format (Backend = einzige Regel-Quelle)
@@ -47,6 +49,15 @@ function setProvider(id) {
localStorage.setItem('provider', id)
}
async function loadFolders() {
try {
const [projekt, uni] = await Promise.all([fetchFolders('projekt'), fetchFolders('uni')])
folders.value = { projekt, uni }
} catch (e) {
console.error('Fehler beim Laden der Ordner:', e)
}
}
async function loadProviders() {
try {
providers.value = await fetchProviders()
@@ -86,12 +97,7 @@ function onSidebarLeave() {
if (!sidebarPinned.value) sidebarSticky.value = false
}
const projectNames = computed(() => projects.value.map((p) => p.name))
const topics = computed(() => {
const isProject = new Set(projectNames.value)
return backendTopics.value.filter((t) => !isProject.has(t))
})
const topics = computed(() => backendTopics.value)
const doneByFormat = computed(() => {
const map = {}
@@ -174,15 +180,7 @@ async function loadBausteine() {
}
}
async function loadProjects() {
try {
projects.value = await fetchProjects()
} catch (e) {
console.error('Fehler beim Laden der Projekte:', e)
}
}
const FORMAT_ORDER = ['OnePager', 'MiniGuide', 'Guide', 'FullGuide']
const FORMAT_ORDER = ['OnePager', 'MiniGuide', 'Guide', 'ProGuide', 'FullGuide']
function autoPreview() {
const map = doneByFormat.value
@@ -201,6 +199,7 @@ function selectTopic(topic) {
sidebarSticky.value = false
elementsOpen.value = false
elementsView.value = false
bausteineView.value = false
elementOpenId.value = null
localStorage.setItem('lastTopic', topic)
loadBausteine()
@@ -258,6 +257,24 @@ async function handleCreateThema({ topic, instructions, sourceType, sourceOrt })
startPolling()
}
async function handleUpdateQuelle({ topic, type, ort, spec }) {
uiError.value = null
try {
await apiUpdateQuelle(topic, { type, ort, spec })
} catch (e) {
uiError.value = e.message
return
}
await loadBausteine() // Schritt-Anzeige folgt ggf. der neuen Quelle (z.B. Link → „Quelle laden")
}
function handleOpenBausteineView() {
if (!selectedTopic.value) return
bausteineView.value = true
elementsView.value = false
previewGuide.value = null
}
async function handleFormatClick({ format, instructions }) {
if (!selectedTopic.value) return
// Kein Duplikat-Start: läuft für Thema+Format schon eine Generierung, ignorieren
@@ -277,23 +294,16 @@ async function handleFormatClick({ format, instructions }) {
startPolling()
}
async function handleDeleteProject(name) {
await apiDeleteProject(name)
if (selectedTopic.value === name) {
selectedTopic.value = null
previewGuide.value = null
}
await loadProjects()
}
function handlePreview(guide) {
previewGuide.value = guide
elementsView.value = false
bausteineView.value = false
}
function handleOpenElements() {
if (!selectedTopic.value) return
elementsView.value = true
bausteineView.value = false
// Rechte Sidebar bleibt zu — sie öffnet erst beim Klick auf ein Element.
}
@@ -338,10 +348,10 @@ async function handleDeleteTopic(topic) {
}
onMounted(async () => {
await Promise.all([loadGuides(), loadTopics(), loadProjects(), loadProviders()])
await Promise.all([loadGuides(), loadTopics(), loadProviders(), loadFolders()])
const savedTopic = localStorage.getItem('lastTopic')
const savedFormat = localStorage.getItem('lastFormat')
if (savedTopic && [...topics.value, ...projectNames.value].includes(savedTopic)) {
if (savedTopic && topics.value.includes(savedTopic)) {
selectTopic(savedTopic)
await nextTick()
const g = doneByFormat.value[savedFormat]
@@ -358,7 +368,6 @@ onMounted(async () => {
<div v-if="!sidebarPinned && sidebarSticky" class="sidebar-backdrop" @click="sidebarSticky = false"></div>
<TopicSidebar
:topics="topics"
:projects="projectNames"
:selectedTopic="selectedTopic"
:stats="stats"
:fortschritt="fortschritt"
@@ -374,17 +383,19 @@ onMounted(async () => {
:dark="darkMode"
:provider="provider"
:providers="providers"
:folders="folders"
@setProvider="setProvider"
@toggleDark="toggleDark"
@select="selectTopic"
@create="createTopic"
@createThema="handleCreateThema"
@updateQuelle="handleUpdateQuelle"
@openBausteineView="handleOpenBausteineView"
@formatClick="handleFormatClick"
@bausteineClick="handleBausteineClick"
@cancelBausteine="handleCancelBausteine"
@resetBausteine="handleResetBausteine"
@deleteTopic="handleDeleteTopic"
@deleteProject="handleDeleteProject"
@cancelGuide="handleCancel"
@deleteGuide="handleDeleteGuide"
@dismissError="handleDismissError"
@@ -394,8 +405,13 @@ onMounted(async () => {
@togglePin="toggleSidebarPin"
@sidebarLeave="onSidebarLeave"
/>
<BausteineUebersicht
v-if="selectedTopic && bausteineView"
:topic="selectedTopic"
@close="bausteineView = false"
/>
<ElementsOverview
v-if="selectedTopic && elementsView"
v-else-if="selectedTopic && elementsView"
:topic="selectedTopic"
:version="elementsVersion"
@open="handleOpenElementDetail"

View File

@@ -124,6 +124,30 @@ export async function fetchProjects() {
return res.json()
}
export async function fetchFolders(kind) {
const res = await fetch(`${BASE}/folders?kind=${encodeURIComponent(kind)}`)
return jsonOrThrow(res)
}
export async function fetchQuelle(topic) {
const res = await fetch(`${BASE}/bausteine/quelle?topic=${encodeURIComponent(topic)}`)
return jsonOrThrow(res)
}
export async function updateQuelle(topic, { type, ort = '', spec = '' }) {
const res = await fetch(`${BASE}/bausteine/quelle`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ topic, type, ort, spec }),
})
return jsonOrThrow(res)
}
export async function fetchBausteineUebersicht(topic) {
const res = await fetch(`${BASE}/bausteine/uebersicht?topic=${encodeURIComponent(topic)}`)
return jsonOrThrow(res)
}
export async function deleteProject(name) {
await fetch(`${BASE}/projects/${encodeURIComponent(name)}`, { method: 'DELETE' })
}

View File

@@ -0,0 +1,211 @@
<script setup>
import { ref, computed, watch } from 'vue'
import { fetchBausteineUebersicht } from '../api.js'
const props = defineProps({
topic: { type: String, required: true },
})
const emit = defineEmits(['close'])
const items = ref([])
const loading = ref(true)
const error = ref(null)
// Stufen-Reihenfolge + Anzeige-Label (Farbe via CSS-Klasse st-<key>)
const STUFEN = [
{ key: 'einfach', label: 'Einfach' },
{ key: 'mittel', label: 'Mittel' },
{ key: 'schwer', label: 'Schwer' },
]
watch(() => props.topic, load, { immediate: true })
async function load() {
loading.value = true
error.value = null
items.value = []
try {
items.value = await fetchBausteineUebersicht(props.topic)
} catch (e) {
error.value = 'Übersicht nicht verfügbar — bitte erst Bausteine erstellen.'
} finally {
loading.value = false
}
}
// Nur nicht-leere Stufen-Gruppen je Baustein (v-if + v-for nicht auf einem Element)
function gruppen(b) {
return STUFEN
.map((st) => ({ ...st, subs: (b.subbausteine || []).filter((s) => s.stufe === st.key) }))
.filter((g) => g.subs.length)
}
const subTotal = computed(() => items.value.reduce((n, b) => n + (b.subbausteine?.length || 0), 0))
</script>
<template>
<div class="bk-view">
<header class="bk-head">
<h1>{{ topic }}</h1>
<span class="bk-sub">Bausteine-Übersicht</span>
<span v-if="items.length" class="bk-count">{{ items.length }} Bausteine · {{ subTotal }} Subbausteine</span>
<span class="bk-spacer"></span>
<button class="bk-close" title="Schließen" @click="emit('close')"></button>
</header>
<div v-if="loading" class="bk-empty-state">Lade</div>
<div v-else-if="error" class="bk-empty-state">{{ error }}</div>
<div v-else-if="!items.length" class="bk-empty-state">Noch keine Bausteine.</div>
<div v-else class="bk-grid">
<article v-for="b in items" :key="b.num" class="bk-card">
<h3 class="bk-title"><span class="bk-num">{{ b.num }}</span>{{ b.titel }}</h3>
<p v-if="b.beschreibung" class="bk-desc">{{ b.beschreibung }}</p>
<div v-if="b.subbausteine && b.subbausteine.length" class="bk-stufen">
<div v-for="g in gruppen(b)" :key="g.key" class="bk-stufe" :class="'st-' + g.key">
<span class="bk-stufe-label">{{ g.label }}</span>
<ul>
<li v-for="s in g.subs" :key="s.titel" :class="{ rand: s.relevanz === 'rand' }">
{{ s.titel }}<span v-if="s.relevanz === 'rand'" class="rand-tag" title="Randthema — nur im FullGuide">Rand</span>
</li>
</ul>
</div>
</div>
<p v-else class="bk-no-subs">Keine Subbausteine.</p>
</article>
</div>
</div>
</template>
<style scoped>
.bk-view {
flex: 1;
min-width: 0;
height: 100dvh;
display: flex;
flex-direction: column;
background: var(--bg-preview);
}
.bk-head {
display: flex;
align-items: baseline;
gap: 0.75rem;
padding: 1.25rem 2rem;
border-bottom: 1px solid var(--border);
background: var(--panel);
}
.bk-head h1 { font-size: 1.5rem; }
.bk-sub { color: var(--text-faint); font-size: 0.9rem; font-weight: 600; }
.bk-count { color: var(--text-muted); font-size: 0.82rem; }
.bk-spacer { flex: 1; }
.bk-close {
align-self: center;
border: 1px solid var(--border-strong);
border-radius: 6px;
background: var(--panel);
color: var(--text);
width: 2rem;
height: 2rem;
cursor: pointer;
}
.bk-close:hover { border-color: var(--accent); }
.bk-empty-state {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
}
.bk-grid {
flex: 1;
overflow-y: auto;
padding: 1.5rem 2rem 4rem;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 1rem;
align-content: start;
}
.bk-card {
background: var(--panel);
border: 1px solid var(--border);
border-top: 3px solid var(--accent-border);
border-radius: 10px;
padding: 1rem 1.1rem;
}
.bk-title {
display: flex;
align-items: center;
gap: 8px;
font-size: 1rem;
margin-bottom: 0.4rem;
}
.bk-num {
flex: 0 0 auto;
min-width: 26px;
height: 26px;
padding: 0 6px;
border-radius: 7px;
background: var(--accent);
color: var(--on-accent);
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 0.78rem;
font-weight: 700;
}
.bk-desc {
color: var(--text-muted);
font-size: 0.85rem;
line-height: 1.45;
margin-bottom: 0.7rem;
}
.bk-stufen { display: flex; flex-direction: column; gap: 0.55rem; }
.bk-stufe {
border-left: 3px solid var(--st);
padding-left: 0.6rem;
}
.bk-stufe.st-einfach { --st: var(--success-border); }
.bk-stufe.st-mittel { --st: var(--warning-border); }
.bk-stufe.st-schwer { --st: var(--danger); }
.bk-stufe-label {
font-size: 0.66rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--st);
}
.bk-stufe ul {
list-style: none;
margin: 0.25rem 0 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.bk-stufe li {
font-size: 0.85rem;
color: var(--text);
line-height: 1.35;
}
.bk-stufe li.rand { color: var(--text-faint); }
.rand-tag {
margin-left: 0.4rem;
font-size: 0.6rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--text-faint);
border: 1px solid var(--border-strong);
border-radius: 4px;
padding: 0 4px;
}
.bk-no-subs { color: var(--text-faint); font-size: 0.8rem; font-style: italic; }
</style>

View File

@@ -1,10 +1,10 @@
<script setup>
import { ref, computed } from 'vue'
import { useConfirm } from '../composables/useConfirm.js'
import { fetchQuelle } from '../api.js'
const props = defineProps({
topics: { type: Array, required: true },
projects: { type: Array, default: () => [] },
selectedTopic: { type: String, default: null },
stats: { type: Object, default: null },
fortschritt: { type: Object, default: () => ({}) },
@@ -20,9 +20,17 @@ const props = defineProps({
dark: { type: Boolean, default: false },
provider: { type: String, default: 'claude' },
providers: { type: Array, default: () => [] },
folders: { type: Object, default: () => ({ projekt: [], uni: [] }) },
})
const emit = defineEmits(['select', 'create', 'createThema', 'formatClick', 'bausteineClick', 'cancelBausteine', 'resetBausteine', 'deleteTopic', 'deleteProject', 'cancelGuide', 'deleteGuide', 'dismissError', 'dismissUiError', 'preview', 'openElements', 'togglePin', 'sidebarLeave', 'toggleDark', 'setProvider'])
const emit = defineEmits(['select', 'create', 'createThema', 'updateQuelle', 'formatClick', 'bausteineClick', 'cancelBausteine', 'resetBausteine', 'deleteTopic', 'cancelGuide', 'deleteGuide', 'dismissError', 'dismissUiError', 'preview', 'openBausteineView', 'openElements', 'togglePin', 'sidebarLeave', 'toggleDark', 'setProvider'])
// Accordion: höchstens ein Panel offen. IDs: 'bausteine', 'fmt-<Format>', 'topic-<Name>'.
const openPanel = ref(null)
const isOpen = (id) => openPanel.value === id
function togglePanel(id) {
openPanel.value = openPanel.value === id ? null : id
}
function providerAvailable(id) {
const p = props.providers.find((x) => x.id === id)
@@ -40,6 +48,7 @@ const trackerItems = computed(() => {
{ label: 'Themen', value: String(props.stats.themen ?? 0), title: 'Themen inkl. Projekte' },
{ label: 'MiniGuides', value: fmt('MiniGuide'), title: 'absolviert/erstellt' },
{ label: 'Guides', value: fmt('Guide'), title: 'absolviert/erstellt' },
{ label: 'ProGuides', value: fmt('ProGuide'), title: 'absolviert/erstellt' },
{ label: 'FullGuides', value: fmt('FullGuide'), title: 'absolviert/erstellt' },
]
})
@@ -48,6 +57,7 @@ const formats = [
{ key: 'OnePager', label: 'OnePager' },
{ key: 'MiniGuide', label: 'MiniGuide' },
{ key: 'Guide', label: 'Guide' },
{ key: 'ProGuide', label: 'ProGuide' },
{ key: 'FullGuide', label: 'FullGuide' },
]
@@ -82,6 +92,12 @@ function handleBausteinePlay() {
emit('bausteineClick', { instructions: '' })
}
// Name-Klick = Primäraktion: fertige Bausteine → Übersicht, sonst Panel auf/zu.
function onBausteineName() {
if (props.bausteine.ready && !props.bausteine.generating) emit('openBausteineView')
else togglePanel('bausteine')
}
function guideStatus(format) {
// Laufende Generierung hat Vorrang — sonst maskiert ein älterer fertiger
// Guide den Lauf und ▶ würde Duplikate starten.
@@ -132,11 +148,11 @@ function abgebrochen(format) {
return latest?.status === 'error' && (latest.error_msg || '').startsWith('Abgebrochen')
}
// Name-Klick: fertiger Guide → Vorschau, sonst Aktions-Panel auf/zu.
function handleFormatClick(format) {
const guide = props.doneByFormat[format]
if (guide) {
emit('preview', guide)
}
if (guide) emit('preview', guide)
else togglePanel('fmt-' + format)
}
// Sperr-Gründe kommen vom Backend (GET /guides/locks) — die Regeln existieren
@@ -179,13 +195,6 @@ function handleDelete(format) {
// Erstellen-Bereich: inline aufklappbar (Name + weitere Infos + Quellen-Typ).
const dlg = ref(false)
const form = ref({ name: '', instructions: '', sourceType: 'thema', sourceOrt: '' })
const SOURCE_HINTS = {
thema: 'Web-Recherche zum Thema.',
link: 'Seite wird gecrawlt (gleiche Domain, begrenzt) — Klausur-Fokus.',
projekt: 'Ordner wird gelesen — Architektur/Features verstehen.',
uni: 'Ordner wird gelesen — Klausur-Vorbereitung.',
}
const sourceHint = computed(() => SOURCE_HINTS[form.value.sourceType])
const canCreate = computed(() => {
if (!form.value.name.trim()) return false
if (['link', 'projekt', 'uni'].includes(form.value.sourceType)) return !!form.value.sourceOrt.trim()
@@ -212,8 +221,45 @@ function confirmDeleteTopic(topic) {
armOrRun('topic-' + topic, () => emit('deleteTopic', topic))
}
function confirmDeleteProject(name) {
armOrRun('project-' + name, () => emit('deleteProject', name))
// --- Thema-Edit: Klick auf ein Thema wählt es UND klappt die Quellen-Form auf ---
const editTopic = ref(null)
const editForm = ref({ type: 'thema', ort: '', spec: '' })
const editLoading = ref(false)
const canSave = computed(() => {
if (['link', 'projekt', 'uni'].includes(editForm.value.type)) return !!editForm.value.ort.trim()
return true
})
async function onTopicClick(t) {
emit('select', t)
if (openPanel.value === 'topic-' + t) { openPanel.value = null; return }
openPanel.value = 'topic-' + t
editTopic.value = t
editLoading.value = true
try {
const q = await fetchQuelle(t)
editForm.value = { type: q.type || 'thema', ort: q.ort || '', spec: q.spec || '' }
} catch {
editForm.value = { type: 'thema', ort: '', spec: '' }
} finally {
editLoading.value = false
}
}
function setEditType(t) {
editForm.value.type = t
editForm.value.ort = ''
}
function saveQuelle() {
if (!canSave.value || !editTopic.value) return
emit('updateQuelle', {
topic: editTopic.value,
type: editForm.value.type,
ort: editForm.value.ort.trim(),
spec: editForm.value.spec.trim(),
})
openPanel.value = null
}
</script>
@@ -242,7 +288,7 @@ function confirmDeleteProject(name) {
<!-- Erstellen: inline aufklappbar (kein Modal) -->
<div v-if="dlg" class="thema-panel">
<input class="dlg-input" v-model="form.name" placeholder="Thema-Name…" @keyup.enter="createThema" autofocus />
<textarea class="dlg-textarea" v-model="form.instructions" rows="3" placeholder="Weitere Informationen / Spezifikation (optional)…"></textarea>
<textarea class="dlg-textarea" v-model="form.instructions" rows="2" placeholder="Weitere Infos (optional)…"></textarea>
<div class="dlg-sources">
<button :class="{ active: form.sourceType === 'thema' }" @click="form.sourceType = 'thema'; form.sourceOrt = ''">Thema</button>
<button :class="{ active: form.sourceType === 'link' }" @click="form.sourceType = 'link'; form.sourceOrt = ''">Link</button>
@@ -254,12 +300,13 @@ function confirmDeleteProject(name) {
class="dlg-input" v-model="form.sourceOrt"
placeholder="https://…" @keyup.enter="createThema"
/>
<input
<select
v-else-if="form.sourceType === 'projekt' || form.sourceType === 'uni'"
class="dlg-input" v-model="form.sourceOrt"
placeholder="Ordner ab ./ (z.B. projects/meinprojekt)" @keyup.enter="createThema"
/>
<p class="dlg-hint">{{ sourceHint }}</p>
>
<option value="" disabled>Ordner wählen</option>
<option v-for="fo in (folders[form.sourceType] || [])" :key="fo.ort" :value="fo.ort">{{ fo.name }}</option>
</select>
<div class="dlg-actions">
<button class="dlg-cancel" @click="dlg = false">Abbrechen</button>
<button class="dlg-create" :disabled="!canCreate" @click="createThema">Erstellen</button>
@@ -283,16 +330,17 @@ function confirmDeleteProject(name) {
<div class="progress-info" v-if="activeGenerations.length">
<div v-for="(line, i) in activeGenerations" :key="i">{{ line }}</div>
</div>
<div class="ord-bausteine">
<div
class="format-row bausteine-row ord-bausteine"
:class="{ 'is-active': bausteineState === 'generating' || bausteine.partial }"
class="format-row bausteine-row"
:class="{ 'is-active': bausteineState === 'generating' || bausteine.partial, 'row-open': isOpen('bausteine') }"
>
<div class="format-name bausteine-name">
<button class="format-name bausteine-name" @click="onBausteineName">
<span class="format-label">Bausteine</span>
<span
v-if="bausteine.partial && bausteineState !== 'generating'"
class="resume-badge"
title="Abgebrochen — ▶ setzt fort"
title="Abgebrochen — Fortsetzen möglich"
>Pausiert</span>
<span class="step-dots">
<span
@@ -303,46 +351,39 @@ function confirmDeleteProject(name) {
:title="s.state === 'active' ? (bausteine.progress || s.label) : s.label"
></span>
</span>
<span
v-if="bausteineState === 'generating'"
class="format-x"
:class="{ armed: pendingConfirm === 'bausteine' }"
title="Aktuellen Schritt abbrechen (Fortschritt bleibt)"
@click.stop="confirmCancelBausteine"
>{{ pendingConfirm === 'bausteine' ? 'Sicher?' : '×' }}</span>
<span
v-else-if="bausteine.partial"
class="format-x"
:class="{ armed: pendingConfirm === 'bausteine' }"
title="Fortschritt löschen"
@click.stop="confirmResetBausteine"
>{{ pendingConfirm === 'bausteine' ? 'Sicher?' : '×' }}</span>
</button>
<button class="panel-toggle" :class="{ open: isOpen('bausteine') }" title="Aktionen" @click.stop="togglePanel('bausteine')"></button>
</div>
<div class="format-actions">
<template v-if="bausteineState !== 'generating'">
<div v-if="isOpen('bausteine')" class="action-panel">
<template v-if="bausteineState === 'generating'">
<button class="panel-btn danger" :class="{ armed: pendingConfirm === 'bausteine' }" @click="confirmCancelBausteine">{{ pendingConfirm === 'bausteine' ? 'Sicher?' : 'Abbrechen' }}</button>
</template>
<template v-else>
<button class="panel-btn play" @click="handleBausteinePlay">{{ bausteine.partial ? 'Fortsetzen' : bausteine.ready ? 'Neu generieren' : 'Generieren' }}</button>
<button
class="action-btn play"
:title="bausteine.partial ? 'Fortsetzen' : bausteine.ready ? 'Bausteine neu erstellen' : 'Bausteine erstellen'"
@click="handleBausteinePlay"
></button>
v-if="bausteine.ready || bausteine.partial"
class="panel-btn danger"
:class="{ armed: pendingConfirm === 'bausteine' }"
@click="confirmResetBausteine"
>{{ pendingConfirm === 'bausteine' ? 'Sicher?' : 'Entfernen' }}</button>
</template>
</div>
</div>
<div v-if="bausteineState === 'generating'" class="format-progress ord-bausteine">
<div v-if="bausteineState === 'generating'" class="format-progress">
{{ bausteine.progress || 'Wartend' }}
</div>
<div v-if="bausteine.error && !bausteine.error.startsWith('Abgebrochen')" class="format-error ord-bausteine">
<div v-if="bausteine.error && !bausteine.error.startsWith('Abgebrochen')" class="format-error">
<span class="format-error-text">{{ bausteine.error }}</span>
</div>
</div>
<!-- OnePager (unabhängig von Bausteinen) steht per CSS-order vor der Bausteine-Zeile -->
<div v-for="f in formats" :key="f.key" :style="{ order: f.key === 'OnePager' ? 1 : 3 }">
<div :class="['format-row', 'fmt-' + guideStatus(f.key), { 'fmt-paused': abgebrochen(f.key) }]">
<div :class="['format-row', 'fmt-' + guideStatus(f.key), { 'fmt-paused': abgebrochen(f.key), 'row-open': isOpen('fmt-' + f.key) }]">
<button class="format-name" @click="handleFormatClick(f.key)">
<span class="format-label">{{ f.label }}</span>
<span
v-if="abgebrochen(f.key)"
class="resume-badge"
title="Abgebrochen — ▶ setzt fort"
title="Abgebrochen — Fortsetzen möglich"
>Pausiert</span>
<span class="step-dots" v-if="guideSteps(f.key).length">
<span
@@ -353,26 +394,28 @@ function confirmDeleteProject(name) {
:title="s.state === 'active' ? (latestByFormat[f.key]?.progress || s.label) : s.label"
></span>
</span>
<span
v-if="guideStatus(f.key) !== 'none' || abgebrochen(f.key)"
class="format-x"
:class="{ armed: pendingConfirm === 'fmt-' + f.key }"
@click.stop="handleDelete(f.key)"
:title="guideStatus(f.key) === 'generating' || guideStatus(f.key) === 'queued' ? 'Abbrechen'
: abgebrochen(f.key) ? 'Fortschritt löschen' : 'Löschen'"
>{{ pendingConfirm === 'fmt-' + f.key ? 'Sicher?' : '×' }}</span>
</button>
<div class="format-actions">
<template v-if="guideStatus(f.key) !== 'generating' && guideStatus(f.key) !== 'queued'">
<button class="panel-toggle" :class="{ open: isOpen('fmt-' + f.key) }" title="Aktionen" @click.stop="togglePanel('fmt-' + f.key)"></button>
</div>
<div v-if="isOpen('fmt-' + f.key)" class="action-panel">
<template v-if="guideStatus(f.key) === 'generating' || guideStatus(f.key) === 'queued'">
<button class="panel-btn danger" :class="{ armed: pendingConfirm === 'fmt-' + f.key }" @click="handleDelete(f.key)">{{ pendingConfirm === 'fmt-' + f.key ? 'Sicher?' : 'Abbrechen' }}</button>
</template>
<template v-else>
<button
class="action-btn play"
class="panel-btn play"
:title="playLock(f.key) || (abgebrochen(f.key) ? 'Fortsetzen' : 'Generieren')"
:disabled="!!playLock(f.key)"
@click="handlePlay(f.key)"
></button>
>{{ abgebrochen(f.key) ? 'Fortsetzen' : guideStatus(f.key) === 'done' ? 'Neu generieren' : 'Generieren' }}</button>
<button
v-if="guideStatus(f.key) !== 'none' || abgebrochen(f.key)"
class="panel-btn danger"
:class="{ armed: pendingConfirm === 'fmt-' + f.key }"
@click="handleDelete(f.key)"
>{{ pendingConfirm === 'fmt-' + f.key ? 'Sicher?' : abgebrochen(f.key) ? 'Fortschritt löschen' : 'Entfernen' }}</button>
</template>
</div>
</div>
<div
v-if="guideStatus(f.key) === 'generating' || guideStatus(f.key) === 'queued'"
class="format-progress"
@@ -393,34 +436,45 @@ function confirmDeleteProject(name) {
<li
v-for="t in topics"
:key="t"
:class="{ active: t === selectedTopic }"
@click="emit('select', t)"
:class="{ active: t === selectedTopic, 'li-open': isOpen('topic-' + t) }"
>
<span>{{ t }}</span>
<div class="topic-row" @click="onTopicClick(t)">
<span class="topic-name">{{ t }}</span>
<span class="panel-toggle" :class="{ open: isOpen('topic-' + t) }"></span>
</div>
<div v-if="isOpen('topic-' + t)" class="thema-panel edit-panel" @click.stop>
<p v-if="editLoading" class="dlg-hint">Lade</p>
<template v-else>
<textarea class="dlg-textarea" v-model="editForm.spec" rows="2" placeholder="Weitere Infos (optional)…"></textarea>
<div class="dlg-sources">
<button :class="{ active: editForm.type === 'thema' }" @click="setEditType('thema')">Thema</button>
<button :class="{ active: editForm.type === 'link' }" @click="setEditType('link')">Link</button>
<button :class="{ active: editForm.type === 'projekt' }" @click="setEditType('projekt')">Projekt</button>
<button :class="{ active: editForm.type === 'uni' }" @click="setEditType('uni')">Uni</button>
</div>
<input
v-if="editForm.type === 'link'"
class="dlg-input" v-model="editForm.ort"
placeholder="https://…"
/>
<select
v-else-if="editForm.type === 'projekt' || editForm.type === 'uni'"
class="dlg-input" v-model="editForm.ort"
>
<option value="" disabled>Ordner wählen</option>
<option v-for="fo in (folders[editForm.type] || [])" :key="fo.ort" :value="fo.ort">{{ fo.name }}</option>
</select>
<div class="dlg-actions">
<button
class="delete-topic"
class="dlg-delete"
:class="{ armed: pendingConfirm === 'topic-' + t }"
@click.stop="confirmDeleteTopic(t)"
title="Thema und alle Guides löschen"
>{{ pendingConfirm === 'topic-' + t ? 'Sicher?' : '×' }}</button>
</li>
<template v-if="projects.length">
<li class="projects-divider">Projekte</li>
<li
v-for="p in projects"
:key="'project-' + p"
:class="{ active: p === selectedTopic, 'project-item': true }"
@click="emit('select', p)"
>
<span>{{ p }}</span>
<button
class="delete-topic"
:class="{ armed: pendingConfirm === 'project-' + p }"
@click.stop="confirmDeleteProject(p)"
title="Projekt entfernen (löscht ./projects-Ordner)"
>{{ pendingConfirm === 'project-' + p ? 'Sicher?' : '×' }}</button>
</li>
@click="confirmDeleteTopic(t)"
>{{ pendingConfirm === 'topic-' + t ? 'Sicher?' : 'Löschen' }}</button>
<button class="dlg-create" :disabled="!canSave" @click="saveQuelle">Aktualisieren</button>
</div>
</template>
</div>
</li>
</ul>
</aside>
</template>
@@ -582,59 +636,35 @@ function confirmDeleteProject(name) {
}
.topic-list li {
padding: 0.6rem 1rem;
cursor: pointer;
font-size: 0.9rem;
color: var(--text);
transition: background 0.15s;
display: flex;
justify-content: space-between;
align-items: center;
}
.topic-list li:hover {
.topic-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 6px;
padding: 0.6rem 1rem;
cursor: pointer;
transition: background 0.15s;
}
.topic-row:hover {
background: var(--accent-soft);
}
.topic-list li.active {
.topic-list li.active .topic-row {
background: var(--accent-soft);
color: var(--accent-hover);
font-weight: 600;
}
.delete-topic {
display: none;
background: none;
border: none;
color: var(--danger);
font-size: 1.1rem;
cursor: pointer;
padding: 0 2px;
line-height: 1;
}
.topic-list li:hover .delete-topic {
display: block;
}
.projects-divider {
cursor: default;
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-faint);
font-weight: 700;
padding: 0.6rem 1rem 0.3rem;
margin-top: 0.4rem;
border-top: 1px solid var(--border);
}
.projects-divider:hover {
background: none;
}
.topic-list li.project-item span::before {
content: '📁 ';
.topic-name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Format section */
@@ -642,7 +672,7 @@ function confirmDeleteProject(name) {
display: flex;
align-items: center;
gap: 8px;
cursor: default;
cursor: pointer;
}
.step-dots {
@@ -756,13 +786,14 @@ function confirmDeleteProject(name) {
.format-name {
flex: 1;
min-width: 0;
background: none;
border: none;
text-align: left;
font-size: 0.85rem;
padding: 4px 8px;
border-radius: 4px;
cursor: default;
cursor: pointer;
color: var(--text-faint);
display: flex;
align-items: center;
@@ -770,6 +801,55 @@ function confirmDeleteProject(name) {
gap: 8px;
}
/* Accordion: Pfeil-Toggle + aufklappendes Aktions-Panel */
.panel-toggle {
flex: 0 0 auto;
background: none;
border: none;
cursor: pointer;
color: var(--text-faint);
font-size: 0.8rem;
line-height: 1;
padding: 4px 8px;
transition: transform 0.15s, color 0.15s;
}
.panel-toggle.open { transform: rotate(180deg); color: var(--text); }
.panel-toggle:hover { color: var(--accent); }
.format-row.row-open,
.topic-list li.li-open .topic-row { background: var(--panel-soft); }
.action-panel {
display: flex;
gap: 0.5rem;
padding: 0.15rem 0.75rem 0.55rem calc(0.75rem + 8px);
}
.panel-btn {
flex: 1;
padding: 0.45rem 0.6rem;
border: 1px solid var(--border-strong);
border-radius: 6px;
background: var(--panel);
color: var(--text);
font-size: 0.82rem;
font-weight: 600;
cursor: pointer;
transition: all 0.15s;
}
.panel-btn:hover { border-color: var(--accent); }
.panel-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.panel-btn:disabled:hover { border-color: var(--border-strong); }
.panel-btn.play {
color: var(--success);
background: var(--success-soft);
border-color: var(--success-border);
}
.panel-btn.play:hover { background: var(--success-soft-hover); }
.panel-btn.danger { color: var(--danger); }
.panel-btn.danger:hover { border-color: var(--danger); }
.panel-btn.armed { background: var(--danger); color: #fff; border-color: var(--danger); }
.format-x {
display: none;
color: var(--danger);
@@ -915,20 +995,20 @@ function confirmDeleteProject(name) {
.new-topic-toggle:hover { background: var(--accent-hover); }
.new-topic-toggle.active { background: var(--accent-hover); }
.thema-panel {
margin: 0.5rem 0;
padding: 0.75rem;
margin: 0.4rem 0;
padding: 0.5rem;
background: var(--panel-soft);
border: 1px solid var(--border);
border-radius: 10px;
border-radius: 8px;
display: flex;
flex-direction: column;
gap: 0.55rem;
gap: 0.35rem;
font-size: 0.85rem;
}
.dlg-input, .dlg-textarea {
width: 100%;
box-sizing: border-box;
padding: 0.5rem 0.6rem;
padding: 0.4rem 0.5rem;
border: 1px solid var(--border);
border-radius: 6px;
background: var(--panel);
@@ -936,23 +1016,23 @@ function confirmDeleteProject(name) {
font: inherit;
}
.dlg-input:focus, .dlg-textarea:focus { outline: none; border-color: var(--accent); }
.dlg-textarea { resize: vertical; min-height: 3rem; }
.dlg-sources { display: flex; gap: 0.4rem; }
.dlg-textarea { resize: vertical; min-height: 2rem; }
.dlg-sources { display: flex; gap: 0.3rem; }
.dlg-sources button {
flex: 1;
padding: 0.45rem 0.2rem;
padding: 0.35rem 0.2rem;
border: 1px solid var(--border);
border-radius: 6px;
background: var(--panel-soft);
color: var(--text);
cursor: pointer;
font-size: 0.82rem;
font-size: 0.8rem;
}
.dlg-sources button.active { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.dlg-hint { margin: 0; font-size: 0.75rem; color: var(--text-faint); }
.dlg-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 0.3rem; }
.dlg-actions { display: flex; justify-content: flex-end; gap: 0.4rem; margin-top: 0.1rem; }
.dlg-actions button {
padding: 0.45rem 0.9rem;
padding: 0.4rem 0.8rem;
border: 1px solid var(--border);
border-radius: 6px;
background: var(--panel-soft);
@@ -962,4 +1042,10 @@ function confirmDeleteProject(name) {
.dlg-create { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.dlg-create:disabled { opacity: 0.45; cursor: default; }
/* Thema-Edit-Panel innerhalb der Themen-Liste */
.edit-panel { margin: 0 0.75rem 0.5rem; }
.dlg-delete { margin-right: auto; color: var(--danger); }
.dlg-delete.armed { background: var(--danger); border-color: var(--danger); color: #fff; font-weight: 700; }
select.dlg-input { cursor: pointer; }
</style>

View File

@@ -0,0 +1,18 @@
Mehrere Agenten haben die Subbausteine des Themas "{topic}" nach Relevanz bewertet (relevant/rand). Bei einigen sind sie sich uneinig. Entscheide für jeden strittigen Subbaustein die finale Relevanz.
STRITTIGE SUBBAUSTEINE (mit den abgegebenen Stimmen):
{strittig}
Relevanz:
- **relevant**: Kern-/Standardwissen, ein ernsthafter Lerner braucht es.
- **rand**: Randnotiz, Spezial-/Nischenfall, „nice to know" — nur für den Komplett-Guide.
Regeln:
- Wäge die Stimmen ab, entscheide fachlich. Im Zweifel **relevant**.
- Für JEDE strittige Nummer genau einen Wert.
Schreibe NUR die JSON-Datei nach: {out_path}
Format (kein weiterer Text):
{{"relevanz": {{"1": "relevant", "4": "rand"}}}}
{extra}

View File

@@ -0,0 +1,19 @@
Bewerte jeden Subbaustein des Themas "{topic}" nach Relevanz: relevant oder rand. Die Relevanz steuert, ob ein Punkt in die fokussierten Guides kommt oder nur in den Komplett-Guide.
SUBBAUSTEINE (Nummer in Klammern der zugehörige Baustein):
{subbausteine}
Relevanz:
- **relevant**: Kern- oder Standardwissen des Themas. Ein ernsthafter Lerner braucht es im normalen Gebrauch. Was man wirklich kennen sollte.
- **rand**: Randnotiz, Spezial-/Nischenfall, „nice to know", Deprecated/Exotik. Für die meisten Lerner verzichtbar — gehört nur in einen Komplett-Guide.
Regeln:
- Bewerte jeden Punkt einzeln, gemessen an SEINEM Baustein und am Thema.
- Im Zweifel **relevant** — lieber zu viel als versehentlich Wichtiges weglassen.
- Urteile nur — erfinde nichts dazu, ändere keine Subbausteine.
Schreibe NUR die JSON-Datei nach: {out_path}
Format (für JEDE Nummer genau ein Wert; kein weiterer Text):
{{"relevanz": {{"1": "relevant", "2": "rand", "3": "relevant"}}}}
{extra}

4456
uni/aak (Copy)/Skript.pdf Normal file

File diff suppressed because it is too large Load Diff

2562
uni/aak (Copy)/Skript.txt Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,817 @@
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
09.06.2025
Hausaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 9
Definition 1 (Vertex Cover (VC)). Für einen (ungerichteten) Graphen G = (V, E) ist ein Vertex
Cover eine Menge von Knoten C ⊆ V , sodass u ∈ C oder v ∈ C für alle { u, v } ∈ E gilt, also ist
für alle Kanten mindestens ein Endpunkt in C.
Für das V ERTEX C OVER Problem ist neben einem Graphen G eine Zahl k ∈ N≥0 gegeben und
es wird gefragt, ob ein Vertex Cover mit Größe (Anzahl der Knoten) höchstens k in G existiert.
Definition 2 (Feedback Vertex Set (FVS)). Für einen gerichteten Graphen G = (V, E) ist ein
Feedback Vertex Set eine Menge von Knoten X ⊆ V , sodass G \ X kreisfrei ist.
Für das F EEDBACK V ERTEX S ET Problem ist neben einem Graphen G eine Zahl k ∈ N≥0 gege-
ben und es wird gefragt, ob ein Feedback Vertex Set mit Größe (Anzahl der Knoten) höchstens
k in G existiert.
1 6 2
5
8 7
3
4
Abbildung 1: Beispiel Graph.
Hausaufgabe 9.1 (Nichtdeterministischer Algorithmus für VC) (5 Punkte)
1. Finden Sie ein minimales Vertex Cover in Abbildung 1. Für ein Vertex Cover ist die
Orientierung der Kanten nicht relevant.
2. Zeigen Sie V ERTEX C OVER ∈ NP, indem Sie einen nichtdeterministischen Algorithmus
angeben, der V ERTEX C OVER in Polynomialzeit löst. Begründen Sie die Korrektheit und
die Laufzeit von Ihrem Algorithmus.
Lösung. 1. Ein minimales Vertex Cover ist zum Beispiel { 3, 5, 6, 7, 8 }.
2. Unser nichtdeterministischer Algorithmus geht wie folgt vor: Für jeden Knoten wird
nichtdeterministisch entschieden, ob dieser im Vertex Cover sein soll. Nachdem dies für
alle Knoten entschieden wurde, wird überprüft, ob nicht mehr als k Knoten gewählt wur-
den und ob für jede Kante mindestens ein Endpunkt im Vertex Cover liegt.
Existiert ein Vertex Cover im Graphen, existiert auch eine Reihe von nichtdeterministi-
schen Entscheidungen, die diese Teilmenge von Knoten auswählt. Diese Teilmenge wird
dann auch von dem Algorithmus akzeptiert. Damit ist der Algorithmus korrekt.
Beide diese Schritte können naiv in Polynomialzeit erledigt werden, also löst dieser Al-
gorithmus das Vertex Cover Problem in Polynomialzeit.
Bewertung 1 Punkt für das Beispiel und 4 Punkte für den Algorithmus, dabei 2 Punkte für
die Beschreibung und jeweils 1 Punkt für Korrektheit und Laufzeit.
Hausaufgabe 9.2 (Polynomieller Verifizierer für FVS) (5 Punkte)
1. Finden Sie ein minimales Feedback Vertex Set in Abbildung 1.
2. Zeigen Sie F EEDBACK V ERTEX S ET ∈ NP, indem Sie einen polynomiellen Verifizierer
für F EEDBACK V ERTEX S ET angeben. Begründen Sie die Korrektheit und die Laufzeit
von Ihrem Verifizierer.
Lösung. 1. Ein minimales FVS ist zum Beispiel { 5, 6 }.
2. Das Zertifikat hat die Form einer Teilmenge X ⊆ V , die beschreibt, welche Knoten das
Feedback Vertex Set bilden sollen. Zum Beispiel über ein Bit pro Knoten. Nun wird
überprüft, ob |X| ≤ k gilt und ob G \ X azyklisch ist.
Hat der Graph ein Feedback Vertex Set von Größe maximal k, gibt es ein Zertifikat, wel-
ches dieses beschreibt. Dieses Zertifikat wird dann von unserem Verifizierer akzeptiert,
damit ist der Verifizierer korrekt.
Die Größe von X zu überprüfen ist naiv in Polynomialzeit möglich. Für den zweiten Test
bietet sich der Algorithmus zur topologischen Sortierung aus der Vorlesung an, welcher in
Polynomialzeit eine topologische Sortierung findet, wenn der gegebene Graph azyklisch
ist. Insgesamt ist dieser Verifizierer korrekt und auch ein polynomieller Verifizierer.
Bewertung 1 Punkt für das Beispiel und 4 Punkte für den Verifizierer, dabei 2 Punkte für die
Beschreibung und jeweils 1 Punkt für Korrektheit und Laufzeit.
Abgabe: 16.06.2025, 10:00 in Moodle bitte beachten Sie die Informationen zum Abgabefor-
mat im Moodlekurs.
Hausaufgabe 9
Marek Lenczewski
Matrikelnummer: 1025252
22. Juni 2025
Hausaufgabe 9.1
Teil 1
Ein minimales Vertex Cover ist C = {2, 7, 5, 4, 1}.
Die Minimale Knotenanzahl ist 5.
Teil 2
Der Algorithmus arbeitet wie folgt:
• Zuerst wird für jeden Knoten v ∈ V nichtdeterministisch entschieden, ob dieser in das
Vertex Cover aufgenommen wird. Dabei wird drauf geachtet, dass die Anzahl k nicht
übersteigt.
• Danach wird geprüft, ob für jede Kante {u, v} ∈ E entweder v ∈ C oder u ∈ C oder beides
zutrifft.
• Falls dies für alle Kanten gilt, akzeptieren wir. Andernfalls lehnen wir ab.
Existiert ein Vertex Cover der Größe höchstens k, dann gibt es auch eine, nichtdeterminis-
tisch ausgewählte, Knotenmenge, die dazu passt. Von dieser werden alle Kanten abgedeckt und
der Algorithmus akzeptiert. Falls es kein Vertex Cover gibt, dann lehnt der Algorithmus ab.
Die Auswahl der Knoten und die Prüfung der Kanten läuft in polynomieller Zeit, also ist dies
ein polynomieller nichtdeterministischer Algorithmus, der VERTEX COVER löst und damit ist
V ERT EXCOV ER ∈ N P .
Hausaufgabe 9.2
Teil 1
Ein minimales Feedback Vertex Set ist X = {1, 5}
Teil 2
Der Verifizierer arbeitet wie folgt:
• Es wird eine Teilmenge X ⊆ V übergeben, die das Feedback Vertex Set darstellen soll.
• Dann wird geprüft, ob |X| ≤ k gilt und es wird abgelehnt, falls es nicht gilt.
• Danach wird ein Graph G = G \ X konstruiert, in dem alle Knoten aus X und alle an X
angrenzenden Kanten entfernt wurden.
1
• Auf dem Graphen G wird eine Tiefensuche durchgeführt, dabei werden Knoten während
der Bearbeitung grau markiert und beim Backtracking schwarz.
• Wird eine Kante zu einem grauen Knoten entdeckt, dann wird abgelehnt, da dies einen
Kreis anzeigt.
• Falls die Tiefensuche den gesamten Graphen durchläuft ohne abzulehnen, dann wird ak-
zeptiert.
Existiert ein Feedback Vertex Set der Größe höchstens k, dann gibt es auch ein Zertifikat, das
genau diese Knotenmenge beschreibt. Alle Teilmengen, die die Tiefensuche überstehen, werden
von dem Verifizierer akzeptiert und sonst abgelehnt.
Die Prüfung der übergebenen Teilmenge und die Konstruktion des Graphen laufen in polyno-
mieller Zeit. Ebenfalls die Tiefensuche läuft in polynomieller Zeit, somit ist auch der Verifizierer
polynomiell und verifiziert die Lösung für das FEEDBACK VERTEX SET in polynomieller
Zeit. Also gilt F EEDBACKV ERT EXSET ∈ N P .
2
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
16.06.2025
Hausaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 10
Definition 1 (Feedback Vertex Set (FVS)). Für einen gerichteten Graphen G = (V, E) ist ein
Feedback Vertex Set eine Menge von Knoten X ⊆ V , sodass G \ X kreisfrei ist.
Für das F EEDBACK V ERTEX S ET Problem ist neben einem Graphen G eine Zahl k ∈ N≥0 gege-
ben und es wird gefragt, ob ein Feedback Vertex Set mit Größe (Anzahl der Knoten) höchstens
k in G existiert.
Hausaufgabe 10.1 (F EEDBACK V ERTEX S ET ist NP-vollständig) (5 Punkte)
Zeigen Sie, dass F EEDBACK V ERTEX S ET NP-vollständig ist.
Hinweis: Reduzieren Sie V ERTEX C OVER auf F EEDBACK V ERTEX S ET. Wenn ein Vertex Cover
aus einem Graphen entfernt wird, hat dieser keine Kanten mehr.
Lösung. F EEDBACK V ERTEX S ET ∈ NP ist bekannt aus der letzten Hausaufgabe. Nun zeigen
wir eine Reduktion von V ERTEX C OVER auf F EEDBACK V ERTEX S ET. Betrachte die folgende
Reduktion:
Für eine gegebene V ERTEX C OVER Instanz (G = (V, E), k) erzeuge den Graphen G = (V, E )
mit E := { (u, v), (v, u) | {u, v} ∈ E }. Gebe (G , k) als F EEDBACK V ERTEX S ET Instanz aus.
Korrektheit:
⇒ (Falls (G, k) eine Ja-Instanz von V ERTEX C OVER ist, dann ist (G , k) eine Ja-Instanz von
F EEDBACK V ERTEX S ET.):
Sei C ⊆ V ein Vertex Cover mit Größe kleiner oder gleich k. Dann enthält G \C keine Kanten.
Damit hat G \C ebenfalls keine Kanten und somit keine Kreise.
⇐ (Falls (G , k) eine Ja-Instanz von F EEDBACK V ERTEX S ET ist, dann ist (G, k) eine Ja-Instanz
von V ERTEX C OVER.):
Sei X ⊆ V ein Feedback Vertex Set mit Größe kleiner oder gleich k. Dann ist X ein Vertex
Cover in G, da ansonsten eine Kante {u, v} ∈ E existiert, für die u ∈
/ X ∧v ∈
/ X gilt. Damit wäre
aber (u, v, u) ein Kreis in G und X somit kein Feedback Vertex Set.
Laufzeit: Das Erzeugen der Menge E geht in Zeit O(|E|). Insgesamt ist die Reduktion dem-
nach in Laufzeit O(|E|), also in polynomieller Laufzeit, durchführbar.
Also existiert eine polynomielle Reduktion von V ERTEX C OVER auf F EEDBACK V ERTEX S ET.
Da V ERTEX C OVER nach den aktuellen Präsenzaufgaben NP-vollständig ist und
F EEDBACK V ERTEX S ET ∈ NP gilt, ist somit F EEDBACK V ERTEX S ET NP-vollständig.
Bewertung 2 Punkte für die Konstruktion, 1 Punkt für den 1. Fall, 1 Punkt für den 2. Fall,
0.5 Punkte für die Laufzeit, 0.5 Punkte für die Beweisführung im Ganzen
Hausaufgabe 10.2 (Turingmaschinen) (5 Punkte)
Entwerfen Sie eine Turingmaschine für die Sprache L = { w ∈ Σ∗ | w ist ein Palindrom } über
einem gegebenen Alphabet Σ und geben Sie die Laufzeit Ihrer Turingmaschine an. Begründen
Sie dabei, warum Ihre Turingmaschine korrekt ist und die angegebene Laufzeit hat.
Lösung. Die Turingmaschine sieht folgendermaßen aus:
(1) Falls kein Wort auf dem Band steht, akzeptiere.
(2) Falls nur ein Buchstabe auf dem Band steht, akzeptiere.
(3) Lese den ersten Buchstaben und bewege danach den Kopf zum letzten Buchstaben. Falls
die beiden Buchstaben verschieden sind, verwerfe. Ansonsten ersetze beide Buchstaben
durch ein neues Symbol x. Ersetze dafür zuerst den letzten Buchstaben und bewege dann
den Kopf zum ersten Buchstaben.
(4) Gehe zu Schritt (1).
Korrektheit: Die Turingmaschine vergleicht immer den ersten und den letzten Buchstaben.
Wenn die Buchstaben nicht gleich sind, ist das Wort kein Palindrom und es wird verworfen.
Ansonsten werden die Buchstaben rausgestrichen (siehe Schritt (3)). Diese Prozedur wird so-
lange wiederholt, bis man in der Mitte des Wortes angekommen ist und entweder nur noch ein
Buchstabe oder kein Buchstabe vorhanden ist. In beiden Fällen ist das Wort ein Palindrom und
es wird akzeptiert (siehe Schritte (1) und (2)).
Laufzeit: Die Schritte (1) bis (3) benötigen jeweils eine Laufzeit von O(n), wobei n hier die
Länge der Eingabe bezeichnet. Da in jedem Durchlauf der Schritte (1) bis (3) zwei Buchstaben
raus gestrichen werden oder das Wort akzeptiert oder verworfen wird, gibt es maximal ⌊n/2⌋
Durchläufe, bis nur noch ein oder kein Buchstabe auf dem Band stehen und somit in den Schrit-
ten (1) oder (2) akzeptiert wird. Damit ergibt sich insgesamt eine Laufzeit von O(n2 ).
Bewertung 2 Punkte für die Turingmaschine, 1 Punkt für die Korrektheit und 2 Punkte für
die Laufzeit: 1 Punkt Angabe, 1 Punkt Begründung
Abgabe: 23.06.2025, 10:00 in Moodle bitte beachten Sie die Informationen zum Abgabefor-
mat im Moodlekurs.
Hausaufgabe 10
Marek Lenczewski
Matrikelnummer: 1025252
22. Juni 2025
Hausaufgabe 10.1
Teil 1: FeedbackVertexSet ∈ NP
Zuerst brauchen wir einen polynomiellen Verifizierer, um zu zeigen dass FeedbackVertexSet
∈ NP.
Der Verifizierer bekommt einen Graphen G und eine Teilmenge X, dieser arbeitet wie folgt:
• Prüfe, ob |X| ≤ k, sonst ablehnen
• Den Graphen G = G \ X konstruieren
• Tiefensuche auf G durchführen, dabei werden Knoten vom aktuellen Pfad als grau mar-
kiert und nach vollständiger Bearbeitung als schwarz. Wird eine Kante zu einem grauen
Knoten gefunden, zeigt dies einen Kreis an und wir lehnen ab
• Akzeptieren, wenn die Tiefensuche nichts findet
Die Schritte 1-4 laufen in polynomieller Zeit, somit läuft der Verifizierer in polynomieller
Zeit. Damit ist F eedbackV ertexSet ∈ N P .
Teil 2: FeedbackVertexSet ist NP-schwer
Jetzt brauchen wir eine Reduktion von VertexCover auf FeedbackVertexSet, um zu zeigen,
dass F eedbackV ertexSet N P Schwer ist.
Konstruktion: Sei dafür ein VertexCover gegeben mit einem Graphen G und einer Zahl k.
Aus G wird ein G , wobei jede ungerichtete Kante {u, v} ∈ E durch zwei gerichteten Kanten
(u, v) und (v, u) zu E ersetzt wird. Das k wird einfach übernommen k = k .
Beweis VertexCover nach FeedbackVertexSet:
• Sei C ein VertexCover von G mit |C| ≤ k
• Da C ein VertexCover ist, wird jede Kante mit C verbunden
• Wenn C entfernt wird, dann hat G \ C keine Kanten mehr
• Dann hat auch G \ C keine Kanten und ist somit Kreisfrei
• Damit ist C ein FeedbackVertexSet für G mit |C| ≤ k
Beweis FeedbackVertexSet nach VertexCover:
1
• Sei X ein FeedbackVertexSet von G mit |X| ≤ k
• Dann ist G \ X kreisfrei
• Angenommen X wäre kein VertexCover von G, dann gäbe es eine Kante {u, v} ∈ E mit
u, v ∈
/X
• Somit wären u, v noch in G \ X vorhanden
• Die Kanten (u, v) und (v, u) würden, durch die Konstruktion, einen Kreis erzeugen
• Das ist ein Widerspruch, somit ist G \ X kreisfrei und X ist ein VertexCover
Da F eedbackV ertexSet ∈ N P und N P schwer ist, folgt dass F eedbackV ertexSet NP-
Vollständig ist. □
Hausaufgabe 10.2
Lösung. Die Turingmaschine arbeitet wie folgt:
1. Falls das Band leer ist oder nur aus Markierungen besteht, akzeptiere
2. Merke das erste unmarkierte Zeichen und ersetze es durch X
3. Laufe zum letzten unmarkierten Zeichen oder verwefe
4. Falls dieses Zeichen nicht mit dem gemerkten übereinstimmt, verwerfe
5. Ersetze es durch X und gehe zurück zum Anfang
6. Gehe zu 1
Korrektheit: Ein Wort ist genau dann ein Palindrom, wenn es sich von vorne und hin-
ten gleich liest. Dies prüft die Turingmaschine, indem sie Schrittweise die äußeren Buchstarben
verifiziert, bis nur noch einer oder keiner Vorhanden ist, dann akzeptiert ist und wenn eine Un-
stimmigkeit auftritt, dann lehnt sie ab.
Laufzeit: Die Turingmaschine hat eine Laufzeit von O(n2 ). In jedem Durchlauf macht sie
O(n) Schritte und das mit O(n) Durchläufen. □
2
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
23.06.2025
Hausaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 11
Definition 1 (Dreiecksüberdeckung eines Graphen (∆ C OVER)). Gegeben ist ein endlicher un-
gerichteter Graph G = (V, E) und eine Zahl k ∈ N. Dieser Graph hat eine Dreiecksüberdeckung,
wenn eine Menge von Knoten C∆ ⊆ V mit |C∆ | ≤ k existiert, so dass zu jedem Teilgraphen (Drei-
eck) D = (VD , ED ) ⊆ (V, E) mit |VD | = 3 und ED = { {v1 , v2 } ∈ VD ×VD | v1 ̸= v2 } von G gilt,
v ∈ C∆ für mindestens ein v ∈ VD .
Hausaufgabe 11.1 (10 Punkte)
(a) (1 Punkt) Markieren Sie im folgenden Graphen (Abbildung 1 (a)) ein V ERTEX C OVER
der Größe 5.
(b) (1 Punkt) Markieren Sie im folgenden Graphen (Abbildung 1 (b)) eine Dreiecksüberde-
ckung der Größe 5.
(c) (8 Punkte) Zeigen Sie, dass ∆ C OVER NP-vollständig ist.
(a) (b)
Abbildung 1: Beispielgraph
Lösung.
(a) (b)
Abbildung 2: Beispielgraph Lösung
(c) Wir zeigen zunächst, ∆ C OVER ∈ NP mittels eines polynomiellen Verifizierers.
Der polynomielle Verifizierer erhält als Zertifikat eine Menge von Knoten C∆ ⊆ V . Zunächst
überprüft er, ob |C∆ | ≤ k. Falls dies nicht der Fall ist, verwerfe die Instanz. Ansonsten überprüfe
für alle Teilgraphen D = (VD , ED ) ⊆ (V, E) mit |VD | = 3 und ED = { {v1 , v2 } ∈ VD ×VD | v1 ̸= v2 }
von G, ob für mindestens ein v ∈ VD auch v ∈ C∆ gilt. Falls dies gilt, akzeptiere. Ansonsten ver-
werfe.
Korrektheit: Der Verifizierer überprüft die geforderten Eigenschaften. Falls ein Graph eine Drei-
ecksüberdeckung besitzt, so existiert ein entsprechendes Zertifikat C∆ und der Verifizierer ak-
zeptiert die Instanz. Falls ein Graph keine Dreiecksüberdeckung besitzt, exisitert kein valides
entsprechendes Zertifikat C∆ und der Verifizierer verwirft die Instanz.
Laufzeit: Es gibt maximal |V |3 verschiedene Teilmengen, die ein Dreieck bilden könnten und
daher überprüft werden müssen. Die Überprüfung geht in O(|V |) Zeit. Da alle anderen Schritte
des Verifizierers in O(1) Zeit erledigt werden können, ergibt sich somit insgesamt eine Laufzeit
von O(|V |4 ), was einer polynomiellen Laufzeit entspricht.
Also gilt ∆ C OVER ∈ NP.
Nun reduzieren wir V ERTEX C OVER auf ∆ C OVER. Betrachte folgende Reduktion:
Sei I = (G = (V, E), k) eine Instanz von V ERTEX C OVER. Bilde den Graphen G = (V , E ) mit
V = V { ve | e ∈ E } und E = E { {ve , e1 }, {ve , e2 } | e = {e1 , e2 } ∈ E }. Gebe I = (G , k)
als ∆ C OVER Instanz aus.
Korrektheit:
⇒ (Falls (G, k) eine Ja-Instanz von V ERTEX C OVER ist, dann ist (G , k) eine Ja-Instanz von ∆
C OVER.):
Sei C ein Vertex Cover mit Größe kleiner oder gleich k von G. Dann ist C ebenfalls eine Drei-
ecksüberdeckung mit Größe kleiner oder gleich k. Offensichtlich gilt |C| ≤ k. Da C ein Vertex
Cover von G ist, gilt für jede Kante {u, v} ∈ E, dass u ∈ C oder v ∈ C. Für alle Teilgraphen
D = (VD , ED ) ⊆ (V, E) mit |VD | = 3 und ED = { {v1 , v2 } ∈ VD ×VD | v1 ̸= v2 } von G gilt damit
direkt, dass mindestens ein v ∈ VD auch in C enthalten ist. Der Graph G besitzt neben allen
solchen Teilgraphen in G zusätzlich solche Teilgraphen (Dreiecke), die durch die Knotenmenge
{ ve | e ∈ E } und die entsprechenden Kanten { e, {ve , e1 }, {ve , e2 } | e = {e1 , e2 } ∈ E } entste-
hen. Für diese Dreiecke gilt aber auch, dass mindestens ein Knoten, nämlich e1 oder e2 , in C
enthalten sein muss, da C ein Vertex Cover ist.
⇐ (Falls (G , k) eine Ja-Instanz von ∆ C OVER ist, dann ist (G, k) eine Ja-Instanz von V ERTEX -
C OVER.):
Sei C∆ eine Dreiecksüberdeckung von G der Größe |C∆ | ≤ k. Ohne Beschränkung der All-
gemeinheit können wir davon ausgehen, dass C∆ ⊆ V gilt: Falls für einen Knoten ve ∈ C∆ gilt,
können wir e1 zu C∆ hinzufügen und ve aus C∆ löschen. Dadurch bleibt die Überdeckungseigen-
schaft erhalten und die Menge wird höchstens kleiner. Nun gilt also C∆ ⊆ V . Die Menge C∆ ist
auch ein Vertex Cover mit Größe kleiner oder gleich k von G. Offensichtlich gilt |C∆ | ≤ k. Da für
alle Teilgraphen D = (VD , ED ) ⊆ (V , E ) mit |VD | = 3 und ED = { {v1 , v2 } ∈ VD ×VD | v1 ̸= v2 }
von G gilt, dass mindestens ein Knoten v ∈ VD ebenfalls in C∆ enthalten sein muss, gilt dies
auch für die Dreiecke {ve , e1 , e2 }. Da außerdem C∆ ⊆ V gilt, gilt e1 ∈ C∆ oder e2 ∈ C∆ für alle
Kanten e ∈ E.
Laufzeit: Das Hinzufügen von einem neuen Knoten und zwei neuen Kanten pro Kante geht in
O(|E|). Damit geht die gesamte Reduktion in O(|E|), also in polynomieller Zeit.
Also existiert eine polynomielle Reduktion von V ERTEX C OVER auf ∆ C OVER. Da V ERTEX -
C OVER NP-vollständig aus den Präsenzaufgaben bekannt ist und ∆ C OVER ∈ NP gilt, ist somit
∆ C OVER NP-vollständig.
Bewertung (a) und (b) jeweils 1 Punkt, (c) gibt 8 Punkte: 1 Punkt Angabe Verifizierer/NDTM,
0,5 Punkte Korrektheit Verifizierer/NDTM, 0,5 Punkte Laufzeit Verifizierer/NDTM, 1 Punkt
Angabe Reduktion, 3 Punkte Korrektheit (je Richtung 1,5 Punkte), 1 Punkt Laufzeit Reduktion,
1 Punkt Beweisführung
Abgabe: 30.06.2025, 10:00 in Moodle bitte beachten Sie die Informationen zum Abgabefor-
mat im Moodlekurs.
Hausaufgabe 11
Marek Lenczewski
Matrikelnummer: 1025252
28. Juni 2025
Hausaufgabe 11.1
a
1
2 3
4 5
6 10
7 9
8
b
a b c
d e
f g
h i j
k l m n
o p q
r s
t u v
c
Teil 1: ∆-Cover ∈ NP
1
Zuerst brauchen wir einen polynomiellen Verifizierer, um zu zeigen, dass ∆-Cover ∈ NP.
Der Verifizierer bekommt einen Graphen G = (V, E), Zahl k und ein Zertifikat C∆ ⊆ V und
arbeitet wie folgt:
1. Prüfe, ob |C∆ | ≤ k
2. Prüfe alle Knotentripel {a, b, c} ⊆ V , ob sie ein Dreieck bilden (also ob {a, b}, {b, c} und
{a, c} ∈ E zutrifft) und ob a, b oder c ∈ C∆
3. Ablehnen, falls ein Dreieck den test nicht besteht, sonst akzeptieren
Die Schritte 1 und 3 laufen in O(1) und Schritt zwei läuft in O(|V |3 ), das ergibt eine poly-
nomielle Laufzeit. Damit ist ∆-Cover ∈ NP.
Teil 2: ∆-Cover ist NP-schwer
Jetzt brauchen wir eine Reduktion von VertexCover auf ∆-Cover, um zu zeigen, dass
∆-Cover NP-schwer ist.
Konstruktion: Sei dafür ein VertexCover gegeben mit einem Graphen G = (V, E) und
einer Zahl k. Aus G wird G = (V , E ), wobei für jede Kante e = {u, v} ∈ E ein neuer Kno-
ten we ∈ V hinzugefügt wird und mit beiden Knoten u, v verbunden wird, sodass die Kanten
{v, we } und {u, we } zu E dazu kommen. Das k = k wird übernommen. So werden aus allen
Kanten Dreiecke.
Beweis VertexCover nach ∆-Cover
• Sei C ein VertexCover für G mit |C| ≤ k
• Zu zeigen sei, dass C auch ein ∆-Cover für G mit |C| ≤ k ist
• Da C ein VertexCover ist, gilt u ∈ C oder v ∈ C
• Jedes Dreieck in G hat die Form {u, v, we } für eine Kante e = {u, v} ∈ E
• Somit hat jedes Dreieck mindestens einen Knoten in C
• Also ist C ein ∆-Cover für G
Beweis ∆-Cover nach VertexCover
• Sei C∆ ein ∆-Cover für G mit |C∆ | ≤ k
• Jede Kante e = {u, v} ∈ E bildet durch {u, v, we } ein Dreieck in G
• Also gilt u, v oder we ∈ C∆ für alle Kanten in G
• Falls we ∈ C∆ , dann kann man we durch u oder v tauschen ohne die Eigenschaft von
∆-Cover zu verletzen, sodass u oder v ∈ C∆ für alle Kanten in G gilt
• Da sich die Knoten aus C∆ nur vertauschen gilt weiter |C| = |C∆ | ≤ k
• Weiter sind in C∆ nur noch die Knoten aus V , somit gilt u ∈ C oder v ∈ C für alle Kanten
E
• Also ist C ein VertexCover für G
Da ∆-Cover ∈ NP und NP-schwer ist, folgt dass ∆-Cover NP-vollständig ist. □
2
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
30.06.2025
Hausaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 12
Hausaufgabe 12.1 (Lower Bound: V ERTEX C OVER) (5 Punkte)
Betrachten Sie die Reduktion aus der Musterlösung zu Präsenzserie 10 von C LIQUE auf V ER -
TEX C OVER .
1. Geben Sie die Anzahl der Knoten, die Anzahl der Kanten und den Wert k für die re-
sultierende V ERTEX C OVER Instanz in Abhängigkeit von der originalen C LIQUE Instanz
an.
2. Zeigen Sie Lower Bounds für V ERTEX C OVER bezüglich Anzahl der Knoten, Anzahl
der Kanten und k basierend auf der ETH und der Reduktion aus der Musterlösung zu
Präsenzserie 10.
Lösung. 1. Sei I = (G = (V, E), k) eine Instanz von C LIQUE und I = (G = (V , E ), k ) die
aus der Reduktion resultierende Instanz von V ERTEX C OVER. Es gilt |V | = |V |, |E | =
1 2
2 |V |(|V | 1) |E| ≤ |V | und k = |V | k ≤ |V |.
2. • Angenommen es gäbe einen Algorithmus, der V ERTEX C OVER in 2o(|V |) · |I|O(1)
löst. Durch die Kombination der Reduktion von C LIQUE auf V ERTEX C OVER und
diesem Algorithmus, existiert dann auch ein 2o(|V |) ·|I|O(1) Algorithmus für C LIQUE,
da |V | = |V | nach Aufgabenteil 1. Aus der Musterlösung der Präsenzserie 12 folgt
somit, dass die ETH falsch ist.
Damit kann es so einen Algorithmus für V ERTEX C OVER nur geben, wenn die ETH
falsch ist.
• Angenommen es gäbe einen Algorithmus, der V ERTEX C OVER in 2o( |E |) · |I|O(1)
löst. Durch die Kombination der Reduktion von C LIQUE auf V ERTEX C OVER und
diesem Algorithmus, existiert dann auch ein 2o(|V |) ·|I|O(1) Algorithmus für C LIQUE,
da |E | ≤ |V |2 nach Aufgabenteil 1. Aus der Musterlösung der Präsenzserie 12 folgt
somit, dass die ETH falsch ist.
Damit kann es so einen Algorithmus für V ERTEX C OVER nur geben, wenn die ETH
falsch ist.
• Angenommen es gäbe einen Algorithmus, der V ERTEX C OVER in 2o(k ) · |I|O(1) löst.
Durch die Kombination der Reduktion von C LIQUE auf V ERTEX C OVER und die-
sem Algorithmus, existiert dann auch ein 2o(|V |) · |I|O(1) Algorithmus für C LIQUE,
da k ≤ |V | nach Aufgabenteil 1. Aus der Musterlösung der Präsenzserie 12 folgt
somit, dass die ETH falsch ist.
Damit kann es so einen Algorithmus für V ERTEX C OVER nur geben, wenn die ETH
falsch ist.
Bewertung 1 Punkt für den ersten Teil und 1.5 + 1.5 + 1 für den zweiten.
Definition 1 (H ITTING S ET). Bei diesem Problem ist ein Universum U, Teilmengen des Uni-
versums F1 , . . . , Fr ⊆ U und eine Zahl k ∈ N≥0 gegeben. Gibt es eine Menge S ⊆ U mit |U| ≤ k
und S ∩ Fi ̸= 0/ für alle i ∈ [r]?
Anschaulicher wird bei diesem Problem nach maximal k Elementen aus dem Universum ge-
fragt, sodass diese Elemente alle gegebenen Mengen Fi „treffen“.
Hausaufgabe 12.2 (Lower Bound: H ITTING S ET) (5 Punkte)
Betrachten Sie folgende Reduktion von 3-SAT auf H ITTING S ET.
Für eine gegebene 3-SAT Instanz I mit n Variablen x1 , . . . , xn und m Klauseln C1 , . . . ,Cm : Als
Universum wählen wir U = { x1 , x̄1 , . . . , xn , x̄n }. Für jede Variable xi fügen wir die Menge Fi :=
{ xi , x̄i } hinzu. Für jede Klausel C j fügen wir die Menge Fn+ j := C j hinzu. Wir setzen k := n
und erhalten damit eine H ITTING S ET Instanz I.
1. Geben Sie die Größe des Universums, die Anzahl der Mengen und die Zahl k aus der
resultierenden H ITTING S ET Instanz in Abhängigkeit von der Anzahl der Variablen n und
der Anzahl der Klauseln m aus der originalen 3-SAT Instanz an.
2. Beweisen Sie Lower Bounds für H ITTING S ET bezüglich Universumsgröße, Anzahl der
Mengen und der Zahl k basierend auf der obigen Reduktion und der ETH.
Lösung. 1. Für die Universumsgröße gilt |U| = 2n, für die Anzahl der Mengen gilt r =
n + m und es gilt k = n.
2. • Angenommen es gäbe einen Algorithmus, der H ITTING S ET in 2o(|U|) · |I|O(1) löst.
Durch die Kombination der Reduktion von 3-SAT auf H ITTING S ET und diesem
Algorithmus, existiert dann auch ein 2o(n) · |I|O(1) Algorithmus für 3-SAT, da |U| =
2n nach Aufgabenteil 1. Damit ist die ETH falsch.
Damit kann es so einen Algorithmus für H ITTING S ET nur geben, wenn die ETH
falsch ist.
• Angenommen es gäbe einen Algorithmus, der H ITTING S ET in 2o(r) · |I|O(1) löst.
Durch die Kombination der Reduktion von 3-SAT auf H ITTING S ET und diesem
Algorithmus, existiert dann auch ein 2o(m) · |I|O(1) Algorithmus für 3-SAT, da r =
n + m nach Aufgabenteil 1 und n ≤ 3m für 3-SAT gilt. Aus dem Sparsification
Lemma folgt damit, dass die ETH falsch ist.
Damit kann es so einen Algorithmus für H ITTING S ET nur geben, wenn die ETH
falsch ist.
• Angenommen es gäbe einen Algorithmus, der H ITTING S ET in 2o(k) · |I|O(1) löst.
Durch die Kombination der Reduktion von 3-SAT auf H ITTING S ET und diesem
Algorithmus, existiert dann auch ein 2o(n) · |I|O(1) Algorithmus für 3-SAT, da k = n
nach Aufgabenteil 1. Damit ist die ETH falsch.
Damit kann es so einen Algorithmus für H ITTING S ET nur geben, wenn die ETH
falsch ist.
Bewertung 1 Punkt für den ersten Teil und 1.5 + 1.5 + 1 für den zweiten.
Abgabe: 07.07.2025, 10:00 in Moodle bitte beachten Sie die Informationen zum Abgabefor-
mat im Moodlekurs.
Hausaufgabe 12
Marek Lenczewski
Matrikelnummer: 1025252
6. Juli 2025
Hausaufgabe 12.1.1
Die Knotenzahl bleibt gleich: |V | = |V | = n
Die Kantenzahl entspricht den nicht vorhandenen Kanten: |E | = |E|
k entspricht allen Knoten, die vorher nicht in der Clique waren: k = n k
Hausaufgabe 12.1.2
Wir wissen, dass 3-SAT laut ETH mindestens 2Ω(n) braucht, wobei n für die Anzahl der Varia-
blen steht.
In der Vorlesung wurde eine Reduktion von 3-SAT auf Clique gezeigt. In der Präsenzaufgabe
10.2 wurde eine Reduktion von Clique auf VertexCover gezeigt. Also gibt es eine Reduktion von
3-SAT zu VertexCover. Somit kann VertexCover nicht schneller lösbar sein als 3-SAT, weil sonst
3-SAT schneller werden würde, was nach ETH nicht geht.
So ergeben sich die folgenden Lower Bounds:
• Bezüglich Anzahl der Knoten: 2Ω(n) , wobei n = |V |. Die Knotenzahl verändert sich
nicht bei den Reduktionen.
• Bezüglich Anzahl der Kanten: 2Ω( m) , wobei m = |E |. Die Kanten können bei den
Reduktionen zu einem quadratischen Wachstum der Kanten führen.
• Bezüglich k : 2Ω(k ) . Bei der Reduktion gilt k = n k, wobei k linear von n abhängt.
1
Hausaufgabe 12.2.1
• Größe des Universums: |U | = 2n. Für jede der n Variablen gibt es zwei Elemente (xi
und xi )
• Anzahl der Mengen: n + m. n sind die Variablenmengen und m die Klauselmengen. (Fi
und Fn+j )
• Parameter: k = n. Wird in der Reduktion so übernommen.
Hausaufgabe 12.2.2
Wir wissen, dass 3-SAT laut ETH mindestens 2Ω(n) braucht, wobei n für die Anzahl der Varia-
blen steht. Somit kann HittingSet nicht schneller sein.
Es ergeben sich die folgenden Lower Bounds für HittingSet:
• Bezüglich Größe des Universums: 2Ω(|U |/2) , da für jede Variable zwei Elemente ins
Universum aufgenommen werden
• Bezüglich Anzahl der Mengen: 2Ω(n) , wobei die Anzahl der Variablen- und Klausel-
mengen (m + n) mindestens n ist
• Bezüglich Zahl k: 2Ω(k) , da in der Reduktion k = n gilt.
2
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
07.07.2025
Hausaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 13
Definition 1 (M AX -3-S AT). Bei dem Problem M AX -3-S AT ist eine Formel φ in konjunktiver
Normalform gegeben, wobei jede Klausel 3 Literale enthält. Gesucht ist eine Belegung β der
Variablen, die die Anzahl v(β ) der erfüllten Klauseln maximiert.
Hausaufgabe 13.1 (M AX -3-S AT) (10 Punkte)
Betrachten Sie folgenden Algorithmus A:
• Sei β0 die Belegung, die alle Variablen auf false setzt.
• Sei β1 die Belegung, die alle Variablen auf true setzt.
• Falls v(β0 ) ≥ v(β1 ), gib β0 zurück.
• Sonst gib β1 zurück.
(a) (6 Punkte) Zeigen Sie, dass obiger Algorithmus Güte 2 hat, d.h. v(A(φ )) ≥ 12 v(OPT (φ ))
gilt für alle Eingaben φ .
(b) (4 Punkte) Geben Sie eine Formel an, bei der der Algorithmus eine Belegung ausgibt, die
genau die Hälfte der maximal erfüllbaren Klauseln erfüllt. Begründen Sie kurz, warum
Ihre Formel geeignet ist.
Hinweis: Sie brauchen nur höchstens zwei Klauseln und vier Variablen.
Lösung. (a) Für jede Klausel C gilt, dass sie von mindestens einer der Belegungen β0 und
β1 erfüllt wird. Wir zeigen nun per Widerspruch, dass der obige Algorithmus eine Güte
von 2 hat:
Angenommen, es gilt v(A(φ )) < 12 v(OPT (φ )) für eine Formel φ . Sei m die Anzahl an
Klauseln in φ . Dann gilt v(OPT (φ )) ≤ m. Da v(A(φ )) < 12 v(OPT (φ )) ≤ 12 m, gilt v(β0 ) <
1 1
2 m und v(β1 ) < 2 m. Da jede Klausel C allerdings von mindestens einer der Belegungen
β0 und β1 erfüllt wird, gilt v(β0 ) ≥ 12 m oder v(β1 ) ≥ 12 m. Dies ist ein Widerspruch.
Also gilt v(A(φ )) ≥ 21 v(OPT (φ )) für alle Eingaben φ und obiger Algorithmus hat Güte
2.
(b) Betrachte folgende Formel: φ = (x1 x2 x3 )∧(¬x0 ¬x2 ¬x3 ) Mit β = {x0 → f alse, x1 →
true, x2 → true, x3 → true} gilt v(β ) = 2. Da φ nur zwei Klauseln hat, gilt somit v(OPT (φ )) =
2. Es gilt allerdings v(β0 ) = 1, da hier nur die zweite Klausel erfüllt ist, und v(β1 ) = 1,
da hier nur die erste Klausel erfüllt ist. Somit gilt v(A(φ )) = 1 = 12 · 2 = 21 v(OPT (φ )).
Bewertung (a) 2 Punkte korrekte Beweisführung im Allgemeinen, 2 Punkte Abschätzung
Algorithmus, 2 Punkte Abschätzung Optimum; (b) 2 Punkte für Angabe einer korrekten Formel,
1 Punkt Ausgabe Algorithmus, 1 Punkt Optimum
Abgabe: 14.07.2025, 10:00 in Moodle bitte beachten Sie die Informationen zum Abgabefor-
mat im Moodlekurs.
Hausaufgabe 13
Marek Lenczewski
Matrikelnummer: 1025252
13. Juli 2025
Hausaufgabe 13.1.a
Zu zeigen ist, dass der Algorithmus die Güte 2 hat, also die Lösung vom Algorithmus mindestens
halb so gut ist wie die optimale Lösung. Also ν(A(ϕ)) ≥ 21 ν(OP T (ϕ)) für alle Eingaben ϕ.
Sei ϕ eine beliebige 3-SAT-Formel mit m Klauseln C1 , C2 , . . . , Cm , wobei jede Klausel genau
3 Literale enthält.
Jede Klausel Ci ist wahr, wenn β0 wahr ist oder wenn β1 wahr ist oder beides. Da die Varia-
blen in Ci nur positiv oder negativ sein können, muss dabei mindestens β0 oder β1 wahr werden.
Der Algorithmus wählt die Belegung β0 oder β1 aus, die die meisten Klauseln Ci erfüllt.
Somit ist die Anzahl der ausgewählten Klauseln Ci mindestens m2 , da eine bei jeder Klausel
mindestens eine Belegung wahr werden muss und somit hat mindestens eine Belegung mindes-
tens m
2 wahre Klauseln.
Sei ν0 = Anzahl der von β0 erfüllten Klauseln und ν1 = Anzahl der von β1 erfüllten Klauseln.
So ergibt sich ν(A(ϕ)) = max{ν0 , ν1 } ≥ ν0 +ν
2
1
≥m
2.
Da die optimale Lösung höchstens alle m Klauseln erfüllen kann, gilt ν(OP T (ϕ)) ≤ m.
ν(OP T (ϕ))
Daraus folgt: ν(A(ϕ)) ≥ m
2 ≥ 2 .
Somit hat der Algorithmus eine Güte von 2.
1
Hausaufgabe 13.1.b
Der Algorithmus erfüllt genau die Hälfte der maximal erfüllbaren Klauseln, wenn jede Klausel
nur aus positiven oder negativen Variablen besteht und sich diese genau gleich aufteilen.
Formel: ϕ = (x1 x2 x3 ) ∧ (¬x1 ¬x2 ¬x3 )
Unter β0 (alle false):
• C1 = (x1 x2 x3 ) = (false false false) = false
• C2 = (¬x1 ¬x2 ¬x3 ) = (true true true) = true
ν(β0 ) = 1
Unter β1 (alle true):
• C1 = (x1 x2 x3 ) = (true true true) = true
• C2 = (¬x1 ¬x2 ¬x3 ) = (false false false) = false
ν(β1 ) = 1
Der Algorithmus wählt ν(A(ϕ)) = max{ν(β0 ), ν(β1 )} = max{1, 1} = 1.
Eine optimale Lösung wäre zum Beispiel x1 = true, x2 = false, x3 = false.
• C1 = (true false false) = true
• C2 = (false true true) = true
Daraus ergibt sich ν(OP T (ϕ)) = 2, also ν(A(ϕ)) = ν(OP2T (ϕ)) . Somit hat es die Güte 2.
2

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,863 @@
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen
19. Juli 2024
Modulprüfung zur Vorlesung
»Analyse von Algorithmen und Komplexität (Komplexitätsteil)«
SS 2024
Name: Matrikel-Nr.:
Hinweise:
• Bearbeiten Sie alle Aufgaben.
• Sie haben 10 Minuten Einlesezeit. Danach haben Sie 120 Minuten Zeit für die Klausurbearbeitung.
• Erlaubte Hilfsmittel: Ein doppelseitig handschriftlich beschriebenes Blatt Papier, (bunte) Stifte (kein
Rot, kein Grün, kein Bleistift).
• Einsichtnahme: 18.08.2024.
Note 4,0 3,7 3,3 3,0 2,7 2,3 2,0 1,7 1,3 1,0
Mindestpunkzahl 17,5 19,5 21,5 23,5 25 27 29 31 33 35
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 1 von 12
Aufgabe 1 KOMPLEXITÄT: A NWENDUNG LPT (4+2+2+2 Punkte)
Gegeben ist folgende Scheduling Instanz:
Jj J1 J2 J3 J4 J5 J6 J7
m=3
pj 5 3 7 8 1 4 2
a) Wenden Sie den LPT-Scheduling Algorithmus auf die obige Instanz an. Geben Sie dafür alle
relevanten Zwischenschritte an, sowie die Reihenfolge in der die Jobs auf Maschinen platziert
werden. Stellen Sie den resultierende Schedule graphisch dar. Eine beispielhafte Darstellung
ist:
J3
J6
J2
J5 J7
J1
J4
m1 m2 m3
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 2 von 12
b) Geben Sie die approximative Güte des Algorithmus LPT an.
c) Geben Sie eine Instanz für m = 2 Maschinen an, bei denen der Algorithmus ListScheduling
eine Güte von 2 1/m erzielt. Geben Sie zusätzlich an, welche Werte die optimale Lösung
OPT und die Lösung von LPT für diese Instanz erzielen.
d) Geben Sie eine Instanz für m = 3 Maschinen an, bei denen der Algorithmus ListScheduling
eine Güte von 2 1/m erzielt. Geben Sie zusätzlich an, welche Werte die optimale Lösung
OPT und die Lösung von LPT für diese Instanz erzielen.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 3 von 12
Aufgabe 2 KOMPLEXITÄT: B EWEIS : K -C LIQUE (10 Punkte)
Beweisen Sie folgende Aussage aus der Vorlesung:
SAT ≤ k-Clique.
Hinweis: NICHT 3-SAT, sondern allgemeines SAT!
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 4 von 12
Aufgabe 3 KOMPLEXITÄT: NP-VOLLSTÄNDIGKEIT (5+5 Punkte) a)
Wir betrachten folgendes Problem:
Problem: CliqueAndIndependetSet
Eingabe: Ein ungerichteter Graph G = (V, E) mit V = 1, . . . , |V | und eine ganze Zahl k ≥ 1.
Entscheide: Gibt es in G sowohl ein Independent Set (Menge von Knoten, die paarweise
nicht adjazent sind, d.h. zwischen denen es keine Kanten gibt) der Größe k und als auch eine
Clique der Größe k?
Zeigen Sie die NP-Schwere von CliqueAndIndependetSet durch Angabe einer Reduktion
eines nach Vorlesung/Übung bekanntermaßen NP-schweren Problems.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 5 von 12
b) Wir betrachten folgendes Problem:
Problem: (a1 = 1)-SubsetSum
Eingabe: Eine Menge von n Items, jedes Item i ∈ [n] hat eine Größe ai ∈ N>0 , wobei a1 = 1,
und ein Zielwert T .
Entscheide: Gibt es I ⊆ [n] sodass ∑i∈I ai = T ?
Zeigen Sie die NP-Schwere von (a1 = 1)-SubsetSum durch Angabe einer Reduktion eines
nach Vorlesung/Übung bekanntermaßen NP-schweren Problems.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 6 von 12
Aufgabe 4 KOMPLEXITÄT: A PPROXIMATIVE A LGORITHMEN (3+7 Punkte)
Wir betrachten folgendes Problem:
Problem: A PPROXIMATE S UBSET S UM
Eingabe: n ganze Zahlen a1 , . . . an und ein Zielwert T . Es gilt ai ≤ T ∀i ∈ [n] sowie ∑i∈[n] ai >
T.
Ziel: Wähle Zahlenmenge S ⊆ {1, . . . n} mit ∑ j∈S a j ≤ T und maximiere ∑ j∈S a j .
Betrachten Sie zu diesem Problem den folgenden Algorithmus GA.
Algorithmus GA((A,T))
1 sortiere Zahlen absteigend, sodass a1 ≥ a2 ≥ · · · ≥ an gilt;
2 integer i = 1;
3 integer sum = 0;
4 boolean tooLarge = false;
5 while i ≤ n and tooLarge = false do
6 if sum+ai ≤ T then
7 sum=sum+ai ;
8 i = i + 1;
9 else
10 tooLarge = true;
11 fi
12 od
13 return sum;
a) Geben Sie eine Konstruktionsvorschrift für eine Instanz I an, mit der der Algorithmus GA
beliebig nah an eine Güte von 2 kommt, also A(I) ≈ OPT2 (I) .
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 7 von 12
b) Zeigen Sie, dass der Algorithmus GA eine approximative Güte von 2 hat, also A(I) ≥ OPT2 (I)
gilt.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 8 von 12
Aufgabe 5 KOMPLEXITÄT: ETH (5+5 Punkte)
a) Betrachten Sie nachfolgende Reduktion von 3-SAT auf k-Color:
1. Eliminiere doppelte Klauseln und Variablen, die in keiner Klausel auftauchen
2. Elimiere Klauseln die eine Variable und ihre Negation enthalten (diese sind immer erfüllt)
3. Seien C1 , . . . ,Cm die Klauseln in der SAT Formel
4. Definiere 
V := { xi , x̄i , vi | i ∈ [n] } C j j ∈ [m] {z} ,
sowie

E := {vi , v j }, {vi , x j }, {vi , x̄ j } i ∈ [n], j ∈ [n] \ {i}
{ {xi , x̄i } | i ∈ [n] }

{xi ,C j } i ∈ [n], j ∈ [m], xi ∈ / Cj

{x̄i ,C j } i ∈ [n], j ∈ [m], x̄i ∈ / Cj
{ {vi , z} | i ∈ [n] }

{C j , z} j ∈ [m]
Welche Lower Bounds ergeben sich unter Annahme der ETH for k-Colour aus dieser Re-
duktion in Hinblick auf
(i) die Anzahl der Knoten |V |; sowie
(ii) die Anzahl der Kanten |E|?
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 9 von 12
b) Wir betrachten folgendes Scheduling Problem:
Problem: 2|prec, pi ∈ {1, 2}|Cmax
Eingabe: Eine Menge J von n Jobs, jeder Job J ∈ J hat eine Ausführungszeit pJ ∈ {1, 2}
sowie Präzedenzconstraints in Form eines gerichteten, azyklischem Graphen G = (J , A),
sowie ein ganze Zahl T ≥ 0.
Entscheide: Existiert ein Schedule, d.h. eine Abbildung, die jedem Job eine Startzeit und
eine Maschine zuweist, sodass (a) sich Jobs auf einer Maschine nicht überlappen (b) für alle
Jobs j, k ∈ J mit ( j, k) ∈ A, dass k erst startet nachdem j vollständig abgearbeitet ist und
(c) der Makespan höchstens T ist?
Wir betrachten die folgende Reduktion von k-Clique auf 2|prec, pi ∈ {1, 2}|Cmax .
Seien G = (V, E) und k gegeben. Wir setzen n = 4|V | + 3|E| und erstellen einen Knoten-Job Ji
für alle i ∈ V mit pi = 1. Des Weiteren erstellen wir Kanten-Jobs J{i, j} für jede Kante {i, j} ∈ E
mit p{i, j} = 2. Abschließend erstellen wir noch 3|V | + 2|E| Dummy Jobs. Diese Jobs haben
Ausführungszeit pdummy = 1.
Wir setzen unsere Präzedenzen nach dem folgenden Schema:
1) (Ji , J{i, j} ) für alle i ∈ V, {i, j} ∈ E
2) Präzedenzen innerhalb der Dummy Jobs.
Zuletzt setzen wir den Makespan T = 2|V | + 2|E|.
(i) Geben Sie die Lower Bounds für 2|prec, pi ∈ {1, 2}|Cmax in Hinblick auf n an, die sich
unter der ETH aus dieser Reduktion, basierend auf den Lower Bounds für k-Clique,
ergeben.
(ii) Geben Sie die Lower Bounds für 2|prec, pi ∈ {1, 2}|Cmax in Hinblick auf T an, die sich
unter der ETH aus dieser Reduktion, basierend auf den Lower Bounds für k-Clique,
ergeben.
Hinweis: Ein beispielhafter Schedule ist unten dargestellt. Die Präzedenzen sind im Graphen
durch gerichtete Kanten abgebildet, daher startet J4 erst nach dem Ende von J1 . Nutzen Sie
für diese Aufgabe die bekannten Lower Bounds aus der Präsenzübung. Diese wurden aus der
Reduktion von 3-SAT auf k-Clique hergeleitet. Hierbei ist der Clique Graph zusammenhän-
gend!
J3
J1
J3 J4
J4
J1 J2
J2
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 10 von 12
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 11 von 12
Aufgabe 6 B ONUSAUFGABE (10 Punkte)
Beweisen oder widerlegen Sie folgende Aussage:
Wenn die ETH fehlschlägt gilt P = NP.
Viel Erfolg!
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 12 von 12
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen
11. Oktober 2024
Modulprüfung zur Vorlesung
»Analyse von Algorithmen und Komplexität (Komplexitätsteil)«
SS 2024
Name: Matrikel-Nr.:
Hinweise:
• Bearbeiten Sie alle Aufgaben.
• Sie haben 10 Minuten Einlesezeit. Danach haben Sie 120 Minuten Zeit für die Klausurbearbeitung.
• Erlaubte Hilfsmittel: Ein doppelseitig handschriftlich beschriebenes Blatt Papier, (bunte) Stifte (kein
Rot, kein Grün, kein Bleistift).
• Einsichtnahme: 30.10.2024
Note 4,0 3,7 3,3 3,0 2,7 2,3 2,0 1,7 1,3 1,0
Mindestpunktzahl 17,5 19,5 21,5 23,5 25 27 29 31 33 35
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 1 von 16
Aufgabe 1 ∆T SP1 (6+2+2 Punkte)
Gegeben sei folgender Graph G = (V, E), bei dem die Kantengewichte jeweils an der nach außen
gerichteten Seite der Kante stehen:
a
4 2
3
e b
4 2
4 3
6 5
d c
2
a) Wenden Sie den Algorithmus ∆T SP1 auf den Graphen G beginnend bei a an. Geben Sie dabei
die Ergebnisse jedes Zwischenschrittes des Algorithmus an.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 2 von 16
b) Beschreiben Sie, was der Algorithmus ∆T SP1 berechnet und geben Sie die Bedingungen an,
die an den Graphen gestellt sind, damit der Algorithmus eine korrekte Lösung berechnet.
c) Begründen Sie, warum der Algorithmus ∆T SP1 eine approximative Güte von 2 besitzt.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 3 von 16
Aufgabe 2 KOMPLEXITÄT: VORLESUNGSBEWEIS SAT (10 Punkte)
Beweisen Sie folgende Aussage:
3-SAT ist NP-vollständig. Zeigen Sie dafür SAT ≤ 3-SAT, nehmen Sie also 3-SAT ∈ NP als
gegeben an.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 4 von 16
Aufgabe 3 KOMPLEXITÄT: NP-VOLLSTÄNDIGKEIT (5+5 Punkte)
a) Wir betrachten folgendes Problem:
Problem: Hitchhikers-HamiltonianCycle
Eingabe: Ein ungerichteter Graph G = (V, E) mit V = {1, . . . , |V |} und für alle v ∈ V gilt
deg(v) ≥ 42.
Entscheide: Gibt es einen Hamiltonkreis in G?
Beweisen Sie die NP-Schwere von Hitchhikers-HamiltonianCycle durch Angabe einer
Reduktion eines nach Vorlesung/Übung bekanntermaßen NP-schweren Problems.
Hinweis: Als Hilfe, geben Sie graphisch die Reduktion für Knotengrad ≥ 10 an.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 5 von 16
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 6 von 16
b) Wir betrachten folgendes Problem:
Problem: AtMostTwoPerSize-SubsetSum
Eingabe: Ein ganzzahliger Zielwert T > 0, eine Menge von n Items, jedes Item i ∈ [n]
hat eine Größe ai ∈ N>0 , jede Größe tritt höchstens zwei Mal auf, d.h. für alle i ∈ [n] gilt
| { i ∈ [n] | ai = ai } | ≤ 2.
Entscheide: Gibt es S ⊆ [n] sodass ∑i∈S ai = T ?
Beweisen Sie die NP-Schwere von AtMostTwoPerSize-SubsetSum durch Angabe einer Re-
duktion eines nach Vorlesung/Übung bekanntermaßen NP-schweren Problems.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 7 von 16
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 8 von 16
Aufgabe 4 KOMPLEXITÄT: A PPROXIMATIVE A LGORITHMEN (10+(10) Punkte)
Wir betrachten das aus der Vorlesung bekannte Makespan Scheduling Problem P||Cmax . Dazu ist
folgender Algorithmus gegeben:
Algorithmus ROUND ROBIN S CHEDULING(I=(J,m))
1 sortiere die Jobs in J so, dass p1 ≥ p2 ≥ · · · ≥ pn gilt;
2 setze B1 = · · · = Bm = 0;
/
3 integer j = 1;
4 integer i = 1;
5 while j <= n do
6 Platziere Job J j auf Maschine Mi ;
7 Bi = Bi {J j };
8 j = j + 1;
9 if i < m then
10 i=i+1
11 else
12 i=1
13 fi
14 od
15 return B1 , . . . , Bm
Betrachten Sie folgendes Beispiel zu der Funktionsweise des Round Robin Scheduling Algorith-
mus. Gegeben sind 3 Maschinen und 6 Jobs J1 , . . . J6 , die bereits richtig sortiert sind. Es gilt
p1 = 7, p2 = 5, p3 = 5, p4 = 4, p5 = 3, p6 = 1. Daraus ergibt sich folgender Schedule:
J4
J5
J6
J1
J2 J3
m1 m2 m3
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 9 von 16
a) Zeigen Sie per Widerspruch, dass der Algorithmus Round Robin Scheduling eine approxima-
tive Güte von 2 hat.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 10 von 16
b) BONUS: Geben Sie die Konstruktionsvorschrift für eine Instanz an, mit der der Algorithmus
Round Robin Scheduling beliebig nah an eine Güte von 2 kommt, also A(I) ≈ 2 · OPT (I).
Nutzen Sie dafür mindestens 3 Maschinen und 7 Jobs, womit eine Rate von A(I) = 53 OPT
zu erreichen ist. Geben sie die optimale Makespan an und die, die der Algorithmus bei Ihrer
Instanz erreicht. Für eine Güte von 53 können bis zu 3 Punkten erreicht werden, bei einer
Güte von 47 sind bis zu 5 Punkte zu erreichen. Geben Sie eine Konstruktionsvorschrift an,
bei denen bei einer beliebigen, festen Anzahl von Maschinen m eine Güte von 2 m1 erreicht
wird, können Sie die vollen 10 Punkte erreichen.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 11 von 16
Aufgabe 5 KOMPLEXITÄT: ETH (5+5 Punkte)
a) Wir betrachten folgendes Problem:
Problem: DominatingSet
Eingabe: Ein ungerichteter Graph G = (V, E) mit V = 1, . . . , |V | und eine Ganzzahl k ≥ 1.
Entscheide: Gibt es eine Menge M ⊆ V der Kardinalität |M| = k derart, dass jeder Knoten
v ∈ V entweder in M ist oder zu einem Knoten in M benachbart ist.
Wir untersuchen nun folgende Reduktion von 3-SAT auf DominatingSet:
1. Seien C1 , . . . ,Cm die Klauseln der 3-SAT-Formel
2. Seien x1 , . . . , xn die Variablen der 3-SAT-Formel
3. Erzeuge die Knoten xi , xi und di für jede Variable xi
4. Erzeuge die Kanten {xi , xi }, {xi , di } und {di xi } für jede Variable xi
5. Für jede Klausel C j erzeuge einen Knoten C j
6. Für jedes Literal einer Klausel C j erzeuge die Kanten {C j , }
Welche unteren Schranken für die Laufzeit folgen damit für DominatingSet unter der ETH
in Bezug auf
(i) die Anzahl der Knoten |V |?
(ii) die Anzahl der Kanten |E|?
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 12 von 16
b) Wir betrachten folgendes Problem:
Problem: GridTiling
Eingabe: Zwei ganze Zahlen k und j und für jedes i ∈ [k] und j ∈ [k] eine Menge Si, j ⊆ [n]2 .
Entscheide: Gibt es (ei, j )(i, j)∈[k]2 derart, dass
1. für alle (i, j) ∈ [k]2 gilt ei, j ∈ Si, j ;
2. für alle i ∈ [k] und j ∈ [k 1] gilt für ei, j = (a, b) und ei, j+1 = (a , b ), dass a = a (dh. die
ausgewählten Tupel müssen in der ersten Komponente übereinstimmen, wenn der erste
Index derselbe ist); und
3. für alle i ∈ [k 1] und j ∈ [k] gilt für ei, j = (a, b) und ei+1, j = (a , b ), dass b = b (dh.
die ausgewählten Tupel müssen in der zweiten Komponente übereinstimmen, wenn der
zweite Index derselbe ist)
Betrachten Sie folgende Beispielinstanz für k = 2, die Elemente der Lösung sind unterstrichen:
S1,1 = {(1, 1), (2, 2)} S1,2 = {(1, 2), (2, 1), (2, 2)}
S2,1 = {(1, 2), (2, 1)} S2,2 = {(1, 1), (2, 2)}
Wir untersuchen folgende Reduktion von Clique:
1. Sei G = (V, E) und eine Zahl k als zu untersuchende Clique Instanz gegeben
2. Wir nehmen ohne Beschränkung der Allgemeinheit an, dass V = {1, . . . , |V |} sowie k ≥ 2
gilt und dass keine isolierten Knoten existieren.
3. Wir übernehmen den Wert von k
4. Für jedes Paar (i, j) ∈ [k]2 definieren wir
(
{ (a, a) | a ∈ V } if i = j
Si, j :=
{ (a, b) | a ̸= b, {a, b} ∈ E } if i ̸= j
Welche unteren Schranken für die Laufzeit folgen damit für Grid Tiling (mit der aus der
Vorlesung bekannten Reduktion von Clique auf 3-SAT) in Hinblick auf
(i) der Gesamtanzahl X := ∑(i, j)∈[k]2 |Si, j | der Tupel in den Mengen; sowie
(ii) der maximalen Anzahl Y := max(i, j)∈[k]2 |Si, j | an Tupeln in einer der Mengen?
Hinweis: Aus der Reduktion in der Vorlesung wissen wir, dass Clique selbst dann noch NP-
schwer ist, wenn k ∈ Θ(|V |) gilt. Sie dürfen also annehmen, dass es eine (globale) Konstante
c > 0 gibt, sodass c · n ≤ k ≤ n.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 13 von 16
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 14 von 16
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 15 von 16
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 16 von 16
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen
14. Juli 2023
Modulprüfung zur Vorlesung
»Analyse von Algorithmen und Komplexität (Komplexitätsteil)«
SS 2023
Name: Matrikel-Nr.:
Hinweise:
• Bearbeiten Sie alle Aufgaben.
• Sie haben 10 Minuten Einlesezeit. Danach haben Sie 120 Minuten Zeit für die Klausurbearbeitung.
• Erlaubte Hilfsmittel: Ein doppelseitig handschriftlich beschriebenes Blatt Papier, (bunte) Stifte (kein
Rot, kein Grün, kein Bleistift).
• Einsichtnahme: Nach Absprache.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 1 von 11
Aufgabe 1 RUCKSACKPROBLEM (3+2+5 Punkte)
Wir betrachten die Anwendung der Approximationsheuristiken für das Rucksackproblem aus der
Vorlesung.
Gegeben sei dafür folgende Instanz des Rucksackproblems mit Kapazität B = 16. Items sind in
der Form (pi , wi ) angegeben.
I = [(1, 4), (1, 1), (1, 3), (11, 13), (3, 3), (5, 6), (1, 5), 16]
a) Wenden Sie den normalen Greedy-Algorithmus auf obige Instanz an. Begründen Sie kurz,
warum die gewählten Items ausgewählt werden. Was ist der Lösungswert?
b) Wenden Sie nun den ModifiedGreedy-Algorithmus an. Wie ändert sich die Lösung?
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 2 von 11
c) Was ist die Güte des ModifiedGreedy-Algorithmus? Geben Sie eine kurze Idee an, wie man
diesen Ansatz modifizieren kann, um die Güte auf 32 oder 43 zu verbessern.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 3 von 11
Aufgabe 2 L ONGEST PATH (3+3+4 Punkte)
Betrachten Sie das folgende Problem:
Problem: L ONGEST PATH
Eingabe: Eine ungerichteter Graph G = (V, E) und eine Zahl k.
Entscheide: Gibt es einen Pfad in G, der mindestens Länge k hat?
Zeigen Sie auf verschiedene Weisen, dass das Problem in NP liegt:
a) Geben Sie ein Zertifikat für L ONGEST PATH an.
b) Beschreiben Sie einen Verifizierer für L ONGEST PATH und geben Sie dessen Laufzeit konkret
an.
c) Beschreiben Sie eine nicht-deterministische Turing-Maschine (in Worten), die L ONGEST PATH
löst. Geben Sie auch hier die Laufzeit konkret an.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 4 von 11
Aufgabe 3 A PPROXIMATIVE A LGORITHMEN (6+4 Punkte)
Das Problem M AX -3-S AT sei folgendermaßen definiert:
Problem: M AX -3-S AT
Eingabe: Eine Formel φ in konjunktiver Normalform, wobei jede Klausel drei Literale enthält.
Ausgabe: Eine Belegung β der Variablen, die die Anzahl v(β ) der erfüllten Klauseln maximiert.
Betrachten Sie folgenden Algorithmus A:
• Sei β0 die Belegung, die alle Variablen auf false setzt.
• Sei β1 die Belegung, die alle Variablen auf true setzt.
• Falls v(β0 ) ≥ v(β1 ), gib β0 zurück.
• Sonst gib β1 zurück.
a) Zeigen Sie, dass obiger Algorithmus Güte 2 hat, d.h. A(φ ) ≥ 12 OPT (φ ) gilt für alle Eingaben
φ.
b) Geben Sie eine Formel an, bei der der Algorithmus eine Belegung ausgibt, die genau die Hälfte
der maximal erfüllbaren Klauseln erfüllt. Begründen Sie kurz, warum Ihre Formel geeignet ist.
Hinweis: Sie brauchen nur höchstens zwei Klauseln und sechs Variablen.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 5 von 11
Aufgabe 4 B EWEIS ZUR VORLESUNG (10 Punkte)
Betrachten Sie folgendes Problem aus der Vorlesung:
Problem: k-C LIQUE
Eingabe: Ein ungerichteter Graph G = (V, E) und eine Zahl k ≥ 1. Eine Clique ist eine Teil-
menge C ⊆ V mit {u, v} ∈ E für alle u, v ∈ C mit u ̸= v.
Entscheide: Hat der gegebene Graph G eine Clique C ⊆ V mit mindestens k Knoten (d.h. mit
|C| ≥ k)?
Beweisen Sie: Das Problem k-C LIQUE ist NP-vollständig.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 6 von 11
Aufgabe 5 NP UND NP-VOLLSTÄNDIGKEIT (4+4+7 Punkte)
a) Beweisen Sie die NP-Vollständigkeit von S UBSET S UM, bei der jede Itemgröße jeweils durch
3 oder durch 7 teilbar ist.
b) Beweisen Sie die NP-Vollständigkeit von 3-C OLOR, wobei jeder Knoten im Graph mindes-
tens Grad 3 hat.
c) Zeigen Sie: Für kein α > 1 gibt es einen approximativen Algorithmus mit Güte α (d.h. mit
Zielfunktionswert ≤ α · OPT) für TSP, außer P = NP (Denken Sie an Wiliam Rowan Hamil-
ton).
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 7 von 11
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 8 von 11
Aufgabe 6 U NTERE S CHRANKEN UND ETH (7+8 Punkte)
Betrachten Sie folgende Reduktionen:
Problem: H ITTING S ET
Eingabe: Eine Menge U sowie r Teilmengen F1 , . . . , Fr ⊆ U und eine Zahl k.
Entscheide: Gibt es eine Menge S ⊆ U mit |S| ≤ k und S ∩ Fi ̸= 0/ für alle i ∈ [r]?
a) 3-SAT ⪯ H ITTING S ET: Seien v1 , . . . , vn die Variablen der Formel und C1 , . . . ,Cm die Klau-
seln. Setze U = { v1 , v1 , . . . , vn , vn } und k = n. Für jede Variable vi definiere eine Menge
Fi = {vi , vi } und für jede Klausel C j definiere eine Menge Fn+ j = C j
Welche unteren Schranken ergeben sich durch obige Reduktion für die Laufzeit von Algorith-
men für H ITTING S ET unter Annahme der ETH in Abhängigkeit von
(i) r?
(ii) |U|?
Beweisen Sie die entsprechenden unteren Schranken!
Hinweis: Sie dürfen wie in den Hausaufgaben zur ETH Faktoren, die polynomiell in der
Eingabekodierung sind, vernachlässigen.
b) 3-S AT ⪯ S UBSET S UM: Seien v1 , . . . , vn die Variablen der Formel und C1 , . . . ,Cm die Klauseln.
Für jede Variable vi erzeuge zwei Items ai und bi , mit den Größen
s(ai ) = 10i1 + ∑ 10n+ j1 und s(bi ) = 10i1 + ∑ 10n+ j1 .
j∈[m] j∈[m]
xi ∈C j xi ∈C j
Zusätzlich erzeuge zwei Items c j und d j für jede Klausel C j mit Größen
s(c j ) = s(d j ) = 10n+ j1 .
Der Zielwert sei
B = ∑ 3 · 10n+ j1 + ∑ 10i1 .

j∈[m] i∈[n]
Welche unteren Schranken ergeben sich durch obige Reduktion für die Laufzeit von Algorith-
men für S UBSET S UM unter Annahme der ETH in Abhängigkeit von
(i) der Anzahl der unterschiedlichen Itemgrößen d?
(ii) der binären Kodierungslänge L der größten Itemgröße ∆ (d.h. L = log(∆))?
Beweisen Sie die entsprechenden unteren Schranken!
Hinweis: Sie dürfen auch hier wie in den Hausaufgaben zur ETH Faktoren, die polynomiell
in der Eingabekodierung sind, vernachlässigen.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 9 von 11
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 10 von 11
Viel Erfolg!
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 11 von 11
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen
19. Oktober 2023
Modulprüfung zur Vorlesung
»Analyse von Algorithmen und Komplexität (Komplexitätsteil)«
SS 2023
Name: Matrikel-Nr.:
Hinweise:
• Bearbeiten Sie alle Aufgaben.
• Sie haben 120 Minuten Zeit für die Klausurbearbeitung.
• Erlaubte Hilfsmittel: Ein einseitig handschriftlich beschriebenes Blatt Papier, (bunte) Stifte (kein Rot,
kein Grün, kein Bleistift, kein Tintenkiller, kein Tipp-Ex).
• Schreiben Sie auf jedes Blatt ihren Namen.
• Wenn Sie Schmierzettel verwenden um eine Aufgabe zu bearbeiten, verweisen Sie in der Aufgabe auf
diese.
• Einsichtnahme: 2.11.23, 13:30-14:30 Uhr.
• Die Klausur hat 6 Aufgaben auf 13 Seiten überprüfen Sie bitte vor der Bearbeitung, dass Ihre Klausur
vollständig ist.
Aufgabe 1 C HRISTOFIDES A LGORITHMUS (3+7 Punkte)
Gegeben sei folgender Graph G = (V, E) :
d
2
3
3
a c
1
2
b
a) Geben Sie an, was Christofides Algorithmus berechnet, und welche approximative Güte er
hat. Welche Eigenschaft müssen die Distanzen neben der Symmetrie noch erfüllen, damit
Christofides Algorithmus korrekt arbeitet.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 1 von 19
b) Wenden Sie den Algorithmus von Christofides auf den Graphen G mit Startknoten a an. Ge-
ben Sie dabei alle Graphen an, die in Zwischenschritten entstehen. Erwähnen Sie ebenfalls
Schritte, die bei dieser Anwendung zu keiner Änderung führen, die der Algorithmus aber
überprüfen muss.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 2 von 19
Aufgabe 2 D OMINATING S ET (3+3+4 Punkte)
Betrachten Sie das folgende Problem:
Problem: D OMINATING S ET
Eingabe: Ein ungerichteter Graph G = (V, E) (wobei V = {1, . . . , n} für eine Zahl n ∈ N≥1 )
und eine Zahl k ∈ N0 .
Entscheide: Gibt es eine Teilmenge D ⊆ V der Knoten mit |D| ≤ k, sodass jeder Knoten v ∈ V
in D enthalten ist oder benachbart zu mindestens einem der Knoten in D ist?
Zeigen Sie auf verschiedene Weisen, dass das Problem in NP liegt:
a) Geben Sie ein Zertifikat für D OMINATING S ET an.
b) Beschreiben Sie einen polynomiellen Verifizierer für D OMINATING S ET und schätzen Sie die
Laufzeit in O-Notation konkret ab.
c) Beschreiben Sie (in Worten) eine polynomielle, nicht-deterministische Turing-Maschine, die
D OMINATING S ET löst. Schätzen Sie auch hier die Laufzeit in O-Notation konkret ab.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 3 von 19
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 4 von 19
Aufgabe 3 A PPROXIMATIVE A LGORITHMEN (6+4 Punkte)
Das Problem M IN -E DGE -C OVER sei folgendermaßen definiert:
Problem: M IN -E DGE -C OVER
Eingabe: Ein zusammenhängender, ungerichteter Graph G = (V, E).
Ausgabe: Eine Teilmenge der Kanten C ⊆ E mit minimaler Kardinalität, sodass jeder Knoten
v ∈ V zu mindestens einer Kante aus C inzident ist.
Betrachten Sie folgenden Algorithmus A:
• Gehe (in beliebiger Reihenfolge) alle Knoten durch:
• Falls der aktuelle Knoten v noch nicht abgedeckt ist, wähle zufällig eine der zu v inzidenten
Kanten und füge sie zu C hinzu.
• Gib anschließend die entstehende Menge C zurück.
a) Zeigen Sie, dass obiger Algorithmus Güte 2 hat, d.h. A(G) ≤ 2 · OPT(G) gilt für alle Eingaben
G.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 5 von 19
b) Sei n ∈ N≥4 gerade. Betrachten Sie den Graphen Gn , der genau n Knoten und n Kanten hat und
einen Kreis beschreibt. D.h. Gn = ({1, . . . , n}, {{i, i+1} | i ∈ {1, . . . , n1}}{{n, 1}}). Wie viele
Kanten hat ein M IN -E DGE -C OVER des Graphen Gn ? Wie schlecht ist die Approximationsrate
des Algorithmus A für Gn im schlimmsten Fall? Geben Sie eine Reihenfolge der Knoten (für
Schritt 1) und eine Auswahl der Kanten (für Schritt 2) an, die zu einer möglichst schlechten
Approximationsrate führen.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 6 von 19
Aufgabe 4 B EWEIS S CHEDULING AUF IDENTISCHEN M ASCHINEN (10 Punkte)
Betrachten Sie das Scheduling-Problem P||Cmax :
Problem: P||Cmax
Eingabe: Eine Liste L = (J1 , . . . , Jn ) von n Jobs mit Ausführungszeiten p1 , . . . , pn ∈ N, und m
identische Maschinen.
Ausgabe: Ein Schedule (Partition von J in m Teilmengen B1 , . . . , Bm ) mit minimaler maximaler
Last Cmax := max ∑ p j .
1≤i≤m J ∈B
j i
Betrachten Sie den folgenden Algorithmus ListScheduling, der einen Schedule berechnet. Sei
LS(I) die Last Cmax eines Schedules des Algorithmus, und OPT(I) die Last Cmax eines optimalen
Schedules zur Eingabe I. Zeigen Sie: Für alle Eingaben I = (L, m) gilt LS(I)/OPT(I) ≤ 2 1/m.
Algorithmus L IST S CHEDULING(L = (J1 , . . . , Jn ), m)
1 for i = 1 to m do
2 Ei = 0; Bi = 0/ ;
3 od
4 for j = 1 to n do
5 wähle Job J j aus Liste L;
6 wähle Maschine Mi mit minimaler Last Ei ;
7 Bi = Bi {J j };
8 Ei = Ei + p j ;
9 od
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 7 von 19
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 8 von 19
Aufgabe 5 NP UND NP-VOLLSTÄNDIGKEIT (4+5+6 Punkte)
Problem: H AMILTONIAN PATH
Eingabe: Ein ungerichteter Graph G = (V, E)
Entscheide: Existiert ein Pfad in G, der jeden Knoten genau einmal besucht?
Problem: H AMILTONIAN C YCLE
Eingabe: Ein ungerichteter Graph G = (V, E)
Entscheide: Existiert ein Kreis in G, der jeden Knoten genau einmal besucht?
(a) Sei L ⊆ S UBSET S UM die Menge der (positiven) SubsetSum-Instanzen, bei denen keine der
Itemgrößen eine Zweierpotenz ist. Zeigen Sie, dass L NP-vollständig ist.
(b) Geben Sie eine polynomielle Reduktion von H AMILTONIAN PATH auf H AMILTONIAN C Y-
CLE an.
(c) Geben Sie eine polynomielle Reduktion von H AMILTONIAN C YCLE auf H AMILTONIAN -
PATH an.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 9 von 19
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 10 von 19
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 11 von 19
Aufgabe 6 U NTERE S CHRANKEN UND ETH (5+5 Punkte)
Im Folgenden bezeichne ⟨I⟩ die Kodierungslänge der Instanz.
(a) Wir betrachten folgendes Problem:
Problem: H ITTING S ET
Eingabe: Eine Menge U sowie r Teilmengen F1 , . . . , Fr ⊆ U und eine Zahl k .
Entscheide: Gibt es eine Menge S ⊆ U mit |S | ≤ k und S ∩ Fi ̸= 0/ für alle i ∈ {1, . . . , r }?
Sie dürfen nutzen, dass sich H ITTING S ET unter Annahme der ETH nicht in Zeit 2o(r ) ⟨I⟩O(1)
und nicht in Zeit 2o(|U |) ⟨I⟩O(1) lösen lässt.
Problem: S ET C OVER
Eingabe: Eine Menge U sowie r Teilmengen F1 , . . . , Fr ⊆ U und eine Zahl k.
Entscheide: Gibt es eine Menge S ⊆ {1, . . . , r} mit |S| ≤ k und i∈S Fi = U?
S
Welche unteren Schranken ergeben sich
(i) in Hinblick auf |U| sowie
(ii) in Hinblick auf r
für S ET C OVER unter Annahme der ETH aus den unteren Schranken für H ITTING S ET, wenn
man folgende Reduktion von SetCover auf HittingSet verwendet?
Sei (F ,U, k) eine S ET C OVER-Instanz. Setze V1 := U und V2 := {1, . . . , r}. Sei V := V1 V˙ 2.
Weiter sei E = { {v, w} | v ∈ V1 , w ∈ V2 , v ∈ Fw }. Damit ist G = (V, E) ein bipartiter Graph
mit Partitionen V1 ,V2 . Setze U := {1, . . . , r}. Erzeuge nun eine Menge Fw für jeden Knoten
w ∈ V1 , indem Fw := { v ∈ V2 | {v, w} ∈ E } gesetzt wird. Sei F := { Fw | w ∈ V1 }. Mit k = k
iie berechnete Instanz ist nun durch (F ,U , k ) gegeben.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 12 von 19
(b) Wir wollen uns mit einem Problem beschäftigen, das ein mächtiges Werkzeug im Bereich
der Optimierung ist: Integrale Lineare Programme (ILPs).
Problem: ILP-F EASIBILITY
Eingabe: Eine Matrix A ∈ ZM×N , eine rechte Seite b ∈ ZM .
Entscheide: Gibt es einen Vektor x ∈ ZN≥0 mit Ax ≤ b, d.h. Ai xi ≤ bi für alle i ∈ {1, . . . , M}?
Welche unteren Schranken ergeben sich
(i) in Hinblick auf M sowie
(ii) im Hinblick auf N
für ILP-F EASIBILITY unter Annahme der ETH, wenn man folgende Reduktion von 3-SAT
auf ILP-F EASIBILITY verwendet?
Sei φ eine 3-SAT Instanz mit m Klauseln (Ci )i∈m und n Variablen. Analog zu linearen Glei-
chungssystemen (Ax = b), die aus M Gleichungen bestehen, haben wir bei Ax ≤ b einen
Satz von M linearen Ungleichungen. Wir konstruieren diese wie folgt: Wir nutzen N := 2n
Variablen in unserem ILP, eine für jedes (mögliche) Literal in der SAT-Formel. Für je-
de SAT-Variable v sei xv die ILP-Variable, die zum SAT-Literal v korrespondiert, und xv̄
die, die zum SAT-Literal v̄ korrespondiert. Für jede Klausel Ci erzeugen wir eine Unglei-
chung ∈Ci x1. Weiter erzeugen wir für jede SAT-Variable v zwei Ungleichungen:
xv +xv̄ ≤ 1 und xv xv̄ ≤ 1. Durch das Eintragen der entsprechenden Koeffizienten in eine
erweiterte Koeffizientenmatrix (bestehend aus Matrix A und rechter Seite b) erhalten wir die
ILP-F EASIBILITY Instanz.
Viel Erfolg!
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 13 von 19

Binary file not shown.

View File

@@ -0,0 +1,480 @@
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
09.06.2025
Präsenzaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 9
Definition 1 (Knapsack (Entscheidungsvariante)). Gegeben ist eine Menge mit n Gegenständen
mit Gewichten w1 , . . . , wn ∈ N≥0 und Profiten p1 , . . . , pn ∈ N≥0 . Weiter sind eine Kapazität
K ∈ N≥0 und ein Zielprofit P ∈ N≥0 gegeben. Bei dem K NAPSACK Problem muss entschieden
werden, ob eine Teilmenge S ⊆ [n] existiert, sodass
∑ wi ≤ K und ∑ pi ≥ P
i∈S i∈S
gilt.
Präsenzaufgabe 9.1 (K NAPSACK in NP)
Zeigen Sie K NAPSACK ∈ NP auf zwei verschiedene Wege.
1. Geben Sie einen nicht deterministischen Algorithmus an, der das Problem in polynomi-
eller Zeit löst.
2. Geben Sie einen polynomiellen Verifizierer für das Problem an.
Wie hängen diese beiden Methoden zusammen?
Lösung. 1. Der Algorithmus arbeitet wie folgt: Für jeden Gegenstand entscheiden wir nicht-
deterministisch, ob er in den Rucksack soll. Anschließend akzeptieren wir, falls die Kapazitäts-
und Profitbedingung erfüllt sind.
Existiert eine valide Rucksackfüllung mit genügend Profit, dann gibt es auch eine Reihe
von nichtdeterministischen Entscheidungen, die diese Füllung findet. Diese wird dann
auch vom Algorithmus akzeptiert.
Der Algorithmus macht polynomiell viele nichtdeterministische Entscheidungen und die
Überprüfung der Eigenschaften ist ebenfalls in Polynomialzeit möglich, also ist dies ein
polynomieller, nichtdeterministischer Algorithmus, der K NAPSACK löst.
2. Unser Zertifikat ist eine Teilmenge S ⊆ [n], die die Auswahl für den Rucksack darstellen
soll. Dies kann zum Beispiel über ein Bit pro Gegenstand realisiert werden. Um dieses
Zertifikat zu verifizieren, berechnen wir ∑i∈S wi und ∑i∈S pi und vergleichen die Werte
mit K und P und akzeptieren entsprechend.
Existiert eine valide Rucksackfüllung mit genügend Profit, dann gibt es auch ein Zertifi-
kat, das diese Füllung beschreibt. Dieses wird dann auch vom Verifizierer akzeptiert.
Das Ausrechnen der Summen und das Überprüfen ist in polynomieller Zeit möglich, also
ist dies ein polynomieller Verifizierer.
In beiden Wegen wird die extra Ressource, die wir zur Verfügung haben, genutzt, um eine
Teilmenge (einen möglichen Rucksack) zu bestimmen und zu überprüfen. In der Vorlesung
wird noch genau gezeigt, dass diese beiden Wege tatsächlich äquivalent sind.
Präsenzaufgabe 9.2 (Transitivität von Polynomialzeitreduktionen)
Zeigen Sie, dass Polynomialzeitreduktionen transitiv sind, d.h., dass für alle Entscheidungspro-
bleme L1 , L2 , L3 ⊆ Σ∗ gilt, dass
L1 ⪯ L2 ∧ L2 ⪯ L3 =⇒ L1 ⪯ L3 .
Lösung. Seien L1 , L2 , L3 Sprachen. Zudem sei R1 ein Algorithmus, der L1 nach L2 in O(na )
reduziert, und R2 ein Algorithmus, der L2 nach L3 in O(nb ) reduziert.
Sei x eine Instanz von L1 der Größe n. Dann benötigt der Aufruf von R1 auf x höchstens O(na )
Zeit.
Sei x die Ausgabe von R1 . Dann hat x eine Größe von höchstens O(na ). Diese Schranke für
die Ausgabe ergibt sich aus der Laufzeit der Reduktion. Der Aufruf von R2 auf x benötigt nun
höchstens O((na )b ) = O(nab ) Zeit. Damit ist die Reduktion von L1 auf L3 in polynomieller Zeit
möglich.
Die Korrektheit ergibt sich aus der Transitivität der Äquivalenz: Sei x die Ausgabe von R2 auf
x , dann gilt
x ∈ L1 ⇐⇒ x ∈ L2 und x ∈ L2 ⇐⇒ x ∈ L3 ,
also auch x ∈ L1 ⇐⇒ x ∈ L3 .
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
16.06.2025
Präsenzaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 10
Präsenzaufgabe 10.1 (Fragen über Fragen)
Diskutieren Sie die folgenden Aussagen (Gelten sie allgemein? Gelten sie nicht? Gelten sie
unter bestimmten Bedingungen? Welche?):
(i) Für jede Sprache, die von einer NDTM in polynomieller Zeit akzeptiert werden kann,
existiert eine DTM, die ebenfalls die Sprache in polynomieller Zeit akzeptiert.
(ii) A ist NP-schwer =⇒ A ∈ P
Lösung. (i) Die Aussage gilt nur, wenn P = NP. Dann liegen alle Probleme in NP (von
NDTM in polynomieller Zeit lösbar) auch in P (von DTM in polynomieller Zeit lösbar).
Falls P ̸= NP, dann nein, weil sonst folgender Widerspruch auftritt: ein Problem in NP \ P
ist von einer NDTM, nicht aber von einer DTM in polynomieller Zeit lösbar. Könnte eine
DTM die NDTM in polynomieller Zeit simulieren, wäre das Problem auch in P.
(ii) Falsch. Es gibt NP-schwere Probleme, die nicht in NP liegen, z.B. das H ALTE-Problem.
Diese liegen folglich auch definitiv nicht in P. NP-schwer ist eine untere Schranke, ∈ NP
eine obere, und wenn beide erfüllt sind, ist ein Problem NP-vollständig.
Definition 1 (Vertex Cover (VC)). Für einen (ungerichteten) Graphen G = (V, E) ist ein Vertex
Cover eine Menge von Knoten C ⊆ V , sodass u ∈ C oder v ∈ C für alle { u, v } ∈ E gilt, also ist
für alle Kanten mindestens ein Endpunkt in C.
Für das V ERTEX C OVER Problem ist neben einem Graphen G eine Zahl k ∈ N≥0 gegeben und
es wird gefragt, ob ein Vertex Cover mit Größe (Anzahl der Knoten) höchstens k in G existiert.
Präsenzaufgabe 10.2 (V ERTEX C OVER ist NP-vollständig)
Zeigen Sie, dass V ERTEX C OVER NP-vollständig ist.
Hinweis: Reduzieren Sie C LIQUE auf V ERTEX C OVER.
Lösung. V ERTEX C OVER ∈ NP ist bekannt aus der letzten Hausaufgabe.
Vorüberlegung zur Reduktion von C LIQUE auf V ERTEX C OVER: Sei eine Instanz mit G =
(V, E) und k ∈ N≥0 von C LIQUE gegeben. Wir invertieren zunächst den Graphen G und erhal-
ten damit G . Nun enthält G genau dann eine unabhängige Menge der Größe , wenn G eine
Clique der Größe enthält. Wenn ein Graph mit n Knoten eine unabhängige Menge mit min-
destens k Knoten hat, dann hat der Graph auch ein Vertex Cover mit maximal n k Knoten
(das Komplement zur unabhängigen Menge). Unsere Instanz für V ERTEX C OVER ist also G
und n k. (k ≤ n können wir annehmen)
Betrachte nun folgende Reduktion:
Sei eine Instanz mit G = (V, E) und k ∈ N≥0 von C LIQUE gegeben. Invertiere den Graphen G
und erhalte damit G . Gebe nun G und n k als Instanz von V ERTEX C OVER zurück.
Korrektheit:
⇒ (Falls (G, k) eine Ja-Instanz von C LIQUE ist, dann ist (G , n k) eine Ja-Instanz von V ER -
TEX C OVER .):
G enthalte eine Clique C der Größe ≥ k. Dann ist V := V \C ein Vertex Cover von G der Größe
≤ n k. Da |C| ≥ k, gilt |V | ≤ n k. Da C eine Clique ist, also alle Knoten aus C mit allen
anderen Knoten aus C verbunden sind, gibt es im invertierten Graphen G keine Kante zwischen
Knoten aus C. Also gilt für jede Kante {u, v} ∈ E , dass u ∈ / C und somit u ∈ V oder
/ C oder v ∈
v ∈ V .
⇐ (Falls (G , n k) eine Ja-Instanz von V ERTEX C OVER ist, dann ist (G, k) eine Ja-Instanz von
C LIQUE.):
G enthalte ein Vertex Cover V der Größe ≤ nk. Dann ist C := V \V eine Clique der Größe ≥
k in G. Da |V | ≤ n k, gilt |C| ≥ k. Für jede Menge {u, v} ⊆ C gilt, dass {u, v} ∈
/ E . Ansonsten
wäre V kein korrektes Vertex Cover. Da G der invertierte Graph von G ist, gilt somit {u, v} ∈ E
für jede Menge {u, v} ⊆ C.
Laufzeit: Das Invertieren des Graphen kann naiv in O(|V |2 · |E|) Zeit, also in polynomieller
Zeit, erledigt werden.
Also existiert eine polynomielle Reduktion von C LIQUE auf V ERTEX C OVER. Da C LIQUE
NP-vollständig ist und V ERTEX C OVER ∈ NP gilt, ist somit V ERTEX C OVER NP-vollständig.
Präsenzaufgabe 10.3 (Turingmaschinen)
n
Entwerfen Sie eine Turingmaschine für die Sprache L = { 02 | n ∈ N } über dem Alphabet
Σ = {0} und geben Sie die Laufzeit Ihrer Turingmaschine an. Begründen Sie die Korrektheit
und die Laufzeit Ihrer Turingmaschine. Diskutieren Sie die Laufzeit Ihrer Turingmaschine im
Vergleich zu einem Algorithmus (mit RAM) für diese Sprache.
Lösung. Die Turingmaschine sieht folgendermaßen aus:
(1) Falls genau eine 0 auf dem Band steht, akzeptiere.
(2) Bewege den Kopf von links nach rechts über die Eingabe und ersetze jede zweite 0 durch
ein neues Symbol x.
(3) Falls das letzte Symbol der Eingabe nun eine 0 ist, verwerfe.
(4) Gehe zu Schritt (1).
Korrektheit: Die Sprache L besteht aus allen Wörtern, die nur Nullen enthalten und deren Länge
eine Zweierpotenz ist. Eine Zahl ist genau dann eine Zweierpotenz, wenn sie nach wiederholtem
Teilen durch 2 irgendwann eine 1 ergibt. Genau das überprüft die Turingmaschine. Wenn bei
diesem wiederholten Teilen eine ungerade Zahl auftritt, ist die Zahl keine Zweierpotenz. In
diesem Fall verwirft die Turingmaschine die Eingabe (siehe Schritt (3)).
Laufzeit: Die angegebene Turingmaschine hat eine Laufzeit von O(n log(n)), wobei n hier die
Länge der Eingabe bezeichnet. Schritt (1) und Schritt (2) benötigen jeweils eine Laufzeit von
O(n). Schritt (3) geht in konstanter Laufzeit O(1). Schritt (4) wiederholt die Schritte (1) bis (3)
bis nur noch eine 0 auf dem Band steht oder vorher abgebrochen wird. Da in jedem Durchlauf
der Schritte (1) bis (3) die Hälfte der Nullen (abgerundet) durch x Symbole ersetzt wird, steht
nach log n Durchläufen nur noch eine Null auf dem Band und es wird nach Schritt (1) akzeptiert
oder es steht nach ⌊log n⌋ 1 Durchläufen eine ungerade Anzahl von Nullen auf dem Band und
es wird nach Schritt (3) verworfen. Also gibt es maximal log n + 1 Durchläufe.
Diskussion: Ein Algorithmus mit RAM könnte folgendermaßen aussehen:
1. Zähle die Buchstaben und erhalte Anzahl m.
2. Falls log m ganzzahlig ist, akzeptiere. Sonst verwerfe.
Dieser Algorithmus hat eine Laufzeit von O(n), wobei n hier die Länge der Eingabe bezeichnet.
Ein Algorithmus mit RAM kann also den zusätzlichen Speicher nutzen, um wesentlich schneller
eine Aufgabe zu erledigen, im Vergleich zu einem Algorithmus, der auf einer Turingmaschine
läuft.
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
23.06.2025
Präsenzaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 11
Präsenzaufgabe 11.1 (Fragen über Fragen)
Diskutieren Sie nachfolgende Aussagen. Sind diese wahr oder falsch?
(a) Für L ∈ NP gilt, aus L ⪯ 3-SAT folgt, dass L NP-vollständig ist.
(b) Gilt für eine Sprache L, dass sowohl L ⪯ 3-SAT als auch 3-SAT ⪯ L, dann ist L NP-vollständig.
(c) Sei L NP-vollständig. Dann gilt L ∈ P genau dann, wenn P = NP.
(d) Es ist möglich, dass 3-SAT ∈ P und C LIQUE ∈
/ P.
Lösung.
/ Offensichtlich gilt L ∈ NP. Aus L ⪯ 3-SAT folgt nur,
(a) Nein, ein Gegenbeispiel ist L = 0.
dass sich L auf 3-SAT reduzieren lässt, nicht anders herum.
(b) Das ist die Definition von NP-vollständig.
(c) Korrekt, da sich jedes Problem auf L reduzieren lässt nach Def. NP-vollständig (und offen-
sichtlich P ⊆ NP).
(d) Nein, weil 3-SAT NP-vollständig ist, lässt sich C LIQUE (liegt bekannterweise in NP, ist
sogar NP-vollständig) auf 3-SAT reduzieren.
Präsenzaufgabe 11.2 (NP-Vollständigkeit)
In dem Problem C LIQUE -N OMEMBER ist ein Graph G = (V, E), ein Knoten v ∈ V sowie eine
Zahl k ∈ N gegeben und es soll entschieden werden, ob es eine Clique mit k Knoten gibt, die
den Knoten v nicht enthält.
Zeigen Sie, dass C LIQUE -N OMEMBER NP-vollständig ist, indem Sie eine Reduktion von C LI -
QUE auf C LIQUE -N OMEMBER angeben. Sie können davon ausgehen, dass C LIQUE -N OMEMBER ∈
NP ist.
Lösung. Clique-Nomember ist NP-schwer:
Sei (G = (V, E), k) eine Eingabe für das Clique Problem.
Idee: Füge einen neuen isolierten Knoten v zu G hinzu.
Wir geben zuerst die Abbildung an: Sei v ̸∈ V . Wir definieren die Eingabe für das Problem
C LIQUE -N OMEMBER als den Graphen G := (V {v}, E), den Knoten v als Knoten, der nicht
benutzt werden darf, und k als gesuchte Cliquengröße. (G , v, k) ist eine gültige Eingabe für
C LIQUE -N OMEMBER und in polynomieller Zeit berechenbar.
Wir zeigen nun: G hat eine k-Clique genau dann, wenn G eine k-Clique ohne v beinhaltet.
⇒:
Sei (G, k) eine Ja-Instanz des C LIQUE Problems. Dann enthält G eine k-Clique C. Dann ist C
auch eine k-Clique in G , da bei der Abbildung keine Kanten entfernt wurden. Da v ̸∈ V , enthält
C den Knoten v nicht. Damit ist C eine k-Clique in G ohne den Knoten v. (G , v, k) ist also eine
Ja-Instanz des C LIQUE -N OMEMBER Problems.
⇐:
Sei (G , v, k) eine Ja-Instanz des C LIQUE -N OMEMBER Problems. Dann enthält G eine k-Clique
C mit v ̸∈ C. Da bei der Abbildung an dem Graphen nichts geändert wurde, außer der Knoten v
hinzugefügt, muss C auch eine k-Clique in G sein. Damit ist (G, k) eine Ja-Instanz des C LIQUE
Problems.
Also existiert eine polynomielle Reduktion von C LIQUE auf C LIQUE -N OMEMBER. Da C LI -
QUE NP-vollständig ist und C LIQUE -N OMEMBER ∈ NP nach Aufgabenstellung gilt, ist somit
C LIQUE -N OMEMBER NP-vollständig.
Präsenzaufgabe 11.3 (NP-Vollständigkeit)
Für das Problem S UBSET S UM C ARDINALITY seien n ganze Zahlen c1 , . . . , cn ∈ N>0 (wobei n
gerade sei) sowie eine Zahl K ∈ N gegeben. Es soll entschieden werden, ob es eine Teilmenge
S ⊂ {1, . . . , n} gibt mit |S| = n/2 und ∑i∈S ci = K.
Zeigen Sie, dass das Problem S UBSET S UM C ARDINALITY NP-vollständig ist. Sie können
davon ausgehen, dass S UBSET S UM C ARDINALITY ∈ NP ist.
Lösung. Subset Sum Cardinality ist NP-schwer:
S UBSET S UM Problem: Gegeben: n ganze Zahlen c1 , . . . , cn ∈ N>0 und Zahl K ∈ N. Frage: Gibt
es eine Teilmenge S ⊆ {0, . . . , n} mit ∑i∈S ci = K?
Reduktion: Sei I = (c1 , . . . , cn , K) eine Eingabe für das S UBSET S UM Problem. Definiere ci :=
ci + 1 für i ≤ n und ci := 1 für i ∈ {n + 1, . . . , 2n}. Wir definieren die Eingabe für das Problem
S UBSET S UM C ARDINALITY als I = (c1 , . . . , c2n , K + n).
Wir zeigen nun: Es gibt eine Lösung für I genau dann, wenn es eine Lösung für I gibt.
⇒:
Sei I eine Ja-Instanz des S UBSET S UM Problems. Dann gibt es eine Menge S ⊆ {1, . . . , n} mit
∑i∈S ci = K. Es gilt also ∑i∈S ci = ∑i∈S (ci + 1) = K + |S|. Sei nun S = {n + 1, . . . , 2n |S|}. Es
gilt |S S | = n und ∑i∈SS ci = ∑i∈S ci + ∑i∈S ci = ∑i∈S (ci + 1) + ∑i∈S 1 = K + |S| + (n |S|) =
K + n. S S ist also eine Lösung für I und I damit eine Ja-Instanz.
⇐:
Es sei I eine Ja-Instanz. Dann gibt es also eine Menge S ⊆ {1, . . . , 2n} mit ∑i∈S ci = K + n und
|S | = n. Sei S := S ∩{1, . . . , n}. Es gilt ∑i∈S ci ∑i∈S ci = n|S|, da die Items in {n+1, . . . , 2n}
das Gewicht 1 haben, und genau n |S| Items übrig sind. Damit gilt ∑i∈S (ci + 1) = ∑i∈S ci =
K + n (n |S|) = K + |S|, woraus folgt, dass ∑i∈S ci = K. Damit ist S eine Lösung für I und
somit I eine Ja-Instanz.
Laufzeit: Die Reduktion kann naiv in einer Zeit von O(n) implementiert werden. Das ist eine
polynomielle Laufzeit.
Also existiert eine polynomielle Reduktion von S UBSET S UM auf S UBSET S UM C ARDINALI -
TY . Da nach Skript S UBSET S UM NP-vollständig ist und S UBSET S UM C ARDINALITY ∈ NP
nach Aufgabenstellung gilt, ist somit S UBSET S UM C ARDINALITY NP-vollständig.
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
30.06.2025
Präsenzaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 12
Präsenzaufgabe 12.1
Im Folgenden sollen Sie herausfinden (und begründen), welche Lower Bounds sich über ETH
und die Reduktionen aus der Vorlesung ergeben. Nutzen Sie hierfür auch das Sparsification
Lemma.
Welche Schranken für die Laufzeit in Abhängigkeit von den natürlichen Parametern (Anzahl
Knoten, Anzahl Kanten, Anzahl Items, Anzahl unterschiedlicher Items, Anzahl Tripel, Kardi-
nalität der Grundmenge, Anzahl unterschiedlicher Tripel, Anzahl unterschiedlicher auftretender
Zahlen, größte auftretende Zahl, . . . ) ergeben sich jeweils aus folgenden (zum Großteil aus der
Vorlesung bekannten) Reduktionen (Laufzeitfaktoren, die polynomiell in der Eingabekodierung
sind, dürfen vernachlässigt werden)?
Schätzen Sie dazu zunächst die verschiedenen Parameter der resultierenden Instanz mithilfe der
Parameter der eingegebenen Instanz geeignet ab.
1. 3-SAT ⪯ k-C LIQUE
2. k-C LIQUE ⪯ k-I NDEPENDENT S ET (Problemdefinition für die Antwort nicht relevant; in
der Reduktion wird der Graph G = (V, E) auf den Komplementgraph (V, E) abgebildet)
3. SAT ⪯ 3-D IMENSIONAL M ATCHING (Hinweis: 3-SAT ⊆ SAT)
4. 3-D IMENSIONAL M ATCHING ⪯ 3-E XACT C OVER
5. 3-E XACT C OVER ⪯ S UBSET S UM
Lösung. Angenommen ETH gilt. Das Sparsification Lemma impliziert, dass man 3-SAT nicht
in 2o(m) · |I|O(1) lösen kann.
1. In der Reduktion werden |V | = O(m) Knoten und |E| = O(m2 ) Kanten erstellt und k = m.
Außerdem gilt n ≤ 3m ∈ O(m).
• Lower bound bzgl. der Anzahl an Knoten: 2o(|V |) · |I|O(1)
Angenommen, es existiert ein Algorithmus, der k-Clique in 2o(|V |) ·|I|O(1) löst. Dann
gibt es auch einen Algorithmus, der 3-SAT in 2o(m) · |I|O(1) löst (Reduktion auf k-
Clique + k-Cliquen Algorithmus). Nach dem Sparsification Lemma gibt es dies nur,
wenn die ETH nicht gilt.
• Lower bound bzgl. der Anzahl an Kanten: 2o( |E|) · |I|O(1) √
Angenommen, es existiert ein Algorithmus, der k-Clique in 2o( |E|) · |I|O(1) löst.
Da |E| ∈ O(m2 ), gibt es dann auch einen Algorithmus, der 3-SAT in 2o(m) · |I|O(1)
löst (Reduktion auf k-Clique + k-Cliquen Algorithmus). Nach dem Sparsification
Lemma gibt es dies nur, wenn die ETH nicht gilt.
• Lower bound bzgl. k: 2o(k) · |I|O(1)
Angenommen, es existiert ein Algorithmus, der k-Clique in 2o(k) · |I|O(1) löst. Dann
gibt es auch einen Algorithmus, der 3-SAT in 2o(m) · |I|O(1) löst (Reduktion auf k-
Clique + k-Cliquen Algorithmus). Nach dem Sparsification Lemma gibt es dies nur,
wenn die ETH nicht gilt.
2. In der Reduktion werden genau |V | Knoten und maximal |E| = O(|V |2 ) Kanten erstellt.
• Lower bound bzgl. der Anzahl an Knoten: 2o(|V |) · |I|O(1)
Angenommen, es existiert ein Algorithmus, der k-Independent-Set in 2o(|V |) · |I|O(1)
löst. Dann gibt es auch einen Algorithmus, der k-Clique in 2o(|V |) · |I|O(1) löst (Re-
duktion auf k-Independent-Set + k-Independent-Set Algorithmus). Nach Aufgaben-
teil 1, gibt es diesen nur, wenn die ETH nicht gilt.
o( |E|)
• Lower bound bzgl. der Anzahl an Kanten: 2 · |I|O(1) √
Angenommen, es existiert ein Algorithmus, der k-Independen-Set in 2o( |E|) ·|I|O(1)
löst. Da |E| ≤ |V |2 , gibt es dann auch einen Algorithmus, der k-Clique in 2o(|V |) ·
|I|O(1) löst (Reduktion auf k-Independent-Set + k-Independent-Set Algorithmus).
Nach Aufgabenteil 1, gibt es diesen nur, wenn die ETH nicht gilt.
3. In der Reduktion werden Mengen mit |U| = |V | = |W | = O(mn) Elementen erstellt und
|T | = O(m2 n2 ) Tupel. Es gilt n ≤ 3m ∈ O(m) für 3-SAT.
• Lower bound bzgl. der Anzahl an Elementen: 2o( |V |) · |I|O(1) √
Angenommen, es existiert ein Algorithmus, der 3-Dimensional-Matching in 2o( |V |) ·
|I|O(1) löst. Da |V | ∈ O(mn) ≤ O(m2 ), gibt es dann auch einen Algorithmus, der
3-SAT in 2o(m) · |I|O(1) löst (Reduktion von SAT auf 3-Dimensional-Matching an-
gewandt auf 3-SAT Instanzen + 3-Dimensional-Matching Algorithmus). Nach dem
Sparsification Lemma geht dies nur, wenn die ETH nicht gilt.
4
• Lower bound bzgl. der Kardinalität von T : 2o( |T |) · |I|O(1) √
4
Angenommen, es existiert ein Algorithmus, der 3-Dimensional-Matching in 2o( |T |) ·
|I|O(1) löst. Da |T | ∈ O(m2 n2 ) ≤ O(m4 ), gibt es dann auch einen Algorithmus, der
3-SAT in 2o(m) · |I|O(1) löst (Reduktion von SAT auf 3-Dimensional-Matching an-
gewandt auf 3-SAT Instanzen + 3-Dimensional-Matching Algorithmus). Nach dem
Sparsification Lemma geht dies nur, wenn die ETH nicht gilt.
4. Das 3-dimensionale Matching ist ein Spezialfall vom 3-Exact Cover. Daher gelten die
Lower Bounds von 3-dimensionalem Matching auch für 3-Exact Cover. Da |U| = 3m ∈
O(|V |), ergibt sich, dass es für 3-Exact Cover unter der ETH keinen Algorithmus √ mit
o( m) O(1) o( |V |)
Laufzeit 2 · |I| geben kann, da sonst 3-dimensionales Matching in 2 ·
|I|O(1) lösbar wäre. Und da |F| = |T |, √ ergibt sich, dass es für 3-Exact Cover unter der ETH
o( 4 |F|)
keinen Algorithmus
√ mit Laufzeit 2 · |I|O(1) geben kann, da sonst 3-dimensionales
4
Matching in 2o( |T |) · |I|O(1) lösbar wäre.
4
5. In der Reduktion wird n = |F| gesetzt. Lower bound bzgl. n: 2o( n)√· |I|O(1)
4
Angenommen, es existiert ein Algorithmus, der SubsetSum in 2o( n) · |I|O(1) löst. Dann
4
|F|)
gibt es auch einen Algorithmus, der 3-Exact Cover in 2o( · |I|O(1) löst. Nach Aufga-
benteil 4, gibt es diesen nur, wenn die ETH nicht gilt.
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
07.07.2025
Präsenzaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 13
Präsenzaufgabe 13.1 (Vertex Cover)
Ein Vertex Cover in einem Graphen G = (V, E) ist eine Menge von Knoten C ⊆ V , so dass für
jede Kante {v, w} ∈ E gilt, dass v ∈ C oder w ∈ C. Beim Optimierungsproblem Minimum Vertex
Cover soll die kardinalitätskleinste Menge C ⊆ V gefunden werden, die ein Vertex Cover von
G ist.
Gegeben ist der folgende approximative Algorithmus mit Güte 2 für VertexCover:
Idee: Wähle eine beliebige Kante. Wenn einer der beiden Endknoten bereits in C ist, verwirf
diese Kante. Sonst, füge beide Endknoten zur Menge C hinzu. Mache dies für jede Kante.
Algorithmus 2A PPROX CV(G = (V, E))
1 C = {}
2 foreach {u, v} ∈ E do
3 if u ̸∈ C and v ̸∈ C then
4 C = C {u, v}
5 fi
6 od
7 return C
Beweisen Sie die Güte.
Lösung. Beweis: Sei C ein minimales Vertex Cover. Wir zeigen |C| ≤ 2|C |.
Sei A die Menge der Kanten, für die beide Endknoten zu C hinzugefügt wurden. Es gilt |C| =
2|A|, da beide Knoten jeder ausgewählten Kante zu C hinzugefügt wurden und alle anderen
Kanten nicht weiter betrachtet werden. Damit folgt auch, dass keine zwei Kanten aus A einen
Knoten gemeinsam haben können. Sei nun C ein minimales Vertex Cover. C enthält nach
Definition mindestens einen Knoten jeder Kante, also insbesondere einen Knoten jeder Kante
aus A. Da keine zwei Kanten aus A vom gleichen Knoten aus C überdeckt werden können, gilt
|C | ≥ |A|. Es folgt |C| = 2|A| ≤ 2|C |. Die Lösung C von 2ApproxCV ist also maximal doppelt
so groß wie die optimale Lösung C . Damit berechnet der Algorithmus eine 2-Approximation.
Präsenzaufgabe 13.2 (TSP)
In der Vorlesung haben Sie zwei approximative Algorithmen für das TSP-Problem kennen ge-
lernt. Der erste Algorithmus ∆T SP1 hat eine Approximationsrate von 2, während der zweite
Algorithmus ∆T SP2 von Christofides eine Approximationsrate von 3/2 besitzt. In dieser Übung
soll gezeigt werden, dass die zweite Rate scharf ist. D.h., dass es eine Folge von Instanzen gibt,
auf denen der Algorithmus immer näher an diese Rate heran kommt.
Wir betrachten den vollständigen Graphen Kn = (V, E) für ein n ∈ N≥6 mit n mod 4 = 2 und
die nachfolgende Gewichtsfunktion d2 : E → R+ . Zeigen Sie, dass
(a) OPT((Kn , d2 )) = n gilt und
(b) eine mögliche Ausführung von ∆TSP2 existiert, die auf Eingabe (Kn , d2 ) eine Tour der
Länge (n 1) + n/2 berechnet.
1 1 1 1
1 3 5 7 9 n1
1 1 1 1 1 1
1 1 1 1
2 4 6 8 10 n
Wir definieren E2 := {{i, i + 2}|i ∈ {1, . . . , n 2}} {{2i + 1, 2i + 2}|i ∈ {0, . . . , n/2 1}} und
d2 , so dass alle Kanten aus E2 auf 1 abgebildet werden und alle Kanten aus E \ E2 auf den Wert
des kürzesten Wegs zwischen diesen Knoten in dem oben abgebildeten Graphen abgebildet
werden.
Lösung. Wichtig bei dieser Aufgabe ist der folgende Fakt: Bei beiden Algorithmen wird ir-
gendein MST genommen und dann irgendeine Reihenfolge der Knoten. Typischerweise wird
diese Reihenfolge durch bestimmte Knoten- oder Kanten-Labels festgelegt (wird zum Beispiel
der Kruskal-Algorithmus zur Konstruktion des MST genutzt, so werden dort die Kanten nach
Gewicht sortiert. Kanten gleichen Gewichts müssen also auch noch durch irgendeine Reihen-
folge festgelegt werden.) Wir gehen also davon aus, dass wir diese Reihenfolge auch wählen
können. Sollte der Algorithmus also einen “besseren” MST oder eine “bessere” Knotenreihen-
folge nutzen, passen wir die Labels dementsprechend an.
Ein möglicher MST ist durch die unten angegebene Zick-Zack-Tour gegeben oder formal durch
h [ i
ET = {{ j, j + 1}, { j + 1, j + 3}, { j + 3, j + 2}, { j + 2, j + 4}}} {{n 1, n}}.
1≤ j≤n5
j mod 4=1
1 1 1 1
1 3 5 7 n3 n1
1 1 1 1 1 1
1 1 1 1
2 4 6 8 n2 n
Es gilt d(T ) = n 1 für die Kosten d(T ) des MST T , da nur Kanten mit Kosten 1 gewählt
werden und n 1 Kanten gewählt werden müssen, um den Zusammenhang sicher zu stellen.
Da jeder Knoten im MST außer 1 und n geraden Grad hat, ist das Matching K sehr simpel,
nämlich K = {{1, n}}. Die Kosten der Kante {1, n} sind n/2 (der kürzeste Pfad von 1 zu n)
und somit gilt d(K) = n/2 für die Kosten von K. Die Rundreise R entspricht einfach dem MST
vereinigt mit der Matchingkante und hat somit Kosten: d(R) = n 1 + n/2.
Die optimale Tour würde erst “oben” und dann “unten” entlang laufen, also von Knoten 1 zu
Knoten 3 gehen, dann zu Knoten 5 und so weiter, bis Knoten n 1 erreicht wurde. Danach
folgen Knoten n, n 2, n 4 und so weiter. Diese Tour hat offensichtlich Kosten n, da wir n
Kanten mit Gewicht 1 nutzen. Somit gilt OPT((Kn , d2 )) = n und wir haben eine Rate von
∆T SP2 ((Kn , d2 )) n 1 + n/2 1
= = 3/2 ≤ 3/2.
OPT((Kn , d2 )) n n
Da limn→∞ 3/2 n1 = 3/2, kommen wir der Rate von 3/2 also beliebig nahe.

4456
uni/aak/Skript.pdf Normal file

File diff suppressed because it is too large Load Diff

2562
uni/aak/Skript.txt Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,817 @@
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
09.06.2025
Hausaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 9
Definition 1 (Vertex Cover (VC)). Für einen (ungerichteten) Graphen G = (V, E) ist ein Vertex
Cover eine Menge von Knoten C ⊆ V , sodass u ∈ C oder v ∈ C für alle { u, v } ∈ E gilt, also ist
für alle Kanten mindestens ein Endpunkt in C.
Für das V ERTEX C OVER Problem ist neben einem Graphen G eine Zahl k ∈ N≥0 gegeben und
es wird gefragt, ob ein Vertex Cover mit Größe (Anzahl der Knoten) höchstens k in G existiert.
Definition 2 (Feedback Vertex Set (FVS)). Für einen gerichteten Graphen G = (V, E) ist ein
Feedback Vertex Set eine Menge von Knoten X ⊆ V , sodass G \ X kreisfrei ist.
Für das F EEDBACK V ERTEX S ET Problem ist neben einem Graphen G eine Zahl k ∈ N≥0 gege-
ben und es wird gefragt, ob ein Feedback Vertex Set mit Größe (Anzahl der Knoten) höchstens
k in G existiert.
1 6 2
5
8 7
3
4
Abbildung 1: Beispiel Graph.
Hausaufgabe 9.1 (Nichtdeterministischer Algorithmus für VC) (5 Punkte)
1. Finden Sie ein minimales Vertex Cover in Abbildung 1. Für ein Vertex Cover ist die
Orientierung der Kanten nicht relevant.
2. Zeigen Sie V ERTEX C OVER ∈ NP, indem Sie einen nichtdeterministischen Algorithmus
angeben, der V ERTEX C OVER in Polynomialzeit löst. Begründen Sie die Korrektheit und
die Laufzeit von Ihrem Algorithmus.
Lösung. 1. Ein minimales Vertex Cover ist zum Beispiel { 3, 5, 6, 7, 8 }.
2. Unser nichtdeterministischer Algorithmus geht wie folgt vor: Für jeden Knoten wird
nichtdeterministisch entschieden, ob dieser im Vertex Cover sein soll. Nachdem dies für
alle Knoten entschieden wurde, wird überprüft, ob nicht mehr als k Knoten gewählt wur-
den und ob für jede Kante mindestens ein Endpunkt im Vertex Cover liegt.
Existiert ein Vertex Cover im Graphen, existiert auch eine Reihe von nichtdeterministi-
schen Entscheidungen, die diese Teilmenge von Knoten auswählt. Diese Teilmenge wird
dann auch von dem Algorithmus akzeptiert. Damit ist der Algorithmus korrekt.
Beide diese Schritte können naiv in Polynomialzeit erledigt werden, also löst dieser Al-
gorithmus das Vertex Cover Problem in Polynomialzeit.
Bewertung 1 Punkt für das Beispiel und 4 Punkte für den Algorithmus, dabei 2 Punkte für
die Beschreibung und jeweils 1 Punkt für Korrektheit und Laufzeit.
Hausaufgabe 9.2 (Polynomieller Verifizierer für FVS) (5 Punkte)
1. Finden Sie ein minimales Feedback Vertex Set in Abbildung 1.
2. Zeigen Sie F EEDBACK V ERTEX S ET ∈ NP, indem Sie einen polynomiellen Verifizierer
für F EEDBACK V ERTEX S ET angeben. Begründen Sie die Korrektheit und die Laufzeit
von Ihrem Verifizierer.
Lösung. 1. Ein minimales FVS ist zum Beispiel { 5, 6 }.
2. Das Zertifikat hat die Form einer Teilmenge X ⊆ V , die beschreibt, welche Knoten das
Feedback Vertex Set bilden sollen. Zum Beispiel über ein Bit pro Knoten. Nun wird
überprüft, ob |X| ≤ k gilt und ob G \ X azyklisch ist.
Hat der Graph ein Feedback Vertex Set von Größe maximal k, gibt es ein Zertifikat, wel-
ches dieses beschreibt. Dieses Zertifikat wird dann von unserem Verifizierer akzeptiert,
damit ist der Verifizierer korrekt.
Die Größe von X zu überprüfen ist naiv in Polynomialzeit möglich. Für den zweiten Test
bietet sich der Algorithmus zur topologischen Sortierung aus der Vorlesung an, welcher in
Polynomialzeit eine topologische Sortierung findet, wenn der gegebene Graph azyklisch
ist. Insgesamt ist dieser Verifizierer korrekt und auch ein polynomieller Verifizierer.
Bewertung 1 Punkt für das Beispiel und 4 Punkte für den Verifizierer, dabei 2 Punkte für die
Beschreibung und jeweils 1 Punkt für Korrektheit und Laufzeit.
Abgabe: 16.06.2025, 10:00 in Moodle bitte beachten Sie die Informationen zum Abgabefor-
mat im Moodlekurs.
Hausaufgabe 9
Marek Lenczewski
Matrikelnummer: 1025252
22. Juni 2025
Hausaufgabe 9.1
Teil 1
Ein minimales Vertex Cover ist C = {2, 7, 5, 4, 1}.
Die Minimale Knotenanzahl ist 5.
Teil 2
Der Algorithmus arbeitet wie folgt:
• Zuerst wird für jeden Knoten v ∈ V nichtdeterministisch entschieden, ob dieser in das
Vertex Cover aufgenommen wird. Dabei wird drauf geachtet, dass die Anzahl k nicht
übersteigt.
• Danach wird geprüft, ob für jede Kante {u, v} ∈ E entweder v ∈ C oder u ∈ C oder beides
zutrifft.
• Falls dies für alle Kanten gilt, akzeptieren wir. Andernfalls lehnen wir ab.
Existiert ein Vertex Cover der Größe höchstens k, dann gibt es auch eine, nichtdeterminis-
tisch ausgewählte, Knotenmenge, die dazu passt. Von dieser werden alle Kanten abgedeckt und
der Algorithmus akzeptiert. Falls es kein Vertex Cover gibt, dann lehnt der Algorithmus ab.
Die Auswahl der Knoten und die Prüfung der Kanten läuft in polynomieller Zeit, also ist dies
ein polynomieller nichtdeterministischer Algorithmus, der VERTEX COVER löst und damit ist
V ERT EXCOV ER ∈ N P .
Hausaufgabe 9.2
Teil 1
Ein minimales Feedback Vertex Set ist X = {1, 5}
Teil 2
Der Verifizierer arbeitet wie folgt:
• Es wird eine Teilmenge X ⊆ V übergeben, die das Feedback Vertex Set darstellen soll.
• Dann wird geprüft, ob |X| ≤ k gilt und es wird abgelehnt, falls es nicht gilt.
• Danach wird ein Graph G = G \ X konstruiert, in dem alle Knoten aus X und alle an X
angrenzenden Kanten entfernt wurden.
1
• Auf dem Graphen G wird eine Tiefensuche durchgeführt, dabei werden Knoten während
der Bearbeitung grau markiert und beim Backtracking schwarz.
• Wird eine Kante zu einem grauen Knoten entdeckt, dann wird abgelehnt, da dies einen
Kreis anzeigt.
• Falls die Tiefensuche den gesamten Graphen durchläuft ohne abzulehnen, dann wird ak-
zeptiert.
Existiert ein Feedback Vertex Set der Größe höchstens k, dann gibt es auch ein Zertifikat, das
genau diese Knotenmenge beschreibt. Alle Teilmengen, die die Tiefensuche überstehen, werden
von dem Verifizierer akzeptiert und sonst abgelehnt.
Die Prüfung der übergebenen Teilmenge und die Konstruktion des Graphen laufen in polyno-
mieller Zeit. Ebenfalls die Tiefensuche läuft in polynomieller Zeit, somit ist auch der Verifizierer
polynomiell und verifiziert die Lösung für das FEEDBACK VERTEX SET in polynomieller
Zeit. Also gilt F EEDBACKV ERT EXSET ∈ N P .
2
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
16.06.2025
Hausaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 10
Definition 1 (Feedback Vertex Set (FVS)). Für einen gerichteten Graphen G = (V, E) ist ein
Feedback Vertex Set eine Menge von Knoten X ⊆ V , sodass G \ X kreisfrei ist.
Für das F EEDBACK V ERTEX S ET Problem ist neben einem Graphen G eine Zahl k ∈ N≥0 gege-
ben und es wird gefragt, ob ein Feedback Vertex Set mit Größe (Anzahl der Knoten) höchstens
k in G existiert.
Hausaufgabe 10.1 (F EEDBACK V ERTEX S ET ist NP-vollständig) (5 Punkte)
Zeigen Sie, dass F EEDBACK V ERTEX S ET NP-vollständig ist.
Hinweis: Reduzieren Sie V ERTEX C OVER auf F EEDBACK V ERTEX S ET. Wenn ein Vertex Cover
aus einem Graphen entfernt wird, hat dieser keine Kanten mehr.
Lösung. F EEDBACK V ERTEX S ET ∈ NP ist bekannt aus der letzten Hausaufgabe. Nun zeigen
wir eine Reduktion von V ERTEX C OVER auf F EEDBACK V ERTEX S ET. Betrachte die folgende
Reduktion:
Für eine gegebene V ERTEX C OVER Instanz (G = (V, E), k) erzeuge den Graphen G = (V, E )
mit E := { (u, v), (v, u) | {u, v} ∈ E }. Gebe (G , k) als F EEDBACK V ERTEX S ET Instanz aus.
Korrektheit:
⇒ (Falls (G, k) eine Ja-Instanz von V ERTEX C OVER ist, dann ist (G , k) eine Ja-Instanz von
F EEDBACK V ERTEX S ET.):
Sei C ⊆ V ein Vertex Cover mit Größe kleiner oder gleich k. Dann enthält G \C keine Kanten.
Damit hat G \C ebenfalls keine Kanten und somit keine Kreise.
⇐ (Falls (G , k) eine Ja-Instanz von F EEDBACK V ERTEX S ET ist, dann ist (G, k) eine Ja-Instanz
von V ERTEX C OVER.):
Sei X ⊆ V ein Feedback Vertex Set mit Größe kleiner oder gleich k. Dann ist X ein Vertex
Cover in G, da ansonsten eine Kante {u, v} ∈ E existiert, für die u ∈
/ X ∧v ∈
/ X gilt. Damit wäre
aber (u, v, u) ein Kreis in G und X somit kein Feedback Vertex Set.
Laufzeit: Das Erzeugen der Menge E geht in Zeit O(|E|). Insgesamt ist die Reduktion dem-
nach in Laufzeit O(|E|), also in polynomieller Laufzeit, durchführbar.
Also existiert eine polynomielle Reduktion von V ERTEX C OVER auf F EEDBACK V ERTEX S ET.
Da V ERTEX C OVER nach den aktuellen Präsenzaufgaben NP-vollständig ist und
F EEDBACK V ERTEX S ET ∈ NP gilt, ist somit F EEDBACK V ERTEX S ET NP-vollständig.
Bewertung 2 Punkte für die Konstruktion, 1 Punkt für den 1. Fall, 1 Punkt für den 2. Fall,
0.5 Punkte für die Laufzeit, 0.5 Punkte für die Beweisführung im Ganzen
Hausaufgabe 10.2 (Turingmaschinen) (5 Punkte)
Entwerfen Sie eine Turingmaschine für die Sprache L = { w ∈ Σ∗ | w ist ein Palindrom } über
einem gegebenen Alphabet Σ und geben Sie die Laufzeit Ihrer Turingmaschine an. Begründen
Sie dabei, warum Ihre Turingmaschine korrekt ist und die angegebene Laufzeit hat.
Lösung. Die Turingmaschine sieht folgendermaßen aus:
(1) Falls kein Wort auf dem Band steht, akzeptiere.
(2) Falls nur ein Buchstabe auf dem Band steht, akzeptiere.
(3) Lese den ersten Buchstaben und bewege danach den Kopf zum letzten Buchstaben. Falls
die beiden Buchstaben verschieden sind, verwerfe. Ansonsten ersetze beide Buchstaben
durch ein neues Symbol x. Ersetze dafür zuerst den letzten Buchstaben und bewege dann
den Kopf zum ersten Buchstaben.
(4) Gehe zu Schritt (1).
Korrektheit: Die Turingmaschine vergleicht immer den ersten und den letzten Buchstaben.
Wenn die Buchstaben nicht gleich sind, ist das Wort kein Palindrom und es wird verworfen.
Ansonsten werden die Buchstaben rausgestrichen (siehe Schritt (3)). Diese Prozedur wird so-
lange wiederholt, bis man in der Mitte des Wortes angekommen ist und entweder nur noch ein
Buchstabe oder kein Buchstabe vorhanden ist. In beiden Fällen ist das Wort ein Palindrom und
es wird akzeptiert (siehe Schritte (1) und (2)).
Laufzeit: Die Schritte (1) bis (3) benötigen jeweils eine Laufzeit von O(n), wobei n hier die
Länge der Eingabe bezeichnet. Da in jedem Durchlauf der Schritte (1) bis (3) zwei Buchstaben
raus gestrichen werden oder das Wort akzeptiert oder verworfen wird, gibt es maximal ⌊n/2⌋
Durchläufe, bis nur noch ein oder kein Buchstabe auf dem Band stehen und somit in den Schrit-
ten (1) oder (2) akzeptiert wird. Damit ergibt sich insgesamt eine Laufzeit von O(n2 ).
Bewertung 2 Punkte für die Turingmaschine, 1 Punkt für die Korrektheit und 2 Punkte für
die Laufzeit: 1 Punkt Angabe, 1 Punkt Begründung
Abgabe: 23.06.2025, 10:00 in Moodle bitte beachten Sie die Informationen zum Abgabefor-
mat im Moodlekurs.
Hausaufgabe 10
Marek Lenczewski
Matrikelnummer: 1025252
22. Juni 2025
Hausaufgabe 10.1
Teil 1: FeedbackVertexSet ∈ NP
Zuerst brauchen wir einen polynomiellen Verifizierer, um zu zeigen dass FeedbackVertexSet
∈ NP.
Der Verifizierer bekommt einen Graphen G und eine Teilmenge X, dieser arbeitet wie folgt:
• Prüfe, ob |X| ≤ k, sonst ablehnen
• Den Graphen G = G \ X konstruieren
• Tiefensuche auf G durchführen, dabei werden Knoten vom aktuellen Pfad als grau mar-
kiert und nach vollständiger Bearbeitung als schwarz. Wird eine Kante zu einem grauen
Knoten gefunden, zeigt dies einen Kreis an und wir lehnen ab
• Akzeptieren, wenn die Tiefensuche nichts findet
Die Schritte 1-4 laufen in polynomieller Zeit, somit läuft der Verifizierer in polynomieller
Zeit. Damit ist F eedbackV ertexSet ∈ N P .
Teil 2: FeedbackVertexSet ist NP-schwer
Jetzt brauchen wir eine Reduktion von VertexCover auf FeedbackVertexSet, um zu zeigen,
dass F eedbackV ertexSet N P Schwer ist.
Konstruktion: Sei dafür ein VertexCover gegeben mit einem Graphen G und einer Zahl k.
Aus G wird ein G , wobei jede ungerichtete Kante {u, v} ∈ E durch zwei gerichteten Kanten
(u, v) und (v, u) zu E ersetzt wird. Das k wird einfach übernommen k = k .
Beweis VertexCover nach FeedbackVertexSet:
• Sei C ein VertexCover von G mit |C| ≤ k
• Da C ein VertexCover ist, wird jede Kante mit C verbunden
• Wenn C entfernt wird, dann hat G \ C keine Kanten mehr
• Dann hat auch G \ C keine Kanten und ist somit Kreisfrei
• Damit ist C ein FeedbackVertexSet für G mit |C| ≤ k
Beweis FeedbackVertexSet nach VertexCover:
1
• Sei X ein FeedbackVertexSet von G mit |X| ≤ k
• Dann ist G \ X kreisfrei
• Angenommen X wäre kein VertexCover von G, dann gäbe es eine Kante {u, v} ∈ E mit
u, v ∈
/X
• Somit wären u, v noch in G \ X vorhanden
• Die Kanten (u, v) und (v, u) würden, durch die Konstruktion, einen Kreis erzeugen
• Das ist ein Widerspruch, somit ist G \ X kreisfrei und X ist ein VertexCover
Da F eedbackV ertexSet ∈ N P und N P schwer ist, folgt dass F eedbackV ertexSet NP-
Vollständig ist. □
Hausaufgabe 10.2
Lösung. Die Turingmaschine arbeitet wie folgt:
1. Falls das Band leer ist oder nur aus Markierungen besteht, akzeptiere
2. Merke das erste unmarkierte Zeichen und ersetze es durch X
3. Laufe zum letzten unmarkierten Zeichen oder verwefe
4. Falls dieses Zeichen nicht mit dem gemerkten übereinstimmt, verwerfe
5. Ersetze es durch X und gehe zurück zum Anfang
6. Gehe zu 1
Korrektheit: Ein Wort ist genau dann ein Palindrom, wenn es sich von vorne und hin-
ten gleich liest. Dies prüft die Turingmaschine, indem sie Schrittweise die äußeren Buchstarben
verifiziert, bis nur noch einer oder keiner Vorhanden ist, dann akzeptiert ist und wenn eine Un-
stimmigkeit auftritt, dann lehnt sie ab.
Laufzeit: Die Turingmaschine hat eine Laufzeit von O(n2 ). In jedem Durchlauf macht sie
O(n) Schritte und das mit O(n) Durchläufen. □
2
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
23.06.2025
Hausaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 11
Definition 1 (Dreiecksüberdeckung eines Graphen (∆ C OVER)). Gegeben ist ein endlicher un-
gerichteter Graph G = (V, E) und eine Zahl k ∈ N. Dieser Graph hat eine Dreiecksüberdeckung,
wenn eine Menge von Knoten C∆ ⊆ V mit |C∆ | ≤ k existiert, so dass zu jedem Teilgraphen (Drei-
eck) D = (VD , ED ) ⊆ (V, E) mit |VD | = 3 und ED = { {v1 , v2 } ∈ VD ×VD | v1 ̸= v2 } von G gilt,
v ∈ C∆ für mindestens ein v ∈ VD .
Hausaufgabe 11.1 (10 Punkte)
(a) (1 Punkt) Markieren Sie im folgenden Graphen (Abbildung 1 (a)) ein V ERTEX C OVER
der Größe 5.
(b) (1 Punkt) Markieren Sie im folgenden Graphen (Abbildung 1 (b)) eine Dreiecksüberde-
ckung der Größe 5.
(c) (8 Punkte) Zeigen Sie, dass ∆ C OVER NP-vollständig ist.
(a) (b)
Abbildung 1: Beispielgraph
Lösung.
(a) (b)
Abbildung 2: Beispielgraph Lösung
(c) Wir zeigen zunächst, ∆ C OVER ∈ NP mittels eines polynomiellen Verifizierers.
Der polynomielle Verifizierer erhält als Zertifikat eine Menge von Knoten C∆ ⊆ V . Zunächst
überprüft er, ob |C∆ | ≤ k. Falls dies nicht der Fall ist, verwerfe die Instanz. Ansonsten überprüfe
für alle Teilgraphen D = (VD , ED ) ⊆ (V, E) mit |VD | = 3 und ED = { {v1 , v2 } ∈ VD ×VD | v1 ̸= v2 }
von G, ob für mindestens ein v ∈ VD auch v ∈ C∆ gilt. Falls dies gilt, akzeptiere. Ansonsten ver-
werfe.
Korrektheit: Der Verifizierer überprüft die geforderten Eigenschaften. Falls ein Graph eine Drei-
ecksüberdeckung besitzt, so existiert ein entsprechendes Zertifikat C∆ und der Verifizierer ak-
zeptiert die Instanz. Falls ein Graph keine Dreiecksüberdeckung besitzt, exisitert kein valides
entsprechendes Zertifikat C∆ und der Verifizierer verwirft die Instanz.
Laufzeit: Es gibt maximal |V |3 verschiedene Teilmengen, die ein Dreieck bilden könnten und
daher überprüft werden müssen. Die Überprüfung geht in O(|V |) Zeit. Da alle anderen Schritte
des Verifizierers in O(1) Zeit erledigt werden können, ergibt sich somit insgesamt eine Laufzeit
von O(|V |4 ), was einer polynomiellen Laufzeit entspricht.
Also gilt ∆ C OVER ∈ NP.
Nun reduzieren wir V ERTEX C OVER auf ∆ C OVER. Betrachte folgende Reduktion:
Sei I = (G = (V, E), k) eine Instanz von V ERTEX C OVER. Bilde den Graphen G = (V , E ) mit
V = V { ve | e ∈ E } und E = E { {ve , e1 }, {ve , e2 } | e = {e1 , e2 } ∈ E }. Gebe I = (G , k)
als ∆ C OVER Instanz aus.
Korrektheit:
⇒ (Falls (G, k) eine Ja-Instanz von V ERTEX C OVER ist, dann ist (G , k) eine Ja-Instanz von ∆
C OVER.):
Sei C ein Vertex Cover mit Größe kleiner oder gleich k von G. Dann ist C ebenfalls eine Drei-
ecksüberdeckung mit Größe kleiner oder gleich k. Offensichtlich gilt |C| ≤ k. Da C ein Vertex
Cover von G ist, gilt für jede Kante {u, v} ∈ E, dass u ∈ C oder v ∈ C. Für alle Teilgraphen
D = (VD , ED ) ⊆ (V, E) mit |VD | = 3 und ED = { {v1 , v2 } ∈ VD ×VD | v1 ̸= v2 } von G gilt damit
direkt, dass mindestens ein v ∈ VD auch in C enthalten ist. Der Graph G besitzt neben allen
solchen Teilgraphen in G zusätzlich solche Teilgraphen (Dreiecke), die durch die Knotenmenge
{ ve | e ∈ E } und die entsprechenden Kanten { e, {ve , e1 }, {ve , e2 } | e = {e1 , e2 } ∈ E } entste-
hen. Für diese Dreiecke gilt aber auch, dass mindestens ein Knoten, nämlich e1 oder e2 , in C
enthalten sein muss, da C ein Vertex Cover ist.
⇐ (Falls (G , k) eine Ja-Instanz von ∆ C OVER ist, dann ist (G, k) eine Ja-Instanz von V ERTEX -
C OVER.):
Sei C∆ eine Dreiecksüberdeckung von G der Größe |C∆ | ≤ k. Ohne Beschränkung der All-
gemeinheit können wir davon ausgehen, dass C∆ ⊆ V gilt: Falls für einen Knoten ve ∈ C∆ gilt,
können wir e1 zu C∆ hinzufügen und ve aus C∆ löschen. Dadurch bleibt die Überdeckungseigen-
schaft erhalten und die Menge wird höchstens kleiner. Nun gilt also C∆ ⊆ V . Die Menge C∆ ist
auch ein Vertex Cover mit Größe kleiner oder gleich k von G. Offensichtlich gilt |C∆ | ≤ k. Da für
alle Teilgraphen D = (VD , ED ) ⊆ (V , E ) mit |VD | = 3 und ED = { {v1 , v2 } ∈ VD ×VD | v1 ̸= v2 }
von G gilt, dass mindestens ein Knoten v ∈ VD ebenfalls in C∆ enthalten sein muss, gilt dies
auch für die Dreiecke {ve , e1 , e2 }. Da außerdem C∆ ⊆ V gilt, gilt e1 ∈ C∆ oder e2 ∈ C∆ für alle
Kanten e ∈ E.
Laufzeit: Das Hinzufügen von einem neuen Knoten und zwei neuen Kanten pro Kante geht in
O(|E|). Damit geht die gesamte Reduktion in O(|E|), also in polynomieller Zeit.
Also existiert eine polynomielle Reduktion von V ERTEX C OVER auf ∆ C OVER. Da V ERTEX -
C OVER NP-vollständig aus den Präsenzaufgaben bekannt ist und ∆ C OVER ∈ NP gilt, ist somit
∆ C OVER NP-vollständig.
Bewertung (a) und (b) jeweils 1 Punkt, (c) gibt 8 Punkte: 1 Punkt Angabe Verifizierer/NDTM,
0,5 Punkte Korrektheit Verifizierer/NDTM, 0,5 Punkte Laufzeit Verifizierer/NDTM, 1 Punkt
Angabe Reduktion, 3 Punkte Korrektheit (je Richtung 1,5 Punkte), 1 Punkt Laufzeit Reduktion,
1 Punkt Beweisführung
Abgabe: 30.06.2025, 10:00 in Moodle bitte beachten Sie die Informationen zum Abgabefor-
mat im Moodlekurs.
Hausaufgabe 11
Marek Lenczewski
Matrikelnummer: 1025252
28. Juni 2025
Hausaufgabe 11.1
a
1
2 3
4 5
6 10
7 9
8
b
a b c
d e
f g
h i j
k l m n
o p q
r s
t u v
c
Teil 1: ∆-Cover ∈ NP
1
Zuerst brauchen wir einen polynomiellen Verifizierer, um zu zeigen, dass ∆-Cover ∈ NP.
Der Verifizierer bekommt einen Graphen G = (V, E), Zahl k und ein Zertifikat C∆ ⊆ V und
arbeitet wie folgt:
1. Prüfe, ob |C∆ | ≤ k
2. Prüfe alle Knotentripel {a, b, c} ⊆ V , ob sie ein Dreieck bilden (also ob {a, b}, {b, c} und
{a, c} ∈ E zutrifft) und ob a, b oder c ∈ C∆
3. Ablehnen, falls ein Dreieck den test nicht besteht, sonst akzeptieren
Die Schritte 1 und 3 laufen in O(1) und Schritt zwei läuft in O(|V |3 ), das ergibt eine poly-
nomielle Laufzeit. Damit ist ∆-Cover ∈ NP.
Teil 2: ∆-Cover ist NP-schwer
Jetzt brauchen wir eine Reduktion von VertexCover auf ∆-Cover, um zu zeigen, dass
∆-Cover NP-schwer ist.
Konstruktion: Sei dafür ein VertexCover gegeben mit einem Graphen G = (V, E) und
einer Zahl k. Aus G wird G = (V , E ), wobei für jede Kante e = {u, v} ∈ E ein neuer Kno-
ten we ∈ V hinzugefügt wird und mit beiden Knoten u, v verbunden wird, sodass die Kanten
{v, we } und {u, we } zu E dazu kommen. Das k = k wird übernommen. So werden aus allen
Kanten Dreiecke.
Beweis VertexCover nach ∆-Cover
• Sei C ein VertexCover für G mit |C| ≤ k
• Zu zeigen sei, dass C auch ein ∆-Cover für G mit |C| ≤ k ist
• Da C ein VertexCover ist, gilt u ∈ C oder v ∈ C
• Jedes Dreieck in G hat die Form {u, v, we } für eine Kante e = {u, v} ∈ E
• Somit hat jedes Dreieck mindestens einen Knoten in C
• Also ist C ein ∆-Cover für G
Beweis ∆-Cover nach VertexCover
• Sei C∆ ein ∆-Cover für G mit |C∆ | ≤ k
• Jede Kante e = {u, v} ∈ E bildet durch {u, v, we } ein Dreieck in G
• Also gilt u, v oder we ∈ C∆ für alle Kanten in G
• Falls we ∈ C∆ , dann kann man we durch u oder v tauschen ohne die Eigenschaft von
∆-Cover zu verletzen, sodass u oder v ∈ C∆ für alle Kanten in G gilt
• Da sich die Knoten aus C∆ nur vertauschen gilt weiter |C| = |C∆ | ≤ k
• Weiter sind in C∆ nur noch die Knoten aus V , somit gilt u ∈ C oder v ∈ C für alle Kanten
E
• Also ist C ein VertexCover für G
Da ∆-Cover ∈ NP und NP-schwer ist, folgt dass ∆-Cover NP-vollständig ist. □
2
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
30.06.2025
Hausaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 12
Hausaufgabe 12.1 (Lower Bound: V ERTEX C OVER) (5 Punkte)
Betrachten Sie die Reduktion aus der Musterlösung zu Präsenzserie 10 von C LIQUE auf V ER -
TEX C OVER .
1. Geben Sie die Anzahl der Knoten, die Anzahl der Kanten und den Wert k für die re-
sultierende V ERTEX C OVER Instanz in Abhängigkeit von der originalen C LIQUE Instanz
an.
2. Zeigen Sie Lower Bounds für V ERTEX C OVER bezüglich Anzahl der Knoten, Anzahl
der Kanten und k basierend auf der ETH und der Reduktion aus der Musterlösung zu
Präsenzserie 10.
Lösung. 1. Sei I = (G = (V, E), k) eine Instanz von C LIQUE und I = (G = (V , E ), k ) die
aus der Reduktion resultierende Instanz von V ERTEX C OVER. Es gilt |V | = |V |, |E | =
1 2
2 |V |(|V | 1) |E| ≤ |V | und k = |V | k ≤ |V |.
2. • Angenommen es gäbe einen Algorithmus, der V ERTEX C OVER in 2o(|V |) · |I|O(1)
löst. Durch die Kombination der Reduktion von C LIQUE auf V ERTEX C OVER und
diesem Algorithmus, existiert dann auch ein 2o(|V |) ·|I|O(1) Algorithmus für C LIQUE,
da |V | = |V | nach Aufgabenteil 1. Aus der Musterlösung der Präsenzserie 12 folgt
somit, dass die ETH falsch ist.
Damit kann es so einen Algorithmus für V ERTEX C OVER nur geben, wenn die ETH
falsch ist.
• Angenommen es gäbe einen Algorithmus, der V ERTEX C OVER in 2o( |E |) · |I|O(1)
löst. Durch die Kombination der Reduktion von C LIQUE auf V ERTEX C OVER und
diesem Algorithmus, existiert dann auch ein 2o(|V |) ·|I|O(1) Algorithmus für C LIQUE,
da |E | ≤ |V |2 nach Aufgabenteil 1. Aus der Musterlösung der Präsenzserie 12 folgt
somit, dass die ETH falsch ist.
Damit kann es so einen Algorithmus für V ERTEX C OVER nur geben, wenn die ETH
falsch ist.
• Angenommen es gäbe einen Algorithmus, der V ERTEX C OVER in 2o(k ) · |I|O(1) löst.
Durch die Kombination der Reduktion von C LIQUE auf V ERTEX C OVER und die-
sem Algorithmus, existiert dann auch ein 2o(|V |) · |I|O(1) Algorithmus für C LIQUE,
da k ≤ |V | nach Aufgabenteil 1. Aus der Musterlösung der Präsenzserie 12 folgt
somit, dass die ETH falsch ist.
Damit kann es so einen Algorithmus für V ERTEX C OVER nur geben, wenn die ETH
falsch ist.
Bewertung 1 Punkt für den ersten Teil und 1.5 + 1.5 + 1 für den zweiten.
Definition 1 (H ITTING S ET). Bei diesem Problem ist ein Universum U, Teilmengen des Uni-
versums F1 , . . . , Fr ⊆ U und eine Zahl k ∈ N≥0 gegeben. Gibt es eine Menge S ⊆ U mit |U| ≤ k
und S ∩ Fi ̸= 0/ für alle i ∈ [r]?
Anschaulicher wird bei diesem Problem nach maximal k Elementen aus dem Universum ge-
fragt, sodass diese Elemente alle gegebenen Mengen Fi „treffen“.
Hausaufgabe 12.2 (Lower Bound: H ITTING S ET) (5 Punkte)
Betrachten Sie folgende Reduktion von 3-SAT auf H ITTING S ET.
Für eine gegebene 3-SAT Instanz I mit n Variablen x1 , . . . , xn und m Klauseln C1 , . . . ,Cm : Als
Universum wählen wir U = { x1 , x̄1 , . . . , xn , x̄n }. Für jede Variable xi fügen wir die Menge Fi :=
{ xi , x̄i } hinzu. Für jede Klausel C j fügen wir die Menge Fn+ j := C j hinzu. Wir setzen k := n
und erhalten damit eine H ITTING S ET Instanz I.
1. Geben Sie die Größe des Universums, die Anzahl der Mengen und die Zahl k aus der
resultierenden H ITTING S ET Instanz in Abhängigkeit von der Anzahl der Variablen n und
der Anzahl der Klauseln m aus der originalen 3-SAT Instanz an.
2. Beweisen Sie Lower Bounds für H ITTING S ET bezüglich Universumsgröße, Anzahl der
Mengen und der Zahl k basierend auf der obigen Reduktion und der ETH.
Lösung. 1. Für die Universumsgröße gilt |U| = 2n, für die Anzahl der Mengen gilt r =
n + m und es gilt k = n.
2. • Angenommen es gäbe einen Algorithmus, der H ITTING S ET in 2o(|U|) · |I|O(1) löst.
Durch die Kombination der Reduktion von 3-SAT auf H ITTING S ET und diesem
Algorithmus, existiert dann auch ein 2o(n) · |I|O(1) Algorithmus für 3-SAT, da |U| =
2n nach Aufgabenteil 1. Damit ist die ETH falsch.
Damit kann es so einen Algorithmus für H ITTING S ET nur geben, wenn die ETH
falsch ist.
• Angenommen es gäbe einen Algorithmus, der H ITTING S ET in 2o(r) · |I|O(1) löst.
Durch die Kombination der Reduktion von 3-SAT auf H ITTING S ET und diesem
Algorithmus, existiert dann auch ein 2o(m) · |I|O(1) Algorithmus für 3-SAT, da r =
n + m nach Aufgabenteil 1 und n ≤ 3m für 3-SAT gilt. Aus dem Sparsification
Lemma folgt damit, dass die ETH falsch ist.
Damit kann es so einen Algorithmus für H ITTING S ET nur geben, wenn die ETH
falsch ist.
• Angenommen es gäbe einen Algorithmus, der H ITTING S ET in 2o(k) · |I|O(1) löst.
Durch die Kombination der Reduktion von 3-SAT auf H ITTING S ET und diesem
Algorithmus, existiert dann auch ein 2o(n) · |I|O(1) Algorithmus für 3-SAT, da k = n
nach Aufgabenteil 1. Damit ist die ETH falsch.
Damit kann es so einen Algorithmus für H ITTING S ET nur geben, wenn die ETH
falsch ist.
Bewertung 1 Punkt für den ersten Teil und 1.5 + 1.5 + 1 für den zweiten.
Abgabe: 07.07.2025, 10:00 in Moodle bitte beachten Sie die Informationen zum Abgabefor-
mat im Moodlekurs.
Hausaufgabe 12
Marek Lenczewski
Matrikelnummer: 1025252
6. Juli 2025
Hausaufgabe 12.1.1
Die Knotenzahl bleibt gleich: |V | = |V | = n
Die Kantenzahl entspricht den nicht vorhandenen Kanten: |E | = |E|
k entspricht allen Knoten, die vorher nicht in der Clique waren: k = n k
Hausaufgabe 12.1.2
Wir wissen, dass 3-SAT laut ETH mindestens 2Ω(n) braucht, wobei n für die Anzahl der Varia-
blen steht.
In der Vorlesung wurde eine Reduktion von 3-SAT auf Clique gezeigt. In der Präsenzaufgabe
10.2 wurde eine Reduktion von Clique auf VertexCover gezeigt. Also gibt es eine Reduktion von
3-SAT zu VertexCover. Somit kann VertexCover nicht schneller lösbar sein als 3-SAT, weil sonst
3-SAT schneller werden würde, was nach ETH nicht geht.
So ergeben sich die folgenden Lower Bounds:
• Bezüglich Anzahl der Knoten: 2Ω(n) , wobei n = |V |. Die Knotenzahl verändert sich
nicht bei den Reduktionen.
• Bezüglich Anzahl der Kanten: 2Ω( m) , wobei m = |E |. Die Kanten können bei den
Reduktionen zu einem quadratischen Wachstum der Kanten führen.
• Bezüglich k : 2Ω(k ) . Bei der Reduktion gilt k = n k, wobei k linear von n abhängt.
1
Hausaufgabe 12.2.1
• Größe des Universums: |U | = 2n. Für jede der n Variablen gibt es zwei Elemente (xi
und xi )
• Anzahl der Mengen: n + m. n sind die Variablenmengen und m die Klauselmengen. (Fi
und Fn+j )
• Parameter: k = n. Wird in der Reduktion so übernommen.
Hausaufgabe 12.2.2
Wir wissen, dass 3-SAT laut ETH mindestens 2Ω(n) braucht, wobei n für die Anzahl der Varia-
blen steht. Somit kann HittingSet nicht schneller sein.
Es ergeben sich die folgenden Lower Bounds für HittingSet:
• Bezüglich Größe des Universums: 2Ω(|U |/2) , da für jede Variable zwei Elemente ins
Universum aufgenommen werden
• Bezüglich Anzahl der Mengen: 2Ω(n) , wobei die Anzahl der Variablen- und Klausel-
mengen (m + n) mindestens n ist
• Bezüglich Zahl k: 2Ω(k) , da in der Reduktion k = n gilt.
2
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
07.07.2025
Hausaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 13
Definition 1 (M AX -3-S AT). Bei dem Problem M AX -3-S AT ist eine Formel φ in konjunktiver
Normalform gegeben, wobei jede Klausel 3 Literale enthält. Gesucht ist eine Belegung β der
Variablen, die die Anzahl v(β ) der erfüllten Klauseln maximiert.
Hausaufgabe 13.1 (M AX -3-S AT) (10 Punkte)
Betrachten Sie folgenden Algorithmus A:
• Sei β0 die Belegung, die alle Variablen auf false setzt.
• Sei β1 die Belegung, die alle Variablen auf true setzt.
• Falls v(β0 ) ≥ v(β1 ), gib β0 zurück.
• Sonst gib β1 zurück.
(a) (6 Punkte) Zeigen Sie, dass obiger Algorithmus Güte 2 hat, d.h. v(A(φ )) ≥ 12 v(OPT (φ ))
gilt für alle Eingaben φ .
(b) (4 Punkte) Geben Sie eine Formel an, bei der der Algorithmus eine Belegung ausgibt, die
genau die Hälfte der maximal erfüllbaren Klauseln erfüllt. Begründen Sie kurz, warum
Ihre Formel geeignet ist.
Hinweis: Sie brauchen nur höchstens zwei Klauseln und vier Variablen.
Lösung. (a) Für jede Klausel C gilt, dass sie von mindestens einer der Belegungen β0 und
β1 erfüllt wird. Wir zeigen nun per Widerspruch, dass der obige Algorithmus eine Güte
von 2 hat:
Angenommen, es gilt v(A(φ )) < 12 v(OPT (φ )) für eine Formel φ . Sei m die Anzahl an
Klauseln in φ . Dann gilt v(OPT (φ )) ≤ m. Da v(A(φ )) < 12 v(OPT (φ )) ≤ 12 m, gilt v(β0 ) <
1 1
2 m und v(β1 ) < 2 m. Da jede Klausel C allerdings von mindestens einer der Belegungen
β0 und β1 erfüllt wird, gilt v(β0 ) ≥ 12 m oder v(β1 ) ≥ 12 m. Dies ist ein Widerspruch.
Also gilt v(A(φ )) ≥ 21 v(OPT (φ )) für alle Eingaben φ und obiger Algorithmus hat Güte
2.
(b) Betrachte folgende Formel: φ = (x1 x2 x3 )∧(¬x0 ¬x2 ¬x3 ) Mit β = {x0 → f alse, x1 →
true, x2 → true, x3 → true} gilt v(β ) = 2. Da φ nur zwei Klauseln hat, gilt somit v(OPT (φ )) =
2. Es gilt allerdings v(β0 ) = 1, da hier nur die zweite Klausel erfüllt ist, und v(β1 ) = 1,
da hier nur die erste Klausel erfüllt ist. Somit gilt v(A(φ )) = 1 = 12 · 2 = 21 v(OPT (φ )).
Bewertung (a) 2 Punkte korrekte Beweisführung im Allgemeinen, 2 Punkte Abschätzung
Algorithmus, 2 Punkte Abschätzung Optimum; (b) 2 Punkte für Angabe einer korrekten Formel,
1 Punkt Ausgabe Algorithmus, 1 Punkt Optimum
Abgabe: 14.07.2025, 10:00 in Moodle bitte beachten Sie die Informationen zum Abgabefor-
mat im Moodlekurs.
Hausaufgabe 13
Marek Lenczewski
Matrikelnummer: 1025252
13. Juli 2025
Hausaufgabe 13.1.a
Zu zeigen ist, dass der Algorithmus die Güte 2 hat, also die Lösung vom Algorithmus mindestens
halb so gut ist wie die optimale Lösung. Also ν(A(ϕ)) ≥ 21 ν(OP T (ϕ)) für alle Eingaben ϕ.
Sei ϕ eine beliebige 3-SAT-Formel mit m Klauseln C1 , C2 , . . . , Cm , wobei jede Klausel genau
3 Literale enthält.
Jede Klausel Ci ist wahr, wenn β0 wahr ist oder wenn β1 wahr ist oder beides. Da die Varia-
blen in Ci nur positiv oder negativ sein können, muss dabei mindestens β0 oder β1 wahr werden.
Der Algorithmus wählt die Belegung β0 oder β1 aus, die die meisten Klauseln Ci erfüllt.
Somit ist die Anzahl der ausgewählten Klauseln Ci mindestens m2 , da eine bei jeder Klausel
mindestens eine Belegung wahr werden muss und somit hat mindestens eine Belegung mindes-
tens m
2 wahre Klauseln.
Sei ν0 = Anzahl der von β0 erfüllten Klauseln und ν1 = Anzahl der von β1 erfüllten Klauseln.
So ergibt sich ν(A(ϕ)) = max{ν0 , ν1 } ≥ ν0 +ν
2
1
≥m
2.
Da die optimale Lösung höchstens alle m Klauseln erfüllen kann, gilt ν(OP T (ϕ)) ≤ m.
ν(OP T (ϕ))
Daraus folgt: ν(A(ϕ)) ≥ m
2 ≥ 2 .
Somit hat der Algorithmus eine Güte von 2.
1
Hausaufgabe 13.1.b
Der Algorithmus erfüllt genau die Hälfte der maximal erfüllbaren Klauseln, wenn jede Klausel
nur aus positiven oder negativen Variablen besteht und sich diese genau gleich aufteilen.
Formel: ϕ = (x1 x2 x3 ) ∧ (¬x1 ¬x2 ¬x3 )
Unter β0 (alle false):
• C1 = (x1 x2 x3 ) = (false false false) = false
• C2 = (¬x1 ¬x2 ¬x3 ) = (true true true) = true
ν(β0 ) = 1
Unter β1 (alle true):
• C1 = (x1 x2 x3 ) = (true true true) = true
• C2 = (¬x1 ¬x2 ¬x3 ) = (false false false) = false
ν(β1 ) = 1
Der Algorithmus wählt ν(A(ϕ)) = max{ν(β0 ), ν(β1 )} = max{1, 1} = 1.
Eine optimale Lösung wäre zum Beispiel x1 = true, x2 = false, x3 = false.
• C1 = (true false false) = true
• C2 = (false true true) = true
Daraus ergibt sich ν(OP T (ϕ)) = 2, also ν(A(ϕ)) = ν(OP2T (ϕ)) . Somit hat es die Güte 2.
2

5320
uni/aak/alle_klausuren.pdf Normal file

File diff suppressed because it is too large Load Diff

863
uni/aak/alle_klausuren.txt Normal file
View File

@@ -0,0 +1,863 @@
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen
19. Juli 2024
Modulprüfung zur Vorlesung
»Analyse von Algorithmen und Komplexität (Komplexitätsteil)«
SS 2024
Name: Matrikel-Nr.:
Hinweise:
• Bearbeiten Sie alle Aufgaben.
• Sie haben 10 Minuten Einlesezeit. Danach haben Sie 120 Minuten Zeit für die Klausurbearbeitung.
• Erlaubte Hilfsmittel: Ein doppelseitig handschriftlich beschriebenes Blatt Papier, (bunte) Stifte (kein
Rot, kein Grün, kein Bleistift).
• Einsichtnahme: 18.08.2024.
Note 4,0 3,7 3,3 3,0 2,7 2,3 2,0 1,7 1,3 1,0
Mindestpunkzahl 17,5 19,5 21,5 23,5 25 27 29 31 33 35
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 1 von 12
Aufgabe 1 KOMPLEXITÄT: A NWENDUNG LPT (4+2+2+2 Punkte)
Gegeben ist folgende Scheduling Instanz:
Jj J1 J2 J3 J4 J5 J6 J7
m=3
pj 5 3 7 8 1 4 2
a) Wenden Sie den LPT-Scheduling Algorithmus auf die obige Instanz an. Geben Sie dafür alle
relevanten Zwischenschritte an, sowie die Reihenfolge in der die Jobs auf Maschinen platziert
werden. Stellen Sie den resultierende Schedule graphisch dar. Eine beispielhafte Darstellung
ist:
J3
J6
J2
J5 J7
J1
J4
m1 m2 m3
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 2 von 12
b) Geben Sie die approximative Güte des Algorithmus LPT an.
c) Geben Sie eine Instanz für m = 2 Maschinen an, bei denen der Algorithmus ListScheduling
eine Güte von 2 1/m erzielt. Geben Sie zusätzlich an, welche Werte die optimale Lösung
OPT und die Lösung von LPT für diese Instanz erzielen.
d) Geben Sie eine Instanz für m = 3 Maschinen an, bei denen der Algorithmus ListScheduling
eine Güte von 2 1/m erzielt. Geben Sie zusätzlich an, welche Werte die optimale Lösung
OPT und die Lösung von LPT für diese Instanz erzielen.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 3 von 12
Aufgabe 2 KOMPLEXITÄT: B EWEIS : K -C LIQUE (10 Punkte)
Beweisen Sie folgende Aussage aus der Vorlesung:
SAT ≤ k-Clique.
Hinweis: NICHT 3-SAT, sondern allgemeines SAT!
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 4 von 12
Aufgabe 3 KOMPLEXITÄT: NP-VOLLSTÄNDIGKEIT (5+5 Punkte) a)
Wir betrachten folgendes Problem:
Problem: CliqueAndIndependetSet
Eingabe: Ein ungerichteter Graph G = (V, E) mit V = 1, . . . , |V | und eine ganze Zahl k ≥ 1.
Entscheide: Gibt es in G sowohl ein Independent Set (Menge von Knoten, die paarweise
nicht adjazent sind, d.h. zwischen denen es keine Kanten gibt) der Größe k und als auch eine
Clique der Größe k?
Zeigen Sie die NP-Schwere von CliqueAndIndependetSet durch Angabe einer Reduktion
eines nach Vorlesung/Übung bekanntermaßen NP-schweren Problems.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 5 von 12
b) Wir betrachten folgendes Problem:
Problem: (a1 = 1)-SubsetSum
Eingabe: Eine Menge von n Items, jedes Item i ∈ [n] hat eine Größe ai ∈ N>0 , wobei a1 = 1,
und ein Zielwert T .
Entscheide: Gibt es I ⊆ [n] sodass ∑i∈I ai = T ?
Zeigen Sie die NP-Schwere von (a1 = 1)-SubsetSum durch Angabe einer Reduktion eines
nach Vorlesung/Übung bekanntermaßen NP-schweren Problems.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 6 von 12
Aufgabe 4 KOMPLEXITÄT: A PPROXIMATIVE A LGORITHMEN (3+7 Punkte)
Wir betrachten folgendes Problem:
Problem: A PPROXIMATE S UBSET S UM
Eingabe: n ganze Zahlen a1 , . . . an und ein Zielwert T . Es gilt ai ≤ T ∀i ∈ [n] sowie ∑i∈[n] ai >
T.
Ziel: Wähle Zahlenmenge S ⊆ {1, . . . n} mit ∑ j∈S a j ≤ T und maximiere ∑ j∈S a j .
Betrachten Sie zu diesem Problem den folgenden Algorithmus GA.
Algorithmus GA((A,T))
1 sortiere Zahlen absteigend, sodass a1 ≥ a2 ≥ · · · ≥ an gilt;
2 integer i = 1;
3 integer sum = 0;
4 boolean tooLarge = false;
5 while i ≤ n and tooLarge = false do
6 if sum+ai ≤ T then
7 sum=sum+ai ;
8 i = i + 1;
9 else
10 tooLarge = true;
11 fi
12 od
13 return sum;
a) Geben Sie eine Konstruktionsvorschrift für eine Instanz I an, mit der der Algorithmus GA
beliebig nah an eine Güte von 2 kommt, also A(I) ≈ OPT2 (I) .
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 7 von 12
b) Zeigen Sie, dass der Algorithmus GA eine approximative Güte von 2 hat, also A(I) ≥ OPT2 (I)
gilt.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 8 von 12
Aufgabe 5 KOMPLEXITÄT: ETH (5+5 Punkte)
a) Betrachten Sie nachfolgende Reduktion von 3-SAT auf k-Color:
1. Eliminiere doppelte Klauseln und Variablen, die in keiner Klausel auftauchen
2. Elimiere Klauseln die eine Variable und ihre Negation enthalten (diese sind immer erfüllt)
3. Seien C1 , . . . ,Cm die Klauseln in der SAT Formel
4. Definiere 
V := { xi , x̄i , vi | i ∈ [n] } C j j ∈ [m] {z} ,
sowie

E := {vi , v j }, {vi , x j }, {vi , x̄ j } i ∈ [n], j ∈ [n] \ {i}
{ {xi , x̄i } | i ∈ [n] }

{xi ,C j } i ∈ [n], j ∈ [m], xi ∈ / Cj

{x̄i ,C j } i ∈ [n], j ∈ [m], x̄i ∈ / Cj
{ {vi , z} | i ∈ [n] }

{C j , z} j ∈ [m]
Welche Lower Bounds ergeben sich unter Annahme der ETH for k-Colour aus dieser Re-
duktion in Hinblick auf
(i) die Anzahl der Knoten |V |; sowie
(ii) die Anzahl der Kanten |E|?
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 9 von 12
b) Wir betrachten folgendes Scheduling Problem:
Problem: 2|prec, pi ∈ {1, 2}|Cmax
Eingabe: Eine Menge J von n Jobs, jeder Job J ∈ J hat eine Ausführungszeit pJ ∈ {1, 2}
sowie Präzedenzconstraints in Form eines gerichteten, azyklischem Graphen G = (J , A),
sowie ein ganze Zahl T ≥ 0.
Entscheide: Existiert ein Schedule, d.h. eine Abbildung, die jedem Job eine Startzeit und
eine Maschine zuweist, sodass (a) sich Jobs auf einer Maschine nicht überlappen (b) für alle
Jobs j, k ∈ J mit ( j, k) ∈ A, dass k erst startet nachdem j vollständig abgearbeitet ist und
(c) der Makespan höchstens T ist?
Wir betrachten die folgende Reduktion von k-Clique auf 2|prec, pi ∈ {1, 2}|Cmax .
Seien G = (V, E) und k gegeben. Wir setzen n = 4|V | + 3|E| und erstellen einen Knoten-Job Ji
für alle i ∈ V mit pi = 1. Des Weiteren erstellen wir Kanten-Jobs J{i, j} für jede Kante {i, j} ∈ E
mit p{i, j} = 2. Abschließend erstellen wir noch 3|V | + 2|E| Dummy Jobs. Diese Jobs haben
Ausführungszeit pdummy = 1.
Wir setzen unsere Präzedenzen nach dem folgenden Schema:
1) (Ji , J{i, j} ) für alle i ∈ V, {i, j} ∈ E
2) Präzedenzen innerhalb der Dummy Jobs.
Zuletzt setzen wir den Makespan T = 2|V | + 2|E|.
(i) Geben Sie die Lower Bounds für 2|prec, pi ∈ {1, 2}|Cmax in Hinblick auf n an, die sich
unter der ETH aus dieser Reduktion, basierend auf den Lower Bounds für k-Clique,
ergeben.
(ii) Geben Sie die Lower Bounds für 2|prec, pi ∈ {1, 2}|Cmax in Hinblick auf T an, die sich
unter der ETH aus dieser Reduktion, basierend auf den Lower Bounds für k-Clique,
ergeben.
Hinweis: Ein beispielhafter Schedule ist unten dargestellt. Die Präzedenzen sind im Graphen
durch gerichtete Kanten abgebildet, daher startet J4 erst nach dem Ende von J1 . Nutzen Sie
für diese Aufgabe die bekannten Lower Bounds aus der Präsenzübung. Diese wurden aus der
Reduktion von 3-SAT auf k-Clique hergeleitet. Hierbei ist der Clique Graph zusammenhän-
gend!
J3
J1
J3 J4
J4
J1 J2
J2
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 10 von 12
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 11 von 12
Aufgabe 6 B ONUSAUFGABE (10 Punkte)
Beweisen oder widerlegen Sie folgende Aussage:
Wenn die ETH fehlschlägt gilt P = NP.
Viel Erfolg!
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 12 von 12
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen
11. Oktober 2024
Modulprüfung zur Vorlesung
»Analyse von Algorithmen und Komplexität (Komplexitätsteil)«
SS 2024
Name: Matrikel-Nr.:
Hinweise:
• Bearbeiten Sie alle Aufgaben.
• Sie haben 10 Minuten Einlesezeit. Danach haben Sie 120 Minuten Zeit für die Klausurbearbeitung.
• Erlaubte Hilfsmittel: Ein doppelseitig handschriftlich beschriebenes Blatt Papier, (bunte) Stifte (kein
Rot, kein Grün, kein Bleistift).
• Einsichtnahme: 30.10.2024
Note 4,0 3,7 3,3 3,0 2,7 2,3 2,0 1,7 1,3 1,0
Mindestpunktzahl 17,5 19,5 21,5 23,5 25 27 29 31 33 35
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 1 von 16
Aufgabe 1 ∆T SP1 (6+2+2 Punkte)
Gegeben sei folgender Graph G = (V, E), bei dem die Kantengewichte jeweils an der nach außen
gerichteten Seite der Kante stehen:
a
4 2
3
e b
4 2
4 3
6 5
d c
2
a) Wenden Sie den Algorithmus ∆T SP1 auf den Graphen G beginnend bei a an. Geben Sie dabei
die Ergebnisse jedes Zwischenschrittes des Algorithmus an.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 2 von 16
b) Beschreiben Sie, was der Algorithmus ∆T SP1 berechnet und geben Sie die Bedingungen an,
die an den Graphen gestellt sind, damit der Algorithmus eine korrekte Lösung berechnet.
c) Begründen Sie, warum der Algorithmus ∆T SP1 eine approximative Güte von 2 besitzt.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 3 von 16
Aufgabe 2 KOMPLEXITÄT: VORLESUNGSBEWEIS SAT (10 Punkte)
Beweisen Sie folgende Aussage:
3-SAT ist NP-vollständig. Zeigen Sie dafür SAT ≤ 3-SAT, nehmen Sie also 3-SAT ∈ NP als
gegeben an.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 4 von 16
Aufgabe 3 KOMPLEXITÄT: NP-VOLLSTÄNDIGKEIT (5+5 Punkte)
a) Wir betrachten folgendes Problem:
Problem: Hitchhikers-HamiltonianCycle
Eingabe: Ein ungerichteter Graph G = (V, E) mit V = {1, . . . , |V |} und für alle v ∈ V gilt
deg(v) ≥ 42.
Entscheide: Gibt es einen Hamiltonkreis in G?
Beweisen Sie die NP-Schwere von Hitchhikers-HamiltonianCycle durch Angabe einer
Reduktion eines nach Vorlesung/Übung bekanntermaßen NP-schweren Problems.
Hinweis: Als Hilfe, geben Sie graphisch die Reduktion für Knotengrad ≥ 10 an.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 5 von 16
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 6 von 16
b) Wir betrachten folgendes Problem:
Problem: AtMostTwoPerSize-SubsetSum
Eingabe: Ein ganzzahliger Zielwert T > 0, eine Menge von n Items, jedes Item i ∈ [n]
hat eine Größe ai ∈ N>0 , jede Größe tritt höchstens zwei Mal auf, d.h. für alle i ∈ [n] gilt
| { i ∈ [n] | ai = ai } | ≤ 2.
Entscheide: Gibt es S ⊆ [n] sodass ∑i∈S ai = T ?
Beweisen Sie die NP-Schwere von AtMostTwoPerSize-SubsetSum durch Angabe einer Re-
duktion eines nach Vorlesung/Übung bekanntermaßen NP-schweren Problems.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 7 von 16
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 8 von 16
Aufgabe 4 KOMPLEXITÄT: A PPROXIMATIVE A LGORITHMEN (10+(10) Punkte)
Wir betrachten das aus der Vorlesung bekannte Makespan Scheduling Problem P||Cmax . Dazu ist
folgender Algorithmus gegeben:
Algorithmus ROUND ROBIN S CHEDULING(I=(J,m))
1 sortiere die Jobs in J so, dass p1 ≥ p2 ≥ · · · ≥ pn gilt;
2 setze B1 = · · · = Bm = 0;
/
3 integer j = 1;
4 integer i = 1;
5 while j <= n do
6 Platziere Job J j auf Maschine Mi ;
7 Bi = Bi {J j };
8 j = j + 1;
9 if i < m then
10 i=i+1
11 else
12 i=1
13 fi
14 od
15 return B1 , . . . , Bm
Betrachten Sie folgendes Beispiel zu der Funktionsweise des Round Robin Scheduling Algorith-
mus. Gegeben sind 3 Maschinen und 6 Jobs J1 , . . . J6 , die bereits richtig sortiert sind. Es gilt
p1 = 7, p2 = 5, p3 = 5, p4 = 4, p5 = 3, p6 = 1. Daraus ergibt sich folgender Schedule:
J4
J5
J6
J1
J2 J3
m1 m2 m3
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 9 von 16
a) Zeigen Sie per Widerspruch, dass der Algorithmus Round Robin Scheduling eine approxima-
tive Güte von 2 hat.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 10 von 16
b) BONUS: Geben Sie die Konstruktionsvorschrift für eine Instanz an, mit der der Algorithmus
Round Robin Scheduling beliebig nah an eine Güte von 2 kommt, also A(I) ≈ 2 · OPT (I).
Nutzen Sie dafür mindestens 3 Maschinen und 7 Jobs, womit eine Rate von A(I) = 53 OPT
zu erreichen ist. Geben sie die optimale Makespan an und die, die der Algorithmus bei Ihrer
Instanz erreicht. Für eine Güte von 53 können bis zu 3 Punkten erreicht werden, bei einer
Güte von 47 sind bis zu 5 Punkte zu erreichen. Geben Sie eine Konstruktionsvorschrift an,
bei denen bei einer beliebigen, festen Anzahl von Maschinen m eine Güte von 2 m1 erreicht
wird, können Sie die vollen 10 Punkte erreichen.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 11 von 16
Aufgabe 5 KOMPLEXITÄT: ETH (5+5 Punkte)
a) Wir betrachten folgendes Problem:
Problem: DominatingSet
Eingabe: Ein ungerichteter Graph G = (V, E) mit V = 1, . . . , |V | und eine Ganzzahl k ≥ 1.
Entscheide: Gibt es eine Menge M ⊆ V der Kardinalität |M| = k derart, dass jeder Knoten
v ∈ V entweder in M ist oder zu einem Knoten in M benachbart ist.
Wir untersuchen nun folgende Reduktion von 3-SAT auf DominatingSet:
1. Seien C1 , . . . ,Cm die Klauseln der 3-SAT-Formel
2. Seien x1 , . . . , xn die Variablen der 3-SAT-Formel
3. Erzeuge die Knoten xi , xi und di für jede Variable xi
4. Erzeuge die Kanten {xi , xi }, {xi , di } und {di xi } für jede Variable xi
5. Für jede Klausel C j erzeuge einen Knoten C j
6. Für jedes Literal einer Klausel C j erzeuge die Kanten {C j , }
Welche unteren Schranken für die Laufzeit folgen damit für DominatingSet unter der ETH
in Bezug auf
(i) die Anzahl der Knoten |V |?
(ii) die Anzahl der Kanten |E|?
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 12 von 16
b) Wir betrachten folgendes Problem:
Problem: GridTiling
Eingabe: Zwei ganze Zahlen k und j und für jedes i ∈ [k] und j ∈ [k] eine Menge Si, j ⊆ [n]2 .
Entscheide: Gibt es (ei, j )(i, j)∈[k]2 derart, dass
1. für alle (i, j) ∈ [k]2 gilt ei, j ∈ Si, j ;
2. für alle i ∈ [k] und j ∈ [k 1] gilt für ei, j = (a, b) und ei, j+1 = (a , b ), dass a = a (dh. die
ausgewählten Tupel müssen in der ersten Komponente übereinstimmen, wenn der erste
Index derselbe ist); und
3. für alle i ∈ [k 1] und j ∈ [k] gilt für ei, j = (a, b) und ei+1, j = (a , b ), dass b = b (dh.
die ausgewählten Tupel müssen in der zweiten Komponente übereinstimmen, wenn der
zweite Index derselbe ist)
Betrachten Sie folgende Beispielinstanz für k = 2, die Elemente der Lösung sind unterstrichen:
S1,1 = {(1, 1), (2, 2)} S1,2 = {(1, 2), (2, 1), (2, 2)}
S2,1 = {(1, 2), (2, 1)} S2,2 = {(1, 1), (2, 2)}
Wir untersuchen folgende Reduktion von Clique:
1. Sei G = (V, E) und eine Zahl k als zu untersuchende Clique Instanz gegeben
2. Wir nehmen ohne Beschränkung der Allgemeinheit an, dass V = {1, . . . , |V |} sowie k ≥ 2
gilt und dass keine isolierten Knoten existieren.
3. Wir übernehmen den Wert von k
4. Für jedes Paar (i, j) ∈ [k]2 definieren wir
(
{ (a, a) | a ∈ V } if i = j
Si, j :=
{ (a, b) | a ̸= b, {a, b} ∈ E } if i ̸= j
Welche unteren Schranken für die Laufzeit folgen damit für Grid Tiling (mit der aus der
Vorlesung bekannten Reduktion von Clique auf 3-SAT) in Hinblick auf
(i) der Gesamtanzahl X := ∑(i, j)∈[k]2 |Si, j | der Tupel in den Mengen; sowie
(ii) der maximalen Anzahl Y := max(i, j)∈[k]2 |Si, j | an Tupeln in einer der Mengen?
Hinweis: Aus der Reduktion in der Vorlesung wissen wir, dass Clique selbst dann noch NP-
schwer ist, wenn k ∈ Θ(|V |) gilt. Sie dürfen also annehmen, dass es eine (globale) Konstante
c > 0 gibt, sodass c · n ≤ k ≤ n.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 13 von 16
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 14 von 16
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 15 von 16
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 16 von 16
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen
14. Juli 2023
Modulprüfung zur Vorlesung
»Analyse von Algorithmen und Komplexität (Komplexitätsteil)«
SS 2023
Name: Matrikel-Nr.:
Hinweise:
• Bearbeiten Sie alle Aufgaben.
• Sie haben 10 Minuten Einlesezeit. Danach haben Sie 120 Minuten Zeit für die Klausurbearbeitung.
• Erlaubte Hilfsmittel: Ein doppelseitig handschriftlich beschriebenes Blatt Papier, (bunte) Stifte (kein
Rot, kein Grün, kein Bleistift).
• Einsichtnahme: Nach Absprache.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 1 von 11
Aufgabe 1 RUCKSACKPROBLEM (3+2+5 Punkte)
Wir betrachten die Anwendung der Approximationsheuristiken für das Rucksackproblem aus der
Vorlesung.
Gegeben sei dafür folgende Instanz des Rucksackproblems mit Kapazität B = 16. Items sind in
der Form (pi , wi ) angegeben.
I = [(1, 4), (1, 1), (1, 3), (11, 13), (3, 3), (5, 6), (1, 5), 16]
a) Wenden Sie den normalen Greedy-Algorithmus auf obige Instanz an. Begründen Sie kurz,
warum die gewählten Items ausgewählt werden. Was ist der Lösungswert?
b) Wenden Sie nun den ModifiedGreedy-Algorithmus an. Wie ändert sich die Lösung?
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 2 von 11
c) Was ist die Güte des ModifiedGreedy-Algorithmus? Geben Sie eine kurze Idee an, wie man
diesen Ansatz modifizieren kann, um die Güte auf 32 oder 43 zu verbessern.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 3 von 11
Aufgabe 2 L ONGEST PATH (3+3+4 Punkte)
Betrachten Sie das folgende Problem:
Problem: L ONGEST PATH
Eingabe: Eine ungerichteter Graph G = (V, E) und eine Zahl k.
Entscheide: Gibt es einen Pfad in G, der mindestens Länge k hat?
Zeigen Sie auf verschiedene Weisen, dass das Problem in NP liegt:
a) Geben Sie ein Zertifikat für L ONGEST PATH an.
b) Beschreiben Sie einen Verifizierer für L ONGEST PATH und geben Sie dessen Laufzeit konkret
an.
c) Beschreiben Sie eine nicht-deterministische Turing-Maschine (in Worten), die L ONGEST PATH
löst. Geben Sie auch hier die Laufzeit konkret an.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 4 von 11
Aufgabe 3 A PPROXIMATIVE A LGORITHMEN (6+4 Punkte)
Das Problem M AX -3-S AT sei folgendermaßen definiert:
Problem: M AX -3-S AT
Eingabe: Eine Formel φ in konjunktiver Normalform, wobei jede Klausel drei Literale enthält.
Ausgabe: Eine Belegung β der Variablen, die die Anzahl v(β ) der erfüllten Klauseln maximiert.
Betrachten Sie folgenden Algorithmus A:
• Sei β0 die Belegung, die alle Variablen auf false setzt.
• Sei β1 die Belegung, die alle Variablen auf true setzt.
• Falls v(β0 ) ≥ v(β1 ), gib β0 zurück.
• Sonst gib β1 zurück.
a) Zeigen Sie, dass obiger Algorithmus Güte 2 hat, d.h. A(φ ) ≥ 12 OPT (φ ) gilt für alle Eingaben
φ.
b) Geben Sie eine Formel an, bei der der Algorithmus eine Belegung ausgibt, die genau die Hälfte
der maximal erfüllbaren Klauseln erfüllt. Begründen Sie kurz, warum Ihre Formel geeignet ist.
Hinweis: Sie brauchen nur höchstens zwei Klauseln und sechs Variablen.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 5 von 11
Aufgabe 4 B EWEIS ZUR VORLESUNG (10 Punkte)
Betrachten Sie folgendes Problem aus der Vorlesung:
Problem: k-C LIQUE
Eingabe: Ein ungerichteter Graph G = (V, E) und eine Zahl k ≥ 1. Eine Clique ist eine Teil-
menge C ⊆ V mit {u, v} ∈ E für alle u, v ∈ C mit u ̸= v.
Entscheide: Hat der gegebene Graph G eine Clique C ⊆ V mit mindestens k Knoten (d.h. mit
|C| ≥ k)?
Beweisen Sie: Das Problem k-C LIQUE ist NP-vollständig.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 6 von 11
Aufgabe 5 NP UND NP-VOLLSTÄNDIGKEIT (4+4+7 Punkte)
a) Beweisen Sie die NP-Vollständigkeit von S UBSET S UM, bei der jede Itemgröße jeweils durch
3 oder durch 7 teilbar ist.
b) Beweisen Sie die NP-Vollständigkeit von 3-C OLOR, wobei jeder Knoten im Graph mindes-
tens Grad 3 hat.
c) Zeigen Sie: Für kein α > 1 gibt es einen approximativen Algorithmus mit Güte α (d.h. mit
Zielfunktionswert ≤ α · OPT) für TSP, außer P = NP (Denken Sie an Wiliam Rowan Hamil-
ton).
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 7 von 11
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 8 von 11
Aufgabe 6 U NTERE S CHRANKEN UND ETH (7+8 Punkte)
Betrachten Sie folgende Reduktionen:
Problem: H ITTING S ET
Eingabe: Eine Menge U sowie r Teilmengen F1 , . . . , Fr ⊆ U und eine Zahl k.
Entscheide: Gibt es eine Menge S ⊆ U mit |S| ≤ k und S ∩ Fi ̸= 0/ für alle i ∈ [r]?
a) 3-SAT ⪯ H ITTING S ET: Seien v1 , . . . , vn die Variablen der Formel und C1 , . . . ,Cm die Klau-
seln. Setze U = { v1 , v1 , . . . , vn , vn } und k = n. Für jede Variable vi definiere eine Menge
Fi = {vi , vi } und für jede Klausel C j definiere eine Menge Fn+ j = C j
Welche unteren Schranken ergeben sich durch obige Reduktion für die Laufzeit von Algorith-
men für H ITTING S ET unter Annahme der ETH in Abhängigkeit von
(i) r?
(ii) |U|?
Beweisen Sie die entsprechenden unteren Schranken!
Hinweis: Sie dürfen wie in den Hausaufgaben zur ETH Faktoren, die polynomiell in der
Eingabekodierung sind, vernachlässigen.
b) 3-S AT ⪯ S UBSET S UM: Seien v1 , . . . , vn die Variablen der Formel und C1 , . . . ,Cm die Klauseln.
Für jede Variable vi erzeuge zwei Items ai und bi , mit den Größen
s(ai ) = 10i1 + ∑ 10n+ j1 und s(bi ) = 10i1 + ∑ 10n+ j1 .
j∈[m] j∈[m]
xi ∈C j xi ∈C j
Zusätzlich erzeuge zwei Items c j und d j für jede Klausel C j mit Größen
s(c j ) = s(d j ) = 10n+ j1 .
Der Zielwert sei
B = ∑ 3 · 10n+ j1 + ∑ 10i1 .

j∈[m] i∈[n]
Welche unteren Schranken ergeben sich durch obige Reduktion für die Laufzeit von Algorith-
men für S UBSET S UM unter Annahme der ETH in Abhängigkeit von
(i) der Anzahl der unterschiedlichen Itemgrößen d?
(ii) der binären Kodierungslänge L der größten Itemgröße ∆ (d.h. L = log(∆))?
Beweisen Sie die entsprechenden unteren Schranken!
Hinweis: Sie dürfen auch hier wie in den Hausaufgaben zur ETH Faktoren, die polynomiell
in der Eingabekodierung sind, vernachlässigen.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 9 von 11
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 10 von 11
Viel Erfolg!
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 11 von 11
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen
19. Oktober 2023
Modulprüfung zur Vorlesung
»Analyse von Algorithmen und Komplexität (Komplexitätsteil)«
SS 2023
Name: Matrikel-Nr.:
Hinweise:
• Bearbeiten Sie alle Aufgaben.
• Sie haben 120 Minuten Zeit für die Klausurbearbeitung.
• Erlaubte Hilfsmittel: Ein einseitig handschriftlich beschriebenes Blatt Papier, (bunte) Stifte (kein Rot,
kein Grün, kein Bleistift, kein Tintenkiller, kein Tipp-Ex).
• Schreiben Sie auf jedes Blatt ihren Namen.
• Wenn Sie Schmierzettel verwenden um eine Aufgabe zu bearbeiten, verweisen Sie in der Aufgabe auf
diese.
• Einsichtnahme: 2.11.23, 13:30-14:30 Uhr.
• Die Klausur hat 6 Aufgaben auf 13 Seiten überprüfen Sie bitte vor der Bearbeitung, dass Ihre Klausur
vollständig ist.
Aufgabe 1 C HRISTOFIDES A LGORITHMUS (3+7 Punkte)
Gegeben sei folgender Graph G = (V, E) :
d
2
3
3
a c
1
2
b
a) Geben Sie an, was Christofides Algorithmus berechnet, und welche approximative Güte er
hat. Welche Eigenschaft müssen die Distanzen neben der Symmetrie noch erfüllen, damit
Christofides Algorithmus korrekt arbeitet.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 1 von 19
b) Wenden Sie den Algorithmus von Christofides auf den Graphen G mit Startknoten a an. Ge-
ben Sie dabei alle Graphen an, die in Zwischenschritten entstehen. Erwähnen Sie ebenfalls
Schritte, die bei dieser Anwendung zu keiner Änderung führen, die der Algorithmus aber
überprüfen muss.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 2 von 19
Aufgabe 2 D OMINATING S ET (3+3+4 Punkte)
Betrachten Sie das folgende Problem:
Problem: D OMINATING S ET
Eingabe: Ein ungerichteter Graph G = (V, E) (wobei V = {1, . . . , n} für eine Zahl n ∈ N≥1 )
und eine Zahl k ∈ N0 .
Entscheide: Gibt es eine Teilmenge D ⊆ V der Knoten mit |D| ≤ k, sodass jeder Knoten v ∈ V
in D enthalten ist oder benachbart zu mindestens einem der Knoten in D ist?
Zeigen Sie auf verschiedene Weisen, dass das Problem in NP liegt:
a) Geben Sie ein Zertifikat für D OMINATING S ET an.
b) Beschreiben Sie einen polynomiellen Verifizierer für D OMINATING S ET und schätzen Sie die
Laufzeit in O-Notation konkret ab.
c) Beschreiben Sie (in Worten) eine polynomielle, nicht-deterministische Turing-Maschine, die
D OMINATING S ET löst. Schätzen Sie auch hier die Laufzeit in O-Notation konkret ab.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 3 von 19
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 4 von 19
Aufgabe 3 A PPROXIMATIVE A LGORITHMEN (6+4 Punkte)
Das Problem M IN -E DGE -C OVER sei folgendermaßen definiert:
Problem: M IN -E DGE -C OVER
Eingabe: Ein zusammenhängender, ungerichteter Graph G = (V, E).
Ausgabe: Eine Teilmenge der Kanten C ⊆ E mit minimaler Kardinalität, sodass jeder Knoten
v ∈ V zu mindestens einer Kante aus C inzident ist.
Betrachten Sie folgenden Algorithmus A:
• Gehe (in beliebiger Reihenfolge) alle Knoten durch:
• Falls der aktuelle Knoten v noch nicht abgedeckt ist, wähle zufällig eine der zu v inzidenten
Kanten und füge sie zu C hinzu.
• Gib anschließend die entstehende Menge C zurück.
a) Zeigen Sie, dass obiger Algorithmus Güte 2 hat, d.h. A(G) ≤ 2 · OPT(G) gilt für alle Eingaben
G.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 5 von 19
b) Sei n ∈ N≥4 gerade. Betrachten Sie den Graphen Gn , der genau n Knoten und n Kanten hat und
einen Kreis beschreibt. D.h. Gn = ({1, . . . , n}, {{i, i+1} | i ∈ {1, . . . , n1}}{{n, 1}}). Wie viele
Kanten hat ein M IN -E DGE -C OVER des Graphen Gn ? Wie schlecht ist die Approximationsrate
des Algorithmus A für Gn im schlimmsten Fall? Geben Sie eine Reihenfolge der Knoten (für
Schritt 1) und eine Auswahl der Kanten (für Schritt 2) an, die zu einer möglichst schlechten
Approximationsrate führen.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 6 von 19
Aufgabe 4 B EWEIS S CHEDULING AUF IDENTISCHEN M ASCHINEN (10 Punkte)
Betrachten Sie das Scheduling-Problem P||Cmax :
Problem: P||Cmax
Eingabe: Eine Liste L = (J1 , . . . , Jn ) von n Jobs mit Ausführungszeiten p1 , . . . , pn ∈ N, und m
identische Maschinen.
Ausgabe: Ein Schedule (Partition von J in m Teilmengen B1 , . . . , Bm ) mit minimaler maximaler
Last Cmax := max ∑ p j .
1≤i≤m J ∈B
j i
Betrachten Sie den folgenden Algorithmus ListScheduling, der einen Schedule berechnet. Sei
LS(I) die Last Cmax eines Schedules des Algorithmus, und OPT(I) die Last Cmax eines optimalen
Schedules zur Eingabe I. Zeigen Sie: Für alle Eingaben I = (L, m) gilt LS(I)/OPT(I) ≤ 2 1/m.
Algorithmus L IST S CHEDULING(L = (J1 , . . . , Jn ), m)
1 for i = 1 to m do
2 Ei = 0; Bi = 0/ ;
3 od
4 for j = 1 to n do
5 wähle Job J j aus Liste L;
6 wähle Maschine Mi mit minimaler Last Ei ;
7 Bi = Bi {J j };
8 Ei = Ei + p j ;
9 od
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 7 von 19
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 8 von 19
Aufgabe 5 NP UND NP-VOLLSTÄNDIGKEIT (4+5+6 Punkte)
Problem: H AMILTONIAN PATH
Eingabe: Ein ungerichteter Graph G = (V, E)
Entscheide: Existiert ein Pfad in G, der jeden Knoten genau einmal besucht?
Problem: H AMILTONIAN C YCLE
Eingabe: Ein ungerichteter Graph G = (V, E)
Entscheide: Existiert ein Kreis in G, der jeden Knoten genau einmal besucht?
(a) Sei L ⊆ S UBSET S UM die Menge der (positiven) SubsetSum-Instanzen, bei denen keine der
Itemgrößen eine Zweierpotenz ist. Zeigen Sie, dass L NP-vollständig ist.
(b) Geben Sie eine polynomielle Reduktion von H AMILTONIAN PATH auf H AMILTONIAN C Y-
CLE an.
(c) Geben Sie eine polynomielle Reduktion von H AMILTONIAN C YCLE auf H AMILTONIAN -
PATH an.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 9 von 19
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 10 von 19
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 11 von 19
Aufgabe 6 U NTERE S CHRANKEN UND ETH (5+5 Punkte)
Im Folgenden bezeichne ⟨I⟩ die Kodierungslänge der Instanz.
(a) Wir betrachten folgendes Problem:
Problem: H ITTING S ET
Eingabe: Eine Menge U sowie r Teilmengen F1 , . . . , Fr ⊆ U und eine Zahl k .
Entscheide: Gibt es eine Menge S ⊆ U mit |S | ≤ k und S ∩ Fi ̸= 0/ für alle i ∈ {1, . . . , r }?
Sie dürfen nutzen, dass sich H ITTING S ET unter Annahme der ETH nicht in Zeit 2o(r ) ⟨I⟩O(1)
und nicht in Zeit 2o(|U |) ⟨I⟩O(1) lösen lässt.
Problem: S ET C OVER
Eingabe: Eine Menge U sowie r Teilmengen F1 , . . . , Fr ⊆ U und eine Zahl k.
Entscheide: Gibt es eine Menge S ⊆ {1, . . . , r} mit |S| ≤ k und i∈S Fi = U?
S
Welche unteren Schranken ergeben sich
(i) in Hinblick auf |U| sowie
(ii) in Hinblick auf r
für S ET C OVER unter Annahme der ETH aus den unteren Schranken für H ITTING S ET, wenn
man folgende Reduktion von SetCover auf HittingSet verwendet?
Sei (F ,U, k) eine S ET C OVER-Instanz. Setze V1 := U und V2 := {1, . . . , r}. Sei V := V1 V˙ 2.
Weiter sei E = { {v, w} | v ∈ V1 , w ∈ V2 , v ∈ Fw }. Damit ist G = (V, E) ein bipartiter Graph
mit Partitionen V1 ,V2 . Setze U := {1, . . . , r}. Erzeuge nun eine Menge Fw für jeden Knoten
w ∈ V1 , indem Fw := { v ∈ V2 | {v, w} ∈ E } gesetzt wird. Sei F := { Fw | w ∈ V1 }. Mit k = k
iie berechnete Instanz ist nun durch (F ,U , k ) gegeben.
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 12 von 19
(b) Wir wollen uns mit einem Problem beschäftigen, das ein mächtiges Werkzeug im Bereich
der Optimierung ist: Integrale Lineare Programme (ILPs).
Problem: ILP-F EASIBILITY
Eingabe: Eine Matrix A ∈ ZM×N , eine rechte Seite b ∈ ZM .
Entscheide: Gibt es einen Vektor x ∈ ZN≥0 mit Ax ≤ b, d.h. Ai xi ≤ bi für alle i ∈ {1, . . . , M}?
Welche unteren Schranken ergeben sich
(i) in Hinblick auf M sowie
(ii) im Hinblick auf N
für ILP-F EASIBILITY unter Annahme der ETH, wenn man folgende Reduktion von 3-SAT
auf ILP-F EASIBILITY verwendet?
Sei φ eine 3-SAT Instanz mit m Klauseln (Ci )i∈m und n Variablen. Analog zu linearen Glei-
chungssystemen (Ax = b), die aus M Gleichungen bestehen, haben wir bei Ax ≤ b einen
Satz von M linearen Ungleichungen. Wir konstruieren diese wie folgt: Wir nutzen N := 2n
Variablen in unserem ILP, eine für jedes (mögliche) Literal in der SAT-Formel. Für je-
de SAT-Variable v sei xv die ILP-Variable, die zum SAT-Literal v korrespondiert, und xv̄
die, die zum SAT-Literal v̄ korrespondiert. Für jede Klausel Ci erzeugen wir eine Unglei-
chung ∈Ci x1. Weiter erzeugen wir für jede SAT-Variable v zwei Ungleichungen:
xv +xv̄ ≤ 1 und xv xv̄ ≤ 1. Durch das Eintragen der entsprechenden Koeffizienten in eine
erweiterte Koeffizientenmatrix (bestehend aus Matrix A und rechter Seite b) erhalten wir die
ILP-F EASIBILITY Instanz.
Viel Erfolg!
Klausur »Analyse von Algorithmen und Komplexität (Komplexitätsteil)« Seite 13 von 19

Binary file not shown.

View File

@@ -0,0 +1,480 @@
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
09.06.2025
Präsenzaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 9
Definition 1 (Knapsack (Entscheidungsvariante)). Gegeben ist eine Menge mit n Gegenständen
mit Gewichten w1 , . . . , wn ∈ N≥0 und Profiten p1 , . . . , pn ∈ N≥0 . Weiter sind eine Kapazität
K ∈ N≥0 und ein Zielprofit P ∈ N≥0 gegeben. Bei dem K NAPSACK Problem muss entschieden
werden, ob eine Teilmenge S ⊆ [n] existiert, sodass
∑ wi ≤ K und ∑ pi ≥ P
i∈S i∈S
gilt.
Präsenzaufgabe 9.1 (K NAPSACK in NP)
Zeigen Sie K NAPSACK ∈ NP auf zwei verschiedene Wege.
1. Geben Sie einen nicht deterministischen Algorithmus an, der das Problem in polynomi-
eller Zeit löst.
2. Geben Sie einen polynomiellen Verifizierer für das Problem an.
Wie hängen diese beiden Methoden zusammen?
Lösung. 1. Der Algorithmus arbeitet wie folgt: Für jeden Gegenstand entscheiden wir nicht-
deterministisch, ob er in den Rucksack soll. Anschließend akzeptieren wir, falls die Kapazitäts-
und Profitbedingung erfüllt sind.
Existiert eine valide Rucksackfüllung mit genügend Profit, dann gibt es auch eine Reihe
von nichtdeterministischen Entscheidungen, die diese Füllung findet. Diese wird dann
auch vom Algorithmus akzeptiert.
Der Algorithmus macht polynomiell viele nichtdeterministische Entscheidungen und die
Überprüfung der Eigenschaften ist ebenfalls in Polynomialzeit möglich, also ist dies ein
polynomieller, nichtdeterministischer Algorithmus, der K NAPSACK löst.
2. Unser Zertifikat ist eine Teilmenge S ⊆ [n], die die Auswahl für den Rucksack darstellen
soll. Dies kann zum Beispiel über ein Bit pro Gegenstand realisiert werden. Um dieses
Zertifikat zu verifizieren, berechnen wir ∑i∈S wi und ∑i∈S pi und vergleichen die Werte
mit K und P und akzeptieren entsprechend.
Existiert eine valide Rucksackfüllung mit genügend Profit, dann gibt es auch ein Zertifi-
kat, das diese Füllung beschreibt. Dieses wird dann auch vom Verifizierer akzeptiert.
Das Ausrechnen der Summen und das Überprüfen ist in polynomieller Zeit möglich, also
ist dies ein polynomieller Verifizierer.
In beiden Wegen wird die extra Ressource, die wir zur Verfügung haben, genutzt, um eine
Teilmenge (einen möglichen Rucksack) zu bestimmen und zu überprüfen. In der Vorlesung
wird noch genau gezeigt, dass diese beiden Wege tatsächlich äquivalent sind.
Präsenzaufgabe 9.2 (Transitivität von Polynomialzeitreduktionen)
Zeigen Sie, dass Polynomialzeitreduktionen transitiv sind, d.h., dass für alle Entscheidungspro-
bleme L1 , L2 , L3 ⊆ Σ∗ gilt, dass
L1 ⪯ L2 ∧ L2 ⪯ L3 =⇒ L1 ⪯ L3 .
Lösung. Seien L1 , L2 , L3 Sprachen. Zudem sei R1 ein Algorithmus, der L1 nach L2 in O(na )
reduziert, und R2 ein Algorithmus, der L2 nach L3 in O(nb ) reduziert.
Sei x eine Instanz von L1 der Größe n. Dann benötigt der Aufruf von R1 auf x höchstens O(na )
Zeit.
Sei x die Ausgabe von R1 . Dann hat x eine Größe von höchstens O(na ). Diese Schranke für
die Ausgabe ergibt sich aus der Laufzeit der Reduktion. Der Aufruf von R2 auf x benötigt nun
höchstens O((na )b ) = O(nab ) Zeit. Damit ist die Reduktion von L1 auf L3 in polynomieller Zeit
möglich.
Die Korrektheit ergibt sich aus der Transitivität der Äquivalenz: Sei x die Ausgabe von R2 auf
x , dann gilt
x ∈ L1 ⇐⇒ x ∈ L2 und x ∈ L2 ⇐⇒ x ∈ L3 ,
also auch x ∈ L1 ⇐⇒ x ∈ L3 .
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
16.06.2025
Präsenzaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 10
Präsenzaufgabe 10.1 (Fragen über Fragen)
Diskutieren Sie die folgenden Aussagen (Gelten sie allgemein? Gelten sie nicht? Gelten sie
unter bestimmten Bedingungen? Welche?):
(i) Für jede Sprache, die von einer NDTM in polynomieller Zeit akzeptiert werden kann,
existiert eine DTM, die ebenfalls die Sprache in polynomieller Zeit akzeptiert.
(ii) A ist NP-schwer =⇒ A ∈ P
Lösung. (i) Die Aussage gilt nur, wenn P = NP. Dann liegen alle Probleme in NP (von
NDTM in polynomieller Zeit lösbar) auch in P (von DTM in polynomieller Zeit lösbar).
Falls P ̸= NP, dann nein, weil sonst folgender Widerspruch auftritt: ein Problem in NP \ P
ist von einer NDTM, nicht aber von einer DTM in polynomieller Zeit lösbar. Könnte eine
DTM die NDTM in polynomieller Zeit simulieren, wäre das Problem auch in P.
(ii) Falsch. Es gibt NP-schwere Probleme, die nicht in NP liegen, z.B. das H ALTE-Problem.
Diese liegen folglich auch definitiv nicht in P. NP-schwer ist eine untere Schranke, ∈ NP
eine obere, und wenn beide erfüllt sind, ist ein Problem NP-vollständig.
Definition 1 (Vertex Cover (VC)). Für einen (ungerichteten) Graphen G = (V, E) ist ein Vertex
Cover eine Menge von Knoten C ⊆ V , sodass u ∈ C oder v ∈ C für alle { u, v } ∈ E gilt, also ist
für alle Kanten mindestens ein Endpunkt in C.
Für das V ERTEX C OVER Problem ist neben einem Graphen G eine Zahl k ∈ N≥0 gegeben und
es wird gefragt, ob ein Vertex Cover mit Größe (Anzahl der Knoten) höchstens k in G existiert.
Präsenzaufgabe 10.2 (V ERTEX C OVER ist NP-vollständig)
Zeigen Sie, dass V ERTEX C OVER NP-vollständig ist.
Hinweis: Reduzieren Sie C LIQUE auf V ERTEX C OVER.
Lösung. V ERTEX C OVER ∈ NP ist bekannt aus der letzten Hausaufgabe.
Vorüberlegung zur Reduktion von C LIQUE auf V ERTEX C OVER: Sei eine Instanz mit G =
(V, E) und k ∈ N≥0 von C LIQUE gegeben. Wir invertieren zunächst den Graphen G und erhal-
ten damit G . Nun enthält G genau dann eine unabhängige Menge der Größe , wenn G eine
Clique der Größe enthält. Wenn ein Graph mit n Knoten eine unabhängige Menge mit min-
destens k Knoten hat, dann hat der Graph auch ein Vertex Cover mit maximal n k Knoten
(das Komplement zur unabhängigen Menge). Unsere Instanz für V ERTEX C OVER ist also G
und n k. (k ≤ n können wir annehmen)
Betrachte nun folgende Reduktion:
Sei eine Instanz mit G = (V, E) und k ∈ N≥0 von C LIQUE gegeben. Invertiere den Graphen G
und erhalte damit G . Gebe nun G und n k als Instanz von V ERTEX C OVER zurück.
Korrektheit:
⇒ (Falls (G, k) eine Ja-Instanz von C LIQUE ist, dann ist (G , n k) eine Ja-Instanz von V ER -
TEX C OVER .):
G enthalte eine Clique C der Größe ≥ k. Dann ist V := V \C ein Vertex Cover von G der Größe
≤ n k. Da |C| ≥ k, gilt |V | ≤ n k. Da C eine Clique ist, also alle Knoten aus C mit allen
anderen Knoten aus C verbunden sind, gibt es im invertierten Graphen G keine Kante zwischen
Knoten aus C. Also gilt für jede Kante {u, v} ∈ E , dass u ∈ / C und somit u ∈ V oder
/ C oder v ∈
v ∈ V .
⇐ (Falls (G , n k) eine Ja-Instanz von V ERTEX C OVER ist, dann ist (G, k) eine Ja-Instanz von
C LIQUE.):
G enthalte ein Vertex Cover V der Größe ≤ nk. Dann ist C := V \V eine Clique der Größe ≥
k in G. Da |V | ≤ n k, gilt |C| ≥ k. Für jede Menge {u, v} ⊆ C gilt, dass {u, v} ∈
/ E . Ansonsten
wäre V kein korrektes Vertex Cover. Da G der invertierte Graph von G ist, gilt somit {u, v} ∈ E
für jede Menge {u, v} ⊆ C.
Laufzeit: Das Invertieren des Graphen kann naiv in O(|V |2 · |E|) Zeit, also in polynomieller
Zeit, erledigt werden.
Also existiert eine polynomielle Reduktion von C LIQUE auf V ERTEX C OVER. Da C LIQUE
NP-vollständig ist und V ERTEX C OVER ∈ NP gilt, ist somit V ERTEX C OVER NP-vollständig.
Präsenzaufgabe 10.3 (Turingmaschinen)
n
Entwerfen Sie eine Turingmaschine für die Sprache L = { 02 | n ∈ N } über dem Alphabet
Σ = {0} und geben Sie die Laufzeit Ihrer Turingmaschine an. Begründen Sie die Korrektheit
und die Laufzeit Ihrer Turingmaschine. Diskutieren Sie die Laufzeit Ihrer Turingmaschine im
Vergleich zu einem Algorithmus (mit RAM) für diese Sprache.
Lösung. Die Turingmaschine sieht folgendermaßen aus:
(1) Falls genau eine 0 auf dem Band steht, akzeptiere.
(2) Bewege den Kopf von links nach rechts über die Eingabe und ersetze jede zweite 0 durch
ein neues Symbol x.
(3) Falls das letzte Symbol der Eingabe nun eine 0 ist, verwerfe.
(4) Gehe zu Schritt (1).
Korrektheit: Die Sprache L besteht aus allen Wörtern, die nur Nullen enthalten und deren Länge
eine Zweierpotenz ist. Eine Zahl ist genau dann eine Zweierpotenz, wenn sie nach wiederholtem
Teilen durch 2 irgendwann eine 1 ergibt. Genau das überprüft die Turingmaschine. Wenn bei
diesem wiederholten Teilen eine ungerade Zahl auftritt, ist die Zahl keine Zweierpotenz. In
diesem Fall verwirft die Turingmaschine die Eingabe (siehe Schritt (3)).
Laufzeit: Die angegebene Turingmaschine hat eine Laufzeit von O(n log(n)), wobei n hier die
Länge der Eingabe bezeichnet. Schritt (1) und Schritt (2) benötigen jeweils eine Laufzeit von
O(n). Schritt (3) geht in konstanter Laufzeit O(1). Schritt (4) wiederholt die Schritte (1) bis (3)
bis nur noch eine 0 auf dem Band steht oder vorher abgebrochen wird. Da in jedem Durchlauf
der Schritte (1) bis (3) die Hälfte der Nullen (abgerundet) durch x Symbole ersetzt wird, steht
nach log n Durchläufen nur noch eine Null auf dem Band und es wird nach Schritt (1) akzeptiert
oder es steht nach ⌊log n⌋ 1 Durchläufen eine ungerade Anzahl von Nullen auf dem Band und
es wird nach Schritt (3) verworfen. Also gibt es maximal log n + 1 Durchläufe.
Diskussion: Ein Algorithmus mit RAM könnte folgendermaßen aussehen:
1. Zähle die Buchstaben und erhalte Anzahl m.
2. Falls log m ganzzahlig ist, akzeptiere. Sonst verwerfe.
Dieser Algorithmus hat eine Laufzeit von O(n), wobei n hier die Länge der Eingabe bezeichnet.
Ein Algorithmus mit RAM kann also den zusätzlichen Speicher nutzen, um wesentlich schneller
eine Aufgabe zu erledigen, im Vergleich zu einem Algorithmus, der auf einer Turingmaschine
läuft.
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
23.06.2025
Präsenzaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 11
Präsenzaufgabe 11.1 (Fragen über Fragen)
Diskutieren Sie nachfolgende Aussagen. Sind diese wahr oder falsch?
(a) Für L ∈ NP gilt, aus L ⪯ 3-SAT folgt, dass L NP-vollständig ist.
(b) Gilt für eine Sprache L, dass sowohl L ⪯ 3-SAT als auch 3-SAT ⪯ L, dann ist L NP-vollständig.
(c) Sei L NP-vollständig. Dann gilt L ∈ P genau dann, wenn P = NP.
(d) Es ist möglich, dass 3-SAT ∈ P und C LIQUE ∈
/ P.
Lösung.
/ Offensichtlich gilt L ∈ NP. Aus L ⪯ 3-SAT folgt nur,
(a) Nein, ein Gegenbeispiel ist L = 0.
dass sich L auf 3-SAT reduzieren lässt, nicht anders herum.
(b) Das ist die Definition von NP-vollständig.
(c) Korrekt, da sich jedes Problem auf L reduzieren lässt nach Def. NP-vollständig (und offen-
sichtlich P ⊆ NP).
(d) Nein, weil 3-SAT NP-vollständig ist, lässt sich C LIQUE (liegt bekannterweise in NP, ist
sogar NP-vollständig) auf 3-SAT reduzieren.
Präsenzaufgabe 11.2 (NP-Vollständigkeit)
In dem Problem C LIQUE -N OMEMBER ist ein Graph G = (V, E), ein Knoten v ∈ V sowie eine
Zahl k ∈ N gegeben und es soll entschieden werden, ob es eine Clique mit k Knoten gibt, die
den Knoten v nicht enthält.
Zeigen Sie, dass C LIQUE -N OMEMBER NP-vollständig ist, indem Sie eine Reduktion von C LI -
QUE auf C LIQUE -N OMEMBER angeben. Sie können davon ausgehen, dass C LIQUE -N OMEMBER ∈
NP ist.
Lösung. Clique-Nomember ist NP-schwer:
Sei (G = (V, E), k) eine Eingabe für das Clique Problem.
Idee: Füge einen neuen isolierten Knoten v zu G hinzu.
Wir geben zuerst die Abbildung an: Sei v ̸∈ V . Wir definieren die Eingabe für das Problem
C LIQUE -N OMEMBER als den Graphen G := (V {v}, E), den Knoten v als Knoten, der nicht
benutzt werden darf, und k als gesuchte Cliquengröße. (G , v, k) ist eine gültige Eingabe für
C LIQUE -N OMEMBER und in polynomieller Zeit berechenbar.
Wir zeigen nun: G hat eine k-Clique genau dann, wenn G eine k-Clique ohne v beinhaltet.
⇒:
Sei (G, k) eine Ja-Instanz des C LIQUE Problems. Dann enthält G eine k-Clique C. Dann ist C
auch eine k-Clique in G , da bei der Abbildung keine Kanten entfernt wurden. Da v ̸∈ V , enthält
C den Knoten v nicht. Damit ist C eine k-Clique in G ohne den Knoten v. (G , v, k) ist also eine
Ja-Instanz des C LIQUE -N OMEMBER Problems.
⇐:
Sei (G , v, k) eine Ja-Instanz des C LIQUE -N OMEMBER Problems. Dann enthält G eine k-Clique
C mit v ̸∈ C. Da bei der Abbildung an dem Graphen nichts geändert wurde, außer der Knoten v
hinzugefügt, muss C auch eine k-Clique in G sein. Damit ist (G, k) eine Ja-Instanz des C LIQUE
Problems.
Also existiert eine polynomielle Reduktion von C LIQUE auf C LIQUE -N OMEMBER. Da C LI -
QUE NP-vollständig ist und C LIQUE -N OMEMBER ∈ NP nach Aufgabenstellung gilt, ist somit
C LIQUE -N OMEMBER NP-vollständig.
Präsenzaufgabe 11.3 (NP-Vollständigkeit)
Für das Problem S UBSET S UM C ARDINALITY seien n ganze Zahlen c1 , . . . , cn ∈ N>0 (wobei n
gerade sei) sowie eine Zahl K ∈ N gegeben. Es soll entschieden werden, ob es eine Teilmenge
S ⊂ {1, . . . , n} gibt mit |S| = n/2 und ∑i∈S ci = K.
Zeigen Sie, dass das Problem S UBSET S UM C ARDINALITY NP-vollständig ist. Sie können
davon ausgehen, dass S UBSET S UM C ARDINALITY ∈ NP ist.
Lösung. Subset Sum Cardinality ist NP-schwer:
S UBSET S UM Problem: Gegeben: n ganze Zahlen c1 , . . . , cn ∈ N>0 und Zahl K ∈ N. Frage: Gibt
es eine Teilmenge S ⊆ {0, . . . , n} mit ∑i∈S ci = K?
Reduktion: Sei I = (c1 , . . . , cn , K) eine Eingabe für das S UBSET S UM Problem. Definiere ci :=
ci + 1 für i ≤ n und ci := 1 für i ∈ {n + 1, . . . , 2n}. Wir definieren die Eingabe für das Problem
S UBSET S UM C ARDINALITY als I = (c1 , . . . , c2n , K + n).
Wir zeigen nun: Es gibt eine Lösung für I genau dann, wenn es eine Lösung für I gibt.
⇒:
Sei I eine Ja-Instanz des S UBSET S UM Problems. Dann gibt es eine Menge S ⊆ {1, . . . , n} mit
∑i∈S ci = K. Es gilt also ∑i∈S ci = ∑i∈S (ci + 1) = K + |S|. Sei nun S = {n + 1, . . . , 2n |S|}. Es
gilt |S S | = n und ∑i∈SS ci = ∑i∈S ci + ∑i∈S ci = ∑i∈S (ci + 1) + ∑i∈S 1 = K + |S| + (n |S|) =
K + n. S S ist also eine Lösung für I und I damit eine Ja-Instanz.
⇐:
Es sei I eine Ja-Instanz. Dann gibt es also eine Menge S ⊆ {1, . . . , 2n} mit ∑i∈S ci = K + n und
|S | = n. Sei S := S ∩{1, . . . , n}. Es gilt ∑i∈S ci ∑i∈S ci = n|S|, da die Items in {n+1, . . . , 2n}
das Gewicht 1 haben, und genau n |S| Items übrig sind. Damit gilt ∑i∈S (ci + 1) = ∑i∈S ci =
K + n (n |S|) = K + |S|, woraus folgt, dass ∑i∈S ci = K. Damit ist S eine Lösung für I und
somit I eine Ja-Instanz.
Laufzeit: Die Reduktion kann naiv in einer Zeit von O(n) implementiert werden. Das ist eine
polynomielle Laufzeit.
Also existiert eine polynomielle Reduktion von S UBSET S UM auf S UBSET S UM C ARDINALI -
TY . Da nach Skript S UBSET S UM NP-vollständig ist und S UBSET S UM C ARDINALITY ∈ NP
nach Aufgabenstellung gilt, ist somit S UBSET S UM C ARDINALITY NP-vollständig.
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
30.06.2025
Präsenzaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 12
Präsenzaufgabe 12.1
Im Folgenden sollen Sie herausfinden (und begründen), welche Lower Bounds sich über ETH
und die Reduktionen aus der Vorlesung ergeben. Nutzen Sie hierfür auch das Sparsification
Lemma.
Welche Schranken für die Laufzeit in Abhängigkeit von den natürlichen Parametern (Anzahl
Knoten, Anzahl Kanten, Anzahl Items, Anzahl unterschiedlicher Items, Anzahl Tripel, Kardi-
nalität der Grundmenge, Anzahl unterschiedlicher Tripel, Anzahl unterschiedlicher auftretender
Zahlen, größte auftretende Zahl, . . . ) ergeben sich jeweils aus folgenden (zum Großteil aus der
Vorlesung bekannten) Reduktionen (Laufzeitfaktoren, die polynomiell in der Eingabekodierung
sind, dürfen vernachlässigt werden)?
Schätzen Sie dazu zunächst die verschiedenen Parameter der resultierenden Instanz mithilfe der
Parameter der eingegebenen Instanz geeignet ab.
1. 3-SAT ⪯ k-C LIQUE
2. k-C LIQUE ⪯ k-I NDEPENDENT S ET (Problemdefinition für die Antwort nicht relevant; in
der Reduktion wird der Graph G = (V, E) auf den Komplementgraph (V, E) abgebildet)
3. SAT ⪯ 3-D IMENSIONAL M ATCHING (Hinweis: 3-SAT ⊆ SAT)
4. 3-D IMENSIONAL M ATCHING ⪯ 3-E XACT C OVER
5. 3-E XACT C OVER ⪯ S UBSET S UM
Lösung. Angenommen ETH gilt. Das Sparsification Lemma impliziert, dass man 3-SAT nicht
in 2o(m) · |I|O(1) lösen kann.
1. In der Reduktion werden |V | = O(m) Knoten und |E| = O(m2 ) Kanten erstellt und k = m.
Außerdem gilt n ≤ 3m ∈ O(m).
• Lower bound bzgl. der Anzahl an Knoten: 2o(|V |) · |I|O(1)
Angenommen, es existiert ein Algorithmus, der k-Clique in 2o(|V |) ·|I|O(1) löst. Dann
gibt es auch einen Algorithmus, der 3-SAT in 2o(m) · |I|O(1) löst (Reduktion auf k-
Clique + k-Cliquen Algorithmus). Nach dem Sparsification Lemma gibt es dies nur,
wenn die ETH nicht gilt.
• Lower bound bzgl. der Anzahl an Kanten: 2o( |E|) · |I|O(1) √
Angenommen, es existiert ein Algorithmus, der k-Clique in 2o( |E|) · |I|O(1) löst.
Da |E| ∈ O(m2 ), gibt es dann auch einen Algorithmus, der 3-SAT in 2o(m) · |I|O(1)
löst (Reduktion auf k-Clique + k-Cliquen Algorithmus). Nach dem Sparsification
Lemma gibt es dies nur, wenn die ETH nicht gilt.
• Lower bound bzgl. k: 2o(k) · |I|O(1)
Angenommen, es existiert ein Algorithmus, der k-Clique in 2o(k) · |I|O(1) löst. Dann
gibt es auch einen Algorithmus, der 3-SAT in 2o(m) · |I|O(1) löst (Reduktion auf k-
Clique + k-Cliquen Algorithmus). Nach dem Sparsification Lemma gibt es dies nur,
wenn die ETH nicht gilt.
2. In der Reduktion werden genau |V | Knoten und maximal |E| = O(|V |2 ) Kanten erstellt.
• Lower bound bzgl. der Anzahl an Knoten: 2o(|V |) · |I|O(1)
Angenommen, es existiert ein Algorithmus, der k-Independent-Set in 2o(|V |) · |I|O(1)
löst. Dann gibt es auch einen Algorithmus, der k-Clique in 2o(|V |) · |I|O(1) löst (Re-
duktion auf k-Independent-Set + k-Independent-Set Algorithmus). Nach Aufgaben-
teil 1, gibt es diesen nur, wenn die ETH nicht gilt.
o( |E|)
• Lower bound bzgl. der Anzahl an Kanten: 2 · |I|O(1) √
Angenommen, es existiert ein Algorithmus, der k-Independen-Set in 2o( |E|) ·|I|O(1)
löst. Da |E| ≤ |V |2 , gibt es dann auch einen Algorithmus, der k-Clique in 2o(|V |) ·
|I|O(1) löst (Reduktion auf k-Independent-Set + k-Independent-Set Algorithmus).
Nach Aufgabenteil 1, gibt es diesen nur, wenn die ETH nicht gilt.
3. In der Reduktion werden Mengen mit |U| = |V | = |W | = O(mn) Elementen erstellt und
|T | = O(m2 n2 ) Tupel. Es gilt n ≤ 3m ∈ O(m) für 3-SAT.
• Lower bound bzgl. der Anzahl an Elementen: 2o( |V |) · |I|O(1) √
Angenommen, es existiert ein Algorithmus, der 3-Dimensional-Matching in 2o( |V |) ·
|I|O(1) löst. Da |V | ∈ O(mn) ≤ O(m2 ), gibt es dann auch einen Algorithmus, der
3-SAT in 2o(m) · |I|O(1) löst (Reduktion von SAT auf 3-Dimensional-Matching an-
gewandt auf 3-SAT Instanzen + 3-Dimensional-Matching Algorithmus). Nach dem
Sparsification Lemma geht dies nur, wenn die ETH nicht gilt.
4
• Lower bound bzgl. der Kardinalität von T : 2o( |T |) · |I|O(1) √
4
Angenommen, es existiert ein Algorithmus, der 3-Dimensional-Matching in 2o( |T |) ·
|I|O(1) löst. Da |T | ∈ O(m2 n2 ) ≤ O(m4 ), gibt es dann auch einen Algorithmus, der
3-SAT in 2o(m) · |I|O(1) löst (Reduktion von SAT auf 3-Dimensional-Matching an-
gewandt auf 3-SAT Instanzen + 3-Dimensional-Matching Algorithmus). Nach dem
Sparsification Lemma geht dies nur, wenn die ETH nicht gilt.
4. Das 3-dimensionale Matching ist ein Spezialfall vom 3-Exact Cover. Daher gelten die
Lower Bounds von 3-dimensionalem Matching auch für 3-Exact Cover. Da |U| = 3m ∈
O(|V |), ergibt sich, dass es für 3-Exact Cover unter der ETH keinen Algorithmus √ mit
o( m) O(1) o( |V |)
Laufzeit 2 · |I| geben kann, da sonst 3-dimensionales Matching in 2 ·
|I|O(1) lösbar wäre. Und da |F| = |T |, √ ergibt sich, dass es für 3-Exact Cover unter der ETH
o( 4 |F|)
keinen Algorithmus
√ mit Laufzeit 2 · |I|O(1) geben kann, da sonst 3-dimensionales
4
Matching in 2o( |T |) · |I|O(1) lösbar wäre.
4
5. In der Reduktion wird n = |F| gesetzt. Lower bound bzgl. n: 2o( n)√· |I|O(1)
4
Angenommen, es existiert ein Algorithmus, der SubsetSum in 2o( n) · |I|O(1) löst. Dann
4
|F|)
gibt es auch einen Algorithmus, der 3-Exact Cover in 2o( · |I|O(1) löst. Nach Aufga-
benteil 4, gibt es diesen nur, wenn die ETH nicht gilt.
CHRISTIAN-ALBRECHTS-UNIVERSITÄT ZU KIEL
Institut für Informatik, Arbeitsgruppe Algorithmen und Komplexität
Prof. Dr. K. Jansen, B. Schumacher, C. Wambsganz
07.07.2025
Präsenzaufgaben zur Vorlesung »Analyse von Algorithmen und
Komplexität«
Blatt 13
Präsenzaufgabe 13.1 (Vertex Cover)
Ein Vertex Cover in einem Graphen G = (V, E) ist eine Menge von Knoten C ⊆ V , so dass für
jede Kante {v, w} ∈ E gilt, dass v ∈ C oder w ∈ C. Beim Optimierungsproblem Minimum Vertex
Cover soll die kardinalitätskleinste Menge C ⊆ V gefunden werden, die ein Vertex Cover von
G ist.
Gegeben ist der folgende approximative Algorithmus mit Güte 2 für VertexCover:
Idee: Wähle eine beliebige Kante. Wenn einer der beiden Endknoten bereits in C ist, verwirf
diese Kante. Sonst, füge beide Endknoten zur Menge C hinzu. Mache dies für jede Kante.
Algorithmus 2A PPROX CV(G = (V, E))
1 C = {}
2 foreach {u, v} ∈ E do
3 if u ̸∈ C and v ̸∈ C then
4 C = C {u, v}
5 fi
6 od
7 return C
Beweisen Sie die Güte.
Lösung. Beweis: Sei C ein minimales Vertex Cover. Wir zeigen |C| ≤ 2|C |.
Sei A die Menge der Kanten, für die beide Endknoten zu C hinzugefügt wurden. Es gilt |C| =
2|A|, da beide Knoten jeder ausgewählten Kante zu C hinzugefügt wurden und alle anderen
Kanten nicht weiter betrachtet werden. Damit folgt auch, dass keine zwei Kanten aus A einen
Knoten gemeinsam haben können. Sei nun C ein minimales Vertex Cover. C enthält nach
Definition mindestens einen Knoten jeder Kante, also insbesondere einen Knoten jeder Kante
aus A. Da keine zwei Kanten aus A vom gleichen Knoten aus C überdeckt werden können, gilt
|C | ≥ |A|. Es folgt |C| = 2|A| ≤ 2|C |. Die Lösung C von 2ApproxCV ist also maximal doppelt
so groß wie die optimale Lösung C . Damit berechnet der Algorithmus eine 2-Approximation.
Präsenzaufgabe 13.2 (TSP)
In der Vorlesung haben Sie zwei approximative Algorithmen für das TSP-Problem kennen ge-
lernt. Der erste Algorithmus ∆T SP1 hat eine Approximationsrate von 2, während der zweite
Algorithmus ∆T SP2 von Christofides eine Approximationsrate von 3/2 besitzt. In dieser Übung
soll gezeigt werden, dass die zweite Rate scharf ist. D.h., dass es eine Folge von Instanzen gibt,
auf denen der Algorithmus immer näher an diese Rate heran kommt.
Wir betrachten den vollständigen Graphen Kn = (V, E) für ein n ∈ N≥6 mit n mod 4 = 2 und
die nachfolgende Gewichtsfunktion d2 : E → R+ . Zeigen Sie, dass
(a) OPT((Kn , d2 )) = n gilt und
(b) eine mögliche Ausführung von ∆TSP2 existiert, die auf Eingabe (Kn , d2 ) eine Tour der
Länge (n 1) + n/2 berechnet.
1 1 1 1
1 3 5 7 9 n1
1 1 1 1 1 1
1 1 1 1
2 4 6 8 10 n
Wir definieren E2 := {{i, i + 2}|i ∈ {1, . . . , n 2}} {{2i + 1, 2i + 2}|i ∈ {0, . . . , n/2 1}} und
d2 , so dass alle Kanten aus E2 auf 1 abgebildet werden und alle Kanten aus E \ E2 auf den Wert
des kürzesten Wegs zwischen diesen Knoten in dem oben abgebildeten Graphen abgebildet
werden.
Lösung. Wichtig bei dieser Aufgabe ist der folgende Fakt: Bei beiden Algorithmen wird ir-
gendein MST genommen und dann irgendeine Reihenfolge der Knoten. Typischerweise wird
diese Reihenfolge durch bestimmte Knoten- oder Kanten-Labels festgelegt (wird zum Beispiel
der Kruskal-Algorithmus zur Konstruktion des MST genutzt, so werden dort die Kanten nach
Gewicht sortiert. Kanten gleichen Gewichts müssen also auch noch durch irgendeine Reihen-
folge festgelegt werden.) Wir gehen also davon aus, dass wir diese Reihenfolge auch wählen
können. Sollte der Algorithmus also einen “besseren” MST oder eine “bessere” Knotenreihen-
folge nutzen, passen wir die Labels dementsprechend an.
Ein möglicher MST ist durch die unten angegebene Zick-Zack-Tour gegeben oder formal durch
h [ i
ET = {{ j, j + 1}, { j + 1, j + 3}, { j + 3, j + 2}, { j + 2, j + 4}}} {{n 1, n}}.
1≤ j≤n5
j mod 4=1
1 1 1 1
1 3 5 7 n3 n1
1 1 1 1 1 1
1 1 1 1
2 4 6 8 n2 n
Es gilt d(T ) = n 1 für die Kosten d(T ) des MST T , da nur Kanten mit Kosten 1 gewählt
werden und n 1 Kanten gewählt werden müssen, um den Zusammenhang sicher zu stellen.
Da jeder Knoten im MST außer 1 und n geraden Grad hat, ist das Matching K sehr simpel,
nämlich K = {{1, n}}. Die Kosten der Kante {1, n} sind n/2 (der kürzeste Pfad von 1 zu n)
und somit gilt d(K) = n/2 für die Kosten von K. Die Rundreise R entspricht einfach dem MST
vereinigt mit der Matchingkante und hat somit Kosten: d(R) = n 1 + n/2.
Die optimale Tour würde erst “oben” und dann “unten” entlang laufen, also von Knoten 1 zu
Knoten 3 gehen, dann zu Knoten 5 und so weiter, bis Knoten n 1 erreicht wurde. Danach
folgen Knoten n, n 2, n 4 und so weiter. Diese Tour hat offensichtlich Kosten n, da wir n
Kanten mit Gewicht 1 nutzen. Somit gilt OPT((Kn , d2 )) = n und wir haben eine Rate von
∆T SP2 ((Kn , d2 )) n 1 + n/2 1
= = 3/2 ≤ 3/2.
OPT((Kn , d2 )) n n
Da limn→∞ 3/2 n1 = 3/2, kommen wir der Rate von 3/2 also beliebig nahe.