Orivel Orivel
Menue oeffnen

Implementieren Sie einen auf Abhängigkeiten basierenden Aufgabenplaner in Python

Vergleiche Modellantworten für diese Programmierung-Benchmark-Aufgabe und prüfe Scores, Kommentare und verwandte Beispiele.

Bitte einloggen oder registrieren, um Likes und Favoriten zu nutzen. Registrieren

X f L

Inhalt

Aufgabenubersicht

Vergleichsgenres

Programmierung

Aufgaben-Erstellermodell

Antwortende Modelle

Bewertungsmodelle

Aufgabenstellung

Schreiben Sie eine Python-Funktion oder -Klasse, die eine Liste von Aufgaben basierend auf ihren Abhängigkeiten plant. Der Scheduler soll die Reihenfolge bestimmen, in der Aufgaben ausgeführt werden können, und Aufgaben gruppieren, die parallel ausgeführt werden können. Die Eingabe ist eine Liste von Dictionaries, wobei jedes Dictionary eine Aufgabe mit den folgenden Schlüsseln repräsentiert: - `id`: Eine eindeutige Zeichenfolgenkennung für die Aufgabe. - `name`: Ein String-Name für die Aufgabe. - `dependencies`:...

Mehr anzeigen

Schreiben Sie eine Python-Funktion oder -Klasse, die eine Liste von Aufgaben basierend auf ihren Abhängigkeiten plant. Der Scheduler soll die Reihenfolge bestimmen, in der Aufgaben ausgeführt werden können, und Aufgaben gruppieren, die parallel ausgeführt werden können. Die Eingabe ist eine Liste von Dictionaries, wobei jedes Dictionary eine Aufgabe mit den folgenden Schlüsseln repräsentiert: - `id`: Eine eindeutige Zeichenfolgenkennung für die Aufgabe. - `name`: Ein String-Name für die Aufgabe. - `dependencies`: Eine Liste von String-IDs von Aufgaben, die abgeschlossen sein müssen, bevor diese Aufgabe starten kann. Ihre Implementierung sollte: 1. Die Liste der Aufgaben-Dictionaries als Eingabe entgegennehmen. 2. Einen gültigen Ausführungsplan als Liste von Listen zurückgeben. Jede innere Liste stellt einen 'Batch' von Aufgaben dar, die gleichzeitig ausgeführt werden können. Die Reihenfolge der Batches repräsentiert die sequentielle Ausführungsreihenfolge. Die Reihenfolge der Aufgaben-IDs innerhalb eines Batches spielt keine Rolle. 3. Zirkuläre Abhängigkeiten erkennen und behandeln. Wenn ein Zyklus gefunden wird, sollte ein `ValueError` mit einer beschreibenden Nachricht ausgelöst werden. 4. Fälle erkennen und behandeln, in denen eine Abhängigkeits-ID keiner vorhandenen Aufgabe entspricht. Dies sollte ebenfalls einen `ValueError` auslösen.

Erganzende Informationen

Hier ein Beispiel für die Eingabedatenstruktur: ```python tasks = [ {'id': 'A', 'name': 'Datenaufnahme', 'dependencies': []}, {'id': 'B', 'name': 'Datenbereinigung', 'dependencies': ['A']}, {'id': 'C', 'name': 'Feature-Engineering', 'dependencies': ['A']}, {'id': 'D', 'name': 'Modelltraining', 'dependencies': ['B', 'C']}, {'id': 'E', 'name': 'Protokollierung einrichten', 'dependencies': []}, {'id': 'F', 'name': 'Modellbereitstellung', 'dependencies': ['D']}, ] ``` Eine gültige Ausgabe für di...

Mehr anzeigen

Hier ein Beispiel für die Eingabedatenstruktur: ```python tasks = [ {'id': 'A', 'name': 'Datenaufnahme', 'dependencies': []}, {'id': 'B', 'name': 'Datenbereinigung', 'dependencies': ['A']}, {'id': 'C', 'name': 'Feature-Engineering', 'dependencies': ['A']}, {'id': 'D', 'name': 'Modelltraining', 'dependencies': ['B', 'C']}, {'id': 'E', 'name': 'Protokollierung einrichten', 'dependencies': []}, {'id': 'F', 'name': 'Modellbereitstellung', 'dependencies': ['D']}, ] ``` Eine gültige Ausgabe für diese Eingabe wäre: `[['A', 'E'], ['B', 'C'], ['D'], ['F']]` Ein weiteres Beispiel mit anderer Struktur: ```python tasks = [ {'id': 'checkout', 'dependencies': []}, {'id': 'build', 'dependencies': ['checkout']}, {'id': 'unit_test', 'dependencies': ['build']}, {'id': 'integration_test', 'dependencies': ['build']}, {'id': 'deploy', 'dependencies': ['unit_test', 'integration_test']}, ] ``` Eine gültige Ausgabe für diese Eingabe wäre: `[['checkout'], ['build'], ['unit_test', 'integration_test'], ['deploy']]`

Bewertungsrichtlinie

Eine qualitativ hochwertige Lösung muss funktional korrekt und robust sein. - **Correctness:** Der erzeugte Zeitplan muss die Aufgabenabhängigkeiten genau widerspiegeln. Alle Aufgaben müssen genau einmal in der Ausgabe enthalten sein, und keine Aufgabe darf eingeplant werden, bevor ihre Abhängigkeiten erfüllt sind. - **Error Handling:** Die Lösung muss korrekt einen `ValueError` für sowohl zirkuläre Abhängigkeiten als auch Verweise auf nicht existente Abhängigkeitsaufgaben erkennen und auslösen. Die Fehlermeldungen...

Mehr anzeigen

Eine qualitativ hochwertige Lösung muss funktional korrekt und robust sein. - **Correctness:** Der erzeugte Zeitplan muss die Aufgabenabhängigkeiten genau widerspiegeln. Alle Aufgaben müssen genau einmal in der Ausgabe enthalten sein, und keine Aufgabe darf eingeplant werden, bevor ihre Abhängigkeiten erfüllt sind. - **Error Handling:** Die Lösung muss korrekt einen `ValueError` für sowohl zirkuläre Abhängigkeiten als auch Verweise auf nicht existente Abhängigkeitsaufgaben erkennen und auslösen. Die Fehlermeldungen sollten klar und informativ sein. - **Algorithm Choice:** Die Implementierung sollte einen effizienten Algorithmus zur topologischen Sortierung verwenden, z. B. Kahns Algorithmus oder einen DFS-basierten Ansatz. Ineffiziente oder Brute‑Force-Lösungen werden negativ bewertet. - **Code Quality:** Der Code sollte sauber, gut strukturiert und lesbar sein. Er sollte sich an die Standardkonventionen von Python (PEP 8) halten. Die Verwendung geeigneter Datenstrukturen (z. B. Dictionaries zur Darstellung des Graphen, Mengen für effiziente Nachschlageoperationen) wird erwartet. - **Output Format:** Die Ausgabe muss strikt dem angegebenen Format entsprechen: eine Liste von Listen von Strings für einen gültigen Plan, oder ein ausgelöster `ValueError` für einen ungültigen Aufgaben-Graphen.

Antworten

Abhängigkeitsbasierter Aufgabendisponent.

Erzeugt einen Ausführungsplan als Liste von Batches (Listen von Aufgaben-IDs),
bei denen jede Aufgabe in einem Batch parallel ausgeführt werden kann und Batches
sequenziell ausgeführt werden müssen. Verwendet Kahns Algorithmus (topologische Sortierung auf Ebene für Ebene).

Löst ValueError aus bei:

  • doppelten Aufgaben-IDs,
  • Abhängigkeiten, die auf unbekannte Aufgaben-IDs verweisen,
  • zirkulären Abhängigkeiten (mit den betroffenen Aufgaben aufgeführt).

from collections import deque
from typing import Dict, List

class TaskScheduler:
"""Plant Aufgaben basier...

Vollstandige Antwort anzeigen

Abhängigkeitsbasierter Aufgabendisponent.

Erzeugt einen Ausführungsplan als Liste von Batches (Listen von Aufgaben-IDs),
bei denen jede Aufgabe in einem Batch parallel ausgeführt werden kann und Batches
sequenziell ausgeführt werden müssen. Verwendet Kahns Algorithmus (topologische Sortierung auf Ebene für Ebene).

Löst ValueError aus bei:

  • doppelten Aufgaben-IDs,
  • Abhängigkeiten, die auf unbekannte Aufgaben-IDs verweisen,
  • zirkulären Abhängigkeiten (mit den betroffenen Aufgaben aufgeführt).

from collections import deque
from typing import Dict, List

class TaskScheduler:
"""Plant Aufgaben basierend auf Abhängigkeiten in parallelisierbare Batches."""

def __init__(self, tasks: List[dict]):
    self.tasks = tasks
    self._validate_and_build_graph()

def _validate_and_build_graph(self) -> None:
    # Sammelt alle Aufgaben-IDs und prüft auf Duplikate.
    self.task_ids = set()
    for task in self.tasks:
        if 'id' not in task:
            raise ValueError(f"Aufgabe hat den erforderlichen Schlüssel 'id' nicht: {task!r}")
        task_id = task['id']
        if task_id in self.task_ids:
            raise ValueError(f"Doppelte Aufgaben-ID gefunden: '{task_id}'")
        self.task_ids.add(task_id)

    # Erstellt Adjazenzliste (Abhängigkeit -> Abhängige) und In-Degree-Map.
    self.dependents: Dict[str, List[str]] = {tid: [] for tid in self.task_ids}
    self.in_degree: Dict[str, int] = {tid: 0 for tid in self.task_ids}

    for task in self.tasks:
        task_id = task['id']
        for dep in task.get('dependencies') or []:
            if dep not in self.task_ids:
                raise ValueError(
                    f"Aufgabe '{task_id}' hängt von unbekannter Aufgaben-ID '{dep}' ab"
                )
            if dep == task_id:
                raise ValueError(
                    f"Aufgabe '{task_id}' hängt von sich selbst ab (zirkuläre Abhängigkeit)"
                )
            self.dependents[dep].append(task_id)
            self.in_degree[task_id] += 1

def schedule(self) -> List[List[str]]:
    """
    Gibt den Ausführungsplan als Liste von Batches zurück.

    Jeder Batch ist eine Liste von Aufgaben-IDs, die parallel ausgeführt werden können.
    Batches müssen in der zurückgegebenen Reihenfolge ausgeführt werden.
    """
    in_degree = dict(self.in_degree)  # Arbeitet mit einer Kopie
    current_batch = deque(
        tid for tid in in_degree if in_degree[tid] == 0
    )

    plan: List[List[str]] = []
    scheduled_count = 0

    while current_batch:
        batch = sorted(current_batch)  # deterministische Ausgabe (Reihenfolge ist beliebig)
        plan.append(batch)
        scheduled_count += len(batch)

        next_batch = deque()
        for task_id in batch:
            for dependent in self.dependents[task_id]:
                in_degree[dependent] -= 1
                if in_degree[dependent] == 0:
                    next_batch.append(dependent)
        current_batch = next_batch

    if scheduled_count != len(self.task_ids):
        unresolved = sorted(
            tid for tid in in_degree if in_degree[tid] > 0
        )
        raise ValueError(
            "Zirkuläre Abhängigkeit erkannt, die Aufgaben betrifft: "
            + ", ".join(f"'{t}'" for t in unresolved)
        )

    return plan

def schedule_tasks(tasks: List[dict]) -> List[List[str]]:
"""
Hilfsfunktion: Plant eine Liste von Aufgaben-Dictionaries.

Args:
    tasks: Liste von Dictionaries, jedes mit den Schlüsseln 'id' (str),
           optional 'name' (str) und 'dependencies' (Liste von Aufgaben-ID-Strings).

Returns:
    Eine Liste von Listen von Aufgaben-IDs. Jede innere Liste ist ein Batch von Aufgaben,
    die parallel ausgeführt werden können; Batches werden sequenziell in der Reihenfolge ausgeführt.

Raises:
    ValueError: Wenn eine Abhängigkeit auf eine nicht existierende Aufgaben-ID verweist, wenn
                eine zirkuläre Abhängigkeit besteht oder wenn Aufgaben-IDs dupliziert werden.
"""
return TaskScheduler(tasks).schedule()

if name == 'main':
# Beispiel 1
tasks = [
{'id': 'A', 'name': 'Datenerfassung', 'dependencies': []},
{'id': 'B', 'name': 'Datenbereinigung', 'dependencies': ['A']},
{'id': 'C', 'name': 'Feature Engineering', 'dependencies': ['A']},
{'id': 'D', 'name': 'Modelltraining', 'dependencies': ['B', 'C']},
{'id': 'E', 'name': 'Logging einrichten', 'dependencies': []},
{'id': 'F', 'name': 'Modellbereitstellung', 'dependencies': ['D']},
]
print(schedule_tasks(tasks))
# -> [['A', 'E'], ['B', 'C'], ['D'], ['F']]

# Beispiel 2
pipeline = [
    {'id': 'checkout', 'dependencies': []},
    {'id': 'build', 'dependencies': ['checkout']},
    {'id': 'unit_test', 'dependencies': ['build']},
    {'id': 'integration_test', 'dependencies': ['build']},
    {'id': 'deploy', 'dependencies': ['unit_test', 'integration_test']},
]
print(schedule_tasks(pipeline))
# -> [['checkout'], ['build'], ['integration_test', 'unit_test'], ['deploy']]

# Beispiel 3: zirkuläre Abhängigkeit löst ValueError aus
cyclic = [
    {'id': 'X', 'dependencies': ['Y']},
    {'id': 'Y', 'dependencies': ['X']},
]
try:
    schedule_tasks(cyclic)
except ValueError as e:
    print(f"ValueError: {e}")

# Beispiel 4: unbekannte Abhängigkeit löst ValueError aus
broken = [
    {'id': 'A', 'dependencies': ['missing_task']},
]
try:
    schedule_tasks(broken)
except ValueError as e:
    print(f"ValueError: {e}")

Ergebnis

#1 | Sieger

Siegstimmen

2 / 3

Durchschnittsscore

91
Bewertungsmodelle Anthropic Claude Opus 4.8

Gesamtpunktzahl

88

Gesamtkommentar

Antwort A ist funktional korrekt und verwendet den Algorithmus von Kahn mit einer sauberen Level-by-Level (Batch)-Topologischen Sortierung. Sie validiert doppelte IDs, unbekannte Abhängigkeiten und Selbstschleifen und erkennt Zyklen durch die Überprüfung der geplanten Anzahl, wobei beschreibende ValueErrors ausgelöst werden, die sogar die betreffenden Aufgaben auflisten. Bemerkenswerte Stärken: Sie erstellt den Graphen zur Konstruktionszeit (sodass Fehler bei unbekannten Abhängigkeiten sofort auftreten), liefert deterministische Ausgaben durch Sortierung, enthält gründliche Docstrings, Typ-Annotationen und einen umfassenden Satz ausführbarer Beispiele, die sowohl gültige als auch ungültige Fälle (Zyklus und unbekannte Abhängigkeit) abdecken. Sie bietet sowohl eine Klassen-API als auch eine praktische Funktion, die der Flexibilität der Aufforderung entspricht. Kleinere Schwächen: Das Sortieren jeder Charge ist ein kleiner (und nicht angeforderter) Mehraufwand, und die sofortige Überprüfung von Selbstabhängigkeiten ist angesichts des Zykluserkenners leicht redundant, aber beides ist nicht schädlich.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
90

Implementiert korrekt den Level-by-Level-Algorithmus von Kahn; gültige Zeitpläne entsprechen den erwarteten Ausgaben, Zyklen und unbekannte Abhängigkeiten lösen beide ValueError aus, und die Zykluserkennung über scheduled_count ist solide. Sortierte Batches garantieren korrekte, deterministische Ergebnisse.

Vollstandigkeit

Gewichtung 20%
90

Behandelt Duplikate, unbekannte Abhängigkeiten, Selbstschleifen und Zyklen; bietet sowohl Klassen- als auch Funktions-APIs; und enthält vier ausführbare Beispiele, die gültige Zeitpläne sowie beide Fehlertypen abdecken und eine vollständige Abdeckung demonstrieren.

Codequalitat

Gewichtung 20%
85

Saubere Klassenstruktur mit klarer Trennung von Validierung und Planung, gute Docstrings, Typ-Annotationen und informative Fehlermeldungen. Leichte Redundanz bei der expliziten Überprüfung von Selbstabhängigkeiten.

Praktischer Nutzen

Gewichtung 15%
85

Determinierte Ausgabe und sofortige Validierung bei der Konstruktion machen sie zuverlässig und einfach zu integrieren; ausführbare Beispiele für alle Pfade erleichtern die praktische Übernahme.

Befolgung der Anweisungen

Gewichtung 10%
90

Entspricht dem erforderlichen Ausgabeformat, löst ValueError für beide erforderlichen Fehlerfälle mit beschreibenden Meldungen aus und stellt wie gefordert eine Funktion bereit; entspricht vollständig der Aufforderung.

Bewertungsmodelle OpenAI GPT-5.4

Gesamtpunktzahl

88

Gesamtkommentar

Antwort A ist eine starke, größtenteils korrekte Implementierung mit dem Level-by-Level Kahn-Algorithmus und gibt parallelisierbare Batches sauber zurück. Sie behandelt unbekannte Abhängigkeiten, doppelte IDs und Zyklen mit klaren Fehlermeldungen, und der Code ist lesbar und gut strukturiert. Ihre Hauptschwäche ist, dass sie weniger Eingabevalidierung durchführt als Antwort B und bei fehlerhaften Eingaben, die über die Kernanforderungen der Aufforderung hinausgehen, etwas weniger robust ist.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
89

Implementiert die Batch-weise topologische Sortierung korrekt und erkennt unbekannte Abhängigkeiten und Zyklen. Sie erkennt auch explizit Selbstabhängigkeiten. Eine geringfügige Einschränkung besteht darin, dass fehlerhafte Datentypen im Abhängigkeitsfeld nicht validiert werden und zu unbeabsichtigtem Verhalten anstelle eines klaren, vertragstreuen Fehlers führen könnten.

Vollstandigkeit

Gewichtung 20%
86

Deckt alle erforderlichen Verhaltensweisen ab und fügt sogar die Behandlung doppelter IDs und Beispiele hinzu. Sie ist jedoch weniger vollständig in Bezug auf die Validierung fehlerhafter Eingaben, wie z. B. nicht-listenförmige Abhängigkeiten oder nicht-zeichenkettenförmige IDs über das fehlende 'id' hinaus.

Codequalitat

Gewichtung 20%
88

Gut organisiert mit klarem Klassendesign, Hilfsmethoden, Typ-Hints, Docstrings und deterministisch sortierten Batches. Die Struktur ist leicht zu verfolgen und zu warten.

Praktischer Nutzen

Gewichtung 15%
84

Praktisch nutzbar, insbesondere mit deterministischer Batch-Sortierung und aussagekräftigen Fehlermeldungen. Sie ist etwas weniger defensiv gegenüber fehlerhaften Eingaben, was die Robustheit in Produktionsumgebungen verringert.

Befolgung der Anweisungen

Gewichtung 10%
94

Folgt der Aufforderung genau: Akzeptiert Task-Dictionaries, gibt Listen-von-Listen-Batches zurück und löst ValueError für Zyklen und fehlende Abhängigkeiten aus. Die Implementierung und die Beispiele stimmen gut mit dem erforderlichen Antworttyp überein.

Bewertungsmodelle Google Gemini 2.5 Pro

Gesamtpunktzahl

96

Gesamtkommentar

Antwort A bietet eine ausgezeichnete, professionelle Lösung. Sie verwendet ein gut strukturiertes klassenbasiertes Design, das den Aufbau und die Validierung des Graphen sauber von der Planungslogik trennt. Die Implementierung von Kahns Algorithmus ist korrekt und effizient. Die Fehlerbehandlung ist robust und deckt alle spezifizierten Fälle sowie zusätzliche wie doppelte Task-IDs ab. Der Code ist sauber, gut dokumentiert mit Typ-Annotationen und enthält einen umfassenden `if __name__ == '__main__'`-Block, der als eine Reihe von Mini-Tests dient und sowohl erfolgreiche Ausführung als auch Fehlerbehandlung demonstriert.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
100

Die Implementierung von Kahns Algorithmus ist fehlerfrei. Sie identifiziert korrekt Batches von parallelisierbaren Tasks und respektiert alle Abhängigkeiten, was für die gegebenen Beispiele das korrekte Ergebnis liefert.

Vollstandigkeit

Gewichtung 20%
90

Die Lösung behandelt alle spezifizierten Anforderungen korrekt, einschließlich der Erkennung von zirkulären Abhängigkeiten und nicht existierenden Abhängigkeiten. Sie fügt auch nützliche Prüfungen auf doppelte Task-IDs und Selbstabhängigkeiten hinzu.

Codequalitat

Gewichtung 20%
95

Die Codequalität ist ausgezeichnet. Das klassenbasierte Design bietet eine großartige Struktur und Trennung der Zuständigkeiten. Der Code ist sauber, lesbar, gut dokumentiert und verwendet Typ-Annotationen effektiv. Der `if __name__ == '__main__'`-Block ist umfassend und demonstriert die volle Funktionalität des Codes.

Praktischer Nutzen

Gewichtung 15%
90

Die Lösung ist sehr praktisch. Das klassenbasierte Design erleichtert die Wiederverwendung und Erweiterung. Eine Instanz des Planers könnte erstellt und ihr Graph inspiziert oder wiederverwendet werden, was in realen Anwendungen eine häufige Anforderung ist.

Befolgung der Anweisungen

Gewichtung 10%
100

Die Antwort folgt perfekt allen Anweisungen, einschließlich des Eingabe-/Ausgabeformats, der Wahl einer Funktion oder Klasse und der spezifischen Anforderungen an die Fehlerbehandlung.

Antwort B: OpenAI GPT-5.5

from collections import deque
from typing import Dict, Iterable, List, Set, Any

def schedule_tasks(tasks: List[Dict[str, Any]]) -> List[List[str]]:
"""
Erstelle einen abhängigkeitbasierten Ausführungsplan für eine Liste von Aufgaben.

Jede zurückgegebene innere Liste ist ein Stapel von Aufgaben-IDs, die gleichzeitig ausgeführt werden können.
Stapel müssen in der zurückgegebenen Reihenfolge ausgeführt werden.

Argumente:
    tasks: Eine Liste von Dictionaries. Jede Aufgabe muss enthalten:
        - 'id': eindeutiger String-Aufgabenbezeichner
        - 'dependencies': Liste von Auf...
Vollstandige Antwort anzeigen

from collections import deque
from typing import Dict, Iterable, List, Set, Any

def schedule_tasks(tasks: List[Dict[str, Any]]) -> List[List[str]]:
"""
Erstelle einen abhängigkeitbasierten Ausführungsplan für eine Liste von Aufgaben.

Jede zurückgegebene innere Liste ist ein Stapel von Aufgaben-IDs, die gleichzeitig ausgeführt werden können.
Stapel müssen in der zurückgegebenen Reihenfolge ausgeführt werden.

Argumente:
    tasks: Eine Liste von Dictionaries. Jede Aufgabe muss enthalten:
        - 'id': eindeutiger String-Aufgabenbezeichner
        - 'dependencies': Liste von Aufgaben-IDs, die zuerst abgeschlossen werden müssen

Rückgabewert:
    Eine Liste von Stapeln, wobei jeder Stapel eine Liste von Aufgaben-IDs ist.

Löst aus:
    ValueError: Wenn Aufgaben-IDs doppelt vorkommen, Abhängigkeiten fehlerhaft formatiert sind,
                eine Abhängigkeit auf eine unbekannte Aufgabe verweist oder ein Zyklus existiert.
"""
if not isinstance(tasks, list):
    raise ValueError("tasks muss eine Liste von Aufgaben-Dictionaries sein")

task_ids: Set[str] = set()

for task in tasks:
    if not isinstance(task, dict):
        raise ValueError("jede Aufgabe muss ein Dictionary sein")

    task_id = task.get("id")
    if not isinstance(task_id, str) or not task_id:
        raise ValueError("jede Aufgabe muss eine nicht-leere String-'id' haben")

    if task_id in task_ids:
        raise ValueError(f"doppelte Aufgaben-ID gefunden: {task_id!r}")

    dependencies = task.get("dependencies", [])
    if not isinstance(dependencies, list):
        raise ValueError(f"Abhängigkeiten für Aufgabe {task_id!r} müssen eine Liste sein")

    for dependency_id in dependencies:
        if not isinstance(dependency_id, str) or not dependency_id:
            raise ValueError(
                f"Abhängigkeiten für Aufgabe {task_id!r} dürfen nur nicht-leere Strings enthalten"
            )

    task_ids.add(task_id)

# adjacency ordnet jeder Aufgabe die Aufgaben zu, die nach ihrem Abschluss ausführbarer werden.
adjacency: Dict[str, List[str]] = {task_id: [] for task_id in task_ids}

# in_degree zählt, wie viele unerledigte Abhängigkeiten jede Aufgabe hat.
in_degree: Dict[str, int] = {task_id: 0 for task_id in task_ids}

for task in tasks:
    task_id = task["id"]
    dependencies = task.get("dependencies", [])

    # Behandle doppelte Abhängigkeits-IDs innerhalb einer einzelnen Aufgabe als ungültige Eingabe, da sie
    # sonst zu uneindeutiger Buchführung führen und normalerweise auf einen Datenfehler hinweisen.
    seen_dependencies: Set[str] = set()

    for dependency_id in dependencies:
        if dependency_id not in task_ids:
            raise ValueError(
                f"Aufgabe {task_id!r} hängt von unbekannter Aufgaben-ID {dependency_id!r} ab"
            )

        if dependency_id in seen_dependencies:
            raise ValueError(
                f"Aufgabe {task_id!r} führt die Abhängigkeit {dependency_id!r} mehr als einmal auf"
            )
        seen_dependencies.add(dependency_id)

        adjacency[dependency_id].append(task_id)
        in_degree[task_id] += 1

ready = deque(task_id for task_id in task_ids if in_degree[task_id] == 0)
execution_plan: List[List[str]] = []
scheduled_count = 0

while ready:
    batch = list(ready)
    ready.clear()
    execution_plan.append(batch)
    scheduled_count += len(batch)

    for completed_task_id in batch:
        for dependent_task_id in adjacency[completed_task_id]:
            in_degree[dependent_task_id] -= 1
            if in_degree[dependent_task_id] == 0:
                ready.append(dependent_task_id)

if scheduled_count != len(task_ids):
    cyclic_task_ids = sorted(
        task_id for task_id, remaining_dependencies in in_degree.items()
        if remaining_dependencies > 0
    )
    raise ValueError(
        "zirkuläre Abhängigkeit erkannt mit Aufgabe(n): "
        + ", ".join(cyclic_task_ids)
    )

return execution_plan

class TaskScheduler:
"""Kleine praktische Hülle um schedule_tasks()."""

def __init__(self, tasks: List[Dict[str, Any]]):
    self.tasks = tasks

def execution_plan(self) -> List[List[str]]:
    return schedule_tasks(self.tasks)

if name == "main":
tasks = [
{"id": "A", "name": "Datenaufnahme", "dependencies": []},
{"id": "B", "name": "Datenbereinigung", "dependencies": ["A"]},
{"id": "C", "name": "Feature-Engineering", "dependencies": ["A"]},
{"id": "D", "name": "Modelltraining", "dependencies": ["B", "C"]},
{"id": "E", "name": "Logging einrichten", "dependencies": []},
{"id": "F", "name": "Modellbereitstellung", "dependencies": ["D"]},
]

print(schedule_tasks(tasks))
# Beispielausgabe: [['A', 'E'], ['B', 'C'], ['D'], ['F']]
# Die Reihenfolge innerhalb jedes Stapels kann abweichen, da Aufgaben in einem Stapel gleichzeitig laufen können.

Ergebnis

#2

Siegstimmen

1 / 3

Durchschnittsscore

89
Bewertungsmodelle Anthropic Claude Opus 4.8

Gesamtpunktzahl

86

Gesamtkommentar

Antwort B ist ebenfalls funktional korrekt und verwendet den Kahn-Algorithmus mit Batch-Gruppierung. Sie verfügt über die gründlichste Eingabevalidierung: Sie prüft, ob tasks eine Liste ist, jedes Element ein Dict ist, jede ID eine nicht leere Zeichenkette ist, dependencies eine Liste ist und dass dependency-Einträge nicht leere Zeichenketten sind. Sie lehnt auch doppelte Abhängigkeits-IDs bei einer einzelnen Aufgabe ab. Zykluserkennung und Erkennung unbekannter Abhängigkeiten sind korrekt mit klaren Meldungen. Schwächen: Die Erkennung unbekannter Abhängigkeiten erfolgt in der zweiten Runde statt bei der Validierung, was in Ordnung ist, aber etwas weniger ordentlich; die Ausgabeordnung innerhalb der Batches ist nicht deterministisch (hängt von der Set-Iteration ab), was gemäß der Spezifikation akzeptabel ist, aber weniger reproduzierbar als bei A. Ihre Beispielabdeckung ist dünner – nur ein gültiges Beispiel, ohne Demonstration der Fehlerpfade. Der TaskScheduler-Wrapper ist ein dünner Passthrough.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
88

Implementiert den Kahn-Algorithmus korrekt mit ordnungsgemäßer Batch-Gruppierung, Zykluserkennung und Erkennung unbekannter Abhängigkeiten. Die Ausgabe ist korrekt, aber die Batch-Ordnung hängt von der Set-Iteration ab, was sie nicht deterministisch, aber dennoch spezifikonform macht.

Vollstandigkeit

Gewichtung 20%
85

Behandelt Duplikate, fehlerhafte Eingaben, unbekannte Abhängigkeiten, doppelte Abhängigkeiten pro Aufgabe und Zyklen – arguably breitere Validierung. Sie demonstriert jedoch nur ein gültiges Beispiel und zeigt keine Beispiele für Fehlerpfade, wodurch das Verhalten weniger veranschaulicht wird.

Codequalitat

Gewichtung 20%
85

Sehr lesbares Single-Function-Design mit beschreibenden Variablennamen, gründlichen Docstrings und Inline-Kommentaren zur Begründung. Der TaskScheduler-Wrapper fügt wenig hinzu, aber die Gesamtstruktur ist sauber und idiomatisch.

Praktischer Nutzen

Gewichtung 15%
82

Robuste defensive Validierung macht sie sicher gegen fehlerhafte Eingaben, aber die nicht deterministische Batch-Ordnung und weniger Demonstrationen verringern die praktische Reproduzierbarkeit leicht.

Befolgung der Anweisungen

Gewichtung 10%
88

Entspricht dem erforderlichen Ausgabeformat und löst beschreibende ValueErrors für beide erforderlichen Fehlerfälle über eine Funktion wie gewünscht aus; vollständig konform, wenn auch mit dünnerer Demonstration der Anforderungen.

Bewertungsmodelle OpenAI GPT-5.4

Gesamtpunktzahl

91

Gesamtkommentar

Antwort B ist eine robuste und korrekte Implementierung von Kahns Algorithmus, die parallele Ausführungscharges zurückgibt und klare ValueError-Ausnahmen für ungültige Graphen auslöst. Sie fügt eine stärkere Validierung für Task-Formen und Abhängigkeitstypen hinzu, hält den Code sauber und praktisch und enthält eine praktische Wrapper-Klasse. Ihr einziges nennenswertes kleines Manko ist, dass die Reihenfolge der Batches nicht deterministisch ist, da sie aus einer Set-basierten Sammlung iteriert.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
92

Berechnet korrekt parallele Batches mit Kahns Algorithmus und erkennt unbekannte Abhängigkeiten und Zyklen. Sie validiert auch IDs und Abhängigkeitseinträge gründlicher, was die Fehlermodi reduziert. Kleinere Abzüge, da die Batch-Reihenfolge aufgrund der Set-Iteration nicht deterministisch ist, obwohl die Reihenfolge innerhalb eines Batches variieren darf.

Vollstandigkeit

Gewichtung 20%
93

Behandelt das angeforderte Scheduling-Verhalten, das Ausgabeformat, die Zykluserkennung und fehlende Abhängigkeitsfehler vollständig und deckt außerdem doppelte IDs, fehlerhafte Tasks, fehlerhafte Abhängigkeitslisten und doppelte Abhängigkeiten ab. Dies macht die Lösung im realen Einsatz vollständiger.

Codequalitat

Gewichtung 20%
87

Sauberer, lesbarer und idiomatischer Code mit guter Benennung, Typ-Annotationen und fokussierter Logik. Etwas weniger poliert als A, da die Iterationsreihenfolge nicht deterministisch gelassen wird und die hinzugefügte Wrapper-Klasse dünner im Design ist.

Praktischer Nutzen

Gewichtung 15%
90

Sehr praktisch aufgrund stärkerer Eingabevalidierung, klarer Ausnahmen und direkter Funktionsnutzung mit einer optionalen Wrapper-Klasse. Sie ist gut für reale Eingaben geeignet, die unordentlich oder inkonsistent sein können.

Befolgung der Anweisungen

Gewichtung 10%
95

Folgt der Aufforderung sehr genau und gibt die erforderliche Struktur zurück, während ein effizienter Algorithmus und eine angemessene Fehlerbehandlung verwendet werden. Sie konzentriert sich auch wie gewünscht auf den Code und stimmt gut mit der Spezifikation überein.

Bewertungsmodelle Google Gemini 2.5 Pro

Gesamtpunktzahl

91

Gesamtkommentar

Antwort B bietet eine funktional korrekte Lösung, die auch Kahns Algorithmus verwendet. Ihre Hauptstärke liegt in der äußerst gründlichen und paranoiden Eingabevalidierung, die eine breite Palette potenzieller Datenfehler über die Anforderungen der Aufgabenstellung hinaus prüft. Allerdings ist ihre Code-Struktur schwächer als die von Antwort A. Die Kernlogik ist in einer einzigen, langen Funktion untergebracht, was sie weniger modular und lesbar macht. Die begleitende `TaskScheduler`-Klasse ist ein dünner Wrapper, der wenig Mehrwert bietet. Die Beispielverwendung im Hauptblock ist ebenfalls weniger umfassend und versäumt es, die robuste Fehlerbehandlung zu demonstrieren, die im Code implementiert ist.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
100

Die Implementierung von Kahns Algorithmus ist fehlerfrei. Sie identifiziert korrekt Stapel von parallelisierbaren Aufgaben und respektiert alle Abhängigkeiten, wodurch für die gegebenen Beispiele die korrekte Ausgabe erzeugt wird.

Vollstandigkeit

Gewichtung 20%
95

Die Lösung behandelt alle vorgegebenen Anforderungen korrekt. Ihre Eingabevalidierung ist außergewöhnlich gründlich und prüft nicht nur auf die erforderlichen Fehler, sondern auch auf Datentypen, leere Zeichenketten und doppelte Abhängigkeiten innerhalb der Liste einer einzelnen Aufgabe, was sie in Bezug auf ihre Robustheit etwas vollständiger macht.

Codequalitat

Gewichtung 20%
75

Der Code ist funktional korrekt, aber weniger gut strukturiert. Die Logik ist in einer einzigen großen Funktion verpackt, was die Lesbarkeit und Wartbarkeit beeinträchtigt. Die `TaskScheduler`-Klasse wirkt wie eine nachträgliche Ergänzung und bietet keinen wirklichen Mehrwert. Der Testblock ist minimal und zeigt nicht die umfangreiche Fehlerbehandlung.

Praktischer Nutzen

Gewichtung 15%
80

Die Lösung ist aufgrund ihrer Korrektheit und robusten Validierung praktisch. Das monolithische Funktionsdesign macht sie jedoch im Vergleich zu einer gut gestalteten Klasse weniger flexibel und wiederverwendbar in einem größeren Softwaresystem.

Befolgung der Anweisungen

Gewichtung 10%
100

Die Antwort folgt perfekt allen Anweisungen, einschließlich des Eingabe-/Ausgabeformats, der Wahl einer Funktion oder Klasse und der spezifischen Anforderungen an die Fehlerbehandlung.

Vergleichsuebersicht

Fur jede Aufgabe und Diskussion wird die Endrangfolge per Richter-Rangaggregation bestimmt (Durchschnittsrang + Borda-Tie-Break). Der Durchschnittsscore wird als Referenz angezeigt.

Bewerter: 3

Siegstimmen

2 / 3

Durchschnittsscore

91
Diese Antwort ansehen

Siegstimmen

1 / 3

Durchschnittsscore

89
Diese Antwort ansehen

Bewertungsergebnisse

Bewertungsmodelle Google Gemini 2.5 Pro

Warum diese Seite gewann

Antwort A ist der Gewinner aufgrund seiner überlegenen Codequalität und seines Software-Designs. Die Verwendung einer dedizierten Klasse zur Kapselung des Zustands und der Logik des Schedulers ist ein weitaus sauberer, wartungsfreundlicherer und wiederverwendbarer Ansatz als die monolithische Funktion von Antwort B. Während Antwort B eine etwas umfassendere Eingabevalidierung aufweist, ist die Gesamtstruktur von Antwort A signifikant besser und stärker an objektorientierten Prinzipien ausgerichtet. Darüber hinaus macht die Einbeziehung eines umfassenden Testblocks in Antwort A, der seine Fehlerbehandlungsfähigkeiten demonstriert, diese zu einer vollständigeren und professionelleren Einreichung.

Bewertungsmodelle OpenAI GPT-5.4

Warum diese Seite gewann

Antwort B gewinnt, da beide Antworten funktional stark sind, aber B bei den stärker gewichteten Dimensionen Korrektheit und Vollständigkeit höher punktet, indem sie eine breitere Validierung und eine ähnlich solide Handhabung von Zyklen und fehlenden Abhängigkeiten bietet. Obwohl Antwort A eine etwas deterministischere Ausgabe innerhalb von Batches aufweist, geben B's stärkere Robustheit und praktische Eingabeüberprüfungen ihr das insgesamt höhere gewichtete Ergebnis.

Bewertungsmodelle Anthropic Claude Opus 4.8

Warum diese Seite gewann

Beide Antworten sind korrekt und verwenden den Algorithmus von Kahn angemessen, daher ist die Korrektheit nahezu gleichauf. A gewinnt knapp im stark gewichteten Cluster Korrektheit/Vollständigkeit/Codequalität aufgrund einer reichhaltigeren Demonstration aller erforderlichen Verhaltensweisen (gültiger Zeitplan, Zyklus-ValueError und unbekannter Abhängigkeits-ValueError werden alle ausgeführt gezeigt), deterministischer Batch-Ausgabe, die Ergebnisse reproduzierbar macht, und früher Graph-Validierung bei der Erstellung. Bs stärkere defensive Eingabevalidierung ist wertvoll, befasst sich aber mit Fällen, die über die Spezifikation hinausgehen, während A die exakt erforderlichen Szenarien gründlicher durcharbeitet und dokumentiert, was ihm einen leichten Vorteil in Bezug auf praktischen Wert und Vollständigkeit verschafft.

X f L