0

J'ai écrit une fonction qui calcule les permutations d'un tableau [a, b, c, ...] à partir d'un index, par exemple:inverse Permutation Index

0 -> a b c 
1 -> a c b 
2 -> b a c 
3 -> b c a 
4 -> c a b 
5 -> c b a  

par cette fonction récursive:

function factorial(n) { return n <= 1 ? 1 : n*factorial(n-1); } 
function permutation(ar, n) { 
    if (ar.length == 1) return [ar[0]]; 
    var x = factorial(ar.length-1); // get first element 
    return ar.splice(Math.floor(n/x),1).concat(permutation(ar, n % x)) 
} 

maintenant, je suis à la recherche d'une fonction qui prend l'indice d'une permutation pour obtenir l'indice de la permutation inverse, à savoir

index perm reversed reversed index 
    **0** -> a b c -> c b a -> **5** 
    **1** -> a c b -> b c a -> **3** 
    **2** -> b a c -> c a b -> **4** 
    **3** -> b c a -> a c b -> **1** 
    **4** -> c a b -> b a c -> **2** 
    **5** -> c b a -> a b c -> **0** 

I peut calculer toutes les permutations, calculer leur inverse et construire son index, mais il semble qu'il devrait y avoir une façon mathématique d'obtenir l'indice de la permutation inverse sans le calculer.

Répondre

0

Je ne sais pas s'il existe une méthode mathématique ou non pour y parvenir, mais vous pouvez y parvenir plus rapidement en utilisant un hashmap.

var dict = {}; 

dict['abc'] = 0; 
dict['acb'] = 1; 
dict['bac'] = 2; 
dict['bca'] = 3; 
dict['cab'] = 4; 
dict['cba'] = 5; 

Donc, une fois que vous avez cela, vous pouvez inverser une chaîne normale et obtenir la valeur de celui-ci son index en utilisant la hashmap ci-dessus formé.

Espérons que cela aide!

+0

Je sais que je peux construire un index (hashmap) sur les éléments inversés, mais pour cela je devrais les calculer tous (imaginez que le tableau des permutations n'était pas 3 mais 300 éléments). J'étais intéressé si je pouvais juste en connaissant l'index d'une entrée calculer l'indice de l'entrée inverse (sans même calculer la permutation elle-même). –

2

si vous jetez un oeil à vos permutations, vous trouverez qu'il est structuré comme suit: (exemple pour longueur = 3)

d'abord vos permutations sont divisés en 3 groupes contenant chacun 2! éléments ces sous-groupes sont ensuite divisés en 2 groupes de longueur 1! , après quoi les sous-sous-groupes ne sont plus divisés.

donc en fait votre permutation peut être « levé les yeux » en premier indiquant quel sous-groupe, il est en indiquant quel groupe puis sous-sous ... il est en

par exemple permutation 2: « bac » est dans le sous-groupe 1 (à partir de 0) et dans le sous-sous-groupe 0.

donc nous pourrions dire 2 = (1,0), comme dans 3 = 1 * (2!) + 0 * (1 !) 4 serait alors (2,0) maintenant si on retourne 2 donc c'est (0,1) et on ajoute 4, (2,0) à cela on obtiendrait (2,1) et ceci est vrai pour toutes les permutations

dans ess : (n = longueur des permutations)

écrivez votre index en tant que * (n-1)! + b * (n-2)! + ... + z * (1!) (a = étage (index/(n-1)), b = étage ((indice% (n-1))/(n-2)!), ...)

trouver un numéro de sorte que si vous retournez le plus petit et les ajouter ensemble, vous obtenez (n-1, n-2, n-3, ..., 1)

il y a probablement un effecient algoritm qui fait cela.

+0

Je ne comprends pas, ce que vous entendez par "retourner le plus petit et les ajouter ensemble". Faisons un exemple - prenons la permutation [c, a, d, b] de l'alphabet [a, b, c, d]. Il a l'index (2,0,1) ou 2 * 6 + 0 * 2 + 1 * 1 = 13 ... Qu'est-ce que je retourne maintenant? –

+0

Je peux transformer cet index en une séquence comme (2,0,3,1), inverser (1,3,0,2), calculer l'indice à partir de (1,2,0) et obtenir un index de que 1 * 6 + 2 * 2 = 10 ... Y a-t-il un moyen d'obtenir directement de (2,0,1) -> (1,2,0)? Je me demande s'il existe une relation ici, qui peut être évaluée sans inverser réellement l'indice? Ou si un indice peut être construit qui est plus facile à inverser? –

+0

je ne l'ai pas regardé à beaucoup c'est juste une relation que j'ai trouvé que je pensais pourrait être utile –