我有这个hw:
我有问题让3.正确输出。也就是说,文件1应该输出[[1],[0,2,3],[1],[1]]
而我得到[[1,2],[0,3],[0],[1]]
这是好的,因为它们都是来自文件1的n=4
的生成树
但这是主要问题:我不知道我的代码有什么问题,对于文件2:我得到:[[10], [], [10], [10], [], [], [], [], [], [], [0, 3, 2], [], []]
我的代码末尾的文件数据。
(编辑:从tree=[]
开始是问题所在,其余的没有问题)
这是我对这个问题的尝试:
import itertools
edge_i=[]
edge_j=[]
x = []
y = []
edgelist = []
n = int(input("Enter value for n:")) #input n for number of vertices
adjlist = [[] for i in range(n)] #create n sublists inside empty initial adjlist
data = [['0','1'],['2','1'],['0','2'],['1','3']]
for line in data: #for loop for appending into adjacency list the correct indices taken from out of the edgelist
#(this line won't be needed when hardcoding input) line = line.replace("\n","").split(" ")
for values in line:
values_as_int = int(values)
edgelist.append(values_as_int)
#set of vertices present in this file - pick out only n vertices
verticesset=set(edgelist)
listofusefulvertices=list(verticesset)[0:n]
P = list(itertools.permutations(listofusefulvertices,2))
x.append(edgelist[0::2])
y.append(edgelist[1::2])
x = sum(x,[])
y = sum(y,[])
dataint=zip(x,y)
datatuples=list(dataint)
outdata = set(datatuples)&set(P)
output=list(outdata)
for k in range(len(output)):
edge_i.append(output[k][0])
edge_i.append(output[k][1])
edge_j.append(output[k][1])
edge_j.append(output[k][0])
for i in range(len(edge_i)):
u = edge_i[i]
v = edge_j[i]
adjlist[u].append(v)
print(adjlist)
tree = []
for vertexNum in range(len(listofusefulvertices)):
tree.append([])
treeVertices = [0]*n
treeVertices[0]=1
for vertex in range(0,n): #(here the range in skeletal code from school used 1,n but it only worked for me when I used 0,n-1 or 0,n)
if treeVertices[vertex] == 1:
for adjVertex in adjlist[vertex]:
if treeVertices[adjVertex] == 0:
treeVertices[adjVertex]=1
tree[adjVertex].append(vertex)
tree[vertex].append(adjVertex)
print(tree)
#The data from files were: file 1: [['0','1'],['2','1'],['0','2'],['1','3']]
# file 2: [['10','2'],['7','4'],['11','3'],['1','12'],['6','8'],['10','3'],['4','9'],['5','7'],['8','12'],['2','11'],['1','6'],['0','10'],['7','2'],['12','5']]
答案 0 :(得分:2)
我没有浏览您的所有代码,您真的应该查看指南Minimal, complete, verifiable example。
但是,将边缘列表转换为图表,然后使用标准mst
算法,例如,整洁的:
def create_graph(edgelist):
graph = {}
for e1, e2 in edgelist:
graph.setdefault(e1, []).append(e2)
graph.setdefault(e2, []).append(e1)
return graph
# Prim's
def mst(start, graph):
closed = set()
edges = []
q = [(start, start)]
while q:
v1, v2 = q.pop()
if v2 in closed:
continue
closed.add(v2)
edges.append((v1, v2))
for v in graph[v2]:
if v in graph:
q.append((v2, v))
del edges[0]
assert len(edges) == len(graph)-1
return edges
>>> graph = create_graph([[10, 2], [7, 4], [11, 3], [1, 12], [6, 8], [10, 3], [4, 9], [5, 7], [8, 12], [2, 11], [1, 6], [0, 10], [7, 2], [12, 5]])
>>> min_gragh = create_graph(mst(0, graph))
>>> min_graph
{0: [10],
1: [6],
2: [11, 7],
3: [10, 11],
4: [7, 9],
5: [7, 12],
6: [8, 1],
7: [2, 5, 4],
8: [12, 6],
9: [4],
10: [0, 3],
11: [3, 2],
12: [5, 8]}
>>> [sorted(min_graph[k]) for k in sorted(min_graph)]
[[10], [6], [7, 11], [10, 11], [7, 9], [7, 12], [1, 8], [2, 4, 5], [6, 12], [4], [0, 3], [2, 3], [5, 8]]
图表可能有多个有效的MST,例如较小的edgelist
生成[[2], [2, 3], [0, 1], [1]]
,这也是一个有效的MST,但与预期的输出不同。
答案 1 :(得分:1)
问题出在最后的主处理循环中。您使用节点0作为起始节点,但随后假设您的连接按数字顺序运行。您标记与节点0(仅节点10)相邻的所有节点,然后接下来接收节点1。那还没有连接,所以你跳过它......但你永远不会回来。
这是我的低技术调试运行中的代码和跟踪:
for vertex in range(0,n): #(here the range in skeletal code from school used 1,n but it only worked for me when I used 0,n-1 or 0,n)
print ("Working on vertex", vertex, treeVertices[vertex] == 1)
if treeVertices[vertex] == 1:
for adjVertex in adjlist[vertex]:
print (" Adjacent vertex", adjVertex, treeVertices[adjVertex] == 0)
if treeVertices[adjVertex] == 0:
treeVertices[adjVertex]=1
tree[adjVertex].append(vertex)
tree[vertex].append(adjVertex)
print("Spanning tree", tree)
输出:
Adjacency list [[10], [12, 6], [11, 7, 10], [11, 10], [9, 7], [7, 12], [8, 1], [5, 4, 2], [6, 12], [4], [0, 3, 2], [2, 3], [1, 8, 5]]
Working on vertex 0 True
Adjacent vertex 10 True
Working on vertex 1 False
Working on vertex 2 False
Working on vertex 3 False
Working on vertex 4 False
Working on vertex 5 False
Working on vertex 6 False
Working on vertex 7 False
Working on vertex 8 False
Working on vertex 9 False
Working on vertex 10 True
Adjacent vertex 0 False
Adjacent vertex 3 True
Adjacent vertex 2 True
Working on vertex 11 False
Working on vertex 12 False
Spanning tree [[10], [], [10], [10], [], [], [], [], [], [], [0, 3, 2], [], []]
看到问题?该算法假设,如果从可用节点移动到更高编号的节点,则查找生成树的流将始终成功。由于这棵树需要几个" down"移动,你不能得到它们。从0开始,标记10,然后跳过节点1-9。当你到达10时,你会添加节点2和3 ......但是你永远不会回过头来展开它们,而这就是你所得到的。
要完成所有这些,请执行以下两项操作之一:
这会让你转向解决方案吗?
答案 2 :(得分:0)
我想我可能通过在顶点的for循环上面添加外部循环while all(treeVertices) == 0:
来修复它。现在对于file2长列表中的n = 13,我得到了这个输出:[[10], [12, 6], [10, 11, 7], [10], [7, 9], [7, 12], [1], [2, 5, 4], [12], [4], [0, 3, 2], [2], [5, 1, 8]]
我不明白的是,为什么没有while any(treeVertices) == 0:
工作而且它必须是all()?我认为当treeVertices列表被1s部分填充时,它将不包含“all”零,但其中的“any”零,应该再次将迭代器发送回其循环。我在python中遇到过多个编码实例,其中any()和all()的使用对我有相反的效果,其中any()的作用类似于all(),而all()的行为与any()相同。知道为什么吗?