Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ianysheva_1.docx
Скачиваний:
14
Добавлен:
16.04.2021
Размер:
160.89 Кб
Скачать

ГУАП

КАФЕДРА № 41

ОТЧЕТ

ЗАЩИЩЕН С ОЦЕНКОЙ

ПРЕПОДАВАТЕЛЬ

ассистент

М.Н. Шелест

должность, уч. степень, звание

подпись, дата

инициалы, фамилия

ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №1

ПРЕДСТАВЛЕНИЕ ГРАФОВ В ЭВМ

по курсу: ПОСТРОЕНИЕ И АНАЛИЗ ГРАФОВЫХ МОДЕЛЕЙ

РАБОТУ ВЫПОЛНИЛА

СТУДЕНТКА ГР.

4716

С.А. Янышева

подпись, дата

инициалы, фамилия

Санкт-Петербург

2020

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

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

  1. Матрица смежности

Вариант работы №20.

Матрица смежности имеет следующий вид:

  1. Описание разработанной программы

В таблице №1 представлен список основных используемых переменных

Таблица №1 – Список основных используемых переменных

Название

Тип данных

Описание

matrica_smezh

numpy array

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

spisok_smezh

numpy array

Список смежности

massiv_zap

list

Массив записей

Листинг программного кода

import numpy as np

import matplotlib.pyplot as plt

import networkx as nx

import sys

import time

# =============================================================================

# Формирование списка смежности

# =============================================================================

def get_list_adjacency(matrix_adjacency):

list_adjacency = np.zeros(([len(matrix_adjacency[matrix_adjacency != 0]), 3]), dtype = np.int)

k = 0

for i in range(len(matrix_adjacency)):

for j in range(len(matrix_adjacency[i][matrix_adjacency[i] != 0])):

list_adjacency[k][0] = i

list_adjacency[k][1] = np.where(matrix_adjacency[i] != 0)[0][j]

list_adjacency[k][2] = matrix_adjacency[i][matrix_adjacency[i] != 0][j]

k += 1

return list_adjacency

# =============================================================================

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

# =============================================================================

def draw_gtaph(list_adjacency, pos, labels):

plt.figure(figsize = (8, 6))

G = nx.DiGraph()

G.add_weighted_edges_from(list_adjacency)

edge_labels = {}

for i in range(len(list_adjacency)):

edge_labels[(list_adjacency[i][0], list_adjacency[i][1])] = list_adjacency[i][2]

nx.draw(G, node_size = 2000, pos = pos, with_labels=True, labels = labels)

nx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels)

plt.show()

# =============================================================================

# Формарирование массива записей

# =============================================================================

def get_structure_matrix(matrix_adjacency, labels):

'''

0 - номер вершины

1 - подпись вершины

2 - исходящие дуги

3 - входящие дуги

4 - исходящие веса

5 - входящие веса

6 - количество исходящих

7 - количество входящих

'''

structure_matrix = [[0] * 8 for _ in range(len(matrix_adjacency))]

for i in range(len(matrix_adjacency)):

structure_matrix[i][0] = i

structure_matrix[i][1] = labels[i]

structure_matrix[i][2] = list(np.where(matrix_adjacency[i] != 0)[0])

structure_matrix[i][3] = list(np.where(matrix_adjacency[:, i] != 0)[0])

structure_matrix[i][4] = list(matrix_adjacency[i][matrix_adjacency[i] != 0])

structure_matrix[i][5] = list(matrix_adjacency[:, i][matrix_adjacency[:, i] != 0])

structure_matrix[i][6] = len(matrix_adjacency[matrix_adjacency[i] != 0])

structure_matrix[i][7] = len(matrix_adjacency[matrix_adjacency[:, i] != 0])

return structure_matrix

# =============================================================================

# Все соседи заданной вернины графа

# =============================================================================

# Чтение и проверка корректности введенного номер вершины

def get_node_number(len_matrix, type_matrix):

print('\n')

print('-'*117)

print('Определение всех соседей заданной вершины графа')

print('Определение производится по', type_matrix)

print('Необхлодимо ввести целое число')

flag = False

while flag == False:

try:

node_number = int(input('Введите номер вершины: '))

if node_number <= len(matrix_adjacency) and node_number >= 0:

flag = True

else:

print('Введена не существующая вершина, попробуйте еще раз')

except ValueError:

print('Вводить необходимо целые числа, попробуйте еще раз')

return node_number

# Матрица смежности

def neighbour_node_matrix_adjacency(matrix_adjacency, status, par):

if status == True:

node_number = get_node_number(len(matrix_adjacency), 'матрице смежности')

else:

node_number = par

rez = np.unique(np.concatenate([np.where(matrix_adjacency[node_number] != 0)[0],

np.where(matrix_adjacency[:, node_number] != 0)[0]], axis = None))

if len(rez) == 0:

rez = 'у вершины нет сосетей'

if status == True:

print('Cоседи вершины - ', node_number, 'состоят из: ', *rez)

print('-'*117)

# Списко смежности

def neighbour_node_list_adjacency(list_adjacency, status, par):

if status == True:

node_number = get_node_number(np.max(list_adjacency[:, :2]), 'списку смежности')

else:

node_number = par

rez = np.unique(np.concatenate([list_adjacency[:, 1][list_adjacency[:, 0] == node_number],

list_adjacency[:, 0][list_adjacency[:, 1] == node_number]]))

if len(rez) == 0:

rez = 'у вершины нету соседей'

if status == True:

print('Соседивершины графа - ', node_number, 'состоят из: ', *rez)

print('-'*117)

# Массив записей

def neighbour_node_structure_matrix(structure_matrix, status, par):

if status == True:

node_number = get_node_number(len(structure_matrix), 'массиву записей')

else:

node_number = par

rez = []

rez.extend(structure_matrix[node_number][2])

rez.extend(structure_matrix[node_number][3])

rez = set(rez)

if len(rez) == 0:

rez = 'у вершины енту соседей'

if status == True:

print('Соседи заданной вершины графа - ', node_number, 'состоят из: ', *rez)

print('-'*117)

# =============================================================================

# Проверка на цепь

# =============================================================================

# Представление цепи в виде списка смежности

def get_chain(len_matrix, type_matrix):

print('\n')

print('-'*117)

print('Проверка заданной последовательности на образование цепи')

print('Определение производится по', type_matrix)

print('Формат ввода через пробел без разделителей')

flag = False

while flag == False:

try:

chain = np.array(list(map(int, input('Введите цепь: ').strip().split(' '))), dtype = np.int)

if np.all(chain <= len_matrix) and np.all(chain >= 0):

flag = True

else:

print('Введены вершины, которых не существует')

except ValueError:

print('Необходимо вводить только целые цифры, попробуйте еще раз')

chain_adjacency = np.zeros([len(chain)-1, 2], dtype = np.int)

for i in range(1, len(chain)):

chain_adjacency[i-1][0] = chain[i-1]

chain_adjacency[i-1][1] = chain[i]

return chain, chain_adjacency

def get_chain_adjacency(chain):

chain_adjacency = np.zeros([len(chain)-1, 2], dtype = np.int)

for i in range(1, len(chain)):

chain_adjacency[i-1][0] = chain[i-1]

chain_adjacency[i-1][1] = chain[i]

return chain_adjacency

# Проверка на цепь по матрице смежности

def check_chain_matrix_adjacency(matrix_adjacency, status, par):

flag = True

if status == True:

chain, chain_adjacency = get_chain(len(matrix_adjacency), 'матрице смежности')

else:

chain_adjacency = par

for i in range(len(chain_adjacency)):

if matrix_adjacency[chain_adjacency[i][0]][chain_adjacency[i][1]] == 0:

flag = False

if status == True:

if flag == True:

print('Последовательность: ', *chain, 'образует цепь')

print('-'*117)

else:

print('Последовательность: ', *chain, 'не образует цепь')

print('-'*117)

# Проверка на цепь по списку смежности

def check_chain_list_adjacency(list_adjacency, status, par):

flag = True

if status == True:

chain, chain_adjacency = get_chain(np.max(list_adjacency[:, :2]), 'списку смежности')

else:

chain_adjacency = par

for i in range(len(chain_adjacency)):

if len(list_adjacency[(list_adjacency[:, 0] == chain_adjacency[i][0])

& (list_adjacency[:, 1] == chain_adjacency[i][1])]) == 0:

flag = False

if status == True:

if flag == True:

print('Последовательность: ', *chain, 'образует цепь')

print('-'*117)

else:

print('Последовательность: ', *chain, 'не образует цепь')

print('-'*117)

# Проверка на цепь по массиву записей

def check_chain_structure_matrix(structure_matrix, status, par):

flag = True

if status == True:

chain, chain_adjacency = get_chain(len(structure_matrix), 'массиву записей')

else:

chain_adjacency = par

for i in range(len(chain_adjacency)):

if chain_adjacency[i][1] not in structure_matrix[chain_adjacency[i][0]][2]:

flag = False

if status == True:

if flag == True:

print('Последовательность: ', *chain, 'образует цепь')

print('-'*117)

else:

print('Последовательность: ', *chain, 'не образует цепь')

print('-'*117)

# =============================================================================

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

# =============================================================================

def get_weight(type_matrix):

print('\n')

print('Определение вершин, сумма весов инцидентных ребер которых больше заданной величины')

print('Определение производится по', type_matrix)

print('Вес должден быть положиьтельным числом')

flag = False

while flag == False:

try:

weight = float(input('Введите вес: '))

if weight > 0:

flag = True

else:

print('Вес должен быть положительным, попробуйте еще раз')

except ValueError:

print('Вводить необходимо числа, попробуйте еще раз')

return weight

# Мартица смежности

def find_node_more_weight_matrix_adjacency(matrix_adjacency, status, par):

if status == True:

weight = get_weight('матрице смежности')

else:

weight = par

sum_weight_matrix_adjacency = np.zeros(len(matrix_adjacency))

for i in range(len(matrix_adjacency)):

sum_weight_matrix_adjacency[i] = np.sum(matrix_adjacency[i]) + np.sum(matrix_adjacency[:, i])

rez = np.where(sum_weight_matrix_adjacency > weight)[0]

if status == True:

print('Номера вершин, сумма весов инцидентных ребер которых больше - ',

weight, 'составляет: ', *rez)

print('-'*117)

# Список смежности

def find_node_more_weight_list_adjacency(list_adjacency, status, par):

if status == True:

weight = get_weight('списку смежности')

else:

weight = par

sum_weight_list_adjacency = np.zeros(np.max(list_adjacency))

for i in range(len(sum_weight_list_adjacency)):

sum_weight_list_adjacency[i] = (np.sum(list_adjacency[:, 2][list_adjacency[:, 0] == i]) +

np.sum(list_adjacency[:, 2][list_adjacency[:, 1] == i]))

rez = np.where(sum_weight_list_adjacency > weight)[0]

if status == True:

print('Номера вершин, сумма весов инцидентных ребер которых больше - ',

weight, 'составляет: ', *rez)

print('-'*117)

# Массив записей

def find_node_more_weight_structure_matrix(structure_matrix, status, par):

sum_weight_structure_matrix = np.zeros(len(structure_matrix))

for i in range(len(structure_matrix)):

sum_weight_structure_matrix[i] = sum(structure_matrix[i][4]) + sum(structure_matrix[i][5])

if status == True:

weight = get_weight('массиву записей')

else:

weight = par

rez = np.where(sum_weight_structure_matrix > weight)[0]

if status == True:

print('Номера вершин, сумма весов инцидентных ребер которых больше - ',

weight, 'составляет: ', *rez)

print('-'*117)

# =============================================================================

# Количества ребер в графе

# =============================================================================

def count_of_edge_matrix_adjacency(matrix_adjacency, status):

rez = len(matrix_adjacency[matrix_adjacency != 0])

if status == True:

print('Количество ребер в графе (матрица смежности): ', rez)

print('-'*109)

def count_of_edge_list_adjacency(list_adjacency, status):

rez = len(list_adjacency)

if status == True:

print('Количество ребер в графе (список смежности): ', rez)

print('-'*109)

def count_of_edge_structure_matrix(structure_matrix, status):

structure_matrix_edge_count = 0

for i in range(len(structure_matrix)):

structure_matrix_edge_count += len(structure_matrix[i][3])

if status == True:

print('Количество ребер в графе (массив записей): ', structure_matrix_edge_count)

print('-'*109)

# =============================================================================

# Память

# =============================================================================

def get_size(matrix_adjacency, list_adjacency, structure_matrix):

print('Матрица смежности занимает -', sys.getsizeof(matrix_adjacency), 'байт')

print('Список смежности занимает -', sys.getsizeof(list_adjacency), 'байт')

print('Массив записей занимает -', sys.getsizeof(structure_matrix), 'байт')

print('-'*109)

# =============================================================================

# Вызовы функций

# =============================================================================

# Задание матрица смежности

matrix_adjacency = np.array([[0, 0, 0, 0, 0, 0, 0],

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

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

[2, 0, 0, 0, 0, 0, 2],

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

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

[0, 0, 0, 0, 0, 0, 0]])

print('Матрица смежности имеет следующий вид:')

for i in range(len(matrix_adjacency)):

print(matrix_adjacency[i])

print('-'*109)

# Списко смежности

list_adjacency = get_list_adjacency(matrix_adjacency)

print('\n')

print('Cписок смежности имеет следующий вид:')

for i in range(len(list_adjacency)):

print(list_adjacency[i])

print('-'*109)

# Расположение вершин на графике

pos = {0: [0.6, 0.6],

1: [0.45, 0.45],

2: [0, 0.5],

3: [0.6, 0.2],

4: [0.2, 0.3],

5: [0.6, 0],

6: [0, 0]}

# Подписи вершин

labels = {0: 'Metis',

1: 'Negroid',

2: 'European',

3: 'Mongoloid',

4: 'Quadroon',

5: 'Mulatto',

6: 'Sambo'}

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

draw_gtaph(list_adjacency, pos, labels)

# Массив записей

structure_matrix = get_structure_matrix(matrix_adjacency, labels)

print('\n')

print('Индексы массива записей имеют следующий смысл:')

print('0 - номер вершины')

print('1 - подпись вершины')

print('2 - исходящие дуги')

print('3 - входящие дуги')

print('4 - исходящие веса')

print('5 - входящие веса')

print('6 - количество исходящих')

print('7 - количество входящих')

print('Массив записей имеет следующий вид:')

for i in range(len(structure_matrix)):

print(structure_matrix[i])

print('-'*109)

# Вес соседей заданной вершины графа

neighbour_node_matrix_adjacency(matrix_adjacency, status = True, par = None)

neighbour_node_list_adjacency(list_adjacency, status = True, par = None)

neighbour_node_structure_matrix(structure_matrix, status = True, par = None)

# Проверка на цепь

check_chain_matrix_adjacency(matrix_adjacency, status = True, par = None)

check_chain_list_adjacency(list_adjacency, status = True, par = None)

check_chain_structure_matrix(structure_matrix, status = True, par = None)

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

find_node_more_weight_matrix_adjacency(matrix_adjacency, status = True, par = None)

find_node_more_weight_list_adjacency(list_adjacency, status = True, par = None)

find_node_more_weight_structure_matrix(structure_matrix, status = True, par = None)

# Количество ребер в графе

count_of_edge_matrix_adjacency(matrix_adjacency, status = True)

count_of_edge_list_adjacency(list_adjacency, status = True)

count_of_edge_structure_matrix(structure_matrix, status = True)

# Память

get_size(matrix_adjacency, list_adjacency, structure_matrix)

# =============================================================================

# Время

# =============================================================================

def get_grid_matrix(count_node):

grid_matrix = np.zeros([count_node*count_node, count_node*count_node])

for i in range(count_node):

for j in range(count_node):

if j + 1 < count_node:

grid_matrix[i*count_node + j, i*count_node + j + 1] = np.random.randint(1, 15)

if i + 1 < count_node:

grid_matrix[i*count_node + j, (i + 1)*count_node + j] = np.random.randint(1, 15)

if j - 1 >= 0:

grid_matrix[i*count_node + j, i*count_node + j - 1] = np.random.randint(1, 15)

if i - 1 >= 0:

grid_matrix[i*count_node + j, (i - 1)*count_node + j] = np.random.randint(1, 15)

return grid_matrix

count_node = 30

matrix_adjacency = get_grid_matrix(count_node)

list_adjacency = get_list_adjacency(matrix_adjacency)

labels = np.arange(count_node*count_node)

structure_matrix = get_structure_matrix(matrix_adjacency, labels)

repit = 100

matrix_adjacency_t1 = np.zeros(repit)

list_adjacency_t1 = np.zeros(repit)

structure_matrix_t1 = np.zeros(repit)

matrix_adjacency_t2 = np.zeros(repit)

list_adjacency_t2 = np.zeros(repit)

structure_matrix_t2 = np.zeros(repit)

matrix_adjacency_t3 = np.zeros(repit)

list_adjacency_t3 = np.zeros(repit)

structure_matrix_t3 = np.zeros(repit)

matrix_adjacency_t4 = np.zeros(repit)

list_adjacency_t4 = np.zeros(repit)

structure_matrix_t4 = np.zeros(repit)

for i in range(repit):

t1 = time.time()

neighbour_node_matrix_adjacency(matrix_adjacency, status = False, par = 1)

matrix_adjacency_t1[i] = time.time() - t1

t2 = time.time()

neighbour_node_list_adjacency(list_adjacency, status = False, par = 1)

list_adjacency_t1[i] = time.time() - t2

t3 = time.time()

neighbour_node_structure_matrix(structure_matrix, status = False, par = 1)

structure_matrix_t1[i] = time.time() - t3

t4 = time.time()

check_chain_matrix_adjacency(matrix_adjacency, status = False, par = [[0, 1], [1, 2], [2, 3]])

matrix_adjacency_t2[i] = time.time() - t4

t5 = time.time()

check_chain_list_adjacency(list_adjacency, status = False, par = [[0, 1], [1, 2], [2, 3]])

list_adjacency_t2[i] = time.time() - t5

t6 = time.time()

check_chain_structure_matrix(structure_matrix, status = False, par = [[0, 1], [1, 2], [2, 3]])

structure_matrix_t2[i] = time.time() - t6

t7 = time.time()

find_node_more_weight_matrix_adjacency(matrix_adjacency, status = False, par = 10)

matrix_adjacency_t3[i] = time.time() - t7

t8 = time.time()

find_node_more_weight_list_adjacency(list_adjacency, status = False, par = 10)

list_adjacency_t3[i] = time.time() - t8

t9 = time.time()

find_node_more_weight_structure_matrix(structure_matrix, status = False, par = 10)

structure_matrix_t3[i] = time.time() - t9

t10 = time.time()

count_of_edge_list_adjacency(list_adjacency, status = False)

matrix_adjacency_t4[i] = time.time() - t10

t11 = time.time()

count_of_edge_list_adjacency(list_adjacency, status = False)

list_adjacency_t4[i] = time.time() - t11

t12 = time.time()

count_of_edge_structure_matrix(structure_matrix, status = False)

structure_matrix_t4[i] = time.time() - t12

print('Время выполнения функций')

print('Вес соседей заданной вершины графа')

print('Матрица смежности: ', np.mean(matrix_adjacency_t1))

print('Списко смежности: ', np.mean(list_adjacency_t1))

print('Массив записей: ', np.mean(structure_matrix_t1))

print('-'*109)

print('Проверка на цепь')

print('Матрица смежности: ', np.mean(matrix_adjacency_t2))

print('Списко смежности: ', np.mean(list_adjacency_t2))

print('Массив записей: ', np.mean(structure_matrix_t2))

print('-'*109)

print('Вершины, сумма весов инцидентных ребер которых больше заданной величины')

print('Матрица смежности: ', np.mean(matrix_adjacency_t3))

print('Списко смежности: ', np.mean(list_adjacency_t3))

print('Массив записей: ', np.mean(structure_matrix_t3))

print('-'*109)

print('Количество ребер в графе')

print('Матрица смежности: ', np.mean(matrix_adjacency_t4))

print('Списко смежности: ', np.mean(list_adjacency_t4))

print('Массив записей: ', np.mean(structure_matrix_t4))

print('-'*109)

На рисунке 1 представлен результат выполнения подпрограмм на определение всех соседей заданной вершины графа, для всех типов матриц.

Рисунок 1 – Поиск соседей заданной вершины графа

На рисунке 2 представлен результат выполнения подпрограмм, определяющих цепи для все типов матриц.

Рисунок 2 – Проверка на цепь

На рисунке 3 представлен результат выполнение подпрограмм определяющих сумму весов инцидентных ребер, которых больше заданной величины, для всех типов матриц.

Рисунок 3 – Сумма весов инцидентных ребер

На рисунке 4 представлен результат определения числа ребер для всех типов матриц.

Рисунок 4 – Число ребер

На рисунке 5 представлен результат определения занимаемой память для всех типов матриц.

Рисунок 5 - Память

На рисунке 6 представлен граф.

Рисунок 6 – Граф

На рисунке 7 представлена матрица смежности, распечатанная в консоли.

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

На рисунке 8 представлен список смежности, распечатанный в консоли.

Рисунок 8 – Список смежности

На рисунке 9 представлен массив записей, распечатанный в консоли.

Рисунок 9 – Массив записей

На рисунке 10 представлены результаты определения среднего времени выполнения подпрограмм. Каждая из подпрограмм запускалась 1000000 раз при одинаковых входных условиях, засекалось время ее выполнения. Полученные результаты были усреднены.

Рисунок 10 – Среднее время выполнения подпрограмм

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