Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 高斯消去模p_Java_Math_Equation Solving_Modular Arithmetic - Fatal编程技术网

Java 高斯消去模p

Java 高斯消去模p,java,math,equation-solving,modular-arithmetic,Java,Math,Equation Solving,Modular Arithmetic,我正试图用Java重写一段代码,用它来求解一组线性方程组,在浮点上进行高斯消去,以处理模素数的方程组。问题是它不起作用,我也不知道出了什么问题。它似乎适用于小的方程组,但不适用于大的方程组,这使得调试变得困难 我的算法取第一行,通过找到第一个元素的倒数来规范化它,然后将行中的每个元素乘以这个倒数。然后它从其他行中减去这一行足够的次数,使它们的第一个元素为零。在下一次迭代中,它转到下一行并执行相同的过程,直到行i的枢轴元素位于列i中。最后,它从前面的行中减去每一行,使每一列中只有一个非零元素(最后

我正试图用Java重写一段代码,用它来求解一组线性方程组,在浮点上进行高斯消去,以处理模素数的方程组。问题是它不起作用,我也不知道出了什么问题。它似乎适用于小的方程组,但不适用于大的方程组,这使得调试变得困难

我的算法取第一行,通过找到第一个元素的倒数来规范化它,然后将行中的每个元素乘以这个倒数。然后它从其他行中减去这一行足够的次数,使它们的第一个元素为零。在下一次迭代中,它转到下一行并执行相同的过程,直到行i的枢轴元素位于列i中。最后,它从前面的行中减去每一行,使每一列中只有一个非零元素(最后一个除外)。(到目前为止,我使用双打,这是没有必要的,但这应该不是一个问题)。这是我的密码:

// Transforms A so that the leftmost square matrix has at most one 1 per row,
    // and no other nonzero elements.
    // O(n^3)
 public static void gauss(int[][] A, int num_columns) {
        int n = A.length;
        int m = A[0].length;

        for (int i = 0; i < num_columns; i++) {
            // Finding row with nonzero element at column i, swap this to row i
            for(int k = i; k < num_columns; k++){
                if(A[k][i] != 0){
                    int t[] = A[i];
                    A[i] = A[k];
                    A[k] = t;
                }
            }
            // Normalize the i-th row.
            int inverse = (int)inverse((long)A[i][i], prime);
            for (int k = i ; k < m; k++) A[i][k] = (A[i][k]*inverse) % prime;

            // Combine the i-th row with the following rows.
            for (int j = 0; j < n; j++) {
                if(j == i) continue;
                int c = A[j][i];
                A[j][i] = 0;
                for (int k = i + 1; k < m; k++){
                    A[j][k] = (A[j][k] - c * A[i][k] + c * prime) % prime;
                }
            }
        }
    }

    public static void gauss(int[][] A) {
        gauss(A, Math.min(A.length, A[0].length));
    }
    public static long gcd(long a, long b){
        if(a < b){
            long temp = a;
            a = b;
            b = temp;
        }
        if(b == 0) return a;
        return gcd(b, a % b);
     }
    public static Pair ext_euclid(long a, long b){
        if(a < b){
            Pair r = ext_euclid(b,a);
            return new Pair(r.second, r.first);
        }
        if(b == 0) return new Pair(1, 0);
        long q = a / b;
        long rem = a - b * q;
        Pair r = ext_euclid(b, rem);
        Pair ret = new Pair(r.second, r.first - q * r.second);
        return ret;
    }

    public static  long inverse(long num, long modulo){
        num = num%modulo;
        Pair p = ext_euclid(num, modulo);
        long ret = p.first;
        if(ret < 0) return (modulo + ret) % modulo;
        return ret % modulo;
    }

    static class Pair{
        public long first;
        public long second;
        public Pair(long frst, long scnd){
            first = frst;
            second = scnd;
        }
    }
这是正确的(第一个变量=0,第二个变量=1.0,第三个变量=0),WolframAlpha可以检查0*k^0+1*k^1+0*k^2的k=1..3

对于这个例子,有10个变量,方程a*k^0+b*k^1+c*k^2。。。(mod 29)对于k=1..11,我有这个矩阵:

1 1 1 1 1 1 1 1 1 1 1 8 
1 2 4 8 16 3 6 12 24 19 9 5 
1 3 9 27 23 11 4 12 7 21 5 12 
1 4 16 6 24 9 7 28 25 13 23 12 
1 5 25 9 16 22 23 28 24 4 20 15 
1 6 7 13 20 4 24 28 23 22 16 0 
1 7 20 24 23 16 25 1 7 20 24 5 
1 8 6 19 7 27 13 17 20 15 4 1 
1 9 23 4 7 5 16 28 20 6 7 18 
1 10 13 14 24 8 22 17 25 18 7 20 
1 11 5 26 25 14 9 12 16 7 7 8  
使用我的算法,我得到了答案:

1 0 0 0 0 0 0 0 0 0 0 18 
0 1 0 0 0 0 0 0 0 0 0 8 
0 0 1 0 0 0 0 0 0 0 0 15 
0 0 0 1 0 0 0 0 0 0 0 11 
0 0 0 0 1 0 0 0 0 0 0 28 
0 0 0 0 0 1 0 0 0 0 0 27 
0 0 0 0 0 0 1 0 0 0 0 7 
0 0 0 0 0 0 0 1 0 0 0 21 
0 0 0 0 0 0 0 0 1 0 0 9 
0 0 0 0 0 0 0 0 0 1 0 24 
0 0 0 0 0 0 0 0 0 0 1 14  
但这是错误的!(可通过WolframAlpha检查)。正确答案应该是(a b c…=(8139432728101012415)


有人能看出我的错误吗?还是我误解了高斯模p的计算方法了?

在第一阶段,你似乎找不到第I个位置有非零的行。考虑到这一点,而且我不知道你的
逆函数是如何工作的,你可能会也可能不会遇到问题

我不明白你为什么要在第二阶段寻找“支点”。你知道他们在第一阶段的位置。事实上,我不明白你为什么有第二阶段。在第一阶段完成所有的消除。这将大大澄清您的代码

我不明白你为什么在矩阵中使用
double
s。我也不明白你为什么到处使用
Math.abs
;平等比较在这里非常合适


最后,你要解决一个范德蒙系统。如果这是您的应用程序,而不仅仅是一个测试用例,您可能应该改用拉格朗日插值。

因此,我现在根据您的建议更新了我的代码,并包括了我的反函数。我还将矩阵更改为整数元素。答案还是一样!与WA核实后,我得到的答案(18,8,15,11,28,27,7,21,9,24,14)对除最后3行以外的所有行都是正确的。这意味着什么?值得一提的是,您的更新代码似乎给出了正确的答案。我猜你的旧代码在某个时候偶然发现了一个0。
1 0 0 0 0 0 0 0 0 0 0 18 
0 1 0 0 0 0 0 0 0 0 0 8 
0 0 1 0 0 0 0 0 0 0 0 15 
0 0 0 1 0 0 0 0 0 0 0 11 
0 0 0 0 1 0 0 0 0 0 0 28 
0 0 0 0 0 1 0 0 0 0 0 27 
0 0 0 0 0 0 1 0 0 0 0 7 
0 0 0 0 0 0 0 1 0 0 0 21 
0 0 0 0 0 0 0 0 1 0 0 9 
0 0 0 0 0 0 0 0 0 1 0 24 
0 0 0 0 0 0 0 0 0 0 1 14