- Мне нужен раздел get_all_msts, чтобы найти Kruskals mst вместо любого (который я пытался изменить, и код мне это не понравилось). Это сделано для того, чтобы я мог убедиться, что мой код правильно регистрируется, когда существует более одного MST, а также отсортировать все возможные пути, чтобы убедиться, что наш минимум имеет наименьший вес. Я мог бы поместить этот код в kruskal_mst, но суть проекта заключается в определении времени, которое занимает алгоритм Крускала с n узлами.
- Таймер, предназначенный для регистрации того, насколько быстро работает алгоритм Крускала, не изменился с 0, поэтому он должен тоже может быть ошибка
- Поскольку мой граф неориентированный, счетчик ребер считает ребро между x, y не равным y, x, хотя на самом деле это так. Каждый раз, когда я меняю этот раздел, мой метод is_connected начинает показывать ошибки. Если бы кто-нибудь мог помочь с какой-либо частью этого, я был бы очень признателен.
Вот мой код:
import random
import time
from collections import defaultdict
max_weight = 20
debug = True
class Graph:
def __init__(self):
# initialize a defaultdict to store the graph edges
self.edges = defaultdict(list)
def add_edge(self, u, v, weight):
# Add an edge between nodes 'u' and 'v' with given weight
self.edges.append((v, weight))
self.edges[v].append((u, weight)) # Since it's an undirected graph, add edge both ways
def generate_random_graph(self, n):
# generate a random undirected graph with 'n' nodes
while True:
for i in range(n):
for j in range(i + 1, n):
# Randomly decide whether to add an edge between nodes
if random.random() < 0.5: # Adjust the probability for edges here
weight = random.randint(1, max_weight)
self.add_edge(i, j, weight)
if(self.is_connected()):
break;
def kruskal_mst(self):
# Kruskal's algorithm to find the minimum spanning tree
mst = []
parent = {}
rank = {}
def find(node):
# find the parent node of the set
if parent[node] != node:
parent[node] = find(parent[node])
return parent[node]
def union(u, v):
# Union operation to merge two sets
root_u = find(u)
root_v = find(v)
if root_u != root_v:
if rank[root_u] < rank[root_v]:
parent[root_u] = root_v
elif rank[root_u] > rank[root_v]:
parent[root_v] = root_u
else:
parent[root_v] = root_u
rank[root_u] += 1
# initialize parent and rank for each node
for node in self.edges:
parent[node] = node
rank[node] = 0
# sort edges by weight
edges = [(weight, u, v) for u in self.edges for v, weight in self.edges]
edges.sort()
# Make MST
for weight, u, v in edges:
if find(u) != find(v):
union(u, v)
mst.append((u, v, weight))
return mst
def is_connected(self):
# Check if the graph is connected using BFS
visited = [False] * len(self.edges)
queue = [0]
visited[0] = True
while queue:
node = queue.pop(0)
for neighbor, _ in self.edges[node]:
if not visited[neighbor]:
visited[neighbor] = True
queue.append(neighbor)
return all(visited)
def get_all_msts(self):
# find all possible minimum spanning trees
all_msts = []
mst_weight = None
for i in range(len(self.mst)):
weight_sum = 0
mst = []
for j, edge in enumerate(self.mst):
if i != j:
mst.append(edge)
weight_sum += edge[2]
if self.is_connected():
if mst_weight is None:
mst_weight = weight_sum
elif mst_weight > weight_sum:
mst_weight = weight_sum
all_msts.append(mst)
# if mst_weight == min(mst_weight for mst in all_msts):
# print("Our MST has the minimum weight compared to all other paths.")
# else:
# print("Our MST does not have the minimum weight compared to all other paths.")
print("Number of MSTs:", len(all_msts) + 1) # will try to mix both MST adnd Kruskal's MST methods later
return all_msts
def get_total_weight(self):
# Calculate the total weight of edges in the graph
return sum(weight for u in self.edges for v, weight in self.edges)
def print_graph(self):
# print the graph
print("Random Graph:")
for u in self.edges:
for v, weight in self.edges:
print(f"{u} -- {v}: {weight}")
def print_mst(self):
# Print the minimum spanning tree
print("\nMinimum Spanning Tree:")
for edge in self.mst:
print(f"{edge[0]} -- {edge[1]}: {edge[2]}")
def gen_mst(self,size):
# run the algo to find minimum spanning trees
self.generate_random_graph(size)
print("Gen mst for size :", size ," and edges ", len(self.edges))
start_time = time.time_ns()
self.mst = self.kruskal_mst()
end_time = time.time_ns()
print("Time taken:", end_time - start_time, "seconds")
if debug:
self.print_graph()
self.print_mst()
total_weight = self.get_total_weight()
mst_weight = sum(edge[2] for edge in self.mst)
if debug: # set to True when debug
all_msts = self.get_all_msts()
print("\nTotal Nodes in Graph:", size)
print("Total Weight of Edges:", total_weight)
print("Minimum Spanning Tree Weight:", mst_weight)
if mst_weight
Подробнее здесь: https://stackoverflow.com/questions/784 ... r-mst-path