Wednesday, 15 May 2013

c# list permutations with limited length -



c# list permutations with limited length -

i have list of offers, want create "chains" (e.g. permutations) limited chain lengths.

i've gotten far creating permutations using kw.combinatorics project. however, default behavior creates permutations in length of list count. i'm not sure how limit chain lengths 'n'.

here's current code:

private static list<list<offers>> getperms(list<offers> list, int chainlength) { list<list<offers>> response = new list<list<offers>>(); foreach (var row in new permutation(list.count).getrows()) { list<offers> innerlist = new list<offers>(); foreach (var mix in permutation.permute(row, list)) { innerlist.add(mix); } response.add(innerlist); innerlist = new list<offers>(); } homecoming response; }

implemented by:

list<list<adserver.offers>> lst = getperms(offers, 2);

i'm not locked in kwcombinatorics if has improve solution offer.

you're not looking permutation, variation. here possible algorithm. prefer iterator methods functions can potentially homecoming many elements. way, caller can decide if needs elements:

ienumerable<ilist<t>> getvariations<t>(ilist<t> offers, int length) { var startindices = new int[length]; var variationelements = new hashset<t>(); //for duplicate detection while (startindices[0] < offers.count) { var variation = new list<t>(length); var valid = true; (int = 0; < length; ++i) { var element = offers[startindices[i]]; if (variationelements.contains(element)) { valid = false; break; } variation.add(element); variationelements.add(element); } if (valid) yield homecoming variation; //count indices startindices[length - 1]++; (int = length - 1; > 0; --i) { if (startindices[i] >= offers.count) { startindices[i] = 0; startindices[i - 1]++; } else break; } variationelements.clear(); } }

the thought algorithm utilize number in offers.count base. 3 offers, digits in range 0-2. increment number step step , homecoming offers reside @ specified indices. if want allow duplicates, can remove check , hashset<t>.

update

here optimized variant duplicate check on index level. in tests lot faster previous variant:

ienumerable<ilist<t>> getvariations<t>(ilist<t> offers, int length) { var startindices = new int[length]; (int = 0; < length; ++i) startindices[i] = i; var indices = new hashset<int>(); // duplicate check while (startindices[0] < offers.count) { var variation = new list<t>(length); (int = 0; < length; ++i) { variation.add(offers[startindices[i]]); } yield homecoming variation; //count indices addone(startindices, length - 1, offers.count - 1); //duplicate check var check = true; while (check) { indices.clear(); (int = 0; <= length; ++i) { if (i == length) { check = false; break; } if (indices.contains(startindices[i])) { var unchangedupto = addone(startindices, i, offers.count - 1); indices.clear(); (int j = 0; j <= unchangedupto; ++j ) { indices.add(startindices[j]); } int nextindex = 0; for(int j = unchangedupto + 1; j < length; ++j) { while (indices.contains(nextindex)) nextindex++; startindices[j] = nextindex++; } break; } indices.add(startindices[i]); } } } } int addone(int[] indices, int position, int maxelement) { //returns index of lastly element has not been changed indices[position]++; (int = position; > 0; --i) { if (indices[i] > maxelement) { indices[i] = 0; indices[i - 1]++; } else homecoming i; } homecoming 0; }

c# list permutation

No comments:

Post a Comment