2016-12-21 4 views
0
non répétitive et rapide

Ma question est la performance:tableau Peupler avec aléatoires « prédéfinis » valeurs,

  • Je veux remplir un tableau N x N, où N va de 2 ... 10 ;
  • Les valeurs doivent provenir d'un alphabet [a, b, c], toutes sont des entiers;
  • L'objectif est de générer un échantillon de toutes les permutations disponibles de ces tableaux avec cet alphabet.

Je veux générer des tableaux uniques différents de 5M. pour un arbitraire N. Si (N < 4) je veux les générer tous puisqu'il y a 43046721 combinaisons uniques.

Mes tentatives, j'ai essayé attaquer à c'est une myriade de façons:

Représentant la matrice comme un nombre ternaire (ce qui est en fait). Fondamentalement je passe un entier et le convertis en sa représentation ternaire (c'est lent comme l'enfer) aux modules/divisions. J'ai également essayé, en créant un tableau [NxN] et la boucle récursivement à travers l'alphabet changer l'index je suis sur, qui va générer toutes les matrices, et ne peut pas réellement générer des échantillons aléatoires lorsque N est plus grande valeur.

J'ai créé une fonction qui semble être la plus efficace pour créer un échantillon aléatoire quand N est grand: à condition qu'elle génère une tonne de valeurs répétées que j'ai essayé d'atténuer avec l'objet js/hashset un nombre ternaire, je peux calculer l'ID à partir des chiffres dans la matrice.

function ipow(base, exp) 
{ 
    var result = 1; 
    while (exp) 
    { 
     if (exp & 1) 
      result *= base; 
     exp >>= 1; 
     base *= base; 
    } 

    return result; 
} 


var alphabet = [0, 1, -1]; 
var array = []; 
var N = 4; 
var repeated = 0; 
var hashset = {}; 
var correct = 0; 


for (var j = 0; j < 43046721; j++) { 
    var matrixId = 0; 
     array= []; 
    for (var i = 0; i < N * N; i++) { 
     var index = Math.floor(Math.random() * alphabet.length); 
     var alph = array[index]; 
     array[i] = alph; 
     matrixId += ipow(3,i) * index; 
    } 
    if (hashset[matrixId] != null) 
    { 
     repeated++; 
     if (repeated < 5000000) 
      j--; 
    }  
    else 
    { 
     hashset[matrixId] = true; 
     matrixId = 0; 
     correct++; 
    }   
} 

L'exemple de code est JS, mais je ne honesly soin, je veux juste trouver un moyen de mieux/beaucoup plus rapide de le faire.

Répondre

0

Je préférerais une approche de représentation ternaire. Pour résoudre les problèmes de performances:

Vous avez déjà dépensé beaucoup de mémoire pour stocker des tables de hachage pour les combinaisons utilisées. Mais il est possible de faire une table avec une représentation ternaire pour un certain nombre de numéros.

Calculez cette table une fois et utilisez-la pour remplir chaque ligne de votre tableau à partir du nouveau nombre généré. Peut-être, le comportement et la période du générateur aléatoire intégré dans JS n'est pas très bon (je ne sais pas) - alors essayez des PRNG plus avancés comme Mersenne twister pour diminuer (négliger?) La probabilité de répéter la même séquence de numéros (décalés de K * number_of_rows).