
- •Задание на курсовую работу
- •Аннотация
- •Содержание
- •Введение
- •1. Система непересекающихся множеств
- •1.1 Описание структуры
- •1.2 Способы оптимизации
- •2. Хранение графа
- •Сортировка слиянием
- •Алгоритм краскала
- •4.1 Остовное дерево
- •4.2 Алгоритм Краскала
- •Заключение
- •Список использованных источников
- •Приложение а исходный код программы
Список использованных источников
Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford. Introduction to Algorithms. — 3rd. — MIT Press, 2009. — ISBN 0-262-03384-4.
Курс лекций осеннего семестра 2022 года по дисциплине «Алгоритмы и структуры данных». СПБ.: Пелевин М.С.: СПбГЭТУ ЛЭТИ, 2022.
Электронная энциклопедия Wikipedia. URL: https://ru.wikipedia.org/ (дата обращения: 12.12.2022)
Электронный ресурс Викиконспекты. URL: http://neerc.ifmo.ru/wiki/ (дата обращения: 12.12.2022).
Приложение а исходный код программы
===================== Main.py =====================
from MergeSort import MergeSort
from ArrayList import ArrayList
from graph import Graph
lines = []
with open('matrix.txt', 'r') as file:
line = file.readline()
for line in file:
lines.append([int(x) for x in line.split()])
file.close()
matrix_size = len(lines[0])
graph = Graph(matrix_size)
elem = 0
for i in range(0, matrix_size-1):
for j in range(i+1, matrix_size):
elem = lines[i][j]
if elem != 0:
graph.add_edge(elem, i, j)
graph.kruskall()
===================== Graph.py =====================
from MergeSort import MergeSort
from ArrayList import ArrayList
class Graph:
def __init__(self, num_nodes):
self.edges = ArrayList()
self.num_nodes = num_nodes
def add_edge(self, weight, num_node1, num_node2):
edge = ArrayList()
edge.add(weight)
edge.add(num_node1)
edge.add(num_node2)
self.edges.add(edge)
def find(self, parent, i):
if parent.get(i) == i:
return i
return self.find(parent, parent.get(i))
def merge_unions(self, parent, sizes, a, b):
a_parent = self.find(parent, a)
b_parent = self.find(parent, b)
#merge smaller to larger
if sizes.get(a_parent) < sizes.get(b_parent):
parent.set(a_parent, b_parent)
elif sizes.get(a_parent) > sizes.get(b_parent):
parent.set(b_parent, a_parent)
else: #if equal
parent.set(b_parent, a_parent)
sizes.set(a_parent, a_parent+1)
def kruskall(self):
MergeSort(self.edges, 0, self.edges.size()-1) #sorted graph
result = ArrayList()
result_arr = ArrayList()
number_edges = 0
i = 0
parent = ArrayList()
sizes = ArrayList()
for node in range(self.edges.size()):
parent.add(node)
sizes.add(0)
while number_edges < self.num_nodes-1:
weight = self.edges.get(i).get(0)
node1 = self.edges.get(i).get(1)
node2 = self.edges.get(i).get(2)
i += 1
a = self.find(parent, node1)
b = self.find(parent, node2)
if a!=b:
number_edges+=1
result_arr = ArrayList()
result_arr.add(weight)
result_arr.add(node1)
result_arr.add(node2)
result.add(result_arr)
self.merge_unions(parent, sizes, a, b)
sum = 0
for j in range(result.size()):
print(result.get(j).get(1), "--", result.get(j).get(2), result.get(j).get(0))
sum += result.get(j).get(0)
print("Общий вес: ", sum)
===================== ArrayList.py =====================
from array import array
import ctypes
class ArrayList():
def __init__(self):
self.count = 0
self.capacity = 16
self.array = self.make_array(self.capacity)
def size(self):
return self.count
def make_array(self, new_capacity):
return (new_capacity * ctypes.py_object)()
def get(self, i):
if i < 0 or i >= self.count:
print('Index is out of range')
return
return self.array[i]
def resize(self, new_capacity):
new_array = self.make_array(new_capacity)
for i in range(self.count):
new_array[i] = self.array[i]
self.array = new_array
self.capacity = new_capacity
def add(self, itm):
if self.count == self.capacity:
self.resize(2 * self.capacity)
self.array[self.count] = itm
self.count += 1
def indexOf(self, element):
for i in range(self.count):
if element == self.array[i]:
return i
return -1
def contains(self, element):
if self.indexOf(element) != -1:
return True
else:
return False
def isEmpty(self):
if self.count == 0:
return True
else:
return False
def set(self, index, element):
if index < 0 or index >= self.count:
print('Index is out of range')
return
self.array[index] = element
def remove_index(self, index):
if self.count == 0:
print("Array is empty")
return
if index < 0 or index >= self.count:
print('Index is out of range')
return
if index==self.count-1:
self.array[index] = 0
self.count-=1
return
for i in range(index, self.count-1):
self.array[i]=self.array[i+1]
self.array[self.count-1] = 0
self.count-=1
def remove_element(self, element):
index = self.indexOf(element)
if index != -1:
self.remove_index(index)
def split(self, str):
for i in range(len(str)):
if str[i]==' ':
continue
else:
self.add(str[i])
def clear(self):
del self.array
self.count = 0
def out(self):
print('[', end=' ')
for i in range(self.count):
print(self.get(i), end= ' ')
print(']')
def split(self, str):
str = str.split()
for i in range(len(str)):
self.add(str[i])
===================== MergeSort.py =====================
from array import array
import ctypes
from ArrayList import ArrayList
import random
def Merge(array, left, mid, right):
left_size = mid - left + 1
right_size = right - mid
left_list = ArrayList()
for i in range(0, left_size):
left_list.add(array.get(left+i))
right_list = ArrayList()
for j in range(0, right_size):
right_list.add(array.get(mid + 1 + j))
i = j = 0
k = left
while i < left_size and j < right_size:
if left_list.get(i).get(0) <= right_list.get(j).get(0):
array.set(k, left_list.get(i))
i += 1
else:
array.set(k, right_list.get(j))
j += 1
k += 1
while i < left_size:
array.set(k, left_list.get(i))
i += 1
k += 1
while i < right_size:
array.set(k, right_list.get(j))
j += 1
k += 1
def MergeSort(array, left, right):
if left < right:
mid = left + (right - left) // 2
MergeSort(array, left, mid)
MergeSort(array, mid+1, right)
Merge(array, left, mid, right)