Juliaで順列と組み合わせを列挙する
プログラムを書いていたらfor文がだんだんと増えていって, 結局は再帰構文に行きつくことに気付いたのではないだろうか. 少しばかり難しいので, 調べた結果をまとめる. 以下では, 全て異なるものを選ぶ場合を考え, 全パターンを列挙するプログラムを考える.
全てを選ぶパターン |
|
|
---|---|---|
順列 | ||
円順列 | ||
数珠順列 | ||
組み合わせ | 1 |
順列
Rosetta Codeで紹介されている順列の列挙のプログラムは
# https://rosettacode.org/wiki/Permutations#Julia
perms(l) = isempty(l) ? [l] : [[x; y] for x in l for y in perms(setdiff(l, x))]
for perm in perms([1,2,3])
println(perm)
end
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
だが, 少しばかり圧縮されすぎていて何をしているのかわからない. 「ある要素を選んで, 残りの要素からまた選ぶ」という, 多少の無駄はあるが直感的な実装を以下に示す. 上記のRosseta Codeの出力と同じである.
function permutations(choices)
permutations = Vector[]
function permutation(choices; chosen=Int64[])
if isempty(choices)
push!(permutations, chosen)
else
for x in choices
permutation(setdiff(choices, [x]), chosen=union(chosen, [x]))
end
end
end
permutation(choices)
return permutations
end
for perm in permutations([1,2,3])
println(perm)
end
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
上記は与えられたリストの全ての要素を並べるパターン. isempty(choices)
からlength(chosen) == k
に変えればよい.
function permutations(choices, k)
permutations = Vector[]
function permutation(choices; chosen=Int64[])
if length(chosen) == k
push!(permutations, chosen)
else
for x in choices
permutation(setdiff(choices, [x]), chosen=union(chosen, [x]))
end
end
end
permutation(choices)
return permutations
end
for perm in permutations([1,2,3], 2)
println(perm)
end
[1, 2]
[1, 3]
[2, 1]
[2, 3]
[3, 1]
[3, 2]
円順列
誰かコメントにください.(個人的には順列だけで十分だったのでひとまず公開しました. ユルシテ)
数珠順列
誰かコメントにください.(個人的には順列だけで十分だったのでひとまず公開しました. ユルシテ)
組み合わせ
# using Pkg
# Pkg.add("Combinatorics")
using Combinatorics
# using Combinatorics
for comb in combinations([1,2,3,4,5], 3)
println(comb)
end
[1, 2, 3]
[1, 2, 4]
[1, 2, 5]
[1, 3, 4]
[1, 3, 5]
[1, 4, 5]
[2, 3, 4]
[2, 3, 5]
[2, 4, 5]
[3, 4, 5]
この記事の元になったノートは下記のリンクにある.
清水団さんが円順列と数珠順列も含めて, さらに同じものを含む場合にも対応した記事を書いてくださいました. 上位互換です.
Author And Source
この問題について(Juliaで順列と組み合わせを列挙する), 我々は、より多くの情報をここで見つけました https://zenn.dev/ohno/articles/03e65bfa028baa著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol