【问题标题】:recursive backtracking to list all subsets with a given sum?递归回溯以列出具有给定总和的所有子集?
【发布时间】:2019-06-07 02:34:24
【问题描述】:

我正在尝试打印总和为给定目标数的所有可能子数组。

# arr -- the array
# n -- length of the array
# target_sum -- sum we want
# target_arr -- subarray we test for having the right sum
# ite -- iterator

def subset_sum(arr,n,target_sum,target_arr=[],ite=0):
    for i in range(ite,n):
        target_arr.append(arr[i])
        if sum(target_arr)==target_sum:
            print (target_arr, len(target_arr))
            target_arr.pop()
            subset_sum(arr,n,target_sum,target_arr,ite+1)
            return
        subset_sum(arr,n,target_sum,target_arr,i+1)
        target_arr.pop()

subset_sum([1,2,3,4],4,4)
[1, 3] 2
[1, 3] 2
[4] 1
[4] 1
[4] 1
[4] 1.

我似乎能够打印所有子数组,但我不知道为什么我的代码让我打印重复项。我认为可以避免重复,因为我在最后弹出子数组(即回溯)。

我的代码在哪里导致重复?我试过了,但不知道为什么。

【问题讨论】:

  • 这是什么语言?
  • 这是在 Python 中。

标签: python recursion recursive-backtracking


【解决方案1】:

我的代码在哪里导致重复?

我将重新排列您的代码:它将返回结果而不是打印它们;它将重新排列其参数,以便不需要传递target_array;它将使用一个更简单的带有重复项的示例输入:

def subset_sum(array, target_sum, start=0, target_array=[]):  # dangerous default value
    solutions = []

    for idx in range(start, len(array)):
        target_array.append(array[idx])

        if sum(target_array) == target_sum:
            solutions.append(list(target_array))
            target_array.pop()
            solutions.extend(subset_sum(array, target_sum, start + 1))
            break

        solutions.extend(subset_sum(array, target_sum, idx + 1))

        target_array.pop()

    return solutions

print(*subset_sum([1, 2, 3], 4))

但它仍然存在相同的重复问题:

> python3 test.py
[1, 3] [1, 3]
>

现在,我将添加一个调试打印语句:

        target_array.pop()
        print(f"print(*subset_sum({array}, {target_sum}, {start}, {target_array}))")
        solutions.extend(subset_sum(array, target_sum, start + 1))

现在我们运行它,我们得到:

> python3 test.py
print(*subset_sum([1, 2, 3], 4, 1, [1]))
print(*subset_sum([1, 2, 3], 4, 2, [1]))
[1, 3] [1, 3]
>

我们可以通过将我们的原始调用替换为以上两个都产生相同输出的调用来确认。通过更多基于print 的侦查,我们可以确定第一个是内循环递归调用的结果,第二个是外循环递归调用的结果。调用(参数)中没有重复,但是两个不同的调用会产生相同的结果。

您可以拔掉头发尝试解决这个问题,或者只是将 solutions 切换为 set 而不是 list,然后让 Python 过滤掉原始示例调用中的重复项:

def subset_sum(array, target_sum, start=0, target_array=[]):  # dangerous default value
    solutions = set()

    for idx in range(start, len(array)):
        target_array.append(array[idx])

        if sum(target_array) == target_sum:
            solutions.add(tuple(target_array))
            target_array.pop()
            solutions |= subset_sum(array, target_sum, start + 1)
            break

        solutions |= subset_sum(array, target_sum, idx + 1)

        target_array.pop()

    return solutions

print(*subset_sum([1, 2, 3, 4], 4))

有输出:

> python3 test.py
(1, 3) (4,)
> 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    • 2020-08-19
    相关资源
    最近更新 更多