Python 3,121,<0.001秒
马丁·巴特纳(Martin Buttner)改进了启发式算法,这意味着我们甚至不需要随机性。
输出:
1447152500.9339304
[1, 4, 10, 13, 28, 31, 37, 40, 82, 85, 91, 94, 109, 112, 118, 121]
[2, 3, 11, 12, 29, 30, 38, 39, 83, 84, 92, 93, 110, 111, 119, 120]
[5, 6, 7, 8, 9, 32, 33, 34, 35, 36, 86, 87, 88, 89, 90, 113, 114, 115, 116, 117]
[14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108]
[41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81]
1447152500.934646 121
码:
from copy import deepcopy
from random import seed, randrange
from time import clock, time
from cProfile import run
n = 5
seed(0)
def heuristic(bucket):
return len(bucket[0]) and bucket[0][-1]
def search():
best = 0
next_add = 1
old_add = 0
lists = [[[],set()] for _ in range(n)]
print(time())
while clock() < 600 and next_add != old_add:
old_add = next_add
lists.sort(key=heuristic, reverse=True)
for i in range(n):
if next_add not in lists[i][1]:
lists[i][0].append(next_add)
lists[i][1].update([next_add + old for old in lists[i][0]])
if next_add > best:
best = next_add
next_add += 1
break
for l in lists:
print(l[0])
print(time(), next_add-1, end='\n\n')
search()
Python 3、112
按前2个元素的总和+偏斜排序
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79]
[7, 8, 9, 10, 11, 12, 13, 27, 28, 29, 30, 31, 32, 33, 80, 81, 82, 83, 84, 85, 86, 100, 101, 102, 103, 104, 105, 106]
[3, 4, 14, 19, 21, 26, 36, 37, 87, 92, 94, 99, 109, 110]
[2, 5, 16, 17, 20, 23, 24, 35, 38, 89, 90, 96, 97, 108, 111]
[1, 6, 15, 18, 22, 25, 34, 39, 88, 91, 93, 95, 98, 107, 112]
1447137688.032085 138.917074 112
我复制了El'endia Starman的数据结构,该数据结构由成对的列表组成,其中对的第一个元素是该存储桶中的元素,第二个是该存储桶的总和。
我从相同的“跟踪可用金额”方法开始。我的排序启发式只是给定列表中最小的两个元素的总和。我还添加了一个小的随机偏斜来尝试不同的可能性。
每次迭代都将每个新数字简单地放置在第一个可用仓中,类似于随机贪婪。一旦失败,它将重新启动。
from copy import deepcopy
from random import seed, randrange
from time import clock, time
n = 5
seed(0)
def skew():
return randrange(9)
best = 0
next_add = old_add = 1
while clock() < 600:
if next_add == old_add:
lists = [[[],[]] for _ in range(n)]
next_add = old_add = 1
old_add = next_add
lists.sort(key=lambda x:sum(x[0][:2]) + skew(), reverse=True)
for i in range(n):
if next_add not in lists[i][1]:
lists[i][0].append(next_add)
lists[i][1].extend([next_add + old for old in lists[i][0]])
if next_add > best:
best = next_add
for l in lists:
print(l[0])
print(time(), clock(), next_add, end='\n\n')
next_add += 1
break
n=59
,并允许号码的最大数量少于排序nextN
给出n=64
。按不允许的数字列表的长度排序(可能重复),可以非常迅速地得出一种优雅的n=30
样式。