Существует алгоритм "посередине", который находит наименьший остаток за время
O (max (| S1 |, | S2 |) log (max (| S1 |, | S2 |))).
Сначала используйте китайскую теорему об остатках, чтобы найти множество T1 всех 0 <= t <n1 * n2, удовлетворяющих t mod n1 в S1 и t mod n2 == 0
и множество T2 всех 0 <= u <n1 * n2, удовлетворяющих t mod n1 == 0 и t mod n2 в S2. </p>
т.е. в примере, приведенном в вопросе:
T1 = {22, 66}
T2 = {0, 7, 35, 63}
Теперь вы ищете искомые суммы (t1 + t2) mod n1 * n2 для любого t1 в T1 и t2 в T2.
Следовательно, наименьший остаток - это либо сумма двух наименьших элементов в T1 и T2, либо двух элементов, которые чуть больше n1 * n2. Если вы сортируете наборы T1 и T2, то лучшее решение для второго случая можно найти, отсканировав первый набор от наименьшего до наибольшего элемента и отсканировав наибольший набор от самого большого до наименьшего элемента, т.е. продвинув позицию в T1 всякий раз, когда сумма меньше, чем n1 * n2 и уменьшается положение в T2, когда она больше, чем n1 * n2.
Если у вас более двух модулей n1 .. nk, то самое быстрое решение, которое я вижу, это разделить модули на два набора, скажем, n1 .. nr и nr + 1 .. nk найти множество T1, такое что t в T1, если t mod ni в Si для всех 1 <= i <= r и t mod ni == 0 для всех r <i <= k. Т2 определяется соответственно.
Сложность зависит от распределения модулей, но обычно должна составлять примерно квадратный корень из числа возможностей. Существует алгоритм Шропеля и Шамира, который может сэкономить память, но не уменьшает сложность времени. </p>
Для вашего приложения, т. Е. Для 50 модулей и 100 сравнений этот алгоритм по-прежнему использует около 100 ^ 25 шагов, что недопустимо. К сожалению, похоже, что нет полиномиального алгоритма.
В частности, известно, что нахождение наименьшего решения x уравнения x ^ 2 == a (mod n), где
n - составное целое число, NP-полное. Но поиск такого решения может уменьшить вашу проблему.
Следовательно, ваша задача в целом должна быть NP-полной, если только у конгруэнции нет какого-то специального свойства, которое можно использовать.