Génération de permutations à l'aide de LINQ
J'ai un ensemble de produits qui doit être planifiée. Il y a des P produits chaque indexés de 1 à P. Chaque produit peut être prévue dans un délai de 0 à T.-je besoin pour la construction de toutes les permutations de produits annexes qui satisfont la contrainte suivantes:
If p1.Index > p2.Index then p1.Schedule >= p2.Schedule.
J'ai du mal à construire l'itérateur. Je sais comment le faire via LINQ lorsque le nombre de produits est connu et constant, mais je ne suis pas sûr de savoir comment générer cette requête lorsque le nombre de produits est un paramètre d'entrée.
Idéalement, je voudrais utiliser le rendement de la syntaxe pour construire cet itérateur.
public class PotentialSchedule()
{
public PotentialSchedule(int[] schedulePermutation)
{
_schedulePermutation = schedulePermutation;
}
private readonly int[] _schedulePermutation;
}
private int _numberProducts = ...;
public IEnumerator<PotentialSchedule> GetEnumerator()
{
int[] permutation = new int[_numberProducts];
//Generate all permutation combinations here -- how?
yield return new PotentialSchedule(permutation);
}
EDIT: Exemple quand _numberProducts = 2
public IEnumerable<PotentialSchedule> GetEnumerator()
{
var query = from p1 in Enumerable.Range(0,T)
from p2 in Enumerable.Range(p2,T)
select new { P1 = p1, P2 = p2};
foreach (var result in query)
yield return new PotentialSchedule(new int[] { result.P1, result.P2 });
}
source d'informationauteur cordialgerm
Vous devez vous connecter pour publier un commentaire.
Si je comprends la question: vous êtes à la recherche pour l'ensemble des séquences d'entiers de longueur P, où chaque entier dans le jeu est entre 0 et T, et la séquence est monotone nondecreasing. Est-ce exact?
La rédaction d'un tel programme à l'aide d'un itérateur blocs est simple:
Qui produit le résultat désiré: nondecreasing séquences de longueur 4 tirées de 0 à 2.
Notez que l'utilisation de multiplier imbriquées les itérateurs pour la concaténation est pas très efficacemais qui s'en soucie? Vous êtes déjà plus de générer un exponentielle nombre de séquences, de sorte que le fait qu'il y a un polynôme inefficacité dans le générateur est sans importance.
La méthode M génère tous monotone nondecreasing séquences d'entiers de longueur p, où les entiers sont entre t1 et t2. Il le fait de manière récursive, à l'aide d'un simple récursivité. Le cas de base est qu'il y a exactement une séquence de longueur zéro, à savoir la séquence vide. La récursivité est le cas pour calculer, disons P = 3, t1 = 0, t2 = 2, permet de calculer:
Et voilà le résultat.
Alternativement, vous pouvez utiliser la requête des compréhensions à la place de l'itérateur de blocs dans la principale méthode récursive:
Qui fait la même chose; il déplace juste les boucles dans le SelectMany méthode.
J'ai utilisé cette bibliothèque pour les combinaisons et trouvé que cela fonctionne bien. L'exemple de programme est un peu déroutant, mais l'article explique ce qui est nécessaire pour utiliser le code.
le tableau ressemble à ceci :
exemple:
si binaryNumber= 001 puis permunation1 = produit1
si binaryNumber= 101 puis permunation1 = product3,produit1
Voici une simple permutation de la méthode d'extension pour C# 7 (valeur tuples intérieure et méthodes). Il est dérivé de @AndrasVaas réponsemais utilise un seul niveau de la paresse (pour empêcher les bugs en raison de la mutation des éléments au fil du temps), perd la
IComparer
fonctionnalité (je n'en avais pas besoin), et est juste un peu plus courte.Aujourd'hui, je suis tombé sur ce et pensé que je pourrais partager mon œuvre.
Pour tous les entiers compris entre N et M, vous devez faire un tableau en premier:
et le lancer à travers
Permutations(Range(1, 10))
:La sortie à partir de la réponse de M. Lippert peut être vu comme toutes les distributions des éléments entre 0 et 2 dans les 4 fentes.
Par exemple
0 3 1
se lit comme "pas de 0, trois 1 et un 2"
C'est loin d'être aussi élégant que la réponse de M. Lippert, mais au moins pas moins efficace