I found nice iterative algorithm for generating combinations in lexicographic order on
For example, for n = 5 and r = 3 it generates combinations starting from
in lexicographic order until
How it works: We set the initial combination = [1, 2, 3] and increase it by
combination(3) = combination(3) + 1 until combination(3) = 5, i.e. we generate:
now combination(3) = 5 so we change to combination(2) and increase it
combination(2) = combination(2) + 1 and set
combination(3) = combination(2) + 1 i.e.
and then combination(3) = combination(3) + 1 until combination(3) = 5, i.e.:
now combination(3) = 5 so we change to combination(2) and increase it
combination(2) = combination(2) + 1
now combination(3) = 5, combination(2) = 4 so we change to combination(1) and increase it by
combination(1) = combination(1) + 1 and for i = 2, 3 we set
combination(i) = combination(i - 1) + 1
then combination(3) = combination(3) + 1
now combination(3) = 5 again so we increase combination(2) = combination(2) + 1 and get
now combination(3) = 5, combination(2) = 4 so we change to combination(1) and increase it by
combination(1) = combination(1) + 1 and get finally
Here is the program:
combinations.f95
Code:
[COLOR=#800080]program[/color] combinations_test
[COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
[COLOR=#2e8b57][b]integer[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color](:, :), [COLOR=#2e8b57][b]allocatable[/b][/color] :: combinations
[COLOR=#2e8b57][b]integer[/b][/color] :: n, r, nr_comb
n [COLOR=#a52a2a][b]=[/b][/color] [COLOR=#ff00ff]5[/color]
r [COLOR=#a52a2a][b]=[/b][/color] [COLOR=#ff00ff]3[/color]
[COLOR=#0000ff]!n = 32[/color]
[COLOR=#0000ff]!r = 16[/color]
[COLOR=#008b8b]call[/color] combination_generator(n, r, [COLOR=#ff00ff].true.[/color])
[COLOR=#800080]end program[/color] combinations_test
[COLOR=#800080]subroutine[/color] combination_generator(n, r, print_combinations)
[COLOR=#0000ff]! see:[/color]
[COLOR=#0000ff]! [URL unfurl="true"]https://www.baeldung.com/java-combinations-algorithm[/URL][/color]
[COLOR=#2e8b57][b]integer[/b][/color], [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]in[/b][/color]) :: n
[COLOR=#2e8b57][b]integer[/b][/color], [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]in[/b][/color]) :: r
[COLOR=#2e8b57][b] logical[/b][/color], [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]in[/b][/color]) :: print_combinations
[COLOR=#2e8b57][b]integer[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color](r) :: combination
[COLOR=#2e8b57][b]integer[/b][/color] :: t, i, k
[COLOR=#6a5acd]10[/color] [COLOR=#a52a2a][b]format[/b][/color]([COLOR=#ff00ff]'Generated Combinations C('[/color],i2,[COLOR=#ff00ff]','[/color],i2,[COLOR=#ff00ff]'):'[/color])
[COLOR=#6a5acd]20[/color] [COLOR=#a52a2a][b]format[/b][/color]([COLOR=#ff00ff]'C('[/color],i2,[COLOR=#ff00ff]','[/color],i2,[COLOR=#ff00ff]') ='[/color])
[COLOR=#a52a2a][b]do[/b][/color] i[COLOR=#a52a2a][b]=[/b][/color][COLOR=#ff00ff]1[/color], r
combination(i) [COLOR=#a52a2a][b]=[/b][/color] i
[COLOR=#a52a2a][b]end do[/b][/color]
[COLOR=#0000ff]! write header[/color]
[COLOR=#a52a2a][b]if[/b][/color] (print_combinations) [COLOR=#a52a2a][b]then[/b][/color]
[COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#ff00ff]10[/color]) n, r
[COLOR=#a52a2a][b]end if[/b][/color]
k [COLOR=#a52a2a][b]=[/b][/color] [COLOR=#ff00ff]0[/color]
[COLOR=#a52a2a][b]do[/b][/color] [COLOR=#a52a2a][b]while[/b][/color](combination(r) [COLOR=#a52a2a][b]<=[/b][/color] n)
k [COLOR=#a52a2a][b]=[/b][/color] k [COLOR=#a52a2a][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
[COLOR=#a52a2a][b]if[/b][/color] (print_combinations) [COLOR=#a52a2a][b]then[/b][/color]
[COLOR=#0000ff]! write one combination[/color]
[COLOR=#a52a2a][b]do[/b][/color] i[COLOR=#a52a2a][b]=[/b][/color][COLOR=#ff00ff]1[/color], r
[COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#ff00ff]'(i3)'[/color],[COLOR=#a52a2a][b]advance[/b][/color][COLOR=#a52a2a][b]=[/b][/color][COLOR=#ff00ff]'no'[/color]) combination(i)
[COLOR=#a52a2a][b]end do[/b][/color]
[COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#a52a2a][b]*[/b][/color])
[COLOR=#a52a2a][b]end if[/b][/color]
[COLOR=#0000ff]! generate next combination in lexicographic order[/color]
t [COLOR=#a52a2a][b]=[/b][/color] r
[COLOR=#a52a2a][b]do[/b][/color] [COLOR=#a52a2a][b]while[/b][/color] ((t [COLOR=#a52a2a][b].ne.[/b][/color] [COLOR=#ff00ff]1[/color]) [COLOR=#a52a2a][b].and.[/b][/color] (combination(t) [COLOR=#a52a2a][b].eq.[/b][/color] n [COLOR=#a52a2a][b]-[/b][/color] r [COLOR=#a52a2a][b]+[/b][/color] t))
t [COLOR=#a52a2a][b]=[/b][/color] t [COLOR=#a52a2a][b]-[/b][/color] [COLOR=#ff00ff]1[/color]
[COLOR=#a52a2a][b]end do[/b][/color]
combination(t) [COLOR=#a52a2a][b]=[/b][/color] combination(t) [COLOR=#a52a2a][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
[COLOR=#a52a2a][b]do[/b][/color] i [COLOR=#a52a2a][b]=[/b][/color] t [COLOR=#a52a2a][b]+[/b][/color] [COLOR=#ff00ff]1[/color], r
combination(i) [COLOR=#a52a2a][b]=[/b][/color] combination(i [COLOR=#a52a2a][b]-[/b][/color] [COLOR=#ff00ff]1[/color]) [COLOR=#a52a2a][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
[COLOR=#a52a2a][b]end do[/b][/color]
[COLOR=#a52a2a][b]end do[/b][/color]
[COLOR=#0000ff]! write nCr: [/color]
[COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#ff00ff]20[/color], [COLOR=#a52a2a][b]advance[/b][/color][COLOR=#a52a2a][b]=[/b][/color][COLOR=#ff00ff]'no'[/color]) n, r
[COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#a52a2a][b]*[/b][/color]) k
[COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#a52a2a][b]*[/b][/color])
[COLOR=#800080]end subroutine[/color] combination_generator
You could get the resulting combination into the file using redirection:
Code:
$ ./combinations > combinations_out.txt
For bigger n, r use first rather
Code:
[COLOR=#008b8b]call[/color] combination_generator(n, r, [COLOR=#ff00ff].false.[/color])
so the subroutine only computes the binomial coefficient C(n,r) and will not write the combinations, because writing large files will take very much time.
For example for n = 32, r = 16 it computes C(32,16) = 601080390. Creating the file with all combinations took very long time and the file has 28 GB. I cannot open it in editor, only display it's head and tail:
Code:
$ head combinations_32_16_out.txt
Generated Combinations C(32,16):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 18
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 19
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 21
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 22
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 23
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 24
$ tail combinations_32_16_out.txt
16 17 18 19 20 21 22 24 25 26 27 28 29 30 31 32
16 17 18 19 20 21 23 24 25 26 27 28 29 30 31 32
16 17 18 19 20 22 23 24 25 26 27 28 29 30 31 32
16 17 18 19 21 22 23 24 25 26 27 28 29 30 31 32
16 17 18 20 21 22 23 24 25 26 27 28 29 30 31 32
16 17 19 20 21 22 23 24 25 26 27 28 29 30 31 32
16 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
C(32,16) = 601080390