从00000000….1开始,最后得到以下序列:
出于好奇,我决定用多项式来近似这些规则,这样细胞不仅可以是0和1,而且可以是介于两者之间的灰色。
def triangle(x,y,z,v0):
v=(y + y * y + y * y * y - 3. * (1. + x) * y * z + z * (1. + z + z * z)) / 3.
return (v-v0)*(v-v0)
因此,如果x,y,z和v0与表中的任何规则匹配,它将返回0,否则返回正的非零值。
def eval():
s = 0.
for i in range(W - 1):
for j in range(1, W + 1):
xx = x[i, (j - 1) % W]
yy = x[i, j % W]
zz = x[i, (j + 1) % W]
r = x[i + 1, j % W]
s += triangle(xx, yy, zz, r)
for j in range(W - 1): s += x[0, j] * x[0, j]
s += (1 - x[0, W - 1]) * (1 - x[0, W - 1])
return torch.sqrt(s)
同样,在这个函数的底部,我为第一行添加了普通条件,这样除了最后一个元素(即1)之外,所有元素都是0。最后我决定用pytorch最小化W*W矩阵上的平方和:
x = Variable(torch.DoubleTensor(W,W).zero_(), requires_grad=True)
opt = torch.optim.LBFGS([x],lr=.1)
for i in range(15500):
def closure():
opt.zero_grad()
s=eval()
s.backward()
return s
opt.step(closure)
full code
,你可以自己试试。问题是,对于10×10,它在~20步内收敛到正确的解:
但如果我用15*15的板,它永远不会收敛:
UPD:改进的收敛图,SOS日志:
我在C++中使用这个代码进行优化:
find_min_using_approximate_derivatives(bfgs_search_strategy(),
objective_delta_stop_strategy(1e-87),
s, x, -1)