Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用Python编写Graham算法?_Python_Algorithm - Fatal编程技术网

如何用Python编写Graham算法?

如何用Python编写Graham算法?,python,algorithm,Python,Algorithm,我正在尝试用Python编写Graham算法(凸包)。我有一些生成随机点的函数: def generatePoints(n): global pointsList for x in range(0, n): rPoint = Point(random.randint(-10, 10), random.randint(-10, 10)) if(rPoint not in pointsList): pointsList.appe

我正在尝试用Python编写Graham算法(凸包)。我有一些生成随机点的函数:

def generatePoints(n):
    global pointsList
    for x in range(0, n):
        rPoint = Point(random.randint(-10, 10), random.randint(-10, 10))
        if(rPoint not in pointsList):
            pointsList.append(rPoint)
然后我有一个函数,它找到Y值最小的点:

def findStartingPoint():
    global startingPoint
    global pointsList
    for pt in pointsList:
        if(pt.y < startingPoint.y):
            startingPoint = pt
        elif(pt.y == startingPoint.y):
            if(pt.x < startingPoint.x):
                startingPoint = pt
    for pt in pointsList:
        if(startingPoint == pt):
            pointsList.remove(pt)
问题来了。我的算法函数如下所示:

def graham():
    global pointsStack
    global pointsList
    pointsStack.push(0)
    pointsStack.push(1)
    pointsStack.push(2)
    for i in range(3, len(pointsList)):
        while isRight(pointsList[i-2], pointsList[i-1], pointsList[i]):
            pointsStack.pop()
        pointsStack.push(i)

它只适用于“堆栈为空异常”(有时它适用于1-for迭代)。我的程序有什么问题?

问题在于
while
循环:

while isRight(pointsList[i-2], pointsList[i-1], pointsList[i]):
    pointsStack.pop()
由于不增加
i
,它将重复从堆栈中弹出,直到它为空(甚至更空)

你犯了一个语义错误。必须提供前两点的不是
点列表,而是堆栈。因此,每次需要从堆栈中弹出一个元素时(将其保存在内存中),
peek
第一个点的堆栈,第二个是刚从堆栈中弹出的元素,最后一个是
pointList[i]
'。如果堆栈实现为列表,则可以使用:

while isRight(pointsList[pointsStack[-2]], pointsList[pointsStack[-1]], pointsList[i]):
        pointsStack.pop()
最后一个方面是,您需要将偏移点添加到
点列表以及最后一个点,以便在返回时,可以选择删除alpha最大的点

您还可以在偏移点为
p1
的点上使用
isRight
功能来优化排序功能

while isRight(pointsList[i-2], pointsList[i-1], pointsList[i]):
    pointsStack.pop()
while isRight(pointsList[pointsStack[-2]], pointsList[pointsStack[-1]], pointsList[i]):
        pointsStack.pop()