파이썬 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()
파이썬 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
패턴이됩니다.