在Python中递归地实现“最小数量的硬币”

用户名

这个问题和这里的问题相同

给定一个硬币列表,它们的值(c1,c2,c3,... cj,...)和总和i。找到总和为i的最小数量的硬币(我们可以使用任意数量的一种类型的硬币),或者报告不可能选择总和为S的硬币。

我昨天刚刚被介绍给动态编程,我试图为此编写代码。

# Optimal substructure: C[i] = 1 + min_j(C[i-cj])
cdict = {}
def C(i, coins):

    if i <= 0:
        return 0

    if i in cdict:
        return cdict[i]
    else:
        answer = 1 + min([C(i - cj, coins) for cj in coins])
        cdict[i] = answer
        return answer

在此,C [i]是金额“ i”的最佳解决方案。程序中可用的硬币为{c1,c2,...,cj,...},我增加了递归限制,以避免最大递归深度超过错误。但是,该程序仅给某人一个正确的答案,当不可能解决时,它并不表示这样做。

我的代码有什么问题以及如何纠正它?

萨米·维拉(Samy Vilar)

这是一个很大的算法问题,但是老实说,我不认为您的实现是正确的,或者可能是因为我不理解您函数的输入/输出,对此我深表歉意。

这是实现的修改版本。

def C(i, coins, cdict = None):
    if cdict == None:
        cdict = {}
    if i <= 0:
        cdict[i] = 0
        return cdict[i]
    elif i in cdict:
        return cdict[i]
    elif i in coins:
        cdict[i] = 1
        return cdict[i]
    else:
        min = 0
        for cj in coins:
            result = C(i - cj, coins)
            if result != 0:
                if min == 0 or (result + 1) < min:
                    min = 1 + result
        cdict[i] = min
        return cdict[i]

这是我尝试解决类似问题的尝试,但是这次返回了硬币列表。我最初从递归算法开始,该算法接受总和和硬币列表,如果找不到此类配置,则该列表可能返回硬币数量最少的列表,或者返回无。

def get_min_coin_configuration(sum = None, coins = None):
if sum in coins: # if sum in coins, nothing to do but return.
    return [sum]
elif max(coins) > sum: # if the largest coin is greater then the sum, there's nothing we can do.
    return None
else: # check for each coin, keep track of the minimun configuration, then return it.
    min_length = None
    min_configuration = None
    for coin in coins:
        results = get_min_coin_configuration(sum = sum - coin, coins = coins)
        if results != None:
            if min_length == None or (1 + len(results)) < len(min_configuration):
                min_configuration = [coin] + results
                min_length = len(min_configuration)
    return min_configuration

好的,现在让我们看看是否可以通过使用动态编程(我称之为缓存)来改善它。

def get_min_coin_configuration(sum = None, coins = None, cache = None):
if cache == None: # this is quite crucial if its in the definition its presistent ...
    cache = {}
if sum in cache:
    return cache[sum]
elif sum in coins: # if sum in coins, nothing to do but return.
    cache[sum] = [sum]
    return cache[sum]
elif max(coins) > sum: # if the largest coin is greater then the sum, there's nothing we can do.
    cache[sum] = None
    return cache[sum]
else: # check for each coin, keep track of the minimun configuration, then return it.
    min_length = None
    min_configuration = None
    for coin in coins:
        results = get_min_coin_configuration(sum = sum - coin, coins = coins, cache = cache)
        if results != None:
            if min_length == None or (1 + len(results)) < len(min_configuration):
                min_configuration = [coin] + results
                min_length = len(min_configuration)
    cache[sum] = min_configuration
    return cache[sum]

现在让我们运行一些测试。

assert all([ get_min_coin_configuration(**test[0]) == test[1] for test in
[({'sum':25,  'coins':[1, 5, 10]}, [5, 10, 10]),
 ({'sum':153, 'coins':[1, 5, 10, 50]}, [1, 1, 1, 50, 50, 50]),
 ({'sum':100, 'coins':[1, 5, 10, 25]}, [25, 25, 25, 25]),
 ({'sum':123, 'coins':[5, 10, 25]}, None),
 ({'sum':100, 'coins':[1,5,25,100]}, [100])] ])

如果此测试不够强大,您也可以执行此操作。

import random
random_sum = random.randint(10**3, 10**4)
result = get_min_coin_configuration(sum = random_sum, coins = random.sample(range(10**3), 200))
assert sum(result) == random_sum

没有这样的硬币组合可能等于我们的random_sum,但我相信它的可能性很小...

我肯定那里有更好的实现方式,我试图强调可读性而不是性能。祝你好运。

更新了先前的代码,它有一个小错误,它假定检查最小代币而不是最大代币,重新编写符合pep8要求的算法,并[]在找不到任何组合而不是的情况下返回None

def get_min_coin_configuration(total_sum, coins, cache=None):  # shadowing python built-ins is frowned upon.
    # assert(all(c > 0 for c in coins)) Assuming all coins are > 0
    if cache is None:  # initialize cache.
        cache = {}
    if total_sum in cache:  # check cache, for previously discovered solution.
        return cache[total_sum]
    elif total_sum in coins:  # check if total_sum is one of the coins.
        cache[total_sum] = [total_sum]
        return [total_sum]
    elif min(coins) > total_sum:  # check feasibility, if min(coins) > total_sum
        cache[total_sum] = []     # no combination of coins will yield solution as per our assumption (all +).
        return []
    else:
        min_configuration = []  # default solution if none found.
        for coin in coins:  # iterate over all coins, check which one will yield the smallest combination.
            results = get_min_coin_configuration(total_sum - coin, coins, cache=cache)  # recursively search.
            if results and (not min_configuration or (1 + len(results)) < len(min_configuration)):  # check if better.
                min_configuration = [coin] + results
        cache[total_sum] = min_configuration  # save this solution, for future calculations.
    return cache[total_sum]



assert all([ get_min_coin_configuration(**test[0]) == test[1] for test in
             [({'total_sum':25,  'coins':[1, 5, 10]}, [5, 10, 10]),
              ({'total_sum':153, 'coins':[1, 5, 10, 50]}, [1, 1, 1, 50, 50, 50]),
              ({'total_sum':100, 'coins':[1, 5, 10, 25]}, [25, 25, 25, 25]),
              ({'total_sum':123, 'coins':[5, 10, 25]}, []),
              ({'total_sum':100, 'coins':[1,5,25,100]}, [100])] ])

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么此递归回溯功能要比非递归函数慢一些,以便计算python更改硬币的最小数量?

来自分类Dev

Clojure:支持meta的最小数量实现?

来自分类Dev

需要一个测试用例,其中给定的最小硬币数量代码在python中失败了?

来自分类Dev

在JavaScript中实现递归硬币找零功能

来自分类Dev

从目录中递归最小地复制文件

来自分类Dev

获得价值所需的最小硬币数量

来自分类Dev

获得价值所需的最小硬币数量

来自分类Dev

尝试确定Java数组中的最小数量和位置

来自分类Dev

在涵盖特定值的列表中查找最小数量的元素

来自分类Dev

更新基于最小数量与状态列在mysql中的列?

来自分类Dev

PostgreSQL获得最小数量(*)?

来自分类Dev

PostgreSQL获得最小数量(*)?

来自分类Dev

python 3.2-使用递归查找列表中的第二个最小数字

来自分类Dev

GUI,用于计算所需的最小硬币数量

来自分类Dev

在Python中递归最小二乘?

来自分类Dev

用递归方式在Python中更改硬币/为什么不起作用?

来自分类Dev

C#Regex字符串中字母数字的最小数量,但可用最小数量中不包含的空格包围

来自分类Dev

TEdit:自动完成并限制最小数量

来自分类Dev

SVG的最小数量是多少?

来自分类Dev

删除最小数量的重叠圆?

来自分类Dev

SQL:如何获取最小数量?

来自分类Dev

查找最小数量并打印的功能

来自分类Dev

如何在产品列表页面中显示“购物车中允许的最小数量”

来自分类Dev

如何在字符串java中打印最大和最小数量的ASCII值

来自分类Dev

如果条件-opencart中的最小数量未定义变量错误

来自分类Dev

在数字列表中查找最小数字的递归方法

来自分类Dev

列出给定数量python所需的硬币

来自分类Dev

Python中可变数量的参数和递归

来自分类Dev

Python中可变数量的参数和递归

Related 相关文章

  1. 1

    为什么此递归回溯功能要比非递归函数慢一些,以便计算python更改硬币的最小数量?

  2. 2

    Clojure:支持meta的最小数量实现?

  3. 3

    需要一个测试用例,其中给定的最小硬币数量代码在python中失败了?

  4. 4

    在JavaScript中实现递归硬币找零功能

  5. 5

    从目录中递归最小地复制文件

  6. 6

    获得价值所需的最小硬币数量

  7. 7

    获得价值所需的最小硬币数量

  8. 8

    尝试确定Java数组中的最小数量和位置

  9. 9

    在涵盖特定值的列表中查找最小数量的元素

  10. 10

    更新基于最小数量与状态列在mysql中的列?

  11. 11

    PostgreSQL获得最小数量(*)?

  12. 12

    PostgreSQL获得最小数量(*)?

  13. 13

    python 3.2-使用递归查找列表中的第二个最小数字

  14. 14

    GUI,用于计算所需的最小硬币数量

  15. 15

    在Python中递归最小二乘?

  16. 16

    用递归方式在Python中更改硬币/为什么不起作用?

  17. 17

    C#Regex字符串中字母数字的最小数量,但可用最小数量中不包含的空格包围

  18. 18

    TEdit:自动完成并限制最小数量

  19. 19

    SVG的最小数量是多少?

  20. 20

    删除最小数量的重叠圆?

  21. 21

    SQL:如何获取最小数量?

  22. 22

    查找最小数量并打印的功能

  23. 23

    如何在产品列表页面中显示“购物车中允许的最小数量”

  24. 24

    如何在字符串java中打印最大和最小数量的ASCII值

  25. 25

    如果条件-opencart中的最小数量未定义变量错误

  26. 26

    在数字列表中查找最小数字的递归方法

  27. 27

    列出给定数量python所需的硬币

  28. 28

    Python中可变数量的参数和递归

  29. 29

    Python中可变数量的参数和递归

热门标签

归档