繁体   English   中英

用3个常数找到所有可能的排列

[英]Finding all possible permutations with 3 Constants

因为我确信您都知道“真正的甜甜圈店问题”( https://math.stackexchange.com/questions/223345/counting-donuts )。 所以我才开始。

我有3个整数,所有三个都是由用户输入的。 和他们一起,我需要计算它们有多少种可能的排列。 我已经有了一些代码,它对于小整数可以正常工作,如果它们变得更大,我的工具实际上可以运行数天/小时?

递归函数来计算可能的排列:

def T(n, k, K):
if k==0: return n==0
return sum(T(n-i, k-1, K) for i in xrange(0, K[k-1]+1))

说明:

  • n =瓶数
  • k =箱子数量,
  • K =一个箱子可容纳的最大瓶子数

每个板条箱的K都不相同,不需要填满,甚至可以为空。

因此,如您所见,我正在计算它们的数量,以在给定X个板条箱中容纳X个给定的瓶中,其中一个板条箱最多可以容纳X个瓶。

更好理解的示例:可以说,我们有:

  • 7瓶(n)
  • 2条箱子(k)-> [k1,k2]
  • k1适合3瓶(K1) ,k2适合5瓶(K2) [k1-> 3,k2-> 5]

因此,有两种将瓶子装到板条箱中的可能性。

另一个:

  • 7瓶(n)
  • 3个箱子(k)-> [k1,k2,k3]
  • k1适合2瓶,K2适合3瓶,K3适合4瓶

6种可能性

上面的代码计算出完美无瑕,但是当我尝试使用它时:

问题:

  • 30瓶(n)
  • 20箱(k)
  • k1-> 1瓶(K1) ,k2-> 2瓶(K2) ,k3-> 3瓶(K3) ,k4-> 4瓶(K4) ..依此类推,直到k20-> 20瓶(K20) ,我确定您知道这个主意。

它需要永远,所以我问你;

题:

我该如何改善上述代码/功能?

您的问题是所进行的计算数量呈指数级增长。 但是这些计算一遍又一遍地计算同一件事。

解决方案是存储中间值AKA备注。

这是python 3.2中的一个版本,使用functools.lru_cache为您做备忘录

import functools

    def T(n, k, K):
      @functools.lru_cache(maxsize=None)
      def Tsub(n,k):
        if k==0: return n==0
        return sum(Tsub(n-i,k-1) for i in range(0, K[k-1]+1))
      return Tsub(n,k)

    print( T(7,2,[3,5]) )
    print( T(7,3,[2,3,4]) )
    print( T(30,20,list(range(20))) )

在我的计算机上,最终结果为2172723680407,并立即获得。

如果您没有python 3.2,可以这样做:

def T(n, k, K):
  cache = {}
  def Tsub(n,k):
    key = (n,k)
    if key in cache:
      return cache[key]
    if k==0:
      cache[key] = (n==0)
      return n==0
    v = sum(Tsub(n-i,k-1) for i in xrange(0, K[k-1]+1))
    cache[key] = v
    return v
  return Tsub(n,k)

print( T(7,2,[3,5]) )
print( T(7,3,[2,3,4]) )
print( T(30,20,list(range(20))) )

函数的奇怪嵌套用于解决无法将列表( K )存储为表键的问题。

暂无
暂无

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

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