在Python中回溯

时间:2014-05-25 09:48:32

标签: python backtracking

我刚刚开始学习Python并尝试写下回溯算法,但似乎我做错了。 由于我是这种语言的新手,我一直试图在互联网上查找,但对此并不太了解。这是我的代码:

n = 3
x = [0] * 3
k = 0
def init ():
    x[k] = 0
def succesor():
    if x[k] < n:
        x[k]+=1
        return 1
    return 0
def valid ():
    i = 1
    for i in range (0,k-1):
        if x[i] == x[k]:
            return 0
    return 1
def solutie ():
    return k == n
def afis():
    print(x)
def back ():
    k = 1
    avemsuccesor = 1
    init()
    while k > 0:
        while avemsuccesor and not valid():
            avemsuccesor = succesor()
        if avemsuccesor:
            if solutie:
                afis()
            else:
                k+=1
                init()
        else:
            k-=1
def main ():
    back()
main ()

当我运行它时,我只得到一个满0的向量。 你能帮帮我吗?

2 个答案:

答案 0 :(得分:2)

一个关键问题是:

if solutie:

正在测试函数的真实性,它始终为True

>>> bool(solutie)
True

而不是它返回的价值的真实性;你应该:

if solutie():
        # ^ note parentheses

此外,您的所有函数都没有参数,因此您完全依赖变量作用域进行访问。这是不明智的,并且使代码很难调试 - 您无法单独测试任何函数。作为一个简单的例子,比较:

def solutie():
    return k == n

def solutie(k, n):
    return k == n

对于前者,测试非常困难 - kn是什么?他们来自哪里?对于后者,这是一个简单的问题

assert solutie(1, 1)
assert not solutie(1, 2)

您遇到的主要问题是:因为k是不可变的,所以除back以外的每个函数中总是使用相同的值。虽然您在k += 1中分配了back,但其他功能(例如valid)仍在使用外部范围内的k == 0。如果更改每个函数以使用显式参数并返回值,例如:

 def successor(x, k, n):
     ...
     return True # use booleans rather than 0 or 1

 ...
     avemsuccesor = succesor(x, k, n) 

您很快就会发现k超出范围,导致IndexError。我不会在这里重写所有内容 - 我将重构您的代码以明确传递值并解决然后出现的错误。

答案 1 :(得分:0)

问题是k定义了两次,一次定义为0,一次定义为1.内部有效,它选择全局k = 0但是无论如何,即使k-1最初为零,所以valid()将在第一次返回1迭代。我不理解这个程序的意图,但这就是它永远不会运行successor()的原因,它实际上从零中修改了向量的元素。