Ecco un altro modo di guardare al problema: Si dispone di un reticolo generato dalle colonne di . Utilizzare l'algoritmo Lenstra – Lenstra – Lovász (LLL) per ottenere una base ridotta di questo reticolo. Se sostituisci con una nuova matrice formata dall'output di LLL, le colonne di genereranno comunque lo stesso reticolo, ma i vettori di base saranno più vicini all'essere ortogonali tra loro e le voci di dovrebbe avere una grandezza inferiore.MMMM−1
Da lì, si contribuirebbe anche a vincolati ogni componente del a parte: ad esempio, è possibile legata la esima componentedi. (A proposito, il limite non è corretto; dobbiamo usare la somma degli elementi su ogni riga, non il massimo.)vi|vi|∑dj=1|(M−1)ij|∥v∥∞≤∥M−1∥
Per valori di fino a circa 30, l'algoritmo LLL finirà praticamente all'istante. Asintoticamente, prende , quindi rallenterà per molto grande , ma allo stesso tempo il numero di punti che dobbiamo controllare cresce esponenzialmente in , quindi il tempo di esecuzione della LLL non è realmente il collo di bottiglia. D'altra parte, i risparmi nel numero di punti che devono essere controllati possono essere enormi. Ho scritto un codice GAP per generare una matrice casuale (stocastica) casuale e confrontare i limiti sui componenti didO(d6)ddMv che otteniamo utilizzando la base originale, rispetto alla base ridotta LLL (A proposito, non abbiamo bisogno di presumere che la matrice sia regolare; ho fatto questa restrizione solo perché questo era il caso nella tua applicazione):
d: = 8;
M: = IdentityMat (d);
perché io in [1..d] do
per j in [1..d] do
M [i] [j]: = Random ([- 10 ^ 8..10 ^ 8]);
od;
M [i]: = M [i] / Somma (M [i]);
od;
L: = LLLReducedBasis (M) .basis;
MM: = M ^ -1 * 1.0;
LL: = L ^ -1 * 1.0;
perché io in [1..d] do
per j in [1..d] do
MM [i] [j]: = MM [i] [j] * SignFloat (MM [i] [j]);
LL [i] [j]: = LL [i] [j] * SignFloat (LL [i] [j]);
od;
od;
Stampa ("Limiti per base originale:");
quelli: = [1..d] * 0 + 1;
v: = MM * quelli;
perché io in [1..d] do
v [i]: = Int (Piano (v [i]));
Stampa (v [i]);
Stampa(" ");
od;
Stampa ( "\ n (");
Stampa (Prodotto (v * 2 + 1));
Stampa ("punti da controllare) \ n");
Stampa ("Bounds for LLL base:");
v: = LL * quelli;
perché io in [1..d] do
v [i]: = Int (Piano (v [i]));
Stampa (v [i]);
Stampa(" ");
od;
Stampa ( "\ n (");
Stampa (Prodotto (v * 2 + 1));
Stampa ("punti da controllare) \ n");
Il seguente output (basato sul seed casuale predefinito, con ) non è atipico:d=8
Limiti per la base originale: 9 23 24 4 23 16 23 4
(258370076349 punti da controllare)
Limiti per la base LLL: 3 3 2 2 3 4 2 3
(2701125 punti da controllare)
Modifica : questo problema è un caso speciale del problema generale dell'enumerazione dei punti reticolari nei polipropilene convessi, che risulta essere un problema ben studiato e che esistono algoritmi più efficienti di quello sopra descritto. Vedi questo documento per un sondaggio.