算法部分综合考试的研究复习题。
设G是一个无向图,其中n个顶点恰好包含一个周期和孤立顶点(即没有叶子)。这意味着如果顶点不在循环中,则顶点的程度为0(隔离),如果它是循环的一部分,则为2。假设图表由邻接矩阵重新表示。 描述一个找到周期长度的效果算法。
我正在寻求帮助来验证我的理解,检查它是否正确以及分析是否正确。
我的答案(伪pythonic)
visited = [] // this will be list of u,v pairs belonging to cycle
for each u,v in G[][]:
if G[u][v] == 1: // is an edge
if G[u][v] in visited : //
return len(visited) // return the length of the cycle, since weve hit begining of cycle
else :
visited.add((u,v))
基于英语的理解
我们知道必须存在一个周期,问题的定义,不需要考虑周期的情况
对于每对顶点,检查它是否为边
如果是边缘,请检查我们之前是否曾经在那里。如果有,我们找到了循环,并返回所有访问边的大小。 (周期大小)
如果它不是访问边缘,请将其添加到访问列表,并继续直到找到源边缘(将循环增加1直到我们到达源)
我认为我的分析可能会失败。因为我们至少访问每个(u,v)对,然后检查它是否是边缘,以及每边缘2次比较。我认为它涉及O(| v | ^ 2 + 2 | E |)
有人可以就效率和正确性提出建议吗?如果我可能有一个逻辑上的飞跃,也可能提供更多基于英语的理解,而不承认逻辑证明?
感谢您的阅读并提前感谢您的帮助。
答案 0 :(得分:2)
考虑到问题中的条件(即图中唯一的边是周期的一部分),周期的长度是图中的边数,这是邻接矩阵中1的数量的一半。 (每个边(i,j)在邻接矩阵中出现两次:A [i,j] = 1且A [j,i] = 1)。
因此,明显的算法是将邻接矩阵的条目求和并除以2.如果有V个顶点,则为O(V ^ 2)。
看起来可能会有所帮助的一件事是,一旦你在邻接矩阵中找到第一个1,就要跟随边缘,直到你回到起点:
Find i, j such that A[i, j]=1.
start = i
cycle_length = 1
repeat
find k != i with A[j, k] = 1
i, j = j, k
cycle_length++
until i = start
此过程终止后,cycle_length
是周期的长度。尽管如此,这仍然是最坏情况的O(V ^ 2),尽管如果你能在周期中快速找到一个顶点,它就是O(V * C),其中C是周期的长度。
您问题中的代码无效。您将(u,v)作为矩阵中的索引进行迭代,并且无法找到相同的(u,v)两次。
答案 1 :(得分:1)
由于只有一个周期,如果一个顶点连接到至少另一个顶点,则顶点是周期的一部分。由于图表是无向的,因此可以使用以下规则:
if a edge between v1 and v2 exists, the edge aswell exists between v2 and v1
或换句话说:算法只需要扫描给出v1 < v2
的矩阵部分,这样即使在最坏情况下读取的矩阵元素数量也会减少50%以上。而且由于正在搜索一个循环,我们可以简单地保存我们在前一个节点之前访问过的每个节点,以确保我们不再访问它并结束,如果我们最终当前节点等于起始节点。 / p>
//search for any node that is in the cycle
int firstNode = -1
for int i in 1 , len(graph)
boolean notIsolated = false
for int j in 0 , i - 1
if graph[i][j] == 1
notIsolated = true
break
if notIsolated
firstNode = i
break
int node_c = firstNode
int node_p = -1
int count = 0
do
//search the neighbour that isn't the previous node with above given
//optimizations
int n
for n in 0 , node_c - 1
if graph[node_c][n] == 1 AND n != node_p
break
//update the nodevars for the next step
node_p = node_c
node_c = n
++count
while node_c != firstNode //continue until the algorithm reaches the startnode
除此之外,还有很多优点(至少我不知道如何进一步优化运行时)。