Comment puis-je trouver tous les sous-ensembles d'un ensemble, avec exactement n éléments?
Je suis en train d'écrire un programme en Python, et j'ai réalisé qu'un problème j'ai besoin pour résoudre exige de moi, étant donné un ensemble S
avec n
éléments (|S|=n), pour tester une fonction sur tous les sous-ensembles possibles d'un certain ordre m
(c'est à dire avec m nombre d'éléments). Pour utiliser la réponse à produire une solution partielle, et puis essayez à nouveau avec la commande suivante m=m+1, jusqu'à ce que m=n.
Je suis sur ma façon d'écrire une solution de la forme:
def findsubsets(S, m):
subsets = set([])
...
return subsets
Mais sachant Python je m'attendais à une solution pour être déjà là.
Quelle est la meilleure façon d'accomplir cette?
scipy.misc.comb(S, m)
donne le nombre de sous-ensembles que vous obtiendrez. Vous devriez vérifier avant de vous exécuter votre code comme le nombre de m-taille des sous-ensembles de S devient très grand, très rapide.- Littéralement eu le même problème, mis à code moi-même, et alors rendu compte qu'il doit exister une bibliothèque Python pour cela!
Vous devez vous connecter pour publier un commentaire.
itertools.combinaisons est votre ami si vous avez la version 2.6 de Python ou plus. Sinon, vérifiez le lien pour une mise en œuvre d'une fonction équivalente.
S: Le jeu pour lequel vous souhaitez trouver des sous-ensembles
m: Le nombre d'éléments dans le sous-ensemble
À l'aide de la fonction canonique pour obtenir le powerset de la le itertools recette page:
Utilisé comme:
carte de jeux si vous le souhaitez, vous pouvez utiliser de l'union, l'intersection, etc...:
Voici un one-liner qui vous donne tous les sous-ensembles des entiers [0..n], et pas seulement les sous-ensembles d'une longueur donnée:
si par exemple la
chain.from_iterable
à la place de l'étoile-l'expansion peut être très long. Et quel est le point de réitérer les combinaisons dans une liste ([ ... ]
), star-l'expansion, enchaînant dans un itérateur (chain
), et puis de le transformer en une liste de nouveau? PS. une meilleure recette est dans leitertools
de la documentation, et dans l'autre (plus tard) de réponse ici.Voici quelques pseudocode - vous pouvez couper même les appels récursifs en stockant les valeurs pour chaque appel que vous allez et avant l'appel récursif de vérifier si l'appel de la valeur est déjà présente.
L'algorithme suivant, disposera de tous les sous-ensembles à l'exclusion de l'ensemble vide.
Ainsi, par exemple, si s = "123" puis la sortie est:
Sans l'aide de
itertools
:En Python 3, vous pouvez utiliser
yield from
pour ajouter un sous-ensemble générateur méthode de buit-dansset
classe:Pour l'exemple ci-dessous l'extrait de code fonctionne comme prévu:
yield from
et avec une algorithmique explicationVoici une manière simple, facile à comprendre algorithme.
k.append(n)
au lieu dek.extend(n)
$ python -c "import itertools; a=[2,3,5,7,11]; print sum([list(itertools.combinations(a, i)) for i in range(len(a)+1)], [])"
[(), (2,), (3,), (5,), (7,), (11,), (2, 3), (2, 5), (2, 7), (2, 11), (3, 5), (3, 7), (3, 11), (5, 7), (5, 11), (7, 11), (2, 3, 5), (2, 3, 7), (2, 3, 11), (2, 5, 7), (2, 5, 11), (2, 7, 11), (3, 5, 7), (3, 5, 11), (3, 7, 11), (5, 7, 11), (2, 3, 5, 7), (2, 3, 5, 11), (2, 3, 7, 11), (2, 5, 7, 11), (3, 5, 7, 11), (2, 3, 5, 7, 11)]