Порівняння раціональних чисел


12

Враховуючи і ,a,b,c,dNb,d{0}

ab<cdad<cb

Мої запитання:

Даноa,b,c,d

  1. Якщо припустити, що ми можемо вирішити в , чи є спосіб вирішити не маючи попередньої форми множення (або ділення), і . Або є якийсь доказ того, що немає способу.O ( | x | + | y | ) a d < c b a d c bx<yZO(|x|+|y|)ad<cbadcb
  2. Чи є більш швидкий метод порівняння раціональних чисел, ніж множення знаменників.

1
@PKG, але множення займе більше лінійного часу. Я думаю, що ми хочемо щось швидше для цього питання.
Джо

1
Складний випадок, коли один інтервал містить інший, наприклад . [a,d][b,c]
PKG

1
Ви неявно припускаєте, що і мають однаковий знак. Інакше напрямок нерівності змінюється. дbd
Ран Г.

1
(1) Множення майже лінійне (пошук алгоритму Фюрера). (2) "Раціональне ціле число", принаймні в контексті теорії алгебраїчних чисел, насправді означає лише ціле число. Ви хочете сказати "раціональне" або "раціональне число".
Yuval Filmus

1
див. також очевидний дублікат Як порівняти раціональні числа?
vzn

Відповіді:


5

Моє поточне дослідження:

Початкова спроба деяких загальних правил

Можна спробувати скласти кілька загальних правил для вирішення раціонального порівняння:

Припустимо, що всі позитивні :a,b,c,d

a<bcdab<cd
Це в основному означає, якщо ліва сторона менше однієї, а права - щонайменше одна, ліва - менше правої сторона. У цьому ж ключі:

abcdabcd

Ще одне правило:

(b>d)(ac)[ab<cd]
Я вважаю це правило логічним, оскільки чим більший знаменник, тим менша кількість, а тим більша чисельник, тим більше число. Отже, якщо ліва сторона має більший знаменник і менший числівник, ліва буде меншою.

Звідси далі, будемо вважати, що , тому що в іншому випадку ми можемо або вирішити це за допомогою наведених вище правил, або повернути питання до , і ми все одно закінчимо цю умову.a<cb<dcd<?ab

Правила : Це правило, в основному, говорить про те, що ви завжди можете відняти числівники від знаменників і встановити результати як чисельники, щоб отримати еквівалентну задачу. Я залишу доказ.

(ba)b<(dc)d[ab<cd]|a<c,b<d

ab<cadb[ab<cd]|a<c,b<d

Це правило дозволяє відняти лівий чисельник та знаменник від правого чисельника та знаменника для еквівалентної задачі.

І звичайно є масштабування:

akbk<cd[ab<cd]|a<c,b<d
Ви можна використовувати масштабування, щоб зробити вищезазначені правила віднімання.

Використовуючи ці правила, ви можете пограти з речами, застосувати їх неодноразово, у розумних поєднаннях, але бувають випадки, коли числа близькі та патологічні.

Застосовуючи попередні правила, ви можете зменшити всі ці проблеми до:

ab<ap+qbp+qab<qq|a>q,b>q

Іноді це можна вирішити прямо зараз, іноді ні. Зазвичай патологічні випадки мають форму:

ab<cd|a>c,b>d,cO(a),dO(b)

Потім ви перегортаєте його і отримуєте те саме, лише на один біт менше. Кожне застосування правил + flip зменшує його на цифру / біт. AFAICT, ви не можете швидко вирішити це, якщо ви не застосуєте правила разів (один раз на кожну цифру / біт) у патологічному випадку, не зважаючи на їх уявну перевагу.O(n)

Відкрита проблема ??

Я зрозумів, що ця проблема здається важче, ніж деякі поточні відкриті проблеми.

Ще слабшою проблемою є визначення:

ad=?bc

І ще слабкіше:

ad=?c

Це відкрита проблема перевірки множення . Вона слабша, бо якби у вас був спосіб визначити , то ви можете легко визначити , тестуючи за допомогою алгоритму двічі, , . Якщо це правда, ви знаєте, що .ad<?bcad=?bcad<?bcbc<?adadbc

Тепер, була відкритою проблемою, принаймні в 1986 році:ad=?c

Складність множення та ділення. Почнемо з дуже простого рівняння ax = b. Якщо розглядати цілі числа, перевірити його розв’язність та знайти рішення x можливо шляхом цілого поділу з залишковим нулем. Для перевірки заданого рішення x буде цілком множинне множення, але цікавою є відкрита проблема, чи існують більш швидкі методи перевірки.

- ARNOLD SCHÖNHAGE в розв’язуванні рівнянь з точки зору складності обчислень

Дуже цікаво, що він також згадав про питання перевірки матричного множення :

Цікавим є також питання, чи може перевірка множення матриці, тобто перевірка того, чи може АВ = G для даного С, можливо зробити швидше.

- ARNOLD SCHÖNHAGE в розв’язуванні рівнянь з точки зору складності обчислень

Це було вирішено, і справді можливо перевірити в час рандомізованим алгоритмом (при цьому є розміром вхідних матриць, тому в основному це лінійний час у розмір вводу). Цікаво, чи можна звести множення до цілих чисел до матричного множення, особливо з їх подібністю, враховуючи подібність цілого множення Карацуби на алгоритми множення матриць, що слідували. Тоді, можливо, якимось чином ми можемо використовувати алгоритм підтвердження множення матриці для цілого множення.O(n2)n×n

У всякому разі, оскільки, наскільки мені відомо, це відкрита проблема, тим сильніша проблема , безумовно, відкрито. Мені цікаво, якщо вирішення проблеми перевірки рівності матиме будь-яке відношення до проблеми перевірки нерівності порівняння.ad<?cd

Невелика зміна нашої проблеми полягала б у тому, якби гарантії дробів будуть зведені до найнижчих умов; в цьому випадку легко визначити, чи . Чи може це мати якесь відношення до порівняльної перевірки зменшених фракцій?ab=?cd

Ще тонкіше питання: що робити, якщо у нас був спосіб перевірити , чи поширюватиметься це на тестування ? Я не бачу, як ви можете використовувати це "обидва способи", як ми це зробили для .ad<?cad=?cad<?cd

Пов'язані:

  • Орієнтовне розпізнавання нестандартних мов кінцевими автоматами

    Вони роблять певну роботу щодо приблизного множення та рандомізованої перевірки, що я не повністю розумію.

  • math.SE: Як порівняти два множення без множення?
  • Припустимо, нам було дозволено попередньо обробити настільки, наскільки ми хотіли в поліноміальний час, чи можемо ми вирішити у лінійному часі?cab=c
  • Чи існує алгоритм множення лінійного часу недетермістичного цілого числа? Дивіться http://compgroups.net/comp.theory/nondeterministic-linear-time-multiplication/1129399

    Існують добре відомі алгоритми множення n-бітних чисел на щось на кшталт складності O (n log (n) log (log (n))). І ми не можемо зробити краще, ніж O (n), оскільки, принаймні, ми повинні подивитися на всі входи. Моє запитання: чи можна насправді досягти O (n) для відповідного класу "недетермінованих" алгоритмів?

    Точніше, чи існує алгоритм, який може приймати два n-розрядних двійкових чисел "a" і "b" і 2n-бітове число "c" і скаже вам в O (n) час, чи "a * b = c"? Якщо ні, чи існує якась інша форма сертифіката C (a, b, c) така, що алгоритм може використовувати його для тестування продукту в лінійний час? Якщо не лінійний час, чи проблема тестування продукту хоча б асимптотично простішою, ніж його обчислення? Будь-які відомі результати в цьому напрямку будуть вітатися.

    Джон.

    ―Johnh4717


1

Ось дуже часткова спроба спростування. Припустимо, що в нашому рішенні ми можемо використовувати лише (постійну кількість) додавань і віднімань, а також постійну кількість наперед заданих чисел wrt. Іншими словами, ми можемо робити постійне число , і т.д. в нашому рішенні. Тоді єдині величини, які ми можемо обчислити, мають вигляд де є попередньо визначеними константами. Зверніть увагу, що можна обчислити за час .modmod 2mod 3q=k1a+k2b+k3c+k4d=kiakqO(|a|)

Відредаговано Це рішення вирішує визначити біт iff . Розглянемо, як як точки в . Біт визначається його положенням wrt поверхня яка є гіперболоїдом у 4 вимірах. Якщо у вхідному просторі є точка , рішення, що вирішує вище, може обчислити точки на обмеженій відстані від цієї вхідної точки, тобто ті точки тощо. Це визначає кубоїд у 4-денному просторі.B:B=1ad>bca,b,c,dR4Bad=bc(a,b,c,d)q:|qa|=k1,

(Як зробити це більш точним?) Відстань від кубої до поверхні, як правило, не обмежене, і, отже, поверхня не може бути обчислена рішенням


Вибачте, що не відповів на це. Я думаю, це може бути просто вище мого розуміння, і я тим часом займався дослідженням можливих відповідей.
Realz Slaw

1

Хороше питання. Чи прийняли б ви рівень довіри?

Можливо, зробіть приблизний поділ. Тобто

Для обчислення граничних приблизних коефіцієнтів a / b праворуч змістіть a на стелю (log_2 (b)), а також на підлогу (log_2 (b)). Тоді ми знаємо, що точний коефіцієнт знаходиться між цими двома значеннями.

Тоді, залежно від відносних розмірів чотирьох цілих чисел, можна виключати певні випадки та отримувати 100% впевненість.

Можна повторити процедуру для іншого, ніж 2, і завдяки послідовності таких операцій підвищити рівень впевненості, поки зміна знаку / розриву зв’язку якимось чином не спостерігається?

Це мій ескіз першого методу.


Якщо ви подивитесь на мою відповідь "поточного дослідження", я думаю, що ці правила щось в цьому роблять. Ви можете продовжувати, багато разів отримуючи 100% впевненість, якщо це потрапляє в одне з перших правил, а в гіршому - ви продовжуєте повторювати останні правила знову і знову, видаляючи трохи кожен раунд, подібно до того, що ви пропонуєте, я думаю. Однак моє запитання стосується чогось остаточного в (а точніше, краще, ніж множення, задовольнило б і це питання), або принаймні рандомізований алгоритм з деякою експоненціально малою ймовірністю невдачі. O(n)O(nlogn)
Realz Slaw

Крім того, якщо можна було б переконатися, що це відкрита проблема, а не якось по суті складніше, ніж перевірка (див. Мою відповідь "Поточне дослідження", розділ " Відкрита проблема" ), чи є якісь інші цікаві існуючі дослідження чи результати з цього приводу, то це теж може бути прийнятною відповіддю. ab=c
Realz Slaw

1

чи є спосіб вирішити рекламу <cb без необхідності попереднього [дорогого] множення

Звичайно.

Ідея: порівняйте десяткове розширення по бітах.

Єдиний неприємний біт полягає в тому, що ми повинні спочатку виключити рівність, оскільки в іншому випадку ми можемо не припинити.
Спочатку корисно спочатку порівняти цілі частини, тому що це легко.

Врахуйте це:

def less( (a,b), (c,d) ) = {
  // Compare integer parts first
  intA = a div b
  intC = c div d

  if intA < intB
    return True
  else if intA > intB
    return False
  else // intA == intB
    // Normalize to a number in [0,1]
    a = a mod b
    c = c mod d

    // Check for equality by reducing both
    // fractions to lowest terms
    (a,b) = lowestTerms(a,b)
    (c,d) = lowestTerms(c,d)

    if a == c and b == d
      return False
    else
      do
        // Compute next digits in decimal fraction 
        a = 10 * a
        c = 10 * c

        intA = a div b
        intC = c div d

        // Remove integer part again
        a = a mod b
        c = c mod d
      while intA == intC

      return intA < intC
    end
  end
}

Зауважте, що do-whileцикл повинен закінчуватися, оскільки числа неоднакові. Ми не знаємо, як довго він працює; якщо цифри дуже близькі, це може бути певний час.

Зрозуміло, що дорогих множин немає; єдине, що нам потрібно - це помножити номінаторів на . Зокрема, ми уникали явного обчислення та .10adcb

Це швидко? Напевно, ні. Існує багато цілих ділень, модулів і gdcs для обчислення, і у нас є цикл, кількість ітерацій якого обернено пропорційно відстані між числами, які ми порівнюємо.


Хелперний метод:

def lowestTerms(a,b) = {
  d = gcd(a,b)
  if d == 1
    return (a,b)
  else
    return lowestTerms(a div d, b div d)
  end
}

Я не думаю, що це в дусі питання. Обчислення та прямо на початку вже займає стільки ж часу, скільки й обчислення та у запитанні, а питання вже говорить "без ... множення (або поділів), та ". Він також запитує алгоритм лінійного часу, який, мабуть, це не так, виходячи з вашого коментаря про цикл, який працює протягом певного часу. a/bc/dadbcadcb
Девід Річербі

@DavidRicherby Hm. Я в основному думав про переливи - тут операції рідше створюють величезну кількість.
Рафаель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.