高斯列主元消去法求解方程组,附c++代码与使用java实现代码

,1,列主元消去法思想

   在顺序消元法中,ann是被除数,所以ann不能为0,另外,若ann很小,计算结果可能引入较大误差。因此,在进行第K次(k>=1)变换前,在[k,n]行之间找到主元素最大的那一行,和第K行交换位置,这样保证akk始终是该列中绝对值最大的那一个。然后在接着使用高斯顺序消元法进行求解即可。

2,代码实现

   在原本顺序消元法的基础上,定义了maxValue列主元最大值,和maxRow列主元最大行,此行也就是需要交换的行。先通过for循环找出列中最大值所在的行,并将该行所在的数组下标,赋值给maxRow。然后在通过一次for循环将当前所在的第K行与找到的最大行进行交换,通过定义一个中间变量temp来将存储两行元素数组中的值进行交换,然后在进行高斯顺序消元法即可。

3,c++代码

      这里c++代码,矩阵数据的输入和输出使用的是txt文件输入输出,具体的txt数据格式请看上一篇关于顺序消元法的代码,C++顺序消元法

#include<cstdlib> 
#include <iostream> 
#include <fstream> 
#include <cmath>
    using namespace std;
    int main(){
        int i,j,k,n;
        double eps,ratio,sum;
        ifstream data_in("gauss_source.txt");
        ofstream data_out("gauss_result.txt");
        //输入增广矩阵系数
        data_in>>n; //输入方程个数
        double *x=new double[n]; //动态分配存储空间(指针)
        double **a =new double*[n]; //二级指针指向指针数组首地址,n 个方程,二维动态数组
        for(i=0; i<n; i++){
            a[i]=new double [n+1];// 给指针数组每个元素申请空间,每个元素都是一个指针,每个方程有 n+1 个系数(包括常数项)    
        }
        for(i=0; i<n; i++){
            for(j=0; j<n; j++){
                data_in>>a[i][j]; //输入系数矩阵
            }
        }
        for(i=0; i<n; i++){
            data_in>>a[i][n]; //输入等号右端向量的各元素 a[][]为增广矩阵
        }
        data_in>>eps; //输入最小主元素.为了避免主元素为 0 的情况,设置一个比较小的实数
        data_in.close();
        
//***********************列主元消去法*******************************
        double maxValue;//列主元最大值
        int maxRow;//列主元最大行,也就是需要交换的行

        for(k=0; k<(n-1); k++) 
        {
            //先找到列主元的最大行
            maxRow=k;
            maxValue=abs(a[k][k]);
            int m;
            for(m=k+1;m<n;m++){ //找到第K列中,最大元素所在的行
                if(abs(a[m][k])>maxValue){
                    maxRow=m;
                    maxValue=abs(a[m][k]);
                }
            }
            //交换第k行与第maxrow行
            //遍历每一个元素
            for(m=k;m<=n;m++){
                double temp=a[k][m];
                a[k][m]=a[maxRow][m];
                a[maxRow][m]=temp;
            }

//*******************接下来是高斯顺序消元法*************************

            for(i=(k+1); i<n; i++){
                if(abs(a[k][k])<eps){
                    cout<<endl<<"主元素太小,求解失败..."<<endl;
                    exit(0);
                }
                ratio=a[i][k]/a[k][k];
                for(j=(k+1); j<(n+1); j++){
                    a[i][j]-=ratio*a[k][j];
                }
                a[i][k]=0;
            }
        }
        x[n-1]=a[n-1][n]/a[n-1][n-1]; //回代
        for(i=(n-2); i>=0; --i){
            sum=0.0;
            for(j=(i+1); j<n; j++){
                sum+=a[i][j]*x[j];
                x[i]=(a[i][n]-sum)/a[i][i];
            }
        }
        //结果输出
        for(i=0; i<n; i++){
            data_out<<"\nx[" <<i<< "]="<<x[i]<<endl;
        }
        data_out.close();
        return 0;
    }

输入:

输出:

再附上自己使用java代码重新实现的顺序消元法的结果,这次采用的是键盘输入的方式,输入数据。

import java.util.Scanner;
import static java.lang.Math.abs;

/**
 * @program: new begin new study
 * @description: 列主元消元法
 * @author: FMm
 * @create: 2022-03-27 20:51
 **/
public class guass_soltuion {
    public static void main(String[] args) {
        int n;//方程未知数的个数
        double eps;//eps最小住院
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入方程的个数:");
        n = sc.nextInt();
        double[] arr = new double[n];
        double[][] arr2 = new double[n][n + 1];
        for (int i = 0; i < n; i++) {//输入矩阵系数与b
            for (int j = 0; j <= n; j++) {
                if (j != n) {
                    System.out.println("请输入第"+(i+1)+"行X"+ j);
                } else {
                    System.out.println("请输入第"+(i+1)+"行b"+ i);
                }
                arr2[i][j] = sc.nextDouble();
            }
        }
        System.out.println("请输入eps");
        eps=sc.nextDouble();
        guass_sequence(arr2,arr,eps,n);
        guass_output(n,arr);

    }
    /**
     * @author: FMm
     * @description: 用通过列主元消去法求上三角矩阵,并回代求值
     * @param: arr2temp 增广矩阵数组
     * @param: arr 用来回代存放xi值得数组
     * @param: eps 
     * @param: n x的个数
     * @return: void
     * @create: 2022/3/29 15:25
     */
    
    public static void guass_sequence (double[][] arr2temp,double[] arr,double eps,int n){
        double maxValue;//列主元最大值
        int maxRow;//列主元最大行,也就是需要交换的行
        double ratio;
        double sum;
     for(int k=0;k<n-1;k++){
         //先找到列主元的最大行
         maxRow=k;
         maxValue=abs(arr2temp[k][k]);
         int m;
         for(m=k+1;m<n;m++){ //找到第K列中,最大元素所在的行
             if(abs(arr2temp[m][k])>maxValue){
                 maxRow=m;
                 maxValue=abs(arr2temp[m][k]);
             }
         }
         //交换第k行与第maxrow行
         //遍历每一个元素
         for(m=k;m<=n;m++){
             double temp=arr2temp[k][m];
             arr2temp[k][m]=arr2temp[maxRow][m];
             arr2temp[maxRow][m]=temp;
         }
         for(int i=(k+1); i<n; i++){
             if(abs(arr2temp[k][k])<eps){
                 System.out.println("主元素太小求解失败");
                 break;
             }
             ratio=arr2temp[i][k]/arr2temp[k][k];
             for(int j=(k+1); j<(n+1); j++){
                 arr2temp[i][j]-=ratio*arr2temp[k][j];
             }
             arr2temp[i][k]=0;
         }
     }
        arr[n-1]=arr2temp[n-1][n]/arr2temp[n-1][n-1]; //回代
        for(int i=(n-2); i>=0; --i){
            sum=0.0;
            for(int j=(i+1); j<n; j++){
                sum+=arr2temp[i][j]*arr[j];
                arr[i]=(arr2temp[i][n]-sum)/arr2temp[i][i];
            }
        }
    }

   /**
    * @author: FMm
    * @description: 输出函数
    * @param: n
    * @param: arr 
    * @return: void
    * @create: 2022/3/29 15:28
    */
   
    public static void guass_output (int n,double[] arr) {
      for (int i=0;i<n;i++){
          System.out.println("X["+i+"]"+"="+arr[i]);
      }
    }

}

 输入及输出结果:

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值