【问题标题】:GaussJordan elimination Algorithm Java高斯乔丹消元算法Java
【发布时间】:2014-12-20 18:17:30
【问题描述】:

我的 Gauss Jordan 消除方法有些问题。它看起来有点过于简单,但在纸面上它应该可以工作。考虑到在 0 的情况下它必须执行交换,它将枢轴设置为 1。然后它减去该行乘以与数据透视列具有相同索引号的剩余行的值 conindex。

我在我的最终算法中使用了这些方法。

行乘法:

public static double[] rowMul(double[] row, double scalar) {
    BigDecimal[] temp = new BigDecimal[row.length];
    BigDecimal s = new BigDecimal(scalar);
    double[] newrow = new double[row.length];

    for (int i = 0; i < row.length; i++) {
        temp[i] = new BigDecimal(row[i]).multiply(s);
        newrow[i] = temp[i].doubleValue();
    }
    return newrow;
}

分割行:

public static double[] rowDiv(double[] row, double divisor) {
    BigDecimal[] temp = new BigDecimal[row.length];
    BigDecimal s = new BigDecimal(divisor);
    double[] newrow = new double[row.length];

    for (int i = 0; i < row.length; i++) {
        temp[i] = new BigDecimal(row[i]).divide(s);
        newrow[i] = temp[i].doubleValue();
    }
    return newrow;
}

行减法:

public static double[] subtractRow(double[] mat1, double[] mat2) {
    double[] c = new double[mat1.length];
    for (int i = 0; i < mat1.length; i++) {
        c[i] = mat1[i] - mat2[i];
    }
    return c;
}

枢轴检查和行交换:

public static boolean checkPivot(double[][] mat, int row) {
    if (mat[row][row] == 0) {
        return true;
    } else {
        return false;
    }
}
// Keeps track of the number of swaps performed to secure a finite solution.
private static int swapcount = 0;

// Mind giving the index value. So row starting from 0 up instead of 1!
public static double[][] swapRow(double[][] mat, int row) {
    swapcount++;
    if (swapcount >= mat.length - row) {
        System.out.println("no possible combinations.");
        swapcount = 0;
        return mat;
    }
    double[] temp = mat[row];
    for (int i = row; i < mat.length - 1; i++) {
        mat[i] = mat[i + 1];
    }
    mat[mat.length - 1] = temp;
    if (checkPivot(mat, row) == true) {
        mat = swapRow(mat, row);
    }
    swapcount = 0;
    return mat;
}

然后是我的最终高斯乔丹算法:

public static double[][] gaussJordan(double[][] matrix) {
    double[][] mat = matrix;
    int m = mat.length;
    for (int i = 0; i < m; i++) {
        if (checkPivot(mat, i) == true) {
            mat = swapRow(mat, i);
        }
        mat[i] = rowDiv(mat[i], mat[i][i]);
        for (int j = 0; j < m; j++) {
            if (j == i) {
                j++;
            } else {
                mat[j] = subtractRow(mat[j], rowMul(mat[i], mat[j][i]));
            }
        }
    }
    return mat;
}

如果我给它这个矩阵来计算怎么办。

private static double[][] elim = {
    {-20,-10,10,-10},
    {  0, 10,-5, 10},
    {-10, 10,15, 20}
};

它以某种方式跳过左侧 3 x 3 方形矩阵的中间列并返回。

1.0 0.375 0.0 0.625 
0.0 1.75  0.0 2.25 
0.0 1.5   1.0 2.5 

预期结果是:

1.0 0.0 0.0 0.14286
0.0 1.0 0.0 1.28571
0.0 0.0 1.0 0.57143

有人可以帮我找出我必须忽略的东西吗?我只是希望它没有什么明显的!谢谢你的麻烦。

【问题讨论】:

  • 请包括预期结果
  • 我没有得到你的问题的答案,但你似乎以一种相当奇怪的方式混合了doubleBigDecimal。尝试使用这两种类型中的任何一种进行代数的问题在于,它们都不能准确地表示像 1/3 这样的简单分数,因此应该给你0 的行操作实际上没有。我建议尝试找到有理数的实现。
  • 好的,谢谢您的反应。我会调查的。
  • 我必须承认这让我有些不安。而且我想我知道一种实现有理数的方法,特别是在除法中。然而,不知何故,感觉不像是导致这个特定问题的原因。尽管如此,我还是会把你的建议牢记在心。再次感谢您。

标签: java algorithm matrix linear-algebra


【解决方案1】:

mat[j] = subtractRow(mat[j], rowMul(mat[i], mat[j][i]));

似乎错了。有了它,mat[j][i] 的新值是 mat[j][i] - (mat[i][i] * mat[j][i]),即 != 0。

我觉得应该是的

mat[j] = subtractRow(mat[j], rowMul(mat[i], mat[j][i] / mat[i][i]));

mat[j][i] 的新值是 mat[j][i] - (mat[i][i] * mat[j][i] / mat[i][i])实际上是 0。

还有:

if (mat[row][row] == 0) {

这对于双打来说是有风险的。我会建议像 Math.abs(mat[row][row])

希望对你有帮助。

【讨论】:

  • 谢谢你的回复,我会去看看!
  • 再次感谢您的回复,尤其是 if (mat[row][row] == 0) { 更改是我没有考虑过的。但是 mat[i][i] 在那个阶段应该已经是 1 所以我不明白你添加那个除法是什么意思?你能再澄清一点吗?再次感谢!
  • 哦,我错过了 mat[i] = rowDiv(mat[i], mat[i][i]);.
  • 此时我一无所有。老实说,我从未见过迭代 for(i=0; ..) for(j=0; ..) 的版本。我一直使用 for(i=0; ..) for(j=i+1; ..)。结果是一个三角矩阵。然后我做了第二次扫描,但使用不同的循环: for(i=n-1; i>=0; i--) for(j=i-1; j>=0; j--) 得到对角矩阵.
  • 谢谢你,你知道你帮了我很多!我采用了您的“双扫”方法,因为它在哪里起作用!一个完美的结局。干杯!!
猜你喜欢
  • 2013-03-23
  • 1970-01-01
  • 2015-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-26
  • 1970-01-01
  • 2012-07-17
相关资源
最近更新 更多