-
Notifications
You must be signed in to change notification settings - Fork 0
/
boss.py
53 lines (41 loc) · 1.19 KB
/
boss.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import numpy as np
from numpy import zeros
from numpy.random import default_rng
def reversed_enumerate(iter, j):
for w in reversed(iter):
yield j, w
j -= 1
def better_mutation(v, order, gsts):
i = order.index(v)
p = len(order)
scores = zeros(p + 1)
prefix = []
score = 0
for j, w in enumerate(order):
scores[j] = gsts[v].trace(prefix) + score
if v != w:
score += gsts[w].trace(prefix)
prefix.append(w)
scores[p] = gsts[v].trace(prefix) + score
best = p
prefix.append(v)
score = 0
for j, w in reversed_enumerate(order, p - 1):
if v != w:
prefix.remove(w)
score += gsts[w].trace(prefix)
scores[j] += score
if scores[j] > scores[best]: best = j
if scores[i] + 1e-6 > scores[best]: return False
order.remove(v)
order.insert(best - int(best > i), v)
return True
def boss(order, gsts, rng=default_rng()):
variables = [v for v in order]
while True:
improved = False
rng.shuffle(variables)
for v in variables:
improved |= better_mutation(v, order, gsts)
if not improved: break
return order