簡體   English   中英

python中的遞歸函數但返回值很奇怪

[英]recursive function in python but with strange return

我正在嘗試用幾個變量求解一個主要方程。 例如:11x + 7y + 3z = 20。 僅非負整數結果。

我在python 3.5.1中使用以下代碼,但結果包含類似[...]的內容。 我想知道是什么嗎 我的代碼是測試從0到最大的每個變量[總值除以相應的變量]。 因為變量可能有很多,所以我想使用遞歸來解決它。

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

我在這里看到三層問題。

1)似乎對遞歸存在誤解。

2)您似乎要解決的問題(建模問題)的復雜性被低估了

3)您的主要問題揭露了python本身缺少的一些技能。

鑒於您的實際問題是“結果包含類似[...]的東西。我想知道是什么?

python中的“ [] ”指定一個列表。

例如:

var = [ 1, 2 ,3 ,4 ]

創建對包含四個分別為值1、2、3和4的整數的列表的引用“ var ”。

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

另一方面, var2是對3個元素的組合列表(一個字符串,另一個列表和一個字符串)的引用。 第二個元素是2個字符串的列表。

因此,您的結果是一個整數列表列表(假設帶有“ ...”的2個列表是整數)。 如果每個子列表的大小相同,您也可以將其視為矩陣。 以及編寫函數的方式,您可能最終得到一個由整數組成的列表,值“ False ”(或最新版本中的“ None ”)

現在到建模問題。 方程11x + 7y + 3z = 20是一個帶有3個未知數的方程。 對我來說,要使用此程序要實現的目標一點也不明確,但是除非您通過選擇2個獨立變量來求解方程式,否則您將不會取得太大的成就。 對於您提供的參數值為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(bounds_x,bounds_y,bounds_z)中的x,y,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, []))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM