Код отладки, создающий случайный связный граф для последующего запуска алгоритма Крускала для пути MST.Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Код отладки, создающий случайный связный граф для последующего запуска алгоритма Крускала для пути MST.

Сообщение Anonymous »

У меня завтра последний срок, но я просто не могу получить этот код. Не лучший в Python, заранее извините! По сути, мой код работает, сначала создавая повторный граф, проверяя его полную связность, а затем запуская алгоритм Крускала. В настоящее время у меня есть несколько проблем.
  • Мне нужен раздел get_all_msts, чтобы найти Kruskals mst вместо любого (который я пытался изменить, и код мне это не понравилось). Это сделано для того, чтобы я мог убедиться, что мой код правильно регистрируется, когда существует более одного MST, а также отсортировать все возможные пути, чтобы убедиться, что наш минимум имеет наименьший вес. Я мог бы поместить этот код в kruskal_mst, но суть проекта заключается в определении времени, которое занимает алгоритм Крускала с n узлами.
  • Таймер, предназначенный для регистрации того, насколько быстро работает алгоритм Крускала, не изменился с 0, поэтому он должен тоже может быть ошибка
  • Поскольку мой граф неориентированный, счетчик ребер считает ребро между x, y не равным y, x, хотя на самом деле это так. Каждый раз, когда я меняю этот раздел, мой метод is_connected начинает показывать ошибки. Если бы кто-нибудь мог помочь с какой-либо частью этого, я был бы очень признателен.
Он должен работать до 100 узлов, но у меня оно меньше, так как я отлаживаю .
Вот мой код:
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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»