简体   繁体   English

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

[英]recursive function in python but with strange return

I am trying to solve a primary equation with several variables. 我正在尝试用几个变量求解一个主要方程。 For example:11x+7y+3z=20. 例如:11x + 7y + 3z = 20。 non-negative integer result only. 仅非负整数结果。

I use code below in python 3.5.1, but the result contains something like [...]. 我在python 3.5.1中使用以下代码,但结果包含类似[...]的内容。 I wonder what is it? 我想知道是什么吗 The code I have is to test every variables from 0 to max [total value divided by corresponding variable]. 我的代码是测试从0到最大的每个变量[总值除以相应的变量]。 Because the variables may be of a large number, I want to use recursion to solve it. 因为变量可能有很多,所以我想使用递归来解决它。

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)

the result is 结果是

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

change to a new one could get clean result, but I still need a global variable: 更改为新的可能会得到干净的结果,但是我仍然需要一个全局变量:

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,[]))

I see three layers of problems here. 我在这里看到三层问题。

1) There seems to be a misunderstanding about recursion. 1)似乎对递归存在误解。

2) There seems to be an underestimation of the complexity of the problem you are trying to solve (a modeling issue) 2)您似乎要解决的问题(建模问题)的复杂性被低估了

3) Your main question exposes some lacking skills in python itself. 3)您的主要问题揭露了python本身缺少的一些技能。

I will address the questions in backward order given that your actual question is "the result contains something like [...]. I wonder what is it?" 鉴于您的实际问题是“结果包含类似[...]的东西。我想知道是什么?

" [] " in python designates a list. python中的“ [] ”指定一个列表。

For example: 例如:

var = [ 1, 2 ,3 ,4 ]

Creates a reference " var " to a list containing 4 integers of values 1, 2, 3 and 4 respectively. 创建对包含四个分别为值1、2、3和4的整数的列表的引用“ var ”。

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

var2 on the other hand is a reference to a composite list of 3 elements, a string, another list and a string. 另一方面, var2是对3个元素的组合列表(一个字符串,另一个列表和一个字符串)的引用。 The 2nd element is a list of 2 strings. 第二个元素是2个字符串的列表。

So your results is a list of lists of integers (assuming the 2 lists with "..." are integers). 因此,您的结果是一个整数列表列表(假设带有“ ...”的2个列表是整数)。 If each sublists are of the same size, you could also think of it as a matrix. 如果每个子列表的大小相同,您也可以将其视为矩阵。 And the way the function is written, you could end up with a composite list of lists of integers, the value " False " (or the value " None " in the newest version) 以及编写函数的方式,您可能最终得到一个由整数组成的列表,值“ False ”(或最新版本中的“ None ”)

Now to the modeling problem. 现在到建模问题。 The equation 11x + 7y + 3z = 20 is one equation with 3 unknowns. 方程11x + 7y + 3z = 20是一个带有3个未知数的方程。 It is not clear at all to me what you want to acheive with this program, but unless you solve the equation by selecting 2 independent variables, you won't achieve much. 对我来说,要使用此程序要实现的目标一点也不明确,但是除非您通过选择2个独立变量来求解方程式,否则您将不会取得太大的成就。 It is not clear at all to me what is the relation between the program and the equation save for the list you provided as argument with the values 11, 7 and 3. 对于您提供的参数值为11、7和3的列表,对我来说,程序和方程之间的关系到底是什么还不清楚。

What I would do (assuming you are looking for triplets of values that solves the equation) is go for the equation: f(x,y) = (20/3) - (11/3)x - (7/3)y. 我会做的(假设您正在寻找能解决该方程的三元组值)用于方程:f(x,y)=(20/3)-(11/3)x-(7/3)y 。 Then the code I would rather write is: 那么我宁愿写的代码是:

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)

Be mindful that the number of solutions to this equation is infinite. 请注意,该方程的解数是无限的。 You could think of it as a straight line in a rectangular prism if you bound the variables. 如果对变量进行绑定,则可以将其视为直角棱镜中的直线。 If you wanted to represent the same line in an abstract number of dimensions, you could rewrite the above as: 如果要用抽象的尺寸表示同一条线,则可以将以上内容重写为:

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

Where nthc is the coefficient of the Nth variable, const is an offset constant, coeffs is a list of coefficients and vars the values of the N-1 other variables. 其中nthc是第N个变量的系数, const是偏移常数, coeffs是系数的列表和vars N-1个其它变量的 For example, we could re-write the func_f as: 例如,我们可以将func_f为:

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

Now about recursion. 现在关于递归。 A recursion is a formulation of a reducible input that can be called repetivitely as to achieve a final result. 递归是可减少的输入的一种形式,可以重复地调用它以获得最终结果。 In pseudo code a recursive algorithm can be formulated as: 用伪代码可以将递归算法表示为:

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.

For example, the fibonacci suite: 例如,斐波那契套件:

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

If you wanted to recusively add elements from a list: 如果您想从列表中添加元素:

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

Hope it helps. 希望能帮助到你。

UPDATE 更新

From comments and original question edits, it appears that we are rather looking for INTEGER solutions to the equation. 从评论和原始问题编辑看来,我们似乎是在寻找方程的整数解。 Of non-negative values. 非负值。 That is quite different. 那是完全不同的。

1) Step one find bounds: use the equation ax + by + cz <= 20 with a,b,c > 0 and x,y,z >= 0 1)第一步查找范围:使用方程ax + by + cz <= 20,其中a,b,c> 0且x,y,z> = 0

2) Step two, simply do [(x, y, z) for x, y, z in zip(bounds_x, bounds_y, bounds_z) if x*11 + y*7 + z*3 - 20 == 0] and you will have a list of valid triplets. 2)第二步,只要x * 11 + y * 7 + z * 3-20 == 0,只需对zip(bounds_x,bounds_y,bounds_z)中的x,y,z执行[[x,y,z),将具有有效的三胞胎列表。

in code: 在代码中:

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)

Here is a solution built from your second one, but without the global variable. 这是从第二个构建的解决方案,但没有全局变量。 Instead, each call passes back a list of solutions; 而是,每个调用都返回一个解决方案列表。 the parent call appends each solution to the current element, making a new list to return. 父调用将每个解决方案附加到当前元素,从而创建一个新列表以返回。

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, []))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM