Génération de séquences d'entiers croissants restreints [dupliquer]

Dec 02 2020

Je recherche un moyen efficace de générer une liste complète de séquences d'entiers

 {a_1,a_2,...,a_n} 

de la longueur $n$ tel que $$0\le a_1\le a_2\le\dots\le a_n< m,$$

avec deux paramètres entiers $n$ et $m$.

Je peux imaginer effectuer cela via

Table[Sort[IntegerDigits[x-1,m,n]],{x,m^n}] 

puis supprimez les doublons, mais il devrait sûrement exister un moyen beaucoup plus efficace.

Réponses

7 cvgmt Dec 02 2020 at 18:51

Puisque nous pouvons cartographier une telle séquence

$$0\leq a_1\leq a_2\leq a_3 \leq \cdots \leq a_{n-1}\leq a_n < m $$ à $$0 < b1=a_1+1 < b2=a_2+2 < b3=a_3+3 <\cdots < b_n=a_n+n < m+n $$ et $\{b_1,b_2,\cdots b_n\}$est le nsous - ensemble deRange[m+n-1]

Et nous pouvons obtenir $\{a_1,a_2,\cdots a_n\}$ de $\{b_1,b_2,\cdots b_n\}-\{1,2,\cdots,n\}$

m = 8;
n = 5;
list = Subsets[Range[m+n-1], {n}]
Subtract[#, Range[n]] & /@ list
3 DanielHuber Dec 02 2020 at 18:38

Avec une petite astuce, nous pouvons le faire en utilisant la Tablefonction. Cela est nécessaire car il Tablepossède l'attribut HoldAll.

Pour un petit exemple, nous définissons d'abord m et n:

m=4;
n=2;

Nous créons ensuite une liste de variables et une liste d'itérateurs et les joignons dans le corps de Table:

var = Table[x[i], {i, n}];
iter = Table[{x[i], x[i - 1] + 1, m-1}, {i, n}] /. x[0] -> -1;
body = PrependTo[iter, var]

Enfin, nous appliquons Tablesur le corps et aplatissons pour obtenir des bretelles superflues:

Flatten[Table @@ body, 1]

Cela donne:

{{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}}