Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы по ПиАА 2024 / Baraeva_Elizaveta_lb2.doc
Скачиваний:
0
Добавлен:
09.09.2026
Размер:
137 Кб
Скачать
  • greedy_algorithm() – функция жадного алгоритма, которая принимает начальную вершину start, конечную вершину end и граф graph в виде словаря. Внутри функции объявляются переменные way, current_vertex, которые представляют путь и текущую вершину соответственно. Затем цикл while продолжается до тех пор, пока текущая вершина не станет равной конечной вершине. Внутри цикла производится поиск следующей вершины с минимальным весом из соседних относительно текущей. Если не удалось найти следующую вершину, и текущая не является конечной, удаляется последняя вершина из пути и продолжается цикл. Если же следующая вершина найдена, она добавляется в путь, и текущая обновляется. По завершении цикла возвращается путь в виде строки.

  • heuristic() – функция, которая принимает текущую вершину vertex и конечную вершину end. Она возвращает эвристическую оценку расстояния между текущей вершиной и конечной вершиной.

  • get_a_star_path() – функция алгорима A*, которая принимает начальную вершину start, конечную вершину end и граф graph в виде словаря. Внутри функции объявляются переменные weight_and_vertex_list, passed, way_length, которые представляют список весов и вершин, пройденные вершины и длины пути соответственно. Затем цикл while продолжается до тех пор, пока список weight_and_vertex_list не будет пустым. На каждой итерации извлекается вершина с минимальным весом из списка. Если текущая вершина равна конечной, то строится кратчайший путь от начальной до конечной вершины и возвращается в виде строки. Если же нет, то для каждой соседней вершины вычисляется предполагаемая длина пути через текущую вершину. Далее если предполагаемая длина пути меньше текущей длины пути до соседней вершины, то обновляется информация о прохождении, длине пути, и соседняя вершина добавляется в список с учетом эвристической оценки.

  • Input_graph() – функция для считывания начальная и конечная вершины, а также ребер графа с их весами в словарь.

  • В блоке if name == "main" сначала вызывается функция input_graph(), а потом соответствующая функция алгоритма.

Тестирование.

Результаты тестирования представлены в табл. 1.

Таблица 1 – Результаты тестирования

№ п/п

Входные данные

Выходные данные

Комментарии

1.

a e

a b 3.0

b c 1.0

c d 1.0

a d 5.0

d e 1.0

abcde

Жадный алгоритм. Верно.

2.

a g

a b 3.0

a c 1.0

b d 2.0

b e 3.0

d e 4.0

e a 1.0

e f 2.0

a g 8.0

f g 1.0

abdefg

Жадный алгоритм. Верно.

3.

a e

a b 3.0

b c 1.0

c d 1.0

a d 5.0

d e 1.0

ade

Алгоритм А*. Верно.

4.

a d

a b 1.0

b c 1.0

c a 1.0

a d 8.0

ad

Алгоритм А*. Верно.

Исследование.

Для проведения исследования был создан генератор графов с вершинами от 3 до 52 и с заполненностью на 75%. По графику (см. рис. 1) можно сделать вывод о том, что при количестве вершин больше 10 алгоритм ветвей и границ начинает сильно проигрывать жадному алгоритму и А*. В то же время при сравнении жадного алгоритма и А* (см. рис. 2) в среднем эффективнее алгоритм А*. Стоит заметить, что жадный алгоритм при большем количестве вершин перебирает существенно больше вершин, чем А*.

Рисунок 1 – График исследования трех алгоритмов

Рисунок 2 – График исследования двух алгоритмов

Вывод.

Были изучены жадный алгоритм и алгоритм А* для построения пути в ориентированном графе.

В ходе выполнения лабораторной работы были реализованы жадный алгоритм, алгоритм А*, точный алгоритм (ветвей и границ), а также для исследования был написан генератор ориентированных графов.

Еще было проведено исследование времяни работы жадного алгоритма, А* и точного алгоритма (ветвей и границ) в зависимости от размера графа, заполненного на 75%. Анализ исследования показал, что жадный алгоритм хоть и проходит больше вершин, но тем не менее работает практически также быстро, как и А*, в то время как точный алгоритм существенно проигрывает обоим алгоритмам. Это подтверждает, что для алгоритма А* была подобрана хорошая эвристическая функция, которая помогает находить оптимальное решение за наименьшее время.

Приложение а исходный код программы

Название файла: greedy_algorithm.py

def greedy_algorithm(start, end, graph):

way = [start]

current_vertex = start

while current_vertex != end:

min_weight = float('inf')

next_vertex = None

for near_vertex, weight in graph[current_vertex].items():

if near_vertex not in way and weight < min_weight:

min_weight = weight

next_vertex = near_vertex

if next_vertex is None and current_vertex != end:

graph[way[-2]][current_vertex] = float('inf')

way.remove(current_vertex)

current_vertex = way[-1]

continue

way.append(next_vertex)

current_vertex = next_vertex

return ''.join(way)

def input_graph():

start_vertex, end_vertex = input().split()

graph = {}

while True:

try:

from_vertex, in_vertex, weight = input().split()

if from_vertex not in graph:

graph[from_vertex] = {}

if in_vertex not in graph:

graph[in_vertex] = {}

graph[from_vertex][in_vertex] = float(weight)

except EOFError:

break

return start_vertex, end_vertex, graph

if __name__ == "__main__":

start_vertex, end_vertex, graph = input_graph()

print(greedy_algorithm(start_vertex, end_vertex, graph))

Название файла: get_a_star_path.py

from greedy_algorithm import input_graph

import heapq

def heuristic(vertex, end):

return abs(ord(end) - ord(vertex))

def get_a_star_path(start, end, graph):

weight_and_vertex_list = [(0, start)]

passed = {}

way_length = {vertex: float('inf') for vertex in graph}

way_length[start] = 0

while weight_and_vertex_list:

current_weight, current_vertex = heapq.heappop(weight_and_vertex_list)

if current_vertex == end:

way = []

while current_vertex in passed:

way.append(current_vertex)

current_vertex = passed[current_vertex]

way.append(start)

return ''.join(reversed(way))

for near_vertex, weight in graph[current_vertex].items():

tentative_way_length = way_length[current_vertex] + weight

if tentative_way_length < way_length[near_vertex]:

passed[near_vertex] = current_vertex

way_length[near_vertex] = tentative_way_length

heapq.heappush(weight_and_vertex_list, (tentative_way_length + heuristic(near_vertex, end), near_vertex))

if __name__ == "__main__":

start_vertex, end_vertex, graph = input_graph()

print(get_a_star_path(start_vertex, end_vertex, graph))

Название файла: branch_and_bound.py

from greedy_algorithm import input_graph

import heapq

def branch_and_bound(start, end, graph):

way_cost, way = float('infinity'), None

queue = []

heapq.heappush(queue, (0, start, [start]))

while queue:

cost, current, way = heapq.heappop(queue)

if current == end and cost < way_cost:

way_cost = cost

way = way

elif current in graph:

for near_vertex, edge_cost in graph[current].items():

new_cost = cost + edge_cost

if new_cost < way_cost:

new_way = way + [near_vertex]

heapq.heappush(queue, (new_cost, near_vertex, new_way))

return ''.join(way)

if __name__ == "__main__":

start_vertex, end_vertex, graph = input_graph()

print(branch_and_bound(start_vertex, end_vertex, graph))

10

Соседние файлы в папке Лабы по ПиАА 2024