code_junkie

Algorithm to return all combinations of k elements from n

Nov 11th, 2011
285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.16 KB | None | 0 0
  1. (* this will find the [x] combination of a [set] list when taking [k] elements *)
  2. let combination_maccaffery set k x =
  3. (* maximize function -- maximize a that is aCb *)
  4. (* return largest c where c < i and choose(c,i) <= z *)
  5. let rec maximize a b x =
  6. if (choose a b ) <= x then a else maximize (a-1) b x
  7. in
  8. let rec iterate n x i = match i with
  9. | 0 -> []
  10. | i ->
  11. let max = maximize n i x in
  12. max :: iterate n (x - (choose max i)) (i-1)
  13. in
  14. if x < 0 then failwith "errors" else
  15. let idxs = iterate (List.length set) x k in
  16. List.map (List.nth set) (List.sort (-) idxs)
  17.  
  18. being
  19.  
  20. being
  21.  
  22. public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k)
  23. {
  24. return k == 0 ? new[] { new T[0] } :
  25. elements.SelectMany((e, i) =>
  26. elements.Skip(i + 1).Combinations(k - 1).Select(c => (new[] {e}).Concat(c)));
  27. }
  28.  
  29. var result = Combinations(new[] { 1, 2, 3, 4, 5 }, 3);
  30.  
  31. 123
  32. 124
  33. 125
  34. 134
  35. 135
  36. 145
  37. 234
  38. 235
  39. 245
  40. 345
  41.  
  42. void print_combinations(const char *string)
  43. {
  44. int i, j, k;
  45. int len = strlen(string);
  46.  
  47. for (i = 0; i < len - 2; i++)
  48. {
  49. for (j = i + 1; j < len - 1; j++)
  50. {
  51. for (k = j + 1; k < len; k++)
  52. printf("%c%c%cn", string[i], string[j], string[k]);
  53. }
  54. }
  55. }
  56.  
  57. void print_combinations(const char *string)
  58. {
  59. int i, j, k;
  60. int len = strlen(string);
  61.  
  62. for (i = 0; i < len - 2; i++)
  63. {
  64. for (j = i + 1; j < len - 1; j++)
  65. {
  66. for (k = j + 1; k < len; k++)
  67. printf("%c%c%cn", string[i], string[j], string[k]);
  68. }
  69. }
  70. }
  71.  
  72. void print_combinations(const char *string)
  73. {
  74. int i, j, k;
  75. int len = strlen(string);
  76.  
  77. for (i = 0; i < len - 2; i++)
  78. {
  79. for (j = i + 1; j < len - 1; j++)
  80. {
  81. for (k = j + 1; k < len; k++)
  82. printf("%c%c%cn", string[i], string[j], string[k]);
  83. }
  84. }
  85. }
  86.  
  87. void print_combinations(const char *string)
  88. {
  89. int i, j, k;
  90. int len = strlen(string);
  91.  
  92. for (i = 0; i < len - 2; i++)
  93. {
  94. for (j = i + 1; j < len - 1; j++)
  95. {
  96. for (k = j + 1; k < len; k++)
  97. printf("%c%c%cn", string[i], string[j], string[k]);
  98. }
  99. }
  100. }
  101.  
  102. void print_combinations(const char *string)
  103. {
  104. int i, j, k;
  105. int len = strlen(string);
  106.  
  107. for (i = 0; i < len - 2; i++)
  108. {
  109. for (j = i + 1; j < len - 1; j++)
  110. {
  111. for (k = j + 1; k < len; k++)
  112. printf("%c%c%cn", string[i], string[j], string[k]);
  113. }
  114. }
  115. }
  116.  
  117. static IEnumerable<string> Combinations(List<string> characters, int length)
  118. {
  119. for (int i = 0; i < characters.Count; i++)
  120. {
  121. // only want 1 character, just return this one
  122. if (length == 1)
  123. yield return characters[i];
  124.  
  125. // want more than one character, return this one plus all combinations one shorter
  126. // only use characters after the current one for the rest of the combinations
  127. else
  128. foreach (string next in Combinations(characters.GetRange(i + 1, characters.Count - (i + 1)), length - 1))
  129. yield return characters[i] + next;
  130. }
  131. }
  132.  
  133. def choose_iter(elements, length):
  134. for i in xrange(len(elements)):
  135. if length == 1:
  136. yield (elements[i],)
  137. else:
  138. for next in choose_iter(elements[i+1:len(elements)], length-1):
  139. yield (elements[i],) + next
  140. def choose(l, k):
  141. return list(choose_iter(l, k))
  142.  
  143. >>> len(list(choose_iter("abcdefgh",3)))
  144. 56
  145.  
  146. def missing(miss,src):
  147. "Returns the list of items in src not present in miss"
  148. return [i for i in src if i not in miss]
  149.  
  150.  
  151. def permutation_gen(n,l):
  152. "Generates all the permutations of n items of the l list"
  153. for i in l:
  154. if n<=1: yield [i]
  155. r = [i]
  156. for j in permutation_gen(n-1,missing([i],l)): yield r+j
  157.  
  158. n<len(l)
  159.  
  160. for comb in permutation_gen(3,list("ABCDEFGH")):
  161. print comb
  162.  
  163. object P26 {
  164. def flatMapSublists[A,B](ls: List[A])(f: (List[A]) => List[B]): List[B] =
  165. ls match {
  166. case Nil => Nil
  167. case sublist@(_ :: tail) => f(sublist) ::: flatMapSublists(tail)(f)
  168. }
  169.  
  170. def combinations[A](n: Int, ls: List[A]): List[List[A]] =
  171. if (n == 0) List(Nil)
  172. else flatMapSublists(ls) { sl =>
  173. combinations(n - 1, sl.tail) map {sl.head :: _}
  174. }
  175. }
  176.  
  177. SELECT A.Letter, B.Letter, C.Letter
  178. FROM Alphabet AS A, Alphabet AS B, Alphabet AS C
  179. WHERE A.Letter<>B.Letter AND A.Letter<>C.Letter AND B.Letter<>C.Letter
  180. AND A.Letter<B.Letter AND B.Letter<C.Letter
  181.  
  182. SELECT * FROM dbo.fn_GetMChooseNCombos('ABCD', 2, '')
  183.  
  184. Word
  185. ----
  186. AB
  187. AC
  188. AD
  189. BC
  190. BD
  191. CD
  192.  
  193. (6 row(s) affected)
  194.  
  195. // author: Sourabh Bhat ([email protected])
  196.  
  197. public class Testing
  198. {
  199. public static void main(String[] args)
  200. {
  201.  
  202. // Test case num = 5, outOf = 8.
  203.  
  204. int num = 5;
  205. int outOf = 8;
  206. int[][] combinations = getCombinations(num, outOf);
  207. for (int i = 0; i < combinations.length; i++)
  208. {
  209. for (int j = 0; j < combinations[i].length; j++)
  210. {
  211. System.out.print(combinations[i][j] + " ");
  212. }
  213. System.out.println();
  214. }
  215. }
  216.  
  217. private static int[][] getCombinations(int num, int outOf)
  218. {
  219. int possibilities = get_nCr(outOf, num);
  220. int[][] combinations = new int[possibilities][num];
  221. int arrayPointer = 0;
  222.  
  223. int[] counter = new int[num];
  224.  
  225. for (int i = 0; i < num; i++)
  226. {
  227. counter[i] = i;
  228. }
  229. breakLoop: while (true)
  230. {
  231. // Initializing part
  232. for (int i = 1; i < num; i++)
  233. {
  234. if (counter[i] >= outOf - (num - 1 - i))
  235. counter[i] = counter[i - 1] + 1;
  236. }
  237.  
  238. // Testing part
  239. for (int i = 0; i < num; i++)
  240. {
  241. if (counter[i] < outOf)
  242. {
  243. continue;
  244. } else
  245. {
  246. break breakLoop;
  247. }
  248. }
  249.  
  250. // Innermost part
  251. combinations[arrayPointer] = counter.clone();
  252. arrayPointer++;
  253.  
  254. // Incrementing part
  255. counter[num - 1]++;
  256. for (int i = num - 1; i >= 1; i--)
  257. {
  258. if (counter[i] >= outOf - (num - 1 - i))
  259. counter[i - 1]++;
  260. }
  261. }
  262.  
  263. return combinations;
  264. }
  265.  
  266. private static int get_nCr(int n, int r)
  267. {
  268. if(r > n)
  269. {
  270. throw new ArithmeticException("r is greater then n");
  271. }
  272. long numerator = 1;
  273. long denominator = 1;
  274. for (int i = n; i >= r + 1; i--)
  275. {
  276. numerator *= i;
  277. }
  278. for (int i = 2; i <= n - r; i++)
  279. {
  280. denominator *= i;
  281. }
  282.  
  283. return (int) (numerator / denominator);
  284. }
  285. }
  286.  
  287. m=(rand()%n)+1; // m will vary from 1 to n
  288.  
  289. for (i=0;i<n;i++) a[i]=i+1;
  290.  
  291. // we want to print all possible C(n,m) combinations of selecting m objects out of n
  292. printf("Printing C(%d,%d) possible combinations ...n", n,m);
  293.  
  294. // This is an adhoc algo that keeps m pointers to the next valid combination
  295. for (i=0;i<m;i++) p[i]=i; // the p[.] contain indices to the a vector whose elements constitute next combination
  296.  
  297. done=false;
  298. while (!done)
  299. {
  300. // print combination
  301. for (i=0;i<m;i++) printf("%2d ", a[p[i]]);
  302. printf("n");
  303.  
  304. // update combination
  305. // method: start with p[m-1]. try to increment it. if it is already at the end, then try moving p[m-2] ahead.
  306. // if this is possible, then reset p[m-1] to 1 more than (the new) p[m-2].
  307. // if p[m-2] can not also be moved, then try p[m-3]. move that ahead. then reset p[m-2] and p[m-1].
  308. // repeat all the way down to p[0]. if p[0] can not also be moved, then we have generated all combinations.
  309. j=m-1;
  310. i=1;
  311. move_found=false;
  312. while ((j>=0) && !move_found)
  313. {
  314. if (p[j]<(n-i))
  315. {
  316. move_found=true;
  317. p[j]++; // point p[j] to next index
  318. for (k=j+1;k<m;k++)
  319. {
  320. p[k]=p[j]+(k-j);
  321. }
  322. }
  323. else
  324. {
  325. j--;
  326. i++;
  327. }
  328. }
  329. if (!move_found) done=true;
  330. }
  331.  
  332. static bool nextCombination(int[] num, int n, int k)
  333. {
  334. bool finished, changed;
  335.  
  336. changed = finished = false;
  337.  
  338. if (k > 0)
  339. {
  340. for (int i = k - 1; !finished && !changed; i--)
  341. {
  342. if (num[i] < (n - 1) - (k - 1) + i)
  343. {
  344. num[i]++;
  345. if (i < k - 1)
  346. {
  347. for (int j = i + 1; j < k; j++)
  348. {
  349. num[j] = num[j - 1] + 1;
  350. }
  351. }
  352. changed = true;
  353. }
  354. finished = (i == 0);
  355. }
  356. }
  357.  
  358. return changed;
  359. }
  360.  
  361. static IEnumerable Combinations<T>(IEnumerable<T> elements, int k)
  362. {
  363. T[] elem = elements.ToArray();
  364. int size = elem.Length;
  365.  
  366. if (k <= size)
  367. {
  368. int[] numbers = new int[k];
  369. for (int i = 0; i < k; i++)
  370. {
  371. numbers[i] = i;
  372. }
  373.  
  374. do
  375. {
  376. yield return numbers.Select(n => elem[n]);
  377. }
  378. while (nextCombination(numbers, size, k));
  379. }
  380. }
  381.  
  382. static void Main(string[] args)
  383. {
  384. int k = 3;
  385. var t = new[] { "dog", "cat", "mouse", "zebra"};
  386.  
  387. foreach (IEnumerable<string> i in Combinations(t, k))
  388. {
  389. Console.WriteLine(string.Join(",", i));
  390. }
  391. }
  392.  
  393. #include <vector>
  394. #include <stdexcept>
  395.  
  396. template <typename Fci> // Fci - forward const iterator
  397. std::vector<std::vector<Fci> >
  398. enumerate_combinations(Fci begin, Fci end, unsigned int combination_size)
  399. {
  400. if(begin == end && combination_size > 0u)
  401. throw std::invalid_argument("empty set and positive combination size!");
  402. std::vector<std::vector<Fci> > result; // empty set of combinations
  403. if(combination_size == 0u) return result; // there is exactly one combination of
  404. // size 0 - emty set
  405. std::vector<Fci> current_combination;
  406. current_combination.reserve(combination_size + 1u); // I reserve one aditional slot
  407. // in my vector to store
  408. // the end sentinel there.
  409. // The code is cleaner thanks to that
  410. for(unsigned int i = 0u; i < combination_size && begin != end; ++i, ++begin)
  411. {
  412. current_combination.push_back(begin); // Construction of the first combination
  413. }
  414. // Since I assume the itarators support only incrementing, I have to iterate over
  415. // the set to get its size, which is expensive. Here I had to itrate anyway to
  416. // produce the first cobination, so I use the loop to also check the size.
  417. if(current_combination.size() < combination_size)
  418. throw std::invalid_argument("combination size > set size!");
  419. result.push_back(current_combination); // Store the first combination in the results set
  420. current_combination.push_back(end); // Here I add mentioned earlier sentinel to
  421. // simplyfy rest of the code. If I did it
  422. // earlier, previous statement would get ugly.
  423. while(true)
  424. {
  425. unsigned int i = combination_size;
  426. Fci tmp; // Thanks to the sentinel I can find first
  427. do // iterator to change, simply by scaning
  428. { // from right to left and looking for the
  429. tmp = current_combination[--i]; // first "bubble". The fact, that it's
  430. ++tmp; // a forward iterator makes it ugly but I
  431. } // can't help it.
  432. while(i > 0u && tmp == current_combination[i + 1u]);
  433.  
  434. // Here is probably my most obfuscated expression.
  435. // Loop above looks for a "bubble". If there is no "bubble", that means, that
  436. // current_combination is the last combination, Expression in the if statement
  437. // below evaluates to true and the function exits returning result.
  438. // If the "bubble" is found however, the ststement below has a sideeffect of
  439. // incrementing the first iterator to the left of the "bubble".
  440. if(++current_combination[i] == current_combination[i + 1u])
  441. return result;
  442. // Rest of the code sets posiotons of the rest of the iterstors
  443. // (if there are any), that are to the right of the incremented one,
  444. // to form next combination
  445.  
  446. while(++i < combination_size)
  447. {
  448. current_combination[i] = current_combination[i - 1u];
  449. ++current_combination[i];
  450. }
  451. // Below is the ugly side of using the sentinel. Well it had to haave some
  452. // disadvantage. Try without it.
  453. result.push_back(std::vector<Fci>(current_combination.begin(),
  454. current_combination.end() - 1));
  455. }
  456. }
  457.  
  458. def combinations(list, k):
  459. """Choose combinations of list, choosing k elements(no repeats)"""
  460. if len(list) < k:
  461. return []
  462. else:
  463. seq = [i for i in range(k)]
  464. while seq:
  465. print [list[index] for index in seq]
  466. seq = get_next_combination(len(list), k, seq)
  467.  
  468. def get_next_combination(num_elements, k, seq):
  469. index_to_move = find_index_to_move(num_elements, seq)
  470. if index_to_move == None:
  471. return None
  472. else:
  473. seq[index_to_move] += 1
  474.  
  475. #for every element past this sequence, move it down
  476. for i, elem in enumerate(seq[(index_to_move+1):]):
  477. seq[i + 1 + index_to_move] = seq[index_to_move] + i + 1
  478.  
  479. return seq
  480.  
  481. def find_index_to_move(num_elements, seq):
  482. """Tells which index should be moved"""
  483. for rev_index, elem in enumerate(reversed(seq)):
  484. if elem < (num_elements - rev_index - 1):
  485. return len(seq) - rev_index - 1
  486. return None
  487.  
  488. (defmacro txaat (some-list taken-at-a-time)
  489. (let* ((vars (reverse (truncate-list '(a b c d e f g h i j) taken-at-a-time))))
  490. `(
  491. ,@(loop for i below taken-at-a-time
  492. for j in vars
  493. with nested = nil
  494. finally (return nested)
  495. do
  496. (setf
  497. nested
  498. `(loop for ,j from
  499. ,(if (< i (1- (length vars)))
  500. `(1+ ,(nth (1+ i) vars))
  501. 0)
  502. below (- (length ,some-list) ,i)
  503. ,@(if (equal i 0)
  504. `(collect
  505. (list
  506. ,@(loop for k from (1- taken-at-a-time) downto 0
  507. append `((nth ,(nth k vars) ,some-list)))))
  508. `(append ,nested))))))))
  509.  
  510. CL-USER> (macroexpand-1 '(txaat '(a b c d) 1))
  511. (LOOP FOR A FROM 0 TO (- (LENGTH '(A B C D)) 1)
  512. COLLECT (LIST (NTH A '(A B C D))))
  513. T
  514. CL-USER> (macroexpand-1 '(txaat '(a b c d) 2))
  515. (LOOP FOR A FROM 0 TO (- (LENGTH '(A B C D)) 2)
  516. APPEND (LOOP FOR B FROM (1+ A) TO (- (LENGTH '(A B C D)) 1)
  517. COLLECT (LIST (NTH A '(A B C D)) (NTH B '(A B C D)))))
  518. T
  519. CL-USER> (macroexpand-1 '(txaat '(a b c d) 3))
  520. (LOOP FOR A FROM 0 TO (- (LENGTH '(A B C D)) 3)
  521. APPEND (LOOP FOR B FROM (1+ A) TO (- (LENGTH '(A B C D)) 2)
  522. APPEND (LOOP FOR C FROM (1+ B) TO (- (LENGTH '(A B C D)) 1)
  523. COLLECT (LIST (NTH A '(A B C D))
  524. (NTH B '(A B C D))
  525. (NTH C '(A B C D))))))
  526. T
  527.  
  528. CL-USER>
  529.  
  530. CL-USER> (txaat '(a b c d) 1)
  531. ((A) (B) (C) (D))
  532. CL-USER> (txaat '(a b c d) 2)
  533. ((A B) (A C) (A D) (B C) (B D) (C D))
  534. CL-USER> (txaat '(a b c d) 3)
  535. ((A B C) (A B D) (A C D) (B C D))
  536. CL-USER> (txaat '(a b c d) 4)
  537. ((A B C D))
  538. CL-USER> (txaat '(a b c d) 5)
  539. NIL
  540. CL-USER> (txaat '(a b c d) 0)
  541. NIL
  542. CL-USER>
Add Comment
Please, Sign In to add comment