Comment puis-je optimiser le Les zones spécifiques de l'algorithme qui sont problématiques sont l'ensemble du qui a une déclaration if-instruction, je pense être supprimée d'une manière ou d'une autre. J'avais une version antérieure de l'algorithme qui avait une partie de la backtracking avant la déclaration de retour et avait donc un Le fond de cet algorithme est qu'il est très difficile de trouver. Par exemple, à Knuth 7.2.1.3 Il dit simplement que Il peut être fait (et donne un exercice pour prouver que l'algorithme est possible), mais ne donne pas d'algorithme. De même, j'ai une demi-douzaine de textes avancés sur Combinatoriques (y compris Papadimitriou et Kreher / Stimson. ) Et aucun d'entre eux ne donne un algorithme pour générer des combinaisons d'un multiset. Kreher le laisse comme un "exercice pour le lecteur". Quoi qu'il en soit, si vous pouvez améliorer l'algorithme comme ci-dessus ou fournir une référence à une mise en œuvre de travail plus efficace que la mienne, je l'apprécierais. S'il vous plaît donner uniquement des algorithmes itératifs (pas de récursion, s'il vous plaît). P> suivant () code> et
hasnext () code> méthodes dans le générateur suivant qui produit des combinaisons d'un multiviseur délimité? (J'ai posté ceci sur C ++ ainsi que Java car le code est compatible C ++ et n'a pas d'éléments spécifiques à Java qui ne convertissent pas directement en C ++.
Hasnext () Code> Méthode qui peut être inutilement compliqué et la ligne: p>
si (actuel [xslot]> 0) aiitemsedué [actuel [xslot]] -; code] > p>
beaucoup plus simple ( ) code> test, mais je ne pouvais pas obtenir cette version à travailler. p>
private static void combination_multiset_test(){
int[] aiItems = { 4, 3, 2, 1, 1 };
int iSlots = 4;
java.util.Iterator<int[]> iterator = combination( aiItems, iSlots );
if( iterator == null ){
System.out.println( "null" );
System.exit( -1 );
}
int xCombination = 0;
while( iterator.hasNext() ){
xCombination++;
int[] combination = iterator.next();
if( combination == null ){
System.out.println( "improper termination, no result" );
System.exit( -1 );
}
System.out.println( xCombination + ": " + Arrays.toString( combination ) );
}
System.out.println( "complete" );
}
1: [4, 1, 1, 1, 2]
2: [4, 1, 1, 1, 3]
3: [4, 1, 1, 1, 4]
4: [4, 1, 1, 2, 2]
5: [4, 1, 1, 2, 3]
6: [4, 1, 1, 2, 4]
7: [4, 1, 1, 3, 4]
8: [4, 1, 2, 2, 3]
9: [4, 1, 2, 2, 4]
10: [4, 1, 2, 3, 4]
11: [4, 2, 2, 3, 4]
complete
3 Réponses :
J'écrirais une simple classe d'assistance qui fait Je vais d'abord envelopper un < Code> non signé INT CODE>, et limitez-le à 32 bits, et peut-être l'étendre par appelle qui devrait prendre au plus Quelques minutes à écrire. p> jeter Produire le sous-ensemble implique simplement appeler Suivant, améliorez Cela résout le problème défini. Pour résoudre le problème Mutltiset, résolvez d'abord le problème défini dérivé (où vous prétendez qu'il n'y a que 0 ou 1 de chaque élément) et itérale sur cela. Ensuite, sur chaque itération de l'ensemble dérivé, accumulez un puis faites quelque chose comme ceci: p> < Pré> xxx pré> exemple en direct: http://ideone.com/8GN1XX p > Dans cet exemple en direct, j'ai ignoré l'optimisation de l'itération définie d'abord et directement itéré sur le multiviseur. p> (limitations: plus de max Je n'ai pas besoin de "nombre d'éléments distincts dans le Multiset ", donc je ne l'ai pas utilisé. p> et voici la version itérative de l'algorithme récursif ci-dessus, à l'aide de la technique habituelle" Tournez la pile de récupération implicite en une pile explicite de la pile d'itération ": P > http://ideone.com/x2zp2f p> p> incrément code>,
highbit code> et
for_each_bit code>.
std :: bitset code> ou a
std :: vecteur
incrément code> est facile, sur une nue 32 bits int. < / p>
highbit code> renvoie la position du bit du bit de jeu le plus élevé. p>
for_each_bit code> a cette signature en C ++: p> < pré> xxx pré>
func code> avec l'index de chaque bit de jeu dans
num code>. p>
hasnext code>, suivez le concept d'itérateur - vous avez un code> Begin code> sous-ensemble et un
fin < / Code> Sous-ensemble, et l'extrémité
code> n'est pas valide pour extraire la valeur de. Dérofier à ces itérateurs produit le sous-ensemble en question (ou produit une usine pour ledit sous-ensemble). P>
fin code> est maintenant facile à travailler - si
highbit code> est> = le nombre d'éléments de votre ensemble, vous avez passé la fin des permutations. p>
commence code> est zéro ou 1, selon si vous voulez le sous-ensemble vide à inclure. p>
Suivant code> incrémente votre
Bignum code>. p>
for_each_bit Code> et mettez cet élément de votre ensemble dans le sous-ensemble. P>
incrément code> pour permettre un accès aléatoire, et vous pouvez ensuite mettre en œuvre itérant sur les sous-ensembles en parallèle! < / p>
std :: vecteur code> du nombre maximum de chaque élément. P>
Taille_t code> éléments de chaque type, et pas plus de capacité maximale de
std :: vecteur code> différents types d'éléments). p>
Je ne comprends pas bien ce que vous obtenez ici, mais vous semblez faire la même erreur que Mel Nicholson ci-dessus, ne pas comprendre la différence entre un ensemble et un multiviseur. La génération de combinaisons d'un multiset est un problème beaucoup plus difficile que de générer les combinaisons d'un ensemble.
@Tylerdurden n'a pas remarqué qu'il s'agissait d'un multiset, mais la génération de combinaisons d'un multiset est une chose triviale à faire au-dessus de la génération de combinaisons d'un ensemble. Prétendre que vous avez 1 de chaque élément au lieu de n et génèrent des combinaisons de l'ensemble dérivé. Pour chaque combinaison de l'ensemble dérivé, itérale sur le produit croisé des comptes de chaque élément (à l'exclusion du vide). Avez-vous besoin du code pour itérair sur les produits croisés des comptes de chaque élément?
Je suppose que je ne vois pas comment aller de la combinaison définie à la combinaison multiset. Si tel est tellement "trivial", pourquoi aucun livre n'a cet algorithme? De plus, si vous pensez que c'est si trivial pourquoi ne montrez-vous pas l'algorithme? Je ne suis intéressé que par les implémentations plus efficaces que la mise en œuvre que j'ai déjà montrée.
Comme indiqué ci-dessus, je cherche un algorithme itératif (non récursif).
@Tylerdurden Version itérative ajoutée. Comme la plupart des réécrites itératives d'algorithmes récursives, il est beaucoup plus facile de comprendre de manière récursive, mais il est fonctionnellement équivalent. Je viens d'enregistrer la profondeur de la taille des index code> et conserva la pile manuellement. Je vais revenir en arrière et ajouter des commentaires maintenant.
C'est très fantaisie, cependant, il génère le powerset pour le multiviseur et non les combinaisons dans un nombre fixe de machines à sous. Je sais que vous pouvez obtenir les combinaisons en filtrant le powerset, mais le but ici est une efficacité. Nous voulons générer uniquement les combinaisons dans un nombre fixe de machines à sous, et non le Powerset dans chaque nombre possible de machines à sous.
@Tylerdurden Oh, vous voulez les sous-ensembles d'un multiset d'une certaine cardinalité! Je me demandais ce que vous vouliez dire par emplacements code>.
Cet article fournit un algorithme itératif efficace pour générer des permutations multiset à la page 8 p>
Cet article fournit un autre algorithme itératif, également à la page 8 p>
Oui, je suis familier avec ces deux papiers. Ils iTent des permutations, pas des combinaisons.
EDIT STRT>: DONE RÉALISATION DE RÉPONSE EN SELON DE LA QUESTION CLÉCIFIÉE IDEA MACE: À nouveau, la sélection résultante peut être codée similaire à une personnalisation système numérique . On pourrait incrémenter un compteur et interpréter ce compteur comme une sélection. P> Cependant, comme il existe une restriction supplémentaire de la taille de la sélection == Donc, tout ce que j'ai fait était de faire un peu d'incrément intelligent qui saute à
Le choix avec une taille correcte directement. P> Désolé, le code est en python.
Mais je l'ai fait d'une manière comparable à l'interface Java Itérator.
Le format d'entrée et de sortie est le suivant: p> le code: p> Notez que les éléments Le Voici un joli squelette pour tester le code: p> résultat de l'entrée performances forte> chaque cible code>.
Un moyen naïf de mettre en œuvre la restriction est de simplement vérifier la taille de la sélection résultante et de sauter ceux qui ne satisfont pas la restriction. Mais c'est lent. P>
code > L'argument n'est pas vraiment utilisé. p>
affirme code> dans le
__ init __ code> est de préciser mon hypothèse sur l'entrée. P> < p> Le
affirmer code> dans le
__ remplissage code> est de montrer une propriété pratique de
auto.ans code> dans le contexte que
__ remplir code > est appelé. p>
([1,3, 1,2,4], 4) code>: p>
suivant () code> appelle
O (h) code> où
h code> est le nombre de types d'éléments (taille de
Haves code> liste). p> p>
La valeur (4 + 1) * (3 + 1) * (1 + 1) * (2 + 1) de votre exemple est le nombre d'entrées dans le Powerset (y compris NULL). Le problème ici est de générer des combinaisons dans un nombre fixe de machines à sous, de ne pas générer le powerset.
Ah je vois, maintenant je pense que je comprends ce que vous voulez - - la même chose que je répondis, mais contraint d'avoir une taille totale spécifique? Attends un peu ... je pense que je peux modifier ...
Haha. Je vais écrire une description plus intuitive de l'algorithme plus tard. Mais pour l'instant, je voudrais souligner que mon algorithme n'utilise que 1 matrice auxiliaire pour garder une trace des progrès de l'itération actuels que ce tableau est également la réponse! Tandis que vous utilisez un supplémentaire.
OK Clarification sur le ce que vous entendez par un multiset borné est. Mais pourriez-vous également clarifier la contrainte code> iSlots code>? Est-ce le nombre de types dans le résultat? Ou est-ce la somme totale de la multiplicité dans le résultat? ou...
Le nombre de machines à sous est le nombre d'éléments de la combinaison. Si vous connaissez la relation binomiale C (N, K), k est le numéro de la machine à sous.
Vous voulez donc une itération sur chaque sous-ensemble d'un multiset d'une certaine cardinalité, ou une itération sur chaque sous-ensemble d'un multiset d'une certaine cardinalité ou moins? Étant donné que la sortie de votre code de test ne semble pas correspondre à votre description de votre problème.
Le code qui est la cible de l'amélioration est documenté avec un paramètre: "@param ctslots le nombre de machines à sous dans lesquelles les éléments vont". Ceci est similaire à la notation C (N, K) si vous êtes familiarisé avec la notation combinatoire "Choisir". k est le nombre de machines à sous. Ici, j'utilise la variable "ctslots" (le nombre de machines à sous)
Oh mon Dieu, votre SUB SUPPORT SUB MULTIS ne correspond pas au format de votre entrée multiples d'entrée, mais êtes plutôt
[# des éléments, 1 index basé sur l'élément 0, 1 Index basé sur l'élément 1, ...] code > ?! Pourquoi?!
@Tylerdurden Veuillez vérifier ma solution modifiée.
@Tylerdurden J'ai une bibliothèque Java sur Github qui fera combinaisons et permutations pour plusieurs séries. Ces classes tentent d'exploiter le changement de commande pour améliorer l'efficacité.