🐈
マルコフ方程式(x^2+y^2+z^2=3xyz)の正の整数解を求めるアルゴリズムを実装してみた
はじめに
この世にはマルコフ方程式というものがあるそうです。マルコフのディオファントス方程式とも言うらしいです(よく知らない)
マルコフ方程式とは、
のことで、この方程式の正の整数解について、
おもしろそうだったので実装してみることにしました。
マルコフ方程式の解き方
全然証明はしないのですが、マルコフ方程式は、なんと、前の項の
(https://mathlog.info/articles/2647 から引用させていただきました)
この図(マルコフ木というらしい)のようにドンドンと解が決まっていくみたいです。すごい!
たとえば、
というようになってすごいです。
書いたコード
そういうわけでコードを書いてみました。
基本的には再帰で解いていき、すでに存在する組があったときは無視するというようなことをしています。冗長ですが
SHOULD_PRINT = True
seed = (1, 1, 1)
cache = set()
def solve(n):
if n == 1:
if SHOULD_PRINT:
print(*seed)
cache.add(seed)
return [seed]
prev_ans_list = solve(n - 1)
ans_list = []
for prev_ans in prev_ans_list:
# x z -> new_y
new_y = 3 * prev_ans[0] * prev_ans[2] - prev_ans[1]
# y z -> new_x
new_x = 3 * prev_ans[1] * prev_ans[2] - prev_ans[0]
ans1 = (prev_ans[0], prev_ans[2], new_y)
ans2 = (prev_ans[1], prev_ans[2], new_x)
if (ans1 not in cache):
ans_list.append(ans1)
cache.add(ans1)
if (ans2 not in cache):
ans_list.append(ans2)
cache.add(ans2)
if SHOULD_PRINT:
if ans1 == ans2:
print(*ans1)
else:
print(*ans1)
print(*ans2)
return ans_list
N = int(input())
solve(N)
# display answers as sorted tuples
# print(sorted(cache))
こんな感じで出力できました。
$ echo 5 | python3 markov_equation.py
1 1 1
1 1 2
1 2 5
1 5 13
2 5 29
1 13 34
5 13 194
2 29 169
5 29 433
心配なのでテストを入れたところ、深さ18まではいい感じに動いているっぽいです。O(2^N)
なので、Nが多いと解けなくなります。
cache = set()
while True:
try:
x = input()
except EOFError:
print('ok')
exit()
a = list(map(int, x.split()))
t = tuple(sorted(a))
if t in cache:
raise Exception('Already existed', t)
cache.add(t)
assert a[0] * a[0] + a[1] * a[1] + a[2] * a[2] == 3 * a[0] * a[1] * a[2], a
コード置き場
Discussion