Aqui está uma outra maneira de olhar para o problema: Você tem uma rede gerado pelas colunas de . Use o algoritmo Lenstra-Lenstra-Lovász (LLL) para obter uma base reduzida dessa estrutura. Se você substituir por uma nova matriz formada pela saída de LLL, as colunas de ainda gerarão a mesma rede, mas os vetores de base estarão mais próximos de serem ortogonais entre si e as entradas de deve ter magnitude menor.MMMM- 1
De lá, também ajudaria a obrigados cada componente do separadamente: ou seja, você pode obrigado a th componentepor. (A propósito, o limite não está correto; precisamos usar a soma dos elementos em cada linha, não o máximo.)vEu|vEu|∑dj = 1| (M- 1)eu j|∥ v∥∞≤ ∥M- 1∥
Para valores de até cerca de 30, o algoritmo LLL terminará praticamente instantaneamente. Assintoticamente, é preciso , então ele diminui a velocidade para muito grande , mas, ao mesmo tempo, o número de pontos que precisamos verificar cresce exponencialmente em , portanto o tempo de execução da LLL não é realmente o gargalo. Por outro lado, a economia no número de pontos que precisam ser verificados pode ser enorme. Escrevi um código GAP para gerar uma matriz regular aleatória (estocástica) e comparar os limites nos componentes dedO (d6)ddMv que obtemos usando a base original, em comparação com a base reduzida de LLL (a propósito, não precisamos assumir que a matriz é regular; eu fiz essa restrição apenas porque esse era o caso em sua aplicação):
d: = 8;
M: = IdentityMat (d);
para i em [1..d] faça
para j em [1..d] faça
M [i] [j]: = Aleatório ([- 10 ^ 8..10 ^ 8]);
od;
M [i]: = M [i] / Soma (M [i]);
od;
L: = LLLReducedBasis (M) .base;
MM: = M ^ -1 * 1,0;
LL = L ^ -1 * 1,0;
para i em [1..d] faça
para j em [1..d] faça
MM [i] [j]: = MM [i] [j] * SignFloat (MM [i] [j]);
LL [i] [j]: = LL [i] [j] * SignFloat (LL [i] [j]);
od;
od;
Imprimir ("Limites para a base original:");
ones: = [1..d] * 0 + 1;
v: = MM * uns;
para i em [1..d] faça
v [i]: = Int (Piso (v [i]));
Imprimir (v [i]);
Impressão(" ");
od;
Imprimir ("\ n ("));
Imprimir (Produto (v * 2 + 1));
Imprimir ("aponta para verificar) \ n");
Print ("Limites para LLL:");
v: = LL * uns;
para i em [1..d] faça
v [i]: = Int (Piso (v [i]));
Imprimir (v [i]);
Impressão(" ");
od;
Imprimir ("\ n ("));
Imprimir (Produto (v * 2 + 1));
Imprimir ("aponta para verificar) \ n");
A saída a seguir (com base na semente aleatória padrão, com ) não é atípica:d= 8
Limites para a base original: 9 23 24 4 23 16 23 4
(258370076349 pontos para verificar)
Limites para a base de LLL: 3 3 2 2 3 4 2 3
(2701125 pontos para verificar)
Edit : Este problema é um caso especial do problema geral de enumerar pontos de treliça em politopos convexos, o que resulta ser um problema bem estudado, e existem algoritmos mais eficientes do que o descrito acima. Veja este artigo para uma pesquisa.