あみだくじの問題をjuliaで!(その2)
はじめに
Xのポストで@yusui_mathさんがこのような数学の問題が投稿されました。
@yusui_mathさんはMathlog
のサイトで表現論・群論を用いて解いている様子が公開されています。
以前,私もZennのサイトであみだくじの問題を考えたことがあったので,今回もJuliaで考えてみることにしました。
まずは実験です
- あみだくじの横棒を
回を引く。(デフォルトはn )n=10^4 - 元の位置に戻る(恒等置換)かチェックする。
- これを
回行って割合を調べる。(デフォルトはm )m=10^4 - この実験を10回繰り返す。
- パッケージは抽象代数パッケージ
AbstractAlgebra.jl
を使いました。
#抽象代数パッケージ
using AbstractAlgebra
#3つの置換
σ₁ = perm([2,1,3,4])
σ₂ = perm([1,3,2,4])
σ₃ = perm([1,2,4,3])
X = [σ₁ , σ₂ , σ₃ ]
# n回横線を引いて,元の位置に戻るかチェックする。これをm回行って割合を調べる。
function prob(n=10^4,m=10^4)
k = 0
for i = 1:m
f = perm([1,2,3,4])
for i = 1:n
f *= rand(X)
end
if f == perm([1,2,3,4])
k += 1
end
end
k/m
end
#割合を10回調べてみる。1/12 = 0.08333 に近ければいい感じ
for _=1:10
@show prob()
end
prob() = 0.0872
prob() = 0.083
prob() = 0.0835
prob() = 0.079
prob() = 0.0882
prob() = 0.0898
prob() = 0.0793
prob() = 0.0845
prob() = 0.0812
prob() = 0.0831
遷移行列を求めて,確率を計算する。
- あみだくじの横線の数
によって,求める確率がどのようになるかを調べます。n - 元に戻るケースだけでなく,全てのケースの確率を考えます。
- 全ての確率の
とn-1 の関係を表す遷移行列n を求めます。A
S(4) の置換群
今回準備した,3つの置換σ₁ = perm([2,1,3,4])
,σ₂ = perm([1,3,2,4])
,σ₃ = perm([1,2,4,3])
の合成で,
σ₁ = Perm([2,1,3,4]);
σ₂ = Perm([1,3,2,4]);
σ₃ = Perm([1,2,4,3]);
X = [A,B,C]
for j =1:5
for i = 1:length(X)
push!(X,X[i]*σ₁,X[i]*σ₂,X[i]*σ₃)
end
X = X |> unique
println("合成$(j+1)回で置換は$(X|>length)種類")
end
合成2回で置換は9種類
合成3回で置換は15種類
合成4回で置換は20種類
合成5回で置換は23種類
合成6回で置換は24種類
A を求めます。
遷移行列あみだくじに
上の式を満たす
Juliaのコード
S(4) を準備
3つの置換と,24通りの- 24通りの置換を作成するのに,組み合わせパッケージ
Combinatorics.jl
を利用しました。 - 1番目の
が恒等置換です。\sigma_1
using AbstractAlgebra,Combinatorics
# 定義された置換
σ₁ = Perm([2,1,3,4]);
σ₂ = Perm([1,3,2,4]);
σ₃ = Perm([1,2,4,3]);
# 置換群S4のすべての置換
X = Perm.(permutations([1,2,3,4]))
24-element Vector{Perm{Int64}}:
()
(3,4)
(2,3)
(2,3,4)
(2,4,3)
(2,4)
(1,2)
(1,2)(3,4)
(1,2,3)
(1,2,3,4)
⋮
(1,3,4)
(1,3)(2,4)
(1,3,2,4)
(1,4,3,2)
(1,4,2)
(1,4,3)
(1,4)
(1,4,2,3)
(1,4)(2,3)
遷移行列を求めるコード
A,B,Cをかけて得られた置換がXの何番目に当たるかを調べる方法がちょっとわからなかったので,ChatGPT-4o
にも助けてもらいました。 findfirst(p -> p == next_perm, X)
と書くようですね。
# 各置換に対して行列を生成
function generate_transition_matrix(X, A, B, C)
n = length(X)
transition_matrix = zeros(Rational{Int}, n, n)
for i in 1:n
current_perm = X[i]
next_perms = [current_perm * A, current_perm * B, current_perm * C]
for next_perm in next_perms
j = findfirst(p -> p == next_perm, X)
if j !== nothing
transition_matrix[i, j] += 1 // 3
end
end
end
return transition_matrix
end
# 置換のリストに基づいて遷移行列を生成
transition_matrix = generate_transition_matrix(X, σ₁ , σ₂ , σ₃)
# 結果を表示
println("Transition Matrix:")
for row in eachrow(transition_matrix)
println(row)
end
Transition Matrix:
Rational{Int64}[0, 1//3, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Rational{Int64}[1//3, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Rational{Int64}[1//3, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Rational{Int64}[0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Rational{Int64}[0, 0, 1//3, 0, 0, 1//3, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Rational{Int64}[0, 0, 0, 1//3, 1//3, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Rational{Int64}[1//3, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Rational{Int64}[0, 1//3, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Rational{Int64}[0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Rational{Int64}[0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 0]
Rational{Int64}[0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0]
Rational{Int64}[0, 0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0]
Rational{Int64}[0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0, 0]
Rational{Int64}[0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0]
Rational{Int64}[0, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0]
Rational{Int64}[0, 0, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0]
Rational{Int64}[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 1//3, 0]
Rational{Int64}[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 1//3]
Rational{Int64}[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 0, 0, 1//3, 1//3, 0, 0, 0]
Rational{Int64}[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 0, 1//3, 0, 0, 1//3, 0, 0]
Rational{Int64}[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0]
Rational{Int64}[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 0, 1//3]
Rational{Int64}[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 0, 0, 1//3]
Rational{Int64}[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1//3, 0, 0, 0, 1//3, 1//3, 0]
値をチェック!
-
で,確率を調べてみました。求めるのはn=1,2,...,10 です。\sigma_1(n)
K = zeros(Rational{Int},24)
K[1] = 1
for i = 1:10
println("$(i)回で元に戻る確率は$((transition_matrix^i * K)[1])")
end
1回で元に戻る確率は0//1
2回で元に戻る確率は1//3
3回で元に戻る確率は0//1
4回で元に戻る確率は17//81
5回で元に戻る確率は0//1
6回で元に戻る確率は115//729
7回で元に戻る確率は0//1
8回で元に戻る確率は283//2187
9回で元に戻る確率は0//1
10回で元に戻る確率は6643//59049
@yusui_mathさんのページの確率と一致しました。
(transition_matrix^30 * K)[1] |> Float64 , 1/12
(0.08370280962869549, 0.08333333333333333)
いい感じです!
Discussion