Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

lab2_graphs

.pdf
Скачиваний:
0
Добавлен:
27.08.2024
Размер:
511.32 Кб
Скачать

1.Цель работы

Реализовать и проверить на тестовом примере базовый алгоритм на графе. Сравнить быстродействие реализованного алгоритма на специальных графах.

2.Ход работы

Создаѐтся неориентированный граф без весов для тестирования базового алгоритма. Его представление в матрице смежности и изображение на рисунках 1-2 соответственно.

Рисунок 1 – Матрица смежности графа

Рисунок 2 – Изображение графа Реализуется выданный по варианту алгоритм – алгоритм поиска

кратчайшего маршрута (поиск в ширину). Его блок-схема представлена на рисунке 3.

2

Рисунок 3 – Блок-схема алгоритма Созданный алгоритм применяется на указанном выше графе. Результат

представлен на рисунке 4.

Рисунок 4 – Результат работы алгоритма Алгоритм искал кратчайший путь от точки 0 до точки 4. Алгоритм

ищет соседей точки, добавляет их в n-й список, который является порядком.

Далее в следующем порядке ищутся соседи соседей и так далее. Описание переменных функции представлен в таблице 1, листинг в Приложении.

Таблица 1 – Описание переменных функции breadeth_shortest_way

Название

Тип данных

Комментарий

 

 

 

df

Dataframe

Матрица смежности графа,

 

 

параметр функции

 

 

 

vertexes

list

Список, содержащий начальную

 

 

и конечную точку маршрута,

 

 

параметр функции

 

 

 

neighbours

list

Список, содержащий соседей

 

 

 

 

3

 

 

 

начальной точки в n-ом порядке

 

 

 

count

int

Переменная итерации цикла

 

 

 

temp

list

Список соседей на n-ом порядке

 

 

 

Реализуется создание графа с правильной треугольной решѐткой.

Изображение графа 3 x 3 представлено на рисунке 5, листинг создания в Приложении.

Рисунок 5 – Граф с правильной треугольной решѐткой

Графы такого типа M x M тестируются на созданном алгоритме несколько раз с количеством узлов от 4 до 81. Результат быстродействия работы алгоритма в зависимости от вершин представлен на рисунке 6.

Рисунок 6 – График зависимости t от M в алгоритме

4

3.Дополнительное задание

Также в рамках дополнительного задания создается функция dop_task,

которая по матрице смежностей выдаѐт узлы графов, между которым максимальная длина пути. Переменные, используемые в функции,

представлены в таблице 2. Листинг функции представлен в Приложении.

Таблица 2 – Переменные функции dop_task

Название

Тип

Комментарий

 

 

 

 

 

 

df

DataFrame

Параметр

функции,

матрица

 

 

смежности

 

 

 

 

 

temp

list

Список,

хранящий расстояние

 

 

между

маршрутами

каждой

 

 

точки

 

 

 

 

 

t

list

Список, хранящий в себе

 

 

результат функции

 

 

 

 

 

 

Функция с переданным параметром df вывела список с одним из

маршрутов [0, 1, 4], где 4 – действительно максимальная длина маршрута в

графе.

4.Вывод

Впрактической ходе работы был реализован алгоритм поиска кратчайшего пути в графе (поиск в ширину). Этот алгоритм был протестирован на простом графе. С помощью специальных графов с правильной треугольной решѐткой была протестирована работа этого алгоритма в зависимости от количества вершин. Судя по полученному графику, можно сделать вывод, что с каждым увеличением количества вершин M время работы алгоритма увеличивается линейно. В реальной практике такой алгоритм мог бы рассчитывать расстояние между городами.

Входе работы проблем не возникло.

5

Приложение

import pandas as pd import numpy as np

import matplotlib.pyplot as plt import networkx as nx

import time

matrix = [[0, 1, 1, 0, 0, 1], [1, 0, 1, 0, 0, 0], [1, 1, 0, 1, 1, 0], [0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 0], [1, 0, 0, 1, 0, 0]]

matrix2 = [[0, 0, 0, 0, 0, 1], [0, 0, 1, 0, 0, 0], [0, 1, 0, 1, 1, 0], [0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 0], [1, 0, 0, 1, 0, 0]]

def get_list_edges(df):

"""Построение списка рёбер"""

edges_list = []

for i in range(len(df.values)):

for j in range(len(df.values[i])): if df.values[i][j] != 0:

edges_list.append([i, j, df.values[i][j]]) return edges_list

def visualisation_graph(edges_list, length):

"""Визуализация графа"""

graph = nx.DiGraph() graph.add_nodes_from(length) graph.add_weighted_edges_from(edges_list) pos = nx.spring_layout(graph) nx.draw(graph, node_size=2000, pos=pos,

with_labels=True)

edge_labels = nx.get_edge_attributes(graph, "weight") nx.draw_networkx_edge_labels(graph, pos, edge_labels=edge_labels) plt.show()

def find_neighbours_matrix(graph_index, df):

"""Поиск соседей по матрице"""

neighbours_list = []

for j in range(len(df.values[graph_index])): if df.values[graph_index][j] != 0:

neighbours_list.append(j)

6

return neighbours_list

def breadeth_shortest_way(df, vertexes):

"Алгоритм поиска кратчайшего пути в ширину" neighbours = []

neighbours.append(find_neighbours_matrix(vertexes[0], df)) if vertexes[1] in neighbours[0]:

return len(neighbours) count = 0

while count < len(df): temp = []

for vertex in neighbours[count]: temp.extend(find_neighbours_matrix(vertex, df))

if vertexes[0] in temp: temp.remove(vertexes[0])

for i in temp:

for j in range(len(neighbours)): if i in neighbours[j]: temp.remove(i)

break neighbours.append(list(set(temp))) if vertexes[1] in neighbours[-1]:

break count += 1

return len(neighbours)

def regular_triangular_lattice(M):

"Построение графа с правильной треугольной решёткой" matrix = np.zeros((M**2, M**2))

for V in range(len(matrix)-1): R = V // M # номер строки

C = V % M # номер столбца if C < M:

matrix[V][V+1] = matrix[V+1][V] = 1 if R < M**2 and (V < M**2 - M):

matrix[V][V+M] = matrix[V+M][V] = 1

if (R % 2 == 0 and C % 2 == 0) or (R % 2 == 1 and C % 2 == 1): if C > 0:

matrix[V][V+M-1] = matrix[V+M-1][V] = 1 if C < M:

matrix[V][V+M+1] = matrix[V+M+1][V] = 1

# Удаление лишних ребер i = M - 1

j = M

for k in range(M - 1): try:

matrix[i][j] = 0 matrix[j][i] = 0 matrix[i][j+M] = 0 matrix[j+M][i] = 0

except BaseException:

7

pass i += M j += M

return matrix

def dop_task(df): temp = []

for i in range(len(df)):

for j in range(i, len(df)): if i != j:

temp.append([i, j, breadeth_shortest_way(df, [i, j])]) t = [0, 0, 0]

for i in range(len(temp)): if temp[i][2] > t[2]:

t = temp[i]

return t

def main():

# Задание 1 m = matrix2 length = []

[length.append(i) for i in range(len(m))]

df = pd.DataFrame(np.array(m), columns=length, index=length)

visualisation_graph(get_list_edges(df), length)

# Задание 2 и 3 print(breadeth_shortest_way(df, [0, 4]))

# Доп задание print(dop_task(df))

# Задание 4

m = regular_triangular_lattice(3) length = []

[length.append(i) for i in range(len(m))]

df = pd.DataFrame(np.array(m), columns=length, index=length)

visualisation_graph(get_list_edges(df), length)

# Задание 5

N = list(np.arange(2, 10)) t = []

for n in N:

m = regular_triangular_lattice(n) length = []

[length.append(i) for i in range(len(m))]

df = pd.DataFrame(np.array(m), columns=length, index=length)

start = time.time() for i in range(10):

breadeth_shortest_way(df, [0, len(df)]) t.append((time.time() - start)/10)

N = [num**2 for num in N]

8

plt.plot(N, t)

plt.xlabel('Количество узлов в графе') plt.ylabel('Время быстродействия t') plt.title('График зависимости t от M в алгоритме') plt.show()

main()

9

Соседние файлы в предмете Построение и анализ графовых моделей