สมมติว่าเรามีค่าจำนวนเต็มยาวสองค่าสูงสุดและต่ำสุด เราต้องหาเศษส่วนร่วม n/d ให้ min <=d <=max และ |n/d - pi| มีขนาดเล็กที่สุด ที่นี่ pi =3.14159265... และหากมีเศษส่วนมากกว่าหนึ่งตัวที่มีเงื่อนไขนี้ ให้คืนค่าเศษส่วนที่มีตัวส่วนน้อยที่สุด
ดังนั้น หากอินพุตมีค่าต่ำสุด =1 สูงสุด =10 เอาต์พุตจะเป็น 22/7
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
- P :=เศษส่วน (5706674932067741 / 1816491048114374) - 3
- a :=0, b :=1, c :=1, d :=1
- farey :=อาร์เรย์ของคู่ มีสองคู่เริ่มต้น (a, b) และ (c, d)
- วนซ้ำสิ่งต่อไปนี้โดยไม่มีเงื่อนไข -
- f :=b + d
- ถ้า f> สูงสุด - ต่ำสุด แล้ว
- ออกมาจากวงจร
- e :=a + c
- ใส่คู่ (e, f) ที่ท้ายแฟรี่
- ถ้า P <ค่าของ (e/f) แล้ว
- c :=e และ d :=f
- ถ้าอย่างนั้น
- a :=e และ b :=f
- p_min :=ชั้นของ (P * ต่ำสุด)
- ในขณะที่ขั้นต่ำ <=สูงสุด ทำ
- c :=0, d :=0
- สำหรับแต่ละคู่ (a, b) ใน farey ทำ
- ถ้าต่ำสุด + b> สูงสุด แล้ว
- ออกมาจากวงจร
- if |(p_min + a)/ (ขั้นต่ำ + b) - P| <|p_min / ขั้นต่ำ - P| แล้ว
- c :=a, d :=b
- ออกมาจากวงจร
- ถ้าต่ำสุด + b> สูงสุด แล้ว
- ถ้า d เหมือนกับ 0 แล้ว
- ออกมาจากวงจร
- p_min :=p_min + c
- o ขั้นต่ำ :=ขั้นต่ำ + d
- o เศษส่วนส่งคืน (p_min + 3 * ต่ำสุด) / ต่ำสุด
ตัวอย่าง
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
from fractions import Fraction def solve(minimum, maximum): P = Fraction(5706674932067741, 1816491048114374) - 3 a, b, c, d = 0, 1, 1, 1 farey = [(a,b),(c,d)] while True: f = b + d if f > maximum - minimum: break e = a + c farey.append((e, f)) if P < Fraction(e, f): c, d = e, f else: a, b = e, f p_min = int(P * minimum) while minimum <= maximum: c, d = 0, 0 for a, b in farey: if minimum + b > maximum: break if abs(Fraction(p_min + a, minimum + b).real - P) < abs(Fraction(p_min, minimum).real - P): c, d = a, b break if d == 0: break p_min += c minimum += d return ("{}/{}".format(p_min + 3 * minimum, minimum)) minimum = 1 maximum = 10 print(solve(minimum, maximum))
อินพุต
4, 27
ผลลัพธ์
22/7