高斯消元法

来源:互联网 发布:成都大数据培训 编辑:程序博客网 时间:2024/05/16 17:30

注:由于除法中循环小数等引起的误差问题没有解决

import java.math.BigDecimal;import java.math.MathContext;import java.math.RoundingMode;import java.util.HashSet;import java.util.Set;/** * Created with IntelliJ IDEA. * User: Administrator * Date: 15-2-2 * Time: 上午10:54 * 高斯消元法解线性方程组 */public class TestGauss {    int n;//总行数    int m;//总列数    /**     * 下三个矩阵相当于n个m元一次线性方程 xishu[i]*bianliang[i] +...xishu[n]*biangliang[m] = changshu[n]     */    //系数矩阵    public BigDecimal[][] xiShu = new BigDecimal[n][m];    //变量矩阵    public BigDecimal[] bianLiang = new BigDecimal[m];    //常数矩阵    public BigDecimal[] changShu = new BigDecimal[n];    /**     * 计算方程组的解的思路(高斯消元法):     * 当等式数少于变量数时无法得出所有变量的准确解     * 由上往下使用前一等式去为下一等式的首个系数不为0的变量消元,得到行梯阵式,知道得出bianLiang[m]     * 然后采用迭代的方式由下往上计算出各个变量的值     */    public void gauss() {        MathContext mc = new MathContext(6, RoundingMode.CEILING);        xiShu = new BigDecimal[][]{                {new BigDecimal(3.0), new BigDecimal(2.0), new BigDecimal(1.0), new BigDecimal(7.0)},                {new BigDecimal(5.0), new BigDecimal(2.0), new BigDecimal(5.0), new BigDecimal(4.0)},                {new BigDecimal(4.0), new BigDecimal(8.0), new BigDecimal(8.0), new BigDecimal(6.0)},                {new BigDecimal(9.0), new BigDecimal(5.0), new BigDecimal(7.0), new BigDecimal(6.0)}};        changShu = new BigDecimal[]{new BigDecimal(90.0), new BigDecimal(104.0), new BigDecimal(172.0), new BigDecimal(172.0)};        bianLiang = new BigDecimal[]{new BigDecimal(0), new BigDecimal(0), new BigDecimal(0), new BigDecimal(0)};        Set<String> xiShuRowCache = new HashSet<String>();        int xiShuRowCount = 0;//系数行数        int xiShuMaxColCount = 0;//系数最大列数        for (BigDecimal[] row : xiShu) {            String rowStr = "";            if (row.length > xiShuMaxColCount) {                xiShuMaxColCount = row.length;            }            for (BigDecimal cell : row) {                if (cell == null) {                    System.err.println("出现null值常数");                    return;                }                rowStr += cell + ",";            }            //并未检测等式中四个常量是否存在相同的因子            if (xiShuRowCache.contains(rowStr)) {                System.out.println("存在重复行。");            } else {                xiShuRowCache.add(rowStr);                xiShuRowCount++;            }        }        if (xiShuRowCount < xiShuMaxColCount) {            System.err.println("变量数大于等式数,无准确解。");            return;        }        //开始进行行数-1次消元        for (int k = 1; k < xiShu.length; k++) {            for (int i = k; i < xiShu.length; i++) {                BigDecimal[] row = xiShu[i];                BigDecimal xiaoYuanXiShu = xiShu[i][k - 1].divide(xiShu[k - 1][k - 1], mc);                for (int j = row.length-1; j >= k-1; j--) {                    if(j != k-1){                    row[j] = row[j].subtract(xiaoYuanXiShu.multiply(xiShu[k - 1][j], mc));                    }else{                     row[j]=new BigDecimal(0);                    }                }                changShu[i] = changShu[i].subtract(xiaoYuanXiShu.multiply(changShu[k - 1], mc));            }            //打印出每次消元后的系数、常数            for(int i = 0; i < xiShu.length; i++){                BigDecimal[] row = xiShu[i];                for (int j = 0; j < row.length; j++) {                    System.out.print(row[j] + "  ");                }                System.out.println(changShu[i]);            }            System.out.println("=====================================");        }        //根据行梯阵式求出各个变量        for(int i = bianLiang.length-1;i>=0;i--){            BigDecimal temp = new BigDecimal(0);            for(int j = bianLiang.length-1;j>=0;j--){                temp =temp.add(bianLiang[j].multiply(xiShu[i][j], mc));            }            bianLiang[i] = changShu[i].subtract(temp).divide(xiShu[i][i],mc);            System.out.println( bianLiang[i]);        }    }    public static void main(String args[]) {        new TestGauss().gauss();    }}


0 0