c# - Generating Permutations using LINQ -


i have set of products must scheduled. there p products each indexed 1 p. each product can scheduled time period 0 t. need construct permutations of product schedules satisfy following constraint:

if p1.index > p2.index p1.schedule >= p2.schedule. 

i struggling construct iterator. know how via linq when number of products known constant, not sure how generate query when number of products input parameter.

ideally use yield syntax construct iterator.

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 permutation combinations here -- how?      yield return new potentialschedule(permutation); } 

edit: example when _numberproducts = 2

public ienumerable<potentialschedule> getenumerator() {     var query = p1 in enumerable.range(0,t)                 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 }); } 

if understand question: looking sequences of integers of length p, each integer in set between 0 , t, , sequence monotone nondecreasing. correct?

writing such program using iterator blocks straightforward:

using system; using system.collections.generic; using system.linq;  static class program {     static ienumerable<t> prepend<t>(t first, ienumerable<t> rest)     {         yield return first;         foreach (var item in rest)             yield return item;     }      static ienumerable<ienumerable<int>> m(int p, int t1, int t2)     {         if (p == 0)             yield return enumerable.empty<int>();         else             (int first = t1; first <= t2; ++first)                 foreach (var rest in m(p - 1, first, t2))                     yield return prepend(first, rest);     }      public static void main()     {         foreach (var sequence in m(4, 0, 2))             console.writeline(string.join(", ", sequence));     } } 

which produces desired output: nondecreasing sequences of length 4 drawn 0 through 2.

0, 0, 0, 0 0, 0, 0, 1 0, 0, 0, 2 0, 0, 1, 1 0, 0, 1, 2 0, 0, 2, 2 0, 1, 1, 1 0, 1, 1, 2 0, 1, 2, 2 0, 2, 2, 2 1, 1, 1, 1 1, 1, 1, 2 1, 1, 2, 2 1, 2, 2, 2 2, 2, 2, 2 

note usage of multiply-nested iterators concatenation not efficient, cares? generating exponential number of sequences, fact there's polynomial inefficiency in generator irrelevant.

the method m generates monotone nondecreasing sequences of integers of length p integers between t1 , t2. recursively, using straightforward recursion. base case there 1 sequence of length zero, namely empty sequence. recursive case in order compute, p = 3, t1 = 0, t2 = 2, compute:

- sequences starting 0 followed sequences of length 2 drawn 0 2. - sequences starting 1 followed sequences of length 2 drawn 1 2. - sequences starting 2 followed sequences of length 2 drawn 2 2. 

and that's result.

alternatively, use query comprehensions instead of iterator blocks in main recursive method:

static ienumerable<t> singleton<t>(t first) {     yield return first; }  static ienumerable<ienumerable<int>> m(int p, int t1, int t2) {     return p == 0 ?          singleton(enumerable.empty<int>()) :           first in enumerable.range(t1, t2 - t1 + 1)         rest in m(p - 1, first, t2)         select prepend(first, rest); } 

that same thing; moves loops selectmany method.


Comments

Popular posts from this blog

asp.net - repeatedly call AddImageUrl(url) to assemble pdf document -

java - Android recognize cell phone with keyboard or not? -

iphone - How would you achieve a LED Scrolling effect? -