背景:我在Python 3中工作,但如果人们用其他编程语言提供答案,我仍然可以使用它。有关功能或高效算法或编程技巧的任何建议都会有所帮助。
问题:我遇到了涉及四(4)个整数及其平均值的问题。
所提供的信息: 1.集合中的整数个数(4) 2.整数的平均值
所需信息: 1.导致给定平均值的可能值列表
注意:集合中的整数数量很少,因此生成列表的有效方法不应该那么难,但到目前为止,我遇到了困难。我一直从数字的总和开始(平均值* 4),但还没找到正确的迭代方法。
编辑: 所有整数都是非负数。就我的目的而言,它们也不超过8位。
答案 0 :(得分:1)
使用和,N而不是平均值。
def all_possibilities(N, k=4):
if k == 1:
yield (N,)
return
for i in xrange(N+1):
for p in all_possibilities(N-i, k-1):
yield (i,) + p
print list(all_possibilities(5))
产地:
[(0, 0, 0, 5), (0, 0, 1, 4), (0, 0, 2, 3), (0, 0, 3, 2), (0, 0, 4, 1),
(0, 0, 5, 0), (0, 1, 0, 4), (0, 1, 1, 3), (0, 1, 2, 2), (0, 1, 3, 1),
(0, 1, 4, 0), (0, 2, 0, 3), (0, 2, 1, 2), (0, 2, 2, 1), (0, 2, 3, 0),
(0, 3, 0, 2), (0, 3, 1, 1), (0, 3, 2, 0), (0, 4, 0, 1), (0, 4, 1, 0),
(0, 5, 0, 0), (1, 0, 0, 4), (1, 0, 1, 3), (1, 0, 2, 2), (1, 0, 3, 1),
(1, 0, 4, 0), (1, 1, 0, 3), (1, 1, 1, 2), (1, 1, 2, 1), (1, 1, 3, 0),
(1, 2, 0, 2), (1, 2, 1, 1), (1, 2, 2, 0), (1, 3, 0, 1), (1, 3, 1, 0),
(1, 4, 0, 0), (2, 0, 0, 3), (2, 0, 1, 2), (2, 0, 2, 1), (2, 0, 3, 0),
(2, 1, 0, 2), (2, 1, 1, 1), (2, 1, 2, 0), (2, 2, 0, 1), (2, 2, 1, 0),
(2, 3, 0, 0), (3, 0, 0, 2), (3, 0, 1, 1), (3, 0, 2, 0), (3, 1, 0, 1),
(3, 1, 1, 0), (3, 2, 0, 0), (4, 0, 0, 1), (4, 0, 1, 0), (4, 1, 0, 0),
(5, 0, 0, 0)]
一般来说,会选择(N + k-1,k-1)解决方案。
利用itertools.combinations
的较短解决方案就是:
import itertools
def all_possibilities(N, k=4):
for c in itertools.combinations(range(N + k - 1), k - 1):
yield tuple(x - y - 1 for x, y in zip(c + (N + k - 1,), (-1,) + c))
答案 1 :(得分:0)
假设您真的在寻找(唯一的)非负整数的集,您可以将整数a, b, c, d
命名为a > b > c > d
并注意它们必须总和为average * 4
。然后你可以找到具有这样的生成器函数的组合:
def get_4set_with_average(average):
target_float = average * 4.0
target = int(target_float)
if target_float != target or target < 6:
raise ValueError('No combinations possible')
for a in xrange(target):
for b in xrange(a):
for c in xrange(b):
for d in xrange(c):
if a + b + c + d == target:
yield([a, b, c, d])
print list(get_4set_with_average(4))
考虑到四个整数之间的关系,可以通过各种方式提高效率......
given that...
a > b > c > d >= 0 and a + b + c + d = target
it must be that...
3 <= a <= target - 3,
2 <= b <= target - a - 1,
(target - a - b) / 2 < c <= target - a - b
这给了我们:
def get_4set_with_average(average):
target_float = average * 4.0
target = int(target_float)
if target_float != target or target < 6:
raise ValueError('No combinations possible')
for a in xrange(3, target - 2):
for b in xrange(1, min(a, target - a)):
for c in xrange(int((target - a - b) / 2) + 1,
min(b, target - a - b + 1)):
yield([a, b, c, target - a - b - c])
(我已对此进行了一些测试,但并未彻底测试 - 您需要检查它。)
毫无疑问,有更高效的算法,但是大量可能的组合使得难以运行大值。 (即使平均值= 20在我的机器上也需要很长时间。)