ГУАП
КАФЕДРА № 41
ОТЧЕТ ЗАЩИЩЕН С ОЦЕНКОЙ
ПРЕПОДАВАТЕЛЬ
ассистент |
|
|
|
М.Н. Шелест |
|
|
|
|
|
|
|
|
|
|
должность, уч. степень, звание |
|
подпись, дата |
|
инициалы, фамилия |
ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №3
СЛУЧАЙНЫЕ ГРАФЫ И ИХ СВОЙСТВА
по курсу: ПОСТРОЕНИЕ И АНАЛИЗ ГРАФОВЫХ МОДЕЛЕЙ
РАБОТУ ВЫПОЛНИЛ СТУДЕНТ ГР. №
подпись, дата |
|
инициалы, фамилия |
Санкт-Петербург 2022
Цель работы
Рассмотреть различные подходы к генерации случайных графов в ЭВМ. Провести анализ свойств созданных графов.
Индивидуальный вариант
Задание согласно индивидуальному варианту №10 в соответствии с таблицами 1-2.
Таблица 1 – Задание индивидуального варианта (тип случайного графа)
№ варианта Алгоритм создания графа
Регулярные структуры
Дана квадратная решетка размером N на N. Закрашивание клетки такой решетки эквивалентно тому, что в граф добавляется вершина. Между двумя вершинами графа ставится ребро тогда, когда клетки решетки, соответствующие этим вершинам, прилегают друг к другу по горизонтали или вертикали (N = 10, р меняется от 0 до 1 с шагом 0.05).
Закрасить M случайно выбранных областей, имеющих форму квадрата 2 на 2 клетки ( = 2/4, расположение области определяется координатами ее левого верхнего угла,
10квадрат должен целиком располагаться на решетке, области могут полностью или частично перекрывать друг друга, но
вершины при этом не дублируются. - округление вверх до целого числа).
Таблица 2 – Задание индивидуального варианта (свойства случайного графа)
№ варианта |
|
Задание |
|
|
|
||
|
Построить график зависимости вероятности существования |
||
|
пути между первым и последним столбцами решетки от |
||
10 |
вероятности |
закрашивания клетки (объем выборки для |
|
вычисления вероятности существования пути выбрать |
|||
|
|||
|
самостоятельно, если задано несколько значений параметра |
||
|
М, должно быть по одному графику для каждого значения). |
||
|
|
|
2
Ход работы
1) Написали подпрограмму, реализующую отображение графа на экране. Функция view_graph для отображения графа на экране. Список использованных переменных в соответствии с таблицей 3, код в соответствии с листингом 1. Результат работы функций в соответствии с рисунком 1.
Таблица 3 – Список переменных подпрограммы из Листинга 1
Название |
Значение |
|
|
adj_mat |
Матрица смежности |
|
|
peaks |
Список вершин |
|
|
curved_value |
Тип отображения связей (прямые или округлие) |
|
|
g |
Объект графа |
|
|
list_edges |
Список ребер |
|
|
weights |
Список весов ребер |
|
|
Листинг 1 – Подпрограмма отображения графа на экране
# Рисует график по МАТРИЦЕ СМЕЖНОСТИ
def view_graph(adj_mat, peaks = [], curved_value = False): if not peaks: peaks = list(adj_mat)
g = ig.Graph() |
# |
создание ориентированного графа |
g.add_vertices(len(peaks))# |
добавление вершин графа |
# добавление идентификаторов и меток к вершинам for i in range(len(g.vs)):
g.vs[i]["id"]= peaks[i] if isinstance(peaks[i], int)
else i
g.vs[i]["label"]= peaks[i]
# получаем список ребер и их веса
list_edges = [(row, col) for col in range(len(adj_mat)) for row in range(len(adj_mat)) if adj_mat[row][col]]
g.add_edges(list_edges) # задаем ребра
# задаем веса ребер
weights = [adj_mat[row][col] for col in range(len(adj_mat)) for row in range(len(adj_mat)) if adj_mat[row][col]]
g.es['label'] = weights |
|
g.es['edge_width'] = weights |
|
g.es["curved"] = curved_value |
# кривизна ребер |
ig.plot(g, bbox = (500, 500) |
# построение графика |
, margin = 30 |
|
, vertex_color = 'white') |
|
return 1 |
|
3
Рисунок 1 – Результат работы функции view_graph
4
2) Согласно варианту, реализовали функцию создания матрицы смежности случайного графа, основываясь на заданном алгоритме.
Визуализировали полученный граф.
Функции get_adjacency_matrix_by_algorithm, get_adjacency_matrix_by_square_lattice и get_square_lattice_by_algorithm для
«Закрашивания» квадратной решетки случайным образом на основе коэффициента вероятности закрашивания p и последующего построения матрицы смежности графа на основе полученной решетки. Список использованных переменных в соответствии с таблицами 4-6, код в соответствии с листингами 2-4. Результат работы функций в соответствии с рисунками 2-3.
Таблица 4 – Список переменных подпрограммы из Листинга 2
Название |
Значение |
p Коэффициент вероятности закрашивания клетки решетки
N Размер решетки
Листинг 2 – Подпрограмма заполнения квадратной решетки
def get_square_lattice_by_algorithm_10(N, p): |
|
||
square_lattice = [[0] * N for i in range(N)] |
# нулевая |
||
матрицы размера N*N |
|
|
|
M = math.ceil(p * N**2 / 4) |
# кол-во областей |
||
# print('Кол-во областей M =', M, end='\n') |
|
||
for iter in range(M): |
# Закрашивание |
областей 2*2 |
|
клетки |
|
|
|
row = rd.randint(0, N-2) |
|
|
|
col = rd.randint(0, N-2) |
|
|
|
square_lattice[row][col] = square_lattice[row][col+1] \ |
|||
= |
square_lattice[row+1][col] |
= |
|
square_lattice[row+1][col+1] = 1 |
|
|
|
return square_lattice |
|
|
|
|
|
|
|
5
Таблица 5 – Список переменных подпрограммы из Листинга 3
Название |
Значение |
|
|
square_lattice |
Заполненная квадратная решетка |
|
|
N |
Размер решетки |
|
|
adj_mat |
Матрица смежности |
|
|
row |
Итератор по номерам строк |
|
|
col |
Итератор по номерам столбцов |
|
|
Листинг 3 – Подпрограмма перевода квадратной решетки в матрицу смежности графа согласно варианту
def get_adjacency_matrix_by_square_lattice(square_lattice): N = len(square_lattice)
adj_mat = pd.DataFrame([[0] * N**2 for iter in range(N**2)])
# нулевая матрица смежности
for row in range(N): # заполнение матрицы смежности for col in range(N):
if square_lattice[row][col] !=0:#закрашена ли клетка if col-1 > 0 and square_lattice[row][col-1] !=
0: # связь с левой клеткой
adj_mat[col + row * (N-1)][(col-1) + row *
(N-1)] = \
adj_mat[(col-1) + row * (N-1)][col + row *
(N-1)] = 1
if col+1 < N and square_lattice[row][col+1] !=
0: # связь с правой клеткой
adj_mat[col + row * (N-1)][(col+1) + row *
(N-1)] = \
adj_mat[(col+1) + row * (N-1)][col + row *
(N-1)] = 1
if row-1 > 0 and square_lattice[row-1][col] !=
0: # связь с верхней клеткой
adj_mat[col + row * (N-1)][col + (row-1) *
(N-1)] = \
adj_mat[col + (row-1) * (N-1)][col + row *
(N-1)] = 1
if row+1 < N and square_lattice[row+1][col] !=
0: # связь с нижней клеткой
adj_mat[col + row * (N-1)][col + (row+1) *
(N-1)] = \
adj_mat[col + (row+1) * (N-1)][col + row *
(N-1)] = 1
for row in reversed(range(N**2)): # удаление личшних вершин if sum(adj_mat[row]) == 0:
adj_mat.drop(labels=[row], axis=0, inplace=True)
6
|
adj_mat.drop(labels=[row], axis=1, inplace=True) |
|
adj_mat.reset_index(drop=True, inplace=True) |
# обновление |
|
индексов |
|
|
adj_mat.columns = range(len(adj_mat)) # обновление названий |
||
колонок |
|
|
return adj_mat |
|
|
|
|
|
Таблица 6 – Список переменных подпрограммы из Листинга 4 |
||
|
|
|
Название |
Значение |
|
|
|
|
algorithm |
Ссылка на функцию алгоритма построения квадратной |
|
|
решетки |
|
|
|
|
p |
Коэффициент вероятности закрашивания клетки решетки |
|
|
|
|
N |
Размер решетки |
|
|
|
|
M |
Количество областей решетки (2*2 клетки) которые нужно |
|
|
закрасить |
|
|
|
|
square_lattice |
Заполненная квадратная решетка |
|
|
|
|
Листинг 4 – Подпрограмма создания матрицы смежности на основе функций
«закрашивания» квадратной решетки и перевода ее в матрицу смежности
графа
def get_adjacency_matrix_by_algorithm(algorithm, p = 0.5, N = 10):
square_lattice = algorithm(N, p)
# print('\nЗаполненая квадратная решетка:', *square_lattice, sep='\n')
return get_adjacency_matrix_by_square_lattice(square_lattice)
7
Рисунок 2 – Результаты работы функций get_adjacency_matrix_by_algorithm, get_adjacency_matrix_by_square_lattice и get_square_lattice_by_algorithm
Рисунок 3 – Результат работы функции view_graph на основе результата функции get_adjacency_matrix_by_algorithm
8
3) Реализовали функцию поиска спектра степеней графа. Построили график по полученному спектру для графа.
Функции get_graph_degree_spectrum и plot_info для нахождения спектра степеней графа и отображения найденных данных на графе. Список использованных переменных в соответствии с таблицами 7-8, код в соответствии с листингами 5-6. Результат работы функций в соответствии с рисунком 4, график в соответствии с рисунком 5.
Таблица 7 – Список переменных подпрограммы из Листинга 5
Название |
Значение |
|
|
data |
Датафрейм данных для построения графика |
|
|
xdata |
Название столбца данных на по оси X |
|
|
ydata |
Название столбца данных на по оси Y |
|
|
title |
Заголовок графика |
|
|
xlabel |
Подпись оси X |
|
|
ylabel |
Подпись оси Y |
|
|
type |
Тип графика (plot – 0 или bar – 1) |
|
|
xstep |
Цена деления по оси X |
|
|
ystep |
Цена деления по оси Y |
|
|
Листинг 5 – Подпрограмма построения графика
def plot_info(data, xdata, ydata, title = 'График', xlabel = 'x', ylabel = 'y', type = 0, xstep = 1, ystep = 1):
fig, ax = plt.subplots() plt.title(title) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) ax.grid()
ax.xaxis.set_major_locator(ticker.MultipleLocator(xstep)) ax.yaxis.set_major_locator(ticker.MultipleLocator(ystep)) match type:
case 0: plt.plot(data[xdata], data[ydata]) case 1: plt.bar(data[xdata], data[ydata])
plt.tight_layout() plt.show()
9
Таблица 8 – Список переменных подпрограммы из Листинга 6
Название |
Значение |
|
|
adj_mat |
Матрица смежности |
|
|
deg_spec |
Датафрейм спектра степеней графа |
|
|
vertex_degree |
Список степеней вершин графа |
|
|
degree |
Итератор по возможным степеням вершин в графе |
|
|
d |
Итератор по списку степеней вершин графа |
|
|
Листинг 6 – Подпрограмма нахождения спектра степеней графа
def get_graph_degree_spectrum(adj_mat):
deg_spec = pd.DataFrame([], columns=['degree', 'frequence'])
# подсчет степеней вершин
vertex_degree = adj_mat.astype(bool).sum(axis=1)
# опрнднлнние частот степеней вершин
for degree in range(min(vertex_degree), max(vertex_degree)+1):
deg_spec.loc[len(deg_spec)] = [degree, len([d for d in vertex_degree if d == degree])]
plot_info(data=deg_spec
,xdata='degree'
,ydata='frequence'
,title='График спектра степеней графа'
,xlabel='Степень вершины'
,ylabel='Кол-во вершин'
,type=1)
return deg_spec
10