行列式优化挑战


13

考虑所有条目均为0或1的30 x 30 Toeplitz矩阵。此难题是查找具有最大行列式的矩阵的简单优化难题。

输入

输出一个30 x 30 Toeplitz矩阵及其所有行列式,其所有条目均为0或1。

得分输出矩阵的行列式。如果两个人得分相同,则第一个答案将获胜。

到目前为止的领先作品

  • 尼克·阿尔杰(Nick Alger)在Matlab中的65,455,857,159,975 (大约(10 ^ 13.8)
  • 65,455,857,159,975在Python中由isaacg(大约10 ^ 13.8)
  • 到2012年,在Mathematica中达到39,994,961,721,988(约10 ^ 13.6)
  • Flounderer在R中的39,788,537,400,052 (大约10 ^ 13.6)
  • Vioz-在Python中获得的8,363,855,075,832(大约10 ^ 12.9)
  • 朱莉娅Julia)的6,984,314,690,903,由Alex A.(大约10 ^ 12.8)

恼人的其他限制2015年7月16日

如果可能的话,请使用任意或高精度算法来计算最终输出行列式,以便我们可以确定它到底是什么(它应该始终是整数)。在python中,应该会有所帮助。


我很惊讶这个问题还没有解决。该答案是否以循环矩阵闻名?
xnor

1
@NickAlger如果该库对所有人公开可用,则可以使用它。
orlp

2
@immibis可悲的是其中有2 ^ 59。

1
有趣的是,两种独立的方法已经获得了具有最大循环矩阵行列式的Toeplitz矩阵。我没有什么数学直觉,为什么?行列式只是二进制Toeplitz矩阵的共同点?
lirtosiast 2015年

1
@ Min_25明天之前我应该​​最多达到19。将会在相关的问题Lembik中为您提供代码/值。使用启发式算法,到目前为止,我在n = 30时的最大值与其他两个张贴者完全相同。多次,涉及随机化。即使我的搜索不限于循环矩阵,每次达到最大值时也会得到循环矩阵。顺便说一句,另一个令我困惑的事实:n = 15的最大值恰好是2 ^ 17。
Reto Koradi

Answers:


11

Matlab 65,455,857,159,975(10 ^ 13.8159)

该方法是在立方体[0,1] ^ 59的内部进行梯度上升,并随机进行许多初始猜测,最后四舍五入以使所有内容均为零和一。

矩阵:

0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0
0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1
1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1
1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1
1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0
0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1
1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1
1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1
1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0
0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1
1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0
0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0
0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0
0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1
1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0   0
0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1   0
0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0   1
1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1   0
0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1   1
1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0   1
1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1   0
0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0   1
1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0   0
0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0   0
0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0   0
0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1   0
0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1   1
1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1   1
1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0   1
1   1   1   0   0   0   0   1   0   1   1   0   1   0   0   1   0   0   0   1   0   1   1   1   0   1   1   1   0   0

码:

% Toeplitz 0-1 determinant optimization

n = 30;
m = n + n-1;

toeplitz_map = @(w) toeplitz(w(n:-1:1), w(n:end));

objective = @(w) det(toeplitz_map(w));

detgrad = @(A) det(A)*inv(A)';

toeplitz_map_matrix = zeros(n^2,m);
for k=1:m
    ek = zeros(m,1);
    ek(k) = 1;
    M = toeplitz_map(ek);
    toeplitz_map_matrix(:,k) = M(:);
end

gradient = @(w) (reshape(detgrad(toeplitz_map(w)),1,n^2)*...
                 toeplitz_map_matrix)';

%check gradient with finite differences
w = randn(m,1);
dw = randn(m,1);
s = 1e-6;
g_diff = (objective(w+s*dw) - objective(w))/s;
g = gradient(w)'*dw;
grad_err = (g - g_diff)/g_diff

warning('off')
disp('multiple gradient ascent:')
w_best = zeros(m,1);
f_best = 0;
for trial=1:100000
    w0 = rand(m,1);
    w = w0;
    alpha0 = 1e-5; %step size
    for k=1:20
        f = objective(w);
        g = gradient(w);
        alpha = alpha0;
        for hh=1:100
            w2 = w + alpha*g;
            f2 = objective(w2);
            if f2 > f
                w = w2;
                break;
            else
                alpha = alpha/2;
            end
        end

        buffer = 1e-4;
        for jj=1:m
            if (w(jj) > 1)
                w(jj) = 1 - buffer;
            elseif (w(jj) < 0)
                w(jj) = 0 + buffer;
            end
        end
    end

    w = round(w);
    f = objective(w);
    if f > f_best
        w_best = w;
        f_best = f;
    end
    disp(trial)
    disp(f_best)
    disp(f)
end

M = toeplitz_map(w_best);

计算梯度的数学公式:

在元素内积(即希尔伯特-施密特内积)中,行列式梯度具有由下式给出的Riesz代表G:

G = det(A)A ^(-*)。

从优化变量(对角值)到Toeplitz矩阵的图J是线性的,因此总梯度g是这两个线性图的组成,

g =(vec(G)* J)',

其中vec()是向量化运算符,它采用矩阵并将其展开为向量。

内部渐变上升:

此后,您要做的就是选择对角线值w_0的初始向量,并对一些小的步长进行alpha迭代:

  1. w_proposed = w_k + alpha * g_k

  2. 要获得w_(k + 1),请采用w_proposed并将[0,1]之外的值截断为0或1

  3. 重复直到满意为止,然后将所有内容四舍五入为0或1。

经过大约80,000次均一随机初始猜测的试验,我的结果实现了这一决定因素。


您提供的OEIS链接用于循环矩阵,这是Topelitz矩阵的特例。因此,仍然有可能做得更好。
isaacg 2015年

@isaacg也极有可能!

是的,当然,我对此不正确。我已经编辑了我的帖子以修复它。
尼克·阿尔杰

1
是的,它在迭代250时达到该值,并在那里停留了100000次迭代。定义行列式2994003的18x18 Toeplitz矩阵的向量为[0,0,0,1,0,1,1,1,1,0,1,1,0,0,0,1,0,1,0, 0,0,1,0,1,1,1,1,0,1,1,0,0,0,1,0],其中顺序从左下到右上。
Nick Alger 2015年

2
当您想出一个新主意并拿出最高编号的IIRC时,我授予了您胜利。哦,这说明了您的答案为何有效math.stackexchange.com/questions/1364471/…

11

带有Numpy的Python 2 65,455,857,159,975〜= 10 ^ 13.8

这是尽可能简单的爬山。使用SymPy进行最终行列式计算以确保准确的结果。用该行列式找到的所有矩阵都是循环的。

使用此行列式找到的矩阵,以从左下到右上的对角线的值给出:

01000100101101000011100111011101000100101101000011100111011
01011101110011100001011010010001011101110011100001011010010
01100001000111011101001110100101100001000111011101001110100
01110100111010010110000100011101110100111010010110000100011
01011101110001000011010010111001011101110001000011010010111
01000101100010110100111101110001000101100010110100111101110
01000100101101000011100111011101000100101101000011100111011

第一个,作为矩阵:

[[1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1]
 [1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1]
 [1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0]
 [0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1]
 [1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1]
 [1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1]
 [1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0]
 [0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0]
 [0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1]
 [1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1]
 [1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1]
 [1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0]
 [0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0]
 [0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0]
 [0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0]
 [0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0 1]
 [1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1 0]
 [0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1 1]
 [1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 1]
 [1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0]
 [0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0 1]
 [1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0 0]
 [0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 0]
 [0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1]
 [1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0]
 [0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0]
 [0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1 0]
 [0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0 1]
 [1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 0]
 [0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1]]

码:

import numpy as np
import sympy as sp
import random
import time
SIZE = 30

random.seed(0)

def gen_diag():
    return [random.randint(0, 1) for i in range(SIZE*2 - 1)]

def diag_to_mat(diag):
    return [diag[a:a+SIZE] for a in range(SIZE-1, -1, -1)]

def diag_to_det(diag):
    matrix = diag_to_mat(diag)
    return np.linalg.det(matrix)

def improve(diag):
    old_diag = diag
    really_old_diag = []
    while really_old_diag != old_diag:
        really_old_diag = old_diag
        for flip_at in range(SIZE * 2 - 1):
            new_diag = old_diag[:]
            new_diag[flip_at] ^= 1
            old_diag = max(old_diag, new_diag, key=diag_to_det)
    return old_diag

overall_best_score = 0
time.clock()
while time.clock() < 500:
    best = improve(gen_diag())
    best_score = diag_to_det(best)
    if best_score > overall_best_score:
        overall_best_score = best_score
        overall_best = best
        print(time.clock(), sp.Matrix(diag_to_mat(overall_best)).det(), ''.join(map(str,overall_best)))


mat = diag_to_mat(overall_best)

sym_mat = sp.Matrix(mat)

print(overall_best)
print(sym_mat.det())

1
真是疯了 辛苦了
Alex A.

.227有点令人担忧。您是否认为有一种方法可以确定决定因素到底是什么?

看来stackoverflow.com/questions/6876377/…可能有助于评估最终决定因素?

@Lembik谢谢-SymPy做到了。
isaacg 2015年

真是太好了!

10

R,39788537400052

这是我尝试进行遗传算法的尝试,但仅限于无性繁殖。我希望我正确理解了挑战。编辑:加快了速度,尝试了其他随机种子,并限制为100代。

    options(scipen=999)

toeplitz <- function(x){
# make toeplitz matrix with first row
# x[1:a] and first col x[(a+1):n]
# where n is the length of x and a= n/2
# Requires x to have even length
#
# [1,1] entry is x[a+1]

N <- length(x)/2
out <- matrix(0, N, N)
out[1,] <- x[1:N]
out[,1] <- x[(N+1):length(x)]
for (i in 2:N){
  for (j in 2:N){
    out[i,j] <- out[i-1, j-1]
  }
} 

out
}

set.seed(1002)

generations <- 100
popsize <- 25
cols <- 60
population <- matrix(sample(0:1, cols*popsize, replace=T), nc=cols)
numfresh <- 5 # number of totally random choices added to population

for (i in 1:generations){

fitness <- apply(population, 1, function(x) det(toeplitz(x)) )
mother <- which(fitness==max(fitness))[1]

population <- matrix(rep(population[mother,], popsize), nc=cols, byrow=T)
for (i in 2:(popsize-numfresh)){
  x <- sample(cols, 1)
  population[i,x] <- 1-population[i,x]
}
for (i in (popsize-numfresh +1):popsize){
  population[i,] <- sample(0:1, cols, replace=T)
}


print(population[1,])
print(fitness[mother])
print(det(toeplitz(population[1,]))) # to check correct

}

输出:

print(population[1, 1:(cols/2)]) # first row
print(population[1, (cols/2+1):(cols)]) # first column (overwrites 1st row)

to <- toeplitz(population[1,])

for (i in 1:(cols/2)) cat(to[i,], "\n")

1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 
0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 
1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 
0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 
0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 
0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 
1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 
1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 
1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 
1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 
0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 
1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 
1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 
1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 
0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 
0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 0 
0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 
0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 
1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 
0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 0 
0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 1 
1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 0 
0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 
0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 0 
0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 0 
0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1 
1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 
0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 1 
1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 1 
1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 1 

很好 您目前正在遥遥领先。

不再有:)

3

朱莉娅6,984,314,690,902.998

这仅构造了1,000,000个随机的Toeplitz矩阵并检查它们的行列式,记录了遇到的最大值。希望有人会提出一个优雅的分析解决方案,但与此同时...

function toeplitz(a, b)
    n = length(a)
    T = Array(Int, n, n)
    T[1,:] = b
    T[:,1] = a
    for i = 2:n
        T[i,2:n] = T[i-1,1:n-1]
    end
    T
end

d = 0
A = Any[]

for i = 1:1000000
    # Construct two random 0,1 arrays
    r1 = rand(0:1, 30)
    r2 = rand(0:1, 30)

    # Compute the determinant of a toeplitz matrix constructed
    # from the two random arrays
    D = det(toeplitz(r1, r2))

    # If the computed determinant is larger than anything we've
    # encountered so far, add it to A so we can access it later
    D > d && begin
        push!(A, (D, r1, r2))
        d = D
    end
end

M,N = findmax([i[1] for i in A])

println("Maximum determinant: ", M, "\n")
println(toeplitz(A[N][2], A[N][3]))

您可以在此处查看输出。


我想知道行列式计算的精确度。我认为基础计算是以双精度完成的吗?由于小数点后的数字为.998,因此最有可能的是,最接近的整数仍然是正确的行列式。通常,当这些矩阵变得相当大时,将通用行列式计算(例如基于标准LR分解)应用于这些矩阵时,就会开始出现浮点精度问题。
Reto Koradi

@RetoKoradi看起来它使用LU分解来获取行列式。
Alex A.

3

Mathematica,39,994,961,721,988(10 ^ 13.60)

一种简单的模拟退火优化方法;尚未优化或调整。

n = 30;
current = -\[Infinity];
best = -\[Infinity];
saved = ConstantArray[0, {2 n - 1}];
m := Array[a[[n + #1 - #2]] &, {n, n}];
improved = True;
iters = 1000;
pmax = 0.1;
AbsoluteTiming[
 While[improved || RandomReal[] < pmax,
   improved = False;
   a = saved;
   Do[
    Do[
      a[[i]] = 1 - a[[i]];
      With[{d = Det[m]},
       If[d > best,
          best = d;
          current = d;
          saved = a;
          improved = True;
          Break[];,
          If[d > current || RandomReal[] < pmax (1 - p/iters),
           current = d;
           Break[];,
           a[[i]] = 1 - a[[i]];
           ]
          ];
        ;
       ],
      {i, 2 n - 1}];,
    {p, iters}];
   ];
 ]
best
Log10[best // N]
a = saved;
m // MatrixForm

样本输出:

{20.714876,Null}
39994961721988
13.602
(1  1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0
0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0
0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0
0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0
0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1
1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0
0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0
0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0
0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0
0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1
1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1
1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0
0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1
1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1
1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1   0
0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1   1
1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1   1
1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0   1
1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1   0
0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1   1
1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0   1
1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0   0
0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0   0
0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0   0
0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1   0
0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0   1
1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1   0
0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1   1
1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1   1
1   1   0   1   0   0   0   0   1   1   0   1   1   1   0   1   1   0   1   1   0   0   0   0   1   0   0   0   0   1

)

1

蟒蛇2,8 363 855 075 832

这涉及一个非常基本的,几乎不存在的策略。

from scipy import linalg

start = 2**28
mdet  = 0
mmat  = []
count = 0
powr  = 1
while 1:
 count += 1
 v = map(int,bin(start)[2:].zfill(59))
 m = [v[29:]]
 for i in xrange(1,30):
     m += [v[29-i:59-i]]
 d = 0
 try: d = linalg.det(m, check_finite=False)
 except: print start
 if d > mdet:
     print d
     print m
     mdet = d
     mmat = m
     start += 1
     powr = 1
 else:
     start += 2**powr
     powr += 1
     if start>(2**59-1):
         start-=2**59-1
         powr = 1
 if count%10000==0: print 'Tried',count

这是经过约5,580,000次尝试后找到的最佳矩阵:

1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 1 0 1 0
1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 1 0 1
1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 1 0
0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 1
1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1
0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 1 0
1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 1
0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0
0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1 0
1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0 1
1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0 0
0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 0
0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0
0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0
0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0
0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0
1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1
0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1
1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1
1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0
1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1
1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1
1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1
1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0
1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1
1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1
0 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0 0
0 0 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 0
1 0 0 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1
0 1 0 0 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1

仍在运行...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.