J’ai des combinaisons comme celle-ci:
1,2,3,4 // index 0
1,2,3,5 // index 1
1,2,3,6 // index 2
et ainsi de suite jusqu’à 7,8,9,10
Donc, ce sera n = 10 k = 4 de la combinatoire
Comment calculer la combinaison par index
Par exemple lorsque mon index == 1
myCmb = func (index)
retourne 1,2,3,5
Ceci est un exemple dont j’ai besoin pour les plus gros nombres, et pour plus de params et sans (si possible) de nombreuses boucles
Je trouve quelque chose comme ceci pour obtenir un poste: http://answers.yahoo.com/question/index?qid=20110320070039AA045ib
Je veux maintenant inverser cette …
Je programme en C ++ Merci pour toute sugesstions ou aide
Il semble que vous souhaitiez trouver la combinaison k pour un nombre donné .
En suivant l’ exemple , voici quelque chose qui devrait fonctionner:
#include #include #include #include #include std::size_t Choose(double n, double k) { using boost::math::binomial_coefficient; if (n < k) return 0; return static_cast(binomial_coefficient(n, k)); } // Returns the largest n such that Choose(n, k) <= pos. int CombinationElement(int k, int pos) { int n = k; int coeff = 1, prev_coeff = 0; while (coeff <= pos) { coeff = Choose(++n, k); prev_coeff = coeff; } return n - 1; } // Returns an k-combination at position pos. std::vector Combination(int k, int pos) { std::vector combination; for (; k > 0; --k) { int n = CombinationElement(k, pos); combination.push_back(n); pos -= Choose(n, k); } return combination; } int main(int argc, char** argv) { using std::cout; using std::endl; if (argc != 3) { cout << "Usage: $ " << argv[0] << " K POS" << endl; cout << "Prints the K-combination at position POS." << endl; return 1; } int k = boost::lexical_cast (argv[1]); int pos = boost::lexical_cast (argv[2]); std::vector combination = Combination(k, pos); for (int i = 0; i < k; i++) cout << combination[i] << " "; cout << std::endl; }
Notez que par commodité, le code dépend de Boost pour calculer les coefficients binomiaux ( boost::math::binomial_coefficient
) et pour parsingr les chaînes en entiers ( boost::lexical_cast
).
Voici une implémentation dans Mathematica du paquet Combinatorica . La sémantique est assez générique, donc je pense que c’est utile. S’il vous plaît laissez un commentaire si vous avez besoin de quoi que ce soit expliqué.
UnrankKSubset::usage = "UnrankKSubset[m, k, l] gives the mth k-subset of set l, listed in lexicographic order." UnrankKSubset[m_Integer, 1, s_List] := {s[[m + 1]]} UnrankKSubset[0, k_Integer, s_List] := Take[s, k] UnrankKSubset[m_Integer, k_Integer, s_List] := Block[{i = 1, n = Length[s], x1, u, $RecursionLimit = Infinity}, u = Binomial[n, k]; While[Binomial[i, k] < u - m, i++]; x1 = n - (i - 1); Prepend[UnrankKSubset[m - u + Binomial[i, k], k-1, Drop[s, x1]], s[[x1]]] ]
L'utilisation est comme:
UnrankKSubset[1, 4, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}]
{1, 2, 3, 5}
Comme vous pouvez le constater, cette fonction s’applique aux ensembles.
Ci-dessous ma tentative d'expliquer le code ci-dessus.
m
un entier, le "rang" de la combinaison dans l'ordre lexigraphique, en partant de zéro. k
un entier, le nombre d'éléments dans chaque combinaison s
une liste, les éléments à partir desquels assembler des combinaisons pour tout rang m
, et toute liste s
, si le nombre d'éléments dans chaque combinaison k
est 1
, alors:
renvoie l'élément m + 1
de la liste s
, elle-même dans une liste.
( + 1
est nécessaire parce que Mathematica indexe un, plutôt que zéro. Je crois qu'en C ++, ce serait s [m])
si le rang m
est 0
alors pour tout k
et tout s
:
renvoyer les k
premiers éléments de s
variables locales: ( i
, n
, x1
, u
)
Binomial
est le coefficient Binomial[7, 5]
: Binomial[7, 5]
= 21
Faire:
i = 1 n = Length[s] u = Binomial[n, k] While[Binomial[i, k] < u - m, i++]; x1 = n - (i - 1);
Puis retournez:
Prepend[ UnrankKSubset[m - u + Binomial[i, k], k - 1, Drop[s, x1]], s[[x1]] ]
C'est-à-dire, "ajoutez" l'élément x1
de la liste s
(rappelez-vous des index Mathematica, alors je pense que ce serait l'index x1 - 1
en C ++) de la liste renvoyée par la fonction UnrankKSubset appelée récursivement avec les arguments:
m - u + Binomial[i, k]
k - 1
Drop[s, x1]
Drop[s, x1]
est le rest de la liste s
avec les premiers éléments x1
supprimés.
Si ce qui précède n’est pas compréhensible, ou si vous vouliez une explication de l’algorithme plutôt que du code, laissez un commentaire et laissez-moi réessayer.