Приближённое сокращение дроби.
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.82] |
|
|
правила раздела Алгоритмы

| Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Приближённое сокращение дроби.
|
Сообщ.
#1
,
|
|
|
|
У меня возник вопрос, который не могу решить сам.
Суть такова, есть несократимая дробь (числитель/знаменатель), нужно сделать так, что бы числитель и знаменатель был не более чем заданное число и при этом, итоговое дробное число было как можно ближе к изначальному. На данный момент я целочисленно делю и числитель и знаменатель на 2 до тех пор(сокращая дробь по возможости), пока не будет достигнута нужная разрядность, но подозреваю, что это не самое точное решение. Если есть какие-то уже известные методики, то приветствуется любая информация. |
|
Сообщ.
#2
,
|
|
|
|
Насколько данная операция критична по времени?
Насколько велики исходные значения числителя и знаменателя? |
|
Сообщ.
#3
,
|
|
|
|
Цитата KIA @ У меня возник вопрос, который не могу решить сам. Суть такова, есть несократимая дробь (числитель/знаменатель), нужно сделать так, что бы числитель и знаменатель был не более чем заданное число и при этом, итоговое дробное число было как можно ближе к изначальному. На данный момент я целочисленно делю и числитель и знаменатель на 2 до тех пор(сокращая дробь по возможости), пока не будет достигнута нужная разрядность, но подозреваю, что это не самое точное решение. Если есть какие-то уже известные методики, то приветствуется любая информация. Не все дроби могут удовлетворять "заданному числу". Ибо может получится дробь 0/число. Ну а методу я бы изобрел следующую, на примере ... ![]() ![]() Пусть дано: Дробь - 17/33 "Заданное число" - 3 int(17/3)=5 int(33/3)=11 <--- выбираем большее (11>5) int(17/11) 1 ------------ = ---- int(33/11) 3 Или я не так понял задачу? Добавлено Цитата JoeUser @ пока не будет достигнута нужная разрядность Если все же "заданное число" - это разрядность, тогда используем для "первого деления" степень основания системы исчисления. |
|
Сообщ.
#4
,
|
|
|
|
Воспользуйся аналогом двоичного поиска, только вместо середины отрезка бери медианту.
Добавлено Цитата JoeUser @ Ну а методу я бы изобрел следующую, на примере ... И на твоём же примере это не работает К 17/33 ближе 2/3, а не 1/3. |
|
Сообщ.
#5
,
|
|
|
|
Цитата JoeUser @ методу я бы изобрел следующую, на примере ... Ну и сбойнула твоя метода - 2/3 ближе к исходнику. |
|
Сообщ.
#6
,
|
|
|
|
Разделить числитель и знаменатель на число K (не обязательно целое) и округлить. K подбираем так, чтобы новые числитель и знаменатель удовлетворяли ограничению.
Цитата Дробь - 17/33 "Заданное число" - 3 K=11 получим 2(1,5454545454545454545454545454545)/3 |
|
Сообщ.
#7
,
|
|
|
|
OpenGL, Akina, да - согласен, неувязочка
Точность хромает. |
|
Сообщ.
#8
,
|
|
|
|
Цитата JoeUser @ Точность хромает. Да в озвученных тобой условиях правильным ответом вообще является 1/2. То, что в результате значения числителя и знаменателя ограничены заданным значением, не запрещает им быть меньше этого предела. |
|
Сообщ.
#9
,
|
|
|
|
Цитата Pavlovsky @ Разделить числитель и знаменатель на число K (не обязательно целое) и округлить. K подбираем так, чтобы новые числитель и знаменатель удовлетворяли ограничению. Это не будет работать если числитель или знаменатель требуемого числа будут строго меньше ограничения. Например, для 2/7 и ограничения 6 ответ 1/4, а твоим алгоритмом - 1/3. Добавлено Цитата Akina @ Да в озвученных тобой условиях правильным ответом вообще является 1/2. Ха. А я-то и не заметил этого |
|
Сообщ.
#10
,
|
|
|
|
KIA
Цепные дроби решают твою задачу оптимальным образом: Цитата подходящая дробь Pn/Qn является наилучшим приближением для x среди всех дробей, знаменатель которых не превосходит Qn; Добавлено P.S. Только тебе надо уйти от начального рационального числа в сторону на небольшую величину, чтобы получить вещественное число, которое будешь приближать. То есть вместо m/n надо приближать m/n + eps, где eps подбирать экспериментально. Иначе цепная дробь быстро выродится, если число рациональное. |
|
Сообщ.
#11
,
|
|
|
|
Цитата OpenGL @ Например, для 2/7 и ограничения 6 ответ 1/4, а твоим алгоритмом - 1/3. 1/3 (отклонение 1/21) на совсем чуть-чуть хуже чем 1/4 (отклонение 1/28). |
|
Сообщ.
#12
,
|
|
|
|
Цитата Pavlovsky @ 1/3 (отклонение 1/21) на совсем чуть-чуть хуже чем 1/4 (отклонение 1/28). Это "чуть-чуть" можно довести до большой величины. Собственно, пример JoeUser это как раз иллюстрирует. |
|
Сообщ.
#13
,
|
|
|
|
А где у нас топикстартер? или ему уже всё по барабану?
|
|
Сообщ.
#14
,
|
|
|
|
Цитата OpenGL @ Это "чуть-чуть" можно довести до большой величины. Чем больше значение ограничения, чуть-чуть превратится совсем в мизерные значения. |
|
Сообщ.
#15
,
|
|
|
|
Народ, а как вам такое:
![]() Если я ниче не напутал с арифметикой, то останется только умножить числитель и знаменатель на нужную степень десятки, и отсечь дробную часть. Точность конечно теряется, но на пятом знаке после запятой. Че скажите, или опять шило? |