我是python的新手,我试图解决此优化问题:

    In How many possible ways can I receive 42 emails in 7 days?


我用Python编写了这个程序来计算所有解决方案:

n = 42
print(n, "emails can be received in the following ways:")
solcount = 0
for d1 in range (n+1):
    for d2 in range (n+1-d1):
        for d3 in range (n+1-d1-d2):
            for d4 in range (n+1-d1-d2-d3):
                for d5 in range (n+1-d1-d2-d3-d4):
                    for d6 in range (n+1-d1-d2-d3-d4-d5):
                        for d7 in range (n+1-d1-d2-d3-d4-d5-d6):
                            if d1+d2+d3+d4+d5+d6+d7 == n:
                                solcount +=1
print("There are", solcount, "possible solutions")


其中d1到d7分别是第1到7天收到的电子邮件数量。

现在,这有两个问题:


运行时间高得离谱,我怀疑这个算法
远非最佳。
该代码不允许我更改天数(例如,如果我将天数固定为变量k)。


我该如何简化呢?

谢谢!

最佳答案

正如罗里·道顿(Rory Daulton)所指出的,这是一个stars and bars问题。我将尝试以一种简单的方式对其进行解释,因此,甚至不必费心去浏览维基百科。

现在,假设您在3天内仅收到5封电子邮件。解决方案的总数与下列字词相同:

"eee|e|e" # represents 3 emails in day1, 1 in day2 and 1 in day3


字谜可以作为符号数量的阶乘除以每个符号重复次数的阶乘乘积的乘积来计算。在我们的简单情况下:

(5 + 3 - 1)!/(5!*(3-1)!)


请注意,我们只需要2天的酒吧三天。

使用这个简单的参数,您可以轻松实现以下解决方案:

from math import factorial

def possibilities(emails, days):
    return factorial(emails + days - 1)//factorial(emails)//factorial(days - 1)


该解决方案不是很有效,因为它可以计算非常大的阶乘。您可以通过寻找一种聪明的方法来计算该值来改进它,或者使用一个为您提供二项式系数的库,例如scipysympy

10-04 20:54