У меня завтра последний срок, но я просто не могу получить этот код. Не лучший в 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))
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)
У меня завтра последний срок, но я просто не могу получить этот код. Не лучший в Python, заранее извините! По сути, мой код работает, сначала создавая повторный граф, проверяя его полную связность, а затем запуская алгоритм Крускала. В настоящее время у меня есть несколько проблем. [list] [*]Мне нужен раздел get_all_msts, чтобы найти Kruskals mst вместо любого (который я пытался изменить, и код мне это не понравилось). Это сделано для того, чтобы я мог убедиться, что мой код правильно регистрируется, когда существует более одного MST, а также отсортировать все возможные пути, чтобы убедиться, что наш минимум имеет наименьший вес. Я мог бы поместить этот код в kruskal_mst, но суть проекта заключается в определении времени, которое занимает алгоритм Крускала с n узлами. [*]Таймер, предназначенный для регистрации того, насколько быстро работает алгоритм Крускала, не изменился с 0, поэтому он должен тоже может быть ошибка [*]Поскольку мой граф неориентированный, счетчик ребер считает ребро между x, y не равным y, x, хотя на самом деле это так. Каждый раз, когда я меняю этот раздел, мой метод is_connected начинает показывать ошибки. Если бы кто-нибудь мог помочь с какой-либо частью этого, я был бы очень признателен. [/list] Он должен работать до 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[u].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[u]] 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[u])
def print_graph(self): # print the graph print("Random Graph:") for u in self.edges: for v, weight in self.edges[u]: 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))
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)
Заранее прошу прощения, если этот код покажется вам длинным, но я все еще новичок в Java, и мне сложно реализовать алгоритм Прима. Когда я отправляю свой сценарий на vocareum, я получаю сообщение о неправильном MST. Я постоянно отслеживаю свой...