优化N位数所有排列和算法

时间:2017-10-27 00:05:04

标签: python algorithm

[注:编程挑战]

挑战说明:

输入:数字列表1,5,6,2,7,4 非重复且无零(数字1-9全部有效)。目标是创建所有排列并将它们全部加起来。我为此使用了itertools排列。我能够在本地机器上用7,8和9digits做一些测试断言。在9位数时,服务器在12秒内超时的时间会增加很多,但我的计算机不会花那么长时间。它只是说要优化我的算法。

下面是如何形成数组的示例,itertools在内部循环的每次迭代中执行此操作。

array for the list      sum (terms of arrays)
[1]                      1 # arrays with only one term (7 different arrays)
[5]                      5
[6]                      6
[2]                      2
[7]                      7
[3]                      3
[4]                      4

[1, 5]                   6 # arrays with two terms (42 different arrays)
[1, 6]                   7
[1, 2]                   3
[1, 7]                   8
[1, 3]                   4
[1, 4]                   5

.....                   ...
[1, 5, 6]               12 # arrays with three terms(210 different arrays)
[1, 5, 2]                8 
[1, 5, 7]               13 
[1, 5, 3]                9 
........                ...

这是我到目前为止所做的,它完成了工作,但我的主要瓶颈是总和,从8位到9位数呈指数增长。功能 传递 两个测试,但在服务器上超时。

for i in range(1, limit + 1):
        for j in permutations(digits, i):
            grandSum =+ grandSum + sum(j)

以下是cProfile运行的结果,7,8,9:

13778 function calls in 0.011 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.011    0.011 <string>:1(<module>)
        7    0.000    0.000    0.000    0.000 GreatTotalAdditions.py:25(removefirstindex)
        1    0.006    0.006    0.011    0.011 GreatTotalAdditions.py:31(gta)
        1    0.000    0.000    0.011    0.011 {built-in method builtins.exec}
       21    0.000    0.000    0.000    0.000 {built-in method builtins.len}
        8    0.000    0.000    0.000    0.000 {built-in method builtins.print}
    13699    0.004    0.000    0.004    0.000 {built-in method builtins.sum}
       25    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        7    0.000    0.000    0.000    0.000 {method 'insert' of 'list' objects}
        7    0.000    0.000    0.000    0.000 {method 'pop' of 'list' objects}

109701 function calls in 0.086 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.085    0.085 <string>:1(<module>)
       11    0.000    0.000    0.000    0.000 GreatTotalAdditions.py:25(removefirstindex)
        1    0.047    0.047    0.085    0.085 GreatTotalAdditions.py:31(gta)
        1    0.000    0.000    0.086    0.086 {built-in method builtins.exec}
       27    0.000    0.000    0.000    0.000 {built-in method builtins.len}
        9    0.000    0.000    0.000    0.000 {built-in method builtins.print}
   109600    0.038    0.000    0.038    0.000 {built-in method builtins.sum}
       28    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
       11    0.000    0.000    0.000    0.000 {method 'insert' of 'list' objects}
       11    0.000    0.000    0.000    0.000 {method 'pop' of 'list' objects}

986553 function calls in 0.701 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.701    0.701 <string>:1(<module>)
       16    0.000    0.000    0.000    0.000 GreatTotalAdditions.py:25(removefirstindex)
        1    0.374    0.374    0.701    0.701 GreatTotalAdditions.py:31(gta)
        1    0.000    0.000    0.701    0.701 {built-in method builtins.exec}
       34    0.000    0.000    0.000    0.000 {built-in method builtins.len}
       10    0.000    0.000    0.000    0.000 {built-in method builtins.print}
   986409    0.327    0.000    0.327    0.000 {built-in method builtins.sum}
       48    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
       16    0.000    0.000    0.000    0.000 {method 'insert' of 'list' objects}
       16    0.000    0.000    0.000    0.000 {method 'pop' of 'list' objects}

以下是我需要帮助的地方: 知道总和占用了大部分计算时间。我想出了这个数学公式,一个3位数字的例子:

(3-1)! *(1 + 2 + 3)*(111)

我的实现如下,请记住我是python的新手:

def sum_them_quick(digits):

    ones = ""
    digitsSum = 0
    # if 3 digits then form 111
    for i in range(len(digits)):
        ones += "1"

    for j in digits:
        digitsSum = digitsSum + j

    return factorial(len(digits)-1) * (digitsSum) * (int(ones))

然而,最后一个函数的结果是错误的,并且与通过的测试的良好结果不对应。我不完全确定排列的数量是否与itertools排列方法不同,但我明天肯定会确认。

0 个答案:

没有答案