Модуль 9 · Урок 36 із 58
Traversal і priority: BFS, DFS, heap та lazy iteration
Traversal — це не лише цикл: порядок frontier, visited policy і tie-breakers визначають результат. Priority queue теж потребує стабільного secondary key, якщо дві задачі мають однаковий пріоритет.
Безпечна algorithm-практика модуля 9
Пакет містить тільки synthetic tasks і graph, deterministic operation counts, локальний Python CLI, tests та read-only verifier. Жодних персональних чи production-даних, credentials, мережевих викликів, machine paths або зовнішніх залежностей.
Graph contract перед traversal
Graph задається nodes та edges; треба визначити directed/undirected semantics, missing neighbor policy, duplicate edges і deterministic order. Без visited cycle може повторювати nodes без кінця. Для tree visited інколи не потрібен, але загальний graph traversal має його явно.
BFS і DFS відповідають різним питанням
BFS використовує FIFO queue і проходить layers; у неваговому graph він підходить для найкоротшої кількості edges. DFS використовує stack або recursion і заглиблюється в branch; він корисний для повного обходу, component exploration чи backtracking, але recursion depth є runtime boundary.
from collections import deque
queue = deque([start])
visited = {start}
while queue:
node = queue.popleft()
for neighbor in sorted(graph.get(node, [])):
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)Mark-on-enqueue запобігає дублюванню frontier. Sorting neighbors дає deterministic навчальний output, але додає cost, який треба назвати.
Heap — partial order для priority workload
heapq підтримує heap invariant: найменший item у heap[0]. Для stable priority queue використовуйте tuple (priority, sequence, task); sequence розв’язує ties і не змушує Python порівнювати несумісні task objects. Stale-entry або priority-update policy має бути документована.
Top-k не завжди потребує full sort
Коли k мале відносно n, heapq.nsmallest/nlargest можуть виконати менше роботи й тримати лише частину елементів. Для великого k повний sort може бути простішим.
Lazy iteration контролює memory
Generator та itertools обробляють items поступово. Це не робить algorithm автоматично швидшим, але може зменшити peak memory і дозволити early stop. Materialization через list(...) повертає full allocation, тому boundary має бути свідомою.
Performance evidence package
Спочатку доведіть correctness і deterministic operation counts на sizes 0, 1, 10, 100. Потім за потреби додайте timeit з окремим setup, кількома repeats, runtime/version та raw vector. Не перетворюйте мікробенчмарк на обіцянку production latency.
- Same result and same validation policy for compared variants.
- Input generation поза measured body.
- Operation count або invariant evidence поруч із timing.
- CPU, I/O і network claims не змішуються.
- Висновок називає range sizes і limitations.
- Regression threshold прив’язаний до contract, а не випадкового best run.
Методичні джерела
Урок, сценарії, пояснення й вправи створені SEOWORK. Посилання ведуть лише на офіційну документацію та Python Wiki.
Закріпіть матеріал уроку
Три сценарні питання. Для зарахування уроку потрібно дати щонайменше дві правильні відповіді.