Python 用动态规划求子集和
我正在练习动态编程,我正在努力调试我的代码。这样做的目的是在给定一系列数字的情况下,找出一个和是否可能。这是我的密码:Python 用动态规划求子集和,python,dynamic-programming,Python,Dynamic Programming,我正在练习动态编程,我正在努力调试我的代码。这样做的目的是在给定一系列数字的情况下,找出一个和是否可能。这是我的密码: a = [2,3,7,8,10] sum = 11 b = list(range(1, sum+1)) m = [[False for z in range(len(b))] for i in range(len(a))] for i, x in enumerate(b): for j, y in enumerate(a): if x==y:
a = [2,3,7,8,10]
sum = 11
b = list(range(1, sum+1))
m = [[False for z in range(len(b))] for i in range(len(a))]
for i, x in enumerate(b):
for j, y in enumerate(a):
if x==y:
m[j][i]=True
elif y<x:
m[j][i] = m[j-1][i]
else:
m[j][i] = m[j-1][i] or m[j-i][y-x]
for i, n in enumerate(m):
print(a[i], n)
据我所知,在我的else语句中,算法应该上升1行,然后查看x和y的差异,并检查该插槽是否可行。例如,在最明显的情况下,最后一行中的最后一个元素。这将是10(y)-11(x),应该一直回到它上面一行的索引1,我们知道这是真的。不完全确定我做错了什么,如果能帮助我理解这一点,我将不胜感激 如果您只输入了正值,我不太明白您为什么需要二维列表。您可以简单地使用1d列表:
coins = [2,3,7,8,10]
sum = 11
接下来,我们初始化列表可能
,该列表说明是否可能获得某个值。我们将可能的[0]
设置为真
,因为这个总数可以在没有硬币的情况下完成
possible = [False for _ in range(sum+1)]
possible[0] = True
现在,您对每个硬币进行迭代,并在列表上进行迭代,如果可能,“升级”值:
for coin in coins:
for i in range(sum-coin,-1,-1):
if possible[i]:
possible[i+coin] = True
之后,列表可能的
显示从0
到(包括求和
)的每个值是否可以构造它。因此,如果可能的[sum]
为True
,则可以构造sum
对于给定的硬币
和总和
,可以得到:
>>> possible
[True, False, True, True, False, True, False, True, True, True, True, True]
因此,可以用硬币构造值0
,2
,3
,5
,7
,8
,9
,10
,11
编辑:跟踪硬币
您还可以通过稍微修改代码来跟踪硬币:
possible = [None for _ in range(sum+1)]
possible[0] = []
for coin in coins:
for i in range(sum-coin,-1,-1):
if possible[i] is not None:
possible[i+coin] = possible[i]+[coin]
现在看来:
>>> possible
[[], None, [2], [3], None, [2, 3], None, [7], [8], [2, 7], [10], [3, 8]]
所以
0
可以用硬币[]
(没有硬币)构造<代码>2可以用[2]
(一枚有值的硬币2
),3
和[3]
,5
和[2,3]
,等等来构造。我不太明白为什么需要一个二维列表…@WillemVanOnsem这不是解决这个问题的动态编程方法吗?不是本身。你知道你在这里干什么吗?如果你只是想知道你是否可以使用这些硬币来求和到给定的值,你可以使用1d列表。你可以重复使用一枚硬币,或者每个数字只能使用一次吗?是的@WillemVanOnsem我明白我在做什么,我论文中的矩阵是有意义的。但代码并不完全正确。我可以用贪婪的方法或者排序的左右方法来解决这个问题,但是我“我试图通过动态规划来实现这一点。我不想得到我感兴趣的答案,更想通过DPAh解决这个问题,好吧,我得到了这个解决方案。但是如果我使用1D数组,就不可能跟踪用于获取解决方案的硬币,对吗?@dumby.Fat.Cat:事实上,只需稍微修改一下代码。啊,这是一个比算法书籍建议的更好的解决方案。非常感谢。我仍然不能完全确定为什么我的代码不能工作,但调试起来比1d要困难得多array@Stupid.Fat.Cat:请记住,这只适用于正值。如果我想保留此解决方案并将其应用于负值,我认为可以对负值进行规范化。如果我将“最大”负值调整为0,并增加总和和其他元素,那么就有可能保持解。
>>> possible
[[], None, [2], [3], None, [2, 3], None, [7], [8], [2, 7], [10], [3, 8]]