저번 글 등차수열
에서는 sympy를 이용하여 등차수열에 관련된 문제를 풀어보는 연습을 했지. 관련 문제를 더 풀어볼 예정이야.
등차수열 복습
첫째항이 $a$이고 공차가 $d$인 등차수열의 $n$번째 항을 $a_n$이라 하면,
$$ a_n = a+ (n-1) d $$
가 되고, python의 RecursiveSeq 를 이용하여 아래와 같이 프로그래밍할 수 있다고 했지.
import numpy as np
from sympy import *
from sympy.series.sequences import * # 아래 RecursiveSeq 를 이용하기 위해 필요
n = symbols("n", integer=True) # 수열의 항 번호
a = symbols("a") # 수열의 첫째항
y = Function("y") # 점화식을 나타내기 위한 함수
d = symbols("d") # 공차
arith = RecursiveSeq(y(n - 1) + d, y(n), n, [a])
# 첫째항이 a이고 y(n-1)+d 가 y(n)이 되는데 n이라는 변수를 매개로 되는 수열
print(arith[:10]) # 10번째 항까지 출력
이제 다른 예제들을 한번 풀어볼게.
문제 1
첫째항과 공차가 모두 정수인 등차수열 $a_n$에 대해 $ a_5 a_7 - a_3^2 =2$ 일 때, $a_n$을 구하여라.
사실 연습장에 풀어도 풀리는 문제야. 한가지 주목해야 할 것은 첫째항과 공차 조건이 모두 '정수'라는 것!
등차수열 $a_n$을 $a_n = a+(n-1)d$라 놓으면, 문제의 식은
$$ (a+4d)(a+6d) - (a+2d)^2 = 2$$
이지. 이것을 전개하여 정리하면
$$ 3ad + 10d^2 =1 \tag{1}$$
이 나오게 됨. 이걸 다시 써보면
$$ d(3a+ 10d)=1$$
이 되지. 그런데 $a, d$가 정수이므로 $d$와 $3a+10d$는 각각 정수이고, 따라서 곱해서 1이 되는 경우는
$d=1~,~ 3a+10d=1$ 이거나 $d=-1~,~3a+10d=-1$ 인 두 가지뿐이야. 정리하면
$$ (a, d) = (-3,1) , (3,-1)$$
이렇게 두 가지 경우가 solution이 된다(만일, $a, d$가 정수라는 조건이 없으면, 이 방정식은 무수히 많은 해를 가질 거야. 변수는 2개가 식은 1개니깐!)
이제 sympy code를 살펴볼까?
from sympy import *
from sympy.series.sequences import RecursiveSeq # 점화식 정의를 위한 module
from sympy.solvers.diophantine.diophantine import diop_solve # 디오판토스 방정식을 풀기 위한 module
a = symbols("a", integer=True) # 첫째항
d = symbols("d", integer=True) # 공차
n = symbols("n") # 항
y = Function('y')
arith = RecursiveSeq(y(n - 1) + d, y(n), n, [a]) # 등차수열 정의
equation = arith[4] * arith[6] - arith[2] ** 2 - 2 # 문제의 방정식
soln = diop_solve(equation) # 방정식의 정수해를 찾는 풀이방법1: diop_solve
print(soln)
soln2 = diophantine(equation) # 방정식의 정수해르 찾는 풀이방법2: diophantine
print(soln2)
위 코드 속의 diophantine이라는 함수를 주목해 보자고. 얘는 주어진 방정식의 정수해를 찾는 모듈이야.
참고
디오판토스 방정식(Diophantine Equation)이란, 다항방정식의 정수해(또는 유리수 해)를 찾는 것. 예컨대 가정 유명한 문제로
$$ x^2 + y^2 = z^2$$
과 같은 피타고라스 방정식의 정수해를 모두 찾는 문제
디오판토스(Diophantus)는 고대 그리스의 수학자로서, 자기 나이를 방정식으로 풀어보라고 문제를 낸 데서 유명해진 인물이지. 어쨌든, 정수들 사이의 관계와 방정식을 탐구했던 고대 그리스 수학 영역에 큰 영향을 끼쳤단 학자야.
python에서는 디오판토스 방정식을 해결하는 솔루션을 만들어놨고, 그 풀이 함수로 대표적인 게
diop_solve 또는 diophantine
이라는 명령어야. 위 두 명령어는 결과의 출력형태를 어떻게 제공할 것인가 차이는 있지만, 본질은 똑같다고 봐야지. 우선 결과를 보자고.
{(3, -1), (-3, 1)}
{(3, -1), (-3, 1)}
첫째 줄이 diop_solve 로 푼 것이고, 둘째 줄은 diophantine 로 푼 결과야. 어때, 똑같지? 직접 수식을 이용해 손으로 푼 결과와도 일치하고.
만일 diophantine을 안 쓰고, solve 명령어로 푼다는 어떻게 될까? 비교해 보자고.
soln3= solve(equation, [a,d]) # solve를 사용하여 a,d의 값을 구함
print(soln3)
결과는
[((1 - 10*d**2)/(3*d), d)]
이거 보시게. 이 결과를 수학적으로 해석하면,
$$ a= \frac{1-10d^2}{3d} , d=d$$
라는 얘기야. 식(1)을 $a$에 대해서 정리한 것에 불과하지, solve라는 명령어를 쓰면, 식(1)을 만족하는 임의의 실수해$(a,d)$를 구하는 문제가 되어 버려서 이런 식으로 결과가 나올 수밖에 없는 것이야.
피타고라스 세 쌍 찾기
from sympy import *
from sympy.series.sequences import RecursiveSeq
from sympy.solvers.diophantine.diophantine import diop_solve
x, y, z = symbols("x y z", integer=True)
equation = x ** 2 + y ** 2 - z ** 2 # 방정식: x^2 + y^2 =z^2
soln = diophantine(equation) # 정수해 풀기
print(soln)
수학적으로 표현해 보면, 정수 $x, y, z$에 대해
$$x^2 + y^2 =z^2$$
를 만족하는 정수쌍 $(x, y, z)$를 파이썬으로 찾을 수 있는지의 문제야.
위 코드를 실행시키면 다음과 같은 결과를 얻지.
{(2*p*q, p**2 - q**2, p**2 + q**2)}
즉, 수학적으로 표현하면, 정수 $p, q$가 존재하여
$$ x = 2pq~,~ y = p^2-q^2 ~,~ z= p^2+q^2$$
이 된다는 뜻이야!
이 문제는 굉장히 유명한 문제로서, 위 세 쌍의 공식을 유클리드 공식(Euclid formula)라고도 해. 여기를 참고하면 자세한 설명을 볼 수 있을 거야.
파이썬은 보면 볼수록 아주 똑똑한 물건인 듯!
정리
from sympy.solvers.diophantine.diophantine import diop_solve | 디오판틴 방정식 풀이를 위해 import 할 모듈 |
diop_solve | 주어진 디오판토스 방정식의 해 찾는 함수 |
diophanine | 주어진 디오판토스 방정식의 해 찾는 함수 |
'파이썬으로 풀어보는 고딩수학 > 수열' 카테고리의 다른 글
등비수열 (0) | 2024.04.01 |
---|---|
등차수열 (0) | 2024.01.02 |
댓글