defanswer(N): result = partition(N) iftype(result) islist: output_string = '+'.join(str(item) for item in result ) output_string = f'{N}={output_string}' eliftype(result) isint: return N return output_string
defpartition_1(N): if N < 3: return N start = 1 end = 2 sum = start + end answer_list = [] whileTrue: if N == sum: answer_list.append(list(range(start, end+1, 1))) start = start + 1 end = start + 1 sum = start + end elifsum < N: end = end + 1 sum = sum + end else: start = start + 1 end = start + 1 sum = start + end if start > int(N//2): break if answer_list: # 很明显, 最后加入answer_list, start数值是最大的, 就会是最短的最优解 return(answer_list[-1]) else: return N
等差数列求和
回忆高中数学知识, 等差数列前n项和的公式为: $S_n = a_1 * n + \frac{n * ( n - 1 ) }{2} * d$
defpartition_2(N): result = [] if N < 3 : return N else: temp_result = None flag = False for n inrange(2,N//2, 1): for a1 inrange(N//2, 0, -1): if N == a1 *n + n * (n-1) / 2: flag = True temp_result = (a1, n) break if flag: break if flag: for i inrange(n): result.append(a1+i) else: return N return result
defcheck_aviable(N,n): # 判断能否有整数解 if (N-int(n*(n-1)/2))%n == 0: return(int((N-int(n*(n-1)/2))/n),n) else: returnFalse
defpartition_3(N): if N in (0,1,2): return N for n inrange(2,N,1): result = check_aviable(N, n) if result: break else: continue if result: answer = [] for i inrange(result[1]): answer.append(result[0]+i) return answer else: return N
测试运行一下
测试用例分别是[8, 15, 123123, 122224, 1231231, 65536].
为了直观地感受各个算法的效果, 我们再引入一个修饰器去记录运算时间.
1 2 3 4 5 6 7 8 9 10 11 12
from time import time deftimer_func(func): # This function shows the execution time of # the function object passed defwrap_func(*args, **kwargs): t1 = time() result = func(*args, **kwargs) t2 = time() print(f'Function {func.__name__!r} executed in {(t2-t1):.4f}s') return result return wrap_func
partition_1
使用穷举法, 其实也没有很慢, 运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12
Function 'partition_1' executed in 0.0000s 8 Function 'partition_1' executed in 0.0000s [7, 8] Function 'partition_1' executed in 0.1748s [61561, 61562] Function 'partition_1' executed in 0.1740s [3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835] Function 'partition_1' executed in 2.0361s [615615, 615616] Function 'partition_1' executed in 0.0823s 65536
partition_2
在这个算法下, 计算像65536这种无法分解的大数, 效率最低, 比上面的穷举法还要慢.
运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12
Function 'partition_2' executed in 0.0000s 8 Function 'partition_2' executed in 0.0000s [7, 8] Function 'partition_2' executed in 0.0000s [61561, 61562] Function 'partition_2' executed in 0.4697s [3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835] Function 'partition_2' executed in 0.0000s [615615, 615616] Function 'partition_2' executed in 253.7682s 65536
partition_3
这是目前看到最高效率的算法了, 运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12
Function 'partition_3' executed in 0.0000s 8 Function 'partition_3' executed in 0.0000s [7, 8] Function 'partition_3' executed in 0.0000s [61561, 61562] Function 'partition_3' executed in 0.0000s [3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835] Function 'partition_3' executed in 0.0000s [615615, 615616] Function 'partition_3' executed in 0.0305s 65536