
Дополнительное задание
Также в рамках дополнительного задания создается функция dop_task, которая по таблице данных ищет вершины в графе, у которых количество входящих в них ребер превышает количество исходящих на заданную величину. Переменные, используемые в функции, представлены в таблице 15. Листинг функции представлен в Приложении.
Таблица 15 – Переменные функции dop_task
-
Название
Тип
Комментарий
data
DataFrame
Параметр функции, матрица записей
vertexes
list
Список, хранящий результаты работы
number
int
Параметр функции, фиксированное значение
Функция с переданным параметром «1» вывела единственную подходящую вершину «Metro Station 2».
Вывод
В ходе работы я построил графы в ЭВМ при помощи матрицы смежности, множества пар вершин и массива структур, визуализировал граф согласно заданному варианту. В ходе работы я выяснил, что самым производительным представлением является множество пар вершин, так как он имеет меньший вес, а также существенное быстрое время работы. Для работы всё же удобнее матрица записей, так как она наглядная для человека.
В ходе работы проблем не возникло.
Приложение
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()