son*_*ong 14 python algorithm integer-partition
我正在尝试为Python找到或开发Integer Partitioning代码.
FYI,整数分区将给定的整数n表示为小于n的整数之和.例如,整数5可以表示为4 + 1 = 3 + 2 = 3 + 1 + 1 = 2 + 2 + 1 = 2 + 1 + 1 + 1 = 1 + 1 + 1 + 1 + 1
我找到了很多解决方案.http://homepages.ed.ac.uk/jkellehe/partitions.php和http://code.activestate.com/recipes/218332-generator-for-integer-partitions/
但是,我真正想要的是限制分区数量.
比如说,#分区k = 2,一个程序只需要显示5 = 4 + 1 = 3 + 2
,
如果k = 3,5 = 3 + 1 + 1 = 2 + 2 + 1
Sna*_*fee 19
我写了一个生成器解决方案
def partitionfunc(n,k,l=1):
'''n is the integer to partition, k is the length of partitions, l is the min partition element size'''
if k < 1:
raise StopIteration
if k == 1:
if n >= l:
yield (n,)
raise StopIteration
for i in range(l,n+1):
for result in partitionfunc(n-i,k-1,i):
yield (i,)+result
Run Code Online (Sandbox Code Playgroud)
这将生成n
具有长度的所有分区,k
每个分区按最小到最大的顺序排列.
快速说明:通过cProfile
使用测试功能,使用生成器方法比使用falsetru的直接方法要快得多lambda x,y: list(partitionfunc(x,y))
.在测试运行中n=50,k-5
,我的代码在.019秒内与直接方法的2.612秒相比.
def part(n, k):
def _part(n, k, pre):
if n <= 0:
return []
if k == 1:
if n <= pre:
return [[n]]
return []
ret = []
for i in range(min(pre, n), 0, -1):
ret += [[i] + sub for sub in _part(n-i, k-1, i)]
return ret
return _part(n, k, n)
Run Code Online (Sandbox Code Playgroud)
例子:
>>> part(5, 1)
[[5]]
>>> part(5, 2)
[[4, 1], [3, 2]]
>>> part(5, 3)
[[3, 1, 1], [2, 2, 1]]
>>> part(5, 4)
[[2, 1, 1, 1]]
>>> part(5, 5)
[[1, 1, 1, 1, 1]]
>>> part(6, 3)
[[4, 1, 1], [3, 2, 1], [2, 2, 2]]
Run Code Online (Sandbox Code Playgroud)
更新
使用记忆:
def part(n, k):
def memoize(f):
cache = [[[None] * n for j in xrange(k)] for i in xrange(n)]
def wrapper(n, k, pre):
if cache[n-1][k-1][pre-1] is None:
cache[n-1][k-1][pre-1] = f(n, k, pre)
return cache[n-1][k-1][pre-1]
return wrapper
@memoize
def _part(n, k, pre):
if n <= 0:
return []
if k == 1:
if n <= pre:
return [(n,)]
return []
ret = []
for i in xrange(min(pre, n), 0, -1):
ret += [(i,) + sub for sub in _part(n-i, k-1, i)]
return ret
return _part(n, k, n)
Run Code Online (Sandbox Code Playgroud)
小智 5
首先我要感谢大家的贡献。我到达这里需要一个算法来生成具有以下详细信息的整数分区:
将一个数字的分区生成为恰好 k 个部分,但也具有 MINIMUM 和 MAXIMUM 约束。
因此,我修改了“Snakes and Coffee”的代码以适应这些新需求:
def partition_min_max(n,k,l, m):
'''n is the integer to partition, k is the length of partitions,
l is the min partition element size, m is the max partition element size '''
if k < 1:
raise StopIteration
if k == 1:
if n <= m and n>=l :
yield (n,)
raise StopIteration
for i in range(l,m+1):
for result in partition_min_max(n-i,k-1,i,m):
yield result+(i,)
>>> x = list(partition_min_max(20 ,3, 3, 10 ))
>>> print(x)
>>> [(10, 7, 3), (9, 8, 3), (10, 6, 4), (9, 7, 4), (8, 8, 4), (10, 5, 5), (9, 6, 5), (8, 7, 5), (8, 6, 6), (7, 7, 6)]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8678 次 |
最近记录: |