Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
labs_dsc.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
104.96 Кб
Скачать

Завдання 5. Створюємо Test Driver для Graph (4 бали)

Драйвер тестування Lab4TestDriver повинен зчитувати вхідні дані зі стандартного вводу або вказаного файлу, використовуючи формат, описаний у розділі «Формат файлів тестових скриптів» і друкувати результати на стандартний вивід. Для того, щоб допомогти вам в розборі формату вхідного файлу, ми надали скелет реалізації синтаксичного аналізатора. Ви повинні заповнити цей файл вашим власним кодом. Будь ласка, не забудьте використовувати PrintWriter з поля output в тестері для виводу результатів.

Пошук найкоротшого шляху (PathFinder)

У цій частині лабораторної роботи ви вправлятиметеся з вашим АТД Graph, запускаючи пошук шляху на ньому. Вам надається більшість коду для пошуку шляху, і ваша робота полягає в поєднанні наданого коду з кодом вашого АТД Graph.

Шлях

При пошуку найкращого маршруту руху між двома точками, MapQuick буде намагатися мінімізувати пройдену відстань. Загальний алгоритм пошуку найкоротшого шляху, з іншого боку, намагається мінімізувати деяку довільну функцію вартості пройденого маршруту. Оскільки абстракція графу носить загальний характер і може підтримувати будь-який тип вузла, необхідна абстракція для подання вартості шляху через граф. Інтерфейс Path забезпечує абстракцію для подання як шляху так і для отримання вартості цього шляху.

Path є Java інтерфейсом, а не класом, тобто він просто містить набір необхідних методів, та не може безпосередньо інстанціюватись, і не надає код класам, які реалізують його. Відділяючи поняття шляху (за допомогою Java інтерфейсу Path) від загальної абстракції Graph, шукати шлях можна у графах з будь-якими типами вузлів якщо існує відповідна реалізація інтерфейсу Path.

Пошук найкоротшого шляху

Наданий вам вихідний код містить реалізацію модифікованої версії алгоритму Дейкстри, який ви можете знайти в будь-якому підручнику з алгоритмізації. Псевдокод алгоритму приведений нижче. У псевдокоді, позначення [a, b, c] означає три елементи послідовність, що складається з “a”, “b”, і “c”, тут ми використовуємо його для представлення шляху. При застосуванні до послідовності, "+" означає об'єднання, наприклад, [а, Ь] + [c, d] = [a, b, c, d]. Якщо “m” асоціативним масивом, то m (key) представляє значення, пов'язане з ключем key асоціативним масивом “m”.

// Return a shortest path from any element of starts to any

// element of goals in a node-weighted graph.

Algorithm node-weighted-shortest-path(Set starts, Set goals) {

// maps nodes -> paths

Map paths = { forall start in starts | (start, [start]) }

// The priority queue contains nodes with priority equal to the cost

// of the shortest path to reach that node. Initially it contains

// the start nodes.

PriorityQueue active = starts

// The set of finished nodes are those for which we know the shortest paths

// from starts and whose children we have already examined.

Set finished = { }

while active is non-empty do {

// queueMin is the element of active with least cost path

queueMin = active.extractMin()

queueMinPath = paths(queueMin)

if (queueMin in goals) {

return queueMinPath

}

// iterate over edges (queueMin, c) in queueMin.edges

for each child c of queueMin {

cpath = queueMinPath + [c]

if (c not in finished) and (c not in active) {

paths(c) = cpath

insert c in active with priority equal to cpath's cost

}

}

insert queueMin in finished

}

// execution reaches this point only if active becomes empty

return No Path Exists

}

Цей алгоритм використовує пріоретизовану чергу, структуру даних колекцію, яка підтримує вставку елементів і вибір найбільш пріоритетного елемента. (Ми використовуємо вартість шляху як пріоритет, таким чином короткі шляхи мають вищий пріоритет.)

Пояснення до алгоритму

Приклад найкоротшого шляху

Завдання 6. Закінчити реалізацію алгоритму пошуку найкоротшого шляху (6 балів)

Завдання 7. Реалізувати тести для алгоритму пошуку найкоротшого шляху (3 балів)

Формат файлу тестового скрипта

Оскільки ви і ваші одногрупники будуть мати різні специфікації для класів в цій лабораторній роботі, то потрібно мати стандартизований інтерфейс для використання, тестування та оцінювання вашого коду. Для цього ми задаємо текстовий скриптовий формат, який використовується для запису інструкцій, що мають виконуватись вашим графом та шукачем шляху.

Тестовий сценарій (скрипт) є простим текстовим файлом де кожна команда займає окремий рядок. Кожен рядок складається із слів, розділених пробілом. Перше слово в кожній рядку є назвою команди. Решта слів є аргументами команди і мають інтерпретуватися в контексті конкретної команди за якою вони слідують. Рядки, які починаються з дієза (решітка (#))вважаються коментарями і повинні бути відображені у виводі при запуску тестового сценарію. Порожні рядки також повинні приводити до порожнього рядка у виводі.

Сценарій тестування маніпулює графами вершин WeightedNode. Кожена WeightedNode має назву і вартість. Після створення WeightedNode, до неї можна звернутися пізніше використовуючи її ім’я. Ми також надали WeightedNodePath який реалізує інтерфейс Path для послідовностей WeightedNodes. Коли драйвер тестування виводить вершину, він повинен зробити це, відображаючи її ім’я, який є типу String. Ім'ям кожного Graph також є String. Драйвер тестування повинен керувати відображенням імен на графи на додаток до відображень імен на вершини. Це може бути досягнуто шляхом підтримки двох HashMap-ів в коді драйвера тестування. Перший HashMap може відображати імена (String) на графи (Graph), а другий може бути використаний для відображення імен на вершини (WeightedNode). Для спрощення розбору файлу, імена вершин і графів повинні містити тільки символи букв та цифр.

Нижче наведений перелік допустимих команд, та значення їхніх аргументів. Кожна команда має пов'язане з нею значення, яке повинне друкуватись на стандартний вивід (зазвичай на консоль), коли команда виконується.

CreateGraph graphName

Створює новий граф з іменем graphName. Граф створюється порожнім (не має вершин і ребер). Виводом команди є:

created graph graphName

Якщо граф з таким іменем вже існує, вивід команди невизначений.

CreateNode nodeName cost

Створює нову вершину з ім'ям NodeName та вартістю задану невід'ємним цілим числом cost. Після створення вершини за допомогою цієї команди, ви можете звернутися до неї через ім'я. Виводом команди є:

created node nodeName with cost cost

У випадку якщо вершина з таким іменем вже існує вивід команди невизначений.

AddNode graphName nodeName

Додає вершину задану рядком nodeName до графу з іменем graphName. Виводом команди є:

added node nodeName to graphName

У випадку якщо вершина з таким іменем вже є у графі вивід команди невизначений.

AddEdge graphName parentNode childNode

Створює ребро в графі з іменем graphName з вершини parentNode до childNode. Виводом команди є:

added edge from parentNode to childNode in graphName

Якщо ребро вже існую у графі, вивід команди невизначений.

ListNodes graphName

Ця команда не змінює граф. Її вивід починається з:

graphName contains:

та продовжується у тому ж рядку, переліком імен усіх вершин графу розділених пробілами. Перелік має бути впорядкованим за алфавітом. Між двокрапкою та іменем першої вершини має бути один пробіл.

ListChildren graphName parentNode

Ця команда не змінює граф. Її вивід починається з:

the children of parentNode in graphName are:

та продовжується у тому ж рядку, переліком імен вершин графу, розділених пробілами, для яких існують ребра з вершини parentNode. Перелік має бути впорядкованим за алфавітом. Між двокрапкою та іменем першої вершини має бути один пробіл.

FindPath graphName from1 [from2 [from3 ... ] ] -> to1 [ to2 [ to3 ... ] ]

Символ -> відділяється , з обох боків,від імен вершин пробілами.

Квадратні дужки позначають необов'язкові елементи. Вони не повинні з'являтися у вхідному файлі, проте може бути задана довільна кількість вершин "з" та "у".

Ця команда не змінює граф. Вона шукає та виводить найкоротший шлях, серед усіх можливих, з кожної із "початкових" до кожної із "кінцевих". Її вивід починається з:

shortest path in graphName:

та продовжується у тому ж рядку, переліком вершин, який описує шлях від X у Y.

Якщо жодного шляху не існує, то виводом має бути:

no path found in graphName

Зауважте, що у першому випадку після двокрапки має бути один пробіл.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]