在Python中使用Kruskal的最小生成树,递归进入无限循环

时间:2015-10-18 15:50:25

标签: python tree minimum

此代码的目的是创建连接每个点的最短路径。我试图在Python中实现Kruskals算法,但是有一个问题,它发生在调用函数findSet(x)时。似乎程序进入无限循环。我试图打印x,x.dad和x.dad.dad和x在关键时刻返回初始x。我真的不知道问题出在哪里。

class Point:
    def __init__(self,x = None, y = None):
        self.x = x
        self.y = y
        self.dad = None
        self.rank = None

class Edge:
    def __init__(self, firstPoint = None, secondPoint = None, value = None):
        self.firstPoint = firstPoint
        self.secondPoint = secondPoint
        if self.firstPoint != None and self.secondPoint != None:
            self.value = abs(firstPoint.x-secondPoint.x) + abs(firstPoint.y - secondPoint.y)
        else:
            self.value = float("inf")

def makeSet(node):
    node.dad = node
    node.rank = 0

def findSet(x):
    print x, x.dad,x.dad.dad
    if x == x.dad:
        return x
    x.dad = findSet(x.dad)
    return x.dad

def unionSet(node1,node2):
    root1 = findSet(node1)
    root2 = findSet(node2)
    if root1.rank < root2.rank:
        root1.dad = root2
    if root1.rank > root2.rank:
        root2.dad = root1
    else:
        root2.dad = root1
        root1.rank += 1


def merge(A, p, q, r):
    L = A[p:q+1]
    R = A[q+1:r+1]
    infinite = Edge()
    L.append(infinite)
    R.append(infinite)
    temp = []
    i = 0
    j = 0
    for k in range(p,r+1):
        if L[i].value <=  R[j].value:
            temp.append(L[i])
            i += 1
        else:
            temp.append(R[j])
            j += 1
    A[p:r+1] = temp

def mergeSort(A,p,r):
    A2 = A
    if p < r:
        q = int((p+r)/2)
        mergeSort(A2, p, q)
        mergeSort(A2, q+1, r)
        merge(A2, p, q, r)

def readPoint(A):
    temp = []
    for i in range(0,len(A), 2):
        tempPoint = Point(A[i],A[i+1])
        makeSet(tempPoint)
        temp.append(tempPoint)
    return temp

def calculateEdges(A):
    tempArray = []
    for i in range(0,len(A)):
        for j in range(i+1,len(A)):
            edge = Edge(A[i], A[j])
            tempArray.append(edge)
    return tempArray

def Kruskal(N, E):
    mergeSort(E,0,len(E)-1)
    j = 0
    i = 0
    total = 0
    while j < N:
        if findSet(E[i].firstPoint) != findSet(E[i].secondPoint):
            unionSet(E[i].firstPoint,E[i].secondPoint)
            j += 1
            total += E[i].value
        if i < len(E) - 1:
            i += 1
    return total


Ar = readPoint([18, 2, 99, 68])
E = calculateEdges(Ar)
print Kruskal(len(Ar),E)

0 个答案:

没有答案