【问题标题】:Minimize the remainder in the chinese remainder theorem中国余数定理中的余数最小化
【发布时间】:2011-09-23 23:05:00
【问题描述】:

我有多个包含多个同余的集合。

在将Chinese remainder theorem 应用于每组中的一个项目时,我试图找到最小的余数。

以 2 套为例:

第一组:

7x + 1
7x + 3

第 2 组:

11 倍
11x + 2
11x + 7
11x + 8

7x + 1 & 11x 得到 77x + 22
我追求最小的余数(在上面的示例中为 77x + 8),而无需测试所有组合。


这是我实际问题的非常简化的版本(大约 50 个集合,每个集合有大约 100 个全等)。

我被困在如何解决这个问题上,任何建议都将不胜感激。

另外,如果我的数学术语不正确,我深表歉意。

【问题讨论】:

    标签: algorithm math complexity-theory chinese-remainder-theorem


    【解决方案1】:

    设集合为 S1, S2, ... Sk,其中每个集合中的模数为 n1 > n2 > ... > nk,Si 中的余数为 a_i1

    这是一个伪代码:

    Find the target modulus, i.e. n = lcm(n1, n2, ..., nk)
    
    Convert the sets Si into hashtables, so that you can check if a certain element is in the set or not.
    
    for (int b = 0; b < n / n1; b++)
        foreach (int c in [a_11, a_12, a_13, ...])
            //candidate target reminder
            a = b*n1 + c
            works = true;
            foreach (int ni in [n2, n3, ..., nk])
               //test if there is an element in Si, which gives the correct reminder
               //if not then this candidate doesn't work, go to the next
               if( not Si contains (a % ni))
                   works = false;
                   break
            if (works)
                print "The solution is n*x+a"
                exit
    

    我们的想法是寻找最小值。如果最小值是 a,那么 a 可以表示为 a=x*n1+y,其中 y 是 S1 中的某个元素,因此我按递增顺序迭代所有可能性。然后对于它们中的每一个,我检查其他集合 - 它们是否包含当前 a 满足的同余。说第二组 S2:应该存在来自 S2 的同余,例如p*n2+q,因此对于某个 p,a = p*n2+q。但这意味着 a % n2 = q(因为 q 是余数)。 IE。 a % n2 应该在 S2 中。

    算法的复杂度为 O (n/n1 * |S1| * k)。 这就是为什么我选择 n1 作为最大模数。但是如果你真的想最小化复杂度,你应该选择集合 Si 使得 n/ni * |Si|最低限度。

    【讨论】:

    • 不确定我是否了解您的所有算法,但您正在测试所有组合?如果不测试所有组合,我不确定他们是否能解决这个问题。
    • 事实上,它并没有测试所有组合。对我来说,测试所有组合意味着迭代所有方法以从每组中获取一个同余,并为它们中的每一个解决中国剩余定理并选择最小值。我的解决方案是寻找最小值。
    • 感谢您的编辑 :D 我明白它现在是如何工作的。 +1 不错的解决方案。我试图从 Bezout un1+vn2=1 中找到最小的余数,但如果不尝试全部就找不到最小值。
    • Bezout 是u*n1+v*n2 = gcd(n1,n2)。显然,如果它们有一个公约数,它就不可能是 1
    【解决方案2】:

    有一种中间相遇算法可以及时找到最小的残差

    O(max(|S1|, |S2|) log(max(|S1|, |S2|)))。

    先用中国剩余定理求出所有0

    即在问题中给出的示例中:

    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 时,当总和大于 n1*n2 时减少 T2 中的位置。

    如果您有两个以上的模数 n1 .. nk,那么我能看到的最快解决方案是将模数分成两组,例如 n1 .. nr 和 nr+1 .. nk 找到集合 T1 使得 t 在T1 iff t mod ni in Si 对于所有 1

    对于您的应用程序,即 50 个模数和 100 个全等,此算法仍然使用大约 100^25 步,这是不可行的。不幸的是,看起来没有多项式算法。 特别是,已知找到方程 x^2 == a (mod n) 的最小解 x,其中 n 是一个高度复合的整数,是 NP 完全的。但是找到这样的解决方案可以减少你的问题。 因此,您的问题通常也应该是 NP 完全的,除非同余具有一些可以利用的特殊属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-25
      • 1970-01-01
      • 2012-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多