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

lab2_graphs

.docx
Скачиваний:
3
Добавлен:
27.08.2024
Размер:
262.91 Кб
Скачать

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

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

  1. Ход работы

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

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

Рисунок 2 – Изображение графа

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

Рисунок 3 – Блок-схема алгоритма

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

Рисунок 4 – Результат работы алгоритма

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

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

Название

Тип данных

Комментарий

df

Dataframe

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

vertexes

list

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

neighbours

list

Список, содержащий соседей начальной точки в n-ом порядке

count

int

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

temp

list

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

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

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

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

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

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

Также в рамках дополнительного задания создается функция dop_task, которая по матрице смежностей выдаёт узлы графов, между которым максимальная длина пути. Переменные, используемые в функции, представлены в таблице 2. Листинг функции представлен в Приложении.

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

Название

Тип

Комментарий

df

DataFrame

Параметр функции, матрица смежности

temp

list

Список, хранящий расстояние между маршрутами каждой точки

t

list

Список, хранящий в себе результат функции

Функция с переданным параметром df вывела список с одним из маршрутов [0, 1, 4], где 4 – действительно максимальная длина маршрута в графе.

  1. Вывод

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

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

Приложение

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)

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:

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]

plt.plot(N, t)

plt.xlabel('Количество узлов в графе')

plt.ylabel('Время быстродействия t')

plt.title('График зависимости t от M в алгоритме')

plt.show()

main()

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