Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab1_graphs.docx
Скачиваний:
6
Добавлен:
27.08.2024
Размер:
263.15 Кб
Скачать
  1. Дополнительное задание

Также в рамках дополнительного задания создается функция dop_task, которая по таблице данных ищет вершины в графе, у которых количество входящих в них ребер превышает количество исходящих на заданную величину. Переменные, используемые в функции, представлены в таблице 15. Листинг функции представлен в Приложении.

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

Название

Тип

Комментарий

data

DataFrame

Параметр функции, матрица записей

vertexes

list

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

number

int

Параметр функции, фиксированное значение

Функция с переданным параметром «1» вывела единственную подходящую вершину «Metro Station 2».

  1. Вывод

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

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

Приложение

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import networkx as nx

import sys

import time

# Задание 2

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

[0, 0, 0, 0, 1, 0],

[10, 8, 0, 4, 0, 0],

[5, 0, 0, 0, 1, 0],

[0, 0, 0, 0, 0, 1],

[0, 0, 0, 1, 0, 0]]

vertexes_names = ['University2', 'University1', 'Home', 'Metro Station 1',

'Metro Station 2', 'Metro Station 3']

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([vertexes_names[i],

vertexes_names[j], df.values[i][j]])

return edges_list

def visualisation_graph(edges_list):

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

graph = nx.DiGraph()

graph.add_nodes_from(vertexes_names)

graph.add_weighted_edges_from(edges_list)

pos = nx.shell_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 info_graph(df):

"""Представление графа в виде массива записей"""

data_list = []

parents_list = [] # Список родителей

child_list = [] # Список детей

child_weights_list = [] # Веса исходящих ребер

parents_weight_list = [] # Веса инцидентных ребер

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

for j in range(len(df.values[i])):

if i != j:

if df.values[i][j] != 0:

child_list.append(vertexes_names[j])

child_weights_list.append(df.values[i][j])

if df.values[j][i] != 0:

parents_list.append(vertexes_names[j])

parents_weight_list.append(df.values[j][i])

data_list.append([i, vertexes_names[i], len(child_list),

child_list.copy(), child_weights_list.copy(),

len(parents_list), parents_list.copy(),

parents_weight_list.copy()])

parents_list.clear()

child_list.clear()

child_weights_list.clear()

parents_weight_list.clear()

return data_list

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 \

and vertexes_names[j] not in neighbours_list:

neighbours_list.append(vertexes_names[j])

if df.values[j][graph_index] != 0 \

and vertexes_names[j] not in neighbours_list:

neighbours_list.append(vertexes_names[j])

return neighbours_list

def find_chain_matrix(vertexes, df):

"""Поиск цепи в матрице по заданным вершинам"""

for i in range(len(vertexes)-1):

if df.loc[vertexes[i]][vertexes[i+1]] == 0:

return False

return True

def find_vertexes_edge_sum_matrix(df, fixed_number):

"""Поиск вершин, сумма инцидентных ребер которых

больше заданной в матрице"""

vertexes = []

for i in range(len(df)):

if df.iloc[:, i].sum() + df.iloc[i].sum() > fixed_number:

vertexes.append(df.columns[i])

return vertexes

def find_sum_edges_matrix(df):

"""Поиск количества рёбер в графе по матрице"""

sum_egdes = 0

for i in range(len(df)):

for j in range(len(df.iloc[i])):

if df.iloc[[j], [i]].values[0][0] > 0:

sum_egdes += 1

return sum_egdes

def find_neighbours_edges(vertex, edges_list):

"""Поиск соседей по списке ребер"""

neighbours_list = []

for i in range(len(edges_list)):

if vertex == edges_list[i][0]:

neighbours_list.append(edges_list[i][1])

if vertex == edges_list[i][1]:

neighbours_list.append(edges_list[i][0])

return neighbours_list

def find_chain_edges(vertexes, edges_list):

"""Поиск цепи в списке ребер по заданным вершинам"""

count = 0

for i in range(len(vertexes)-1):

for j in range(len(edges_list)):

if edges_list[j][0] == vertexes[i] and (

edges_list[j][1] == vertexes[i+1]):

count += 1

break

if count == len(vertexes) - 1:

return True

else:

return False

def find_vertexes_edge_sum_edges(edges_list, fixed_number):

"""Поиск вершин, сумма инцидентных ребер которых больше заданной

в списке ребер"""

vertexes_names

vertexes = []

for i in range(len(vertexes_names)):

sum = 0

for j in range(len(edges_list)):

if vertexes_names[i] in edges_list[j]:

sum += edges_list[j][2]

if sum > fixed_number:

vertexes.append(vertexes_names[i])

return vertexes

def find_sum_edges_edges(edges_list):

"""Поиск количества рёбер в графе по списку ребер"""

return len(edges_list)

def find_neighbours_datalist(vertex_index, data):

"""Поиск соседей по таблице данных"""

vertexes = []

[vertexes.append(i) for i in data.iloc[vertex_index]['Список детей']]

[vertexes.append(i) for i in data.iloc[vertex_index]['Список родителей']]

return vertexes

def find_chain_datalist(vertexes, data):

"""Поиск цепи в таблице данных по заданным вершинам в таблице данных"""

count = 0

for i in range(len(vertexes)-1):

if vertexes[i+1] in data.loc[

data['Имя вершины'] == vertexes[i]]['Список детей'].values[0]:

count += 1

if count == len(vertexes)-1:

return True

else:

return False

def find_vertexes_edge_sum_datalist(data, fixed_number):

"""Поиск вершин, сумма инцидентных ребер которых больше заданной"""

vertexes = []

for i in range(len(data.index)):

count = sum(data.iloc[i]['Веса исходящих ребер']) + (

sum(data.iloc[i]['Веса входящих ребер']))

if count > fixed_number:

vertexes.append(data.iloc[i]['Имя вершины'])

return vertexes

def find_sum_edges_datalist(data):

"""Поиск количества рёбер в графе по таблице данных"""

count = 0

for i in range(len(data.index)):

count += int(data.iloc[i]['Количество детей'])

return count

def dop_task(data, number):

"""Поиск вершин, у которых количество входящих в них ребер превышает

количество исходящих на заданную величину"""

vertexes = []

for i in range(len(data.index)):

if len(data.iloc[i]['Список детей']) + number == (

len(data.iloc[i]['Список родителей'])):

vertexes.append(data.iloc[i]['Имя вершины'])

return vertexes

def main():

# Задание 2

df = pd.DataFrame(np.array(matrix), columns=vertexes_names,

index=vertexes_names)

print(df, '\n')

# Задание 3

edges_list = get_list_edges(df)

print(edges_list, '\n')

# Задание 4

visualisation_graph(edges_list)

# Задание 5

data_list = info_graph(df)

data_columns = ['№ Вершины', 'Имя вершины', 'Количество детей',

'Список детей', 'Веса исходящих ребер',

'Количество родителей', 'Список родителей',

'Веса входящих ребер']

df_2 = pd.DataFrame(np.array(data_list, dtype=object),

columns=data_columns,)

print(df_2, '\n')

# Задание 6

number_vertex = int(input(

'Введите номер вершины для поиска соседей (число): '))

numbers_for_chain = []

while True:

try:

numbers_for_chain.append(int(input(

'Введите номер вершины для цепи (число): ')))

except BaseException:

break

vertexes_for_chain = []

[vertexes_for_chain.append(vertexes_names[i]) for i in numbers_for_chain]

fixed_number = int(input('Введите заданную величину (число): '))

# Через матрицу смежности

neighbours1 = find_neighbours_matrix(number_vertex, df)

chain1 = find_chain_matrix(vertexes_for_chain, df)

vertexes1 = find_vertexes_edge_sum_matrix(df, fixed_number)

sum_edges1 = find_sum_edges_matrix(df)

print(find_neighbours_matrix.__doc__, ': ', neighbours1)

print(find_chain_matrix.__doc__, ': ', chain1)

print(find_vertexes_edge_sum_matrix.__doc__, ': ', vertexes1)

print(find_sum_edges_matrix.__doc__, ': ', sum_edges1, '\n')

# Через список рёбер

neighbours2 = find_neighbours_edges(vertexes_names[number_vertex],

edges_list)

chain2 = find_chain_edges(vertexes_for_chain, edges_list)

vertexes2 = find_vertexes_edge_sum_edges(edges_list, fixed_number)

sum_edges2 = find_sum_edges_edges(edges_list)

print(find_neighbours_edges.__doc__, ': ', neighbours2)

print(find_chain_edges.__doc__, ': ', chain2)

print(find_vertexes_edge_sum_edges.__doc__, ': ', vertexes2)

print(find_sum_edges_edges.__doc__, ': ', sum_edges2, '\n')

# Через таблицу данных

neighbours3 = find_neighbours_datalist(number_vertex, df_2)

chain3 = find_chain_datalist(vertexes_for_chain, df_2)

vertexes3 = find_vertexes_edge_sum_datalist(df_2, fixed_number)

sum_edges3 = find_sum_edges_datalist(df_2)

print(find_neighbours_datalist.__doc__, ': ', neighbours3)

print(find_chain_datalist.__doc__, ': ', chain3)

print(find_vertexes_edge_sum_datalist.__doc__, ': ', vertexes3)

print(find_sum_edges_datalist.__doc__, ': ', sum_edges3, '\n')

# Задание 7

print('Размер матрицы смежности =', sys.getsizeof(df), 'байт.')

print('Размер списка ребер =', sys.getsizeof(edges_list), 'байт.')

print('Размер таблицы данных =', sys.getsizeof(df_2), 'байт.')

# Задание 8

print('\n', 'Время выполнений каждой функций 10**6 раз', '\n')

times = 100

start = time.time()

[find_neighbours_matrix(number_vertex, df) for i in range(times)]

print(find_neighbours_matrix.__doc__, '=',

time.time() - start, 'c.')

start = time.time()

[find_chain_matrix(vertexes_for_chain, df) for i in range(times)]

print(find_chain_matrix.__doc__, '=',

time.time() - start, 'c.')

start = time.time()

[find_vertexes_edge_sum_matrix(df, fixed_number) for i in range(times)]

print(find_vertexes_edge_sum_matrix.__doc__, '=',

time.time() - start, 'c.')

start = time.time()

[find_sum_edges_matrix(df) for i in range(times)]

print(find_sum_edges_matrix.__doc__, '=',

time.time() - start, 'c.', '\n')

start = time.time()

[find_neighbours_edges(vertexes_names[number_vertex],

edges_list) for i in range(times)]

print(find_neighbours_edges.__doc__, '=',

time.time() - start, 'c.')

start = time.time()

[find_chain_edges(vertexes_for_chain, edges_list) for i in range(times)]

print(find_chain_edges.__doc__, '=',

time.time() - start, 'c.')

start = time.time()

[find_vertexes_edge_sum_edges(edges_list, fixed_number)

for i in range(times)]

print(find_vertexes_edge_sum_edges.__doc__, '=',

time.time() - start, 'c.')

start = time.time()

[find_sum_edges_edges(edges_list) for i in range(times)]

print(find_sum_edges_edges.__doc__, '=',

time.time() - start, 'c.', '\n')

start = time.time()

[find_neighbours_datalist(number_vertex, df_2) for i in range(times)]

print(find_neighbours_datalist.__doc__, '=',

time.time() - start, 'c.')

start = time.time()

[find_chain_datalist(vertexes_for_chain, df_2) for i in range(times)]

print(find_chain_datalist.__doc__, '=',

time.time() - start, 'c.')

start = time.time()

[find_vertexes_edge_sum_datalist(df_2, fixed_number) for i in range(times)]

print(find_vertexes_edge_sum_datalist.__doc__, '=',

time.time() - start, 'c.')

start = time.time()

[find_sum_edges_datalist(df_2) for i in range(times)]

print(find_sum_edges_datalist.__doc__, '=',

time.time() - start, 'c.', '\n')

# Доп задание

number = 1

print(dop_task(df_2, number))

main()

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