python中的递归函数,但返回奇怪

2024-06-02 08:53:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我想解一个有几个变量的基本方程。为了例如:11x+7y+3z=20。仅限非负整数结果。你知道吗

我在Python3.5.1中使用下面的代码,但是结果包含类似[…]的内容。我想知道是什么? 我的代码是测试从0到max的每个变量[总值除以相应的变量]。因为变量的数量可能很大,所以我想用递归来解决它。你知道吗

def equation (a,b,relist):
    global total
    if len(a)>1:
        for i in range(b//a[0]+1):
            corelist=relist.copy()
            corelist+=[i]
            testrest=equation(a[1:],b-a[0]*i,corelist)
            if testrest:
                total+=[testrest]

        return total
    else:

        if b%a[0]==0:
            relist+=[b//a[0]]            
            return relist
        else:
            return False


total=[]
re=equation([11,7,3],20,[])

print(re)

结果是

[[0, 2, 2], [...], [1, 0, 3], [...]]

更改为新的可以得到干净的结果,但我仍然需要一个全局变量:

def equation (a,b,relist):
global total
if len(a)>1:
    for i in range(b//a[0]+1):
        corelist=relist.copy()
        corelist+=[i]
        equation(a[1:],b-a[0]*i,corelist)

    return total
else:

    if b%a[0]==0:
        relist+=[b//a[0]]
        total+=[relist]
        return 
    else:
        return

total=[]
print(equation([11,7,3],20,[]))

Tags: 代码inforlenreturnifdefrange
2条回答

我看到这里有三层问题。你知道吗

1)似乎对递归有误解。你知道吗

2)似乎低估了您试图解决的问题的复杂性(建模问题)

3)您的主要问题暴露了python本身的一些不足。你知道吗

如果你的实际问题是“结果包含类似[…]的内容”,我将按倒序来回答这些问题。不知道是什么?”你知道吗

python中的“[]”指定一个列表。你知道吗

例如:

var = [ 1, 2 ,3 ,4 ]

创建对分别包含值1、2、3和4的4个整数的列表的引用“var”。你知道吗

var2 = [ "hello", ["foo", "bar"], "world" ]

另一方面,var2是对由3个元素组成的复合列表的引用,一个字符串、另一个列表和一个字符串。第二个元素是两个字符串的列表。你知道吗

因此,您的结果是一个整数列表(假设带“…”的两个列表是整数)。如果每个子列表的大小相同,也可以将其视为一个矩阵。以编写函数的方式,您可以得到一个整数列表的复合列表,即值“False”(或最新版本中的值“None”)

现在是建模问题。方程11x+7y+3z=20是一个含有3个未知数的方程。我一点也不清楚你想用这个程序得到什么,但是除非你通过选择两个自变量来解这个方程,否则你不会有多大的收获。我一点也不清楚程序和方程之间的关系是什么,除了您作为参数提供的值为11、7和3的列表之外。你知道吗

我要做的(假设你正在寻找解这个方程的三元组值)是去解这个方程:f(x,y)=(20/3)-(11/3)x-(7/3)y。那么我想写的代码是:

def func_f(x, y):
    return 20.0/3.0 - (11.0/3.0) * x - (7.0/3.0) * y

list_of_list_of_triplets = []
for (x, y) in zip(range(100),range(100)):
    list_of_triplet = [x, y, func_f(x,y)]
    list_of_list_of_triplets += [list_of_triplet] # or .append(list_of_triplet)

注意这个方程的解的数目是无限的。如果你限制变量,你可以把它想象成一条矩形棱镜中的直线。如果您想用抽象的维度数表示同一行,可以将上面的内容重写为:

def func_multi_f(nthc, const, coeffs, vars):
    return const - sum([a*b/nth for a,b in zip(coeffs, vars)])

其中,nthc是第N个变量的系数,const是偏移常量,coeffs是系数列表,vars是N-1个其他变量的值。例如,我们可以将func_f重写为:

def func_f(x,y):
    return func_multi_f(3.0, 20.0, [11.0, 7.0], [x,y])

现在是递归。递归是可还原输入的一种形式,可以重复调用以获得最终结果。在伪代码中,递归算法可以表示为:

input = a reduced value or input items
if input has reached final state: return final value
operation = perform something on input and reduce it, combine with return value of this algorithm with reduced input.

例如,斐波那契套件:

def fibonacci(val):
    if val == 1:
       return 1
    return fibonacci(val - 1) + val

如果要从列表中重复添加元素:

def sum_recursive(list):
    if len(list) == 1:
       return list[0]
    return sum_recursive(list[:-1]) + list[-1]

希望有帮助。你知道吗

更新

从注释和原始问题编辑来看,我们似乎更倾向于寻找方程的整数解。非负值。这是完全不同的。你知道吗

1)第一步查找边界:使用公式ax+by+cz<;=20,其中a,b,c>;0和x,y,z>;=0

2)第二步,如果x*11+y*7+z*3-20==0,只需对zip中的x,y,z(bounds\u x,bounds\u y,bounds\u z)执行[(x,y,z)即可得到一个有效的三元组列表。你知道吗

在代码中:

def bounds(coeff, const):
    return [val for val in range(const) if coeff * val <= const]

def combine_bounds(bounds_list):
    # here you have to write your recusive function to build
    # all possible combinations assuming N dimensions

def sols(coeffs, const):
    bounds_lists = [bounds(a, const) for a in coeffs]
    return [vals for vals in combine_bounds(bounds_lists) if sum([a*b for a,b in zip(coeff, vals)] - const == 0)

这是从第二个解决方案构建的解决方案,但是没有全局变量。相反,每个调用都会传回一个解决方案列表;父调用会将每个解决方案附加到当前元素,生成一个要返回的新列表。你知道吗

def equation (a, b):
    result = []
    if len(a) > 1:
        # For each valid value of the current coefficient,
        #    recur on the remainder of the list.
        for i in range(b // a[0]+1):
            soln = equation(a[1:], b-a[0]*i)

            # prepend the current coefficient
            #   to each solution of the recursive call.
            for item in soln:
                result.append([i] + item)
    else:
        # Only one item left: is it a solution?
        if b%a[0] == 0:
            # Success: return a list of the one element
            result = [[b // a[0]]]
        else:
            # Failure: return empty list
            result = []

    return result

print(equation([11, 7, 3], 20, []))

相关问题 更多 >