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のデータ構造をコピーしました。ペアの最初の要素はそのバケット内の要素であり、2番目はそのバケットの合計です。
私は同じ「利用可能な金額を追跡する」アプローチから始めます。私のソートヒューリスティックは、特定のリスト内の最小の2つの要素の合計です。また、さまざまな可能性を試すために小さなランダムスキューを追加します。
各反復は、ランダムな欲張りと同様に、最初に利用可能なビンに新しい数をそれぞれ配置するだけです。これが失敗すると、単に再起動します。
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
パターンになります。