c++ 高斯消元算法实现

c++有回代消元和无回代消元的算法

在工程技术和工程管理中有许多问题经常可以归结为线性方程组类型的数学模型,这些模型中方程和未知量个数常常有多个,而且方程个数与未知量个数也不一定相同。那么这样的线性方程组是否有解呢?如果有解,解是否唯一?若解不唯一,解的结构如何呢?

高斯消元即是用矩阵求解方程组的方法

如下是高斯消元的c++代码,包含求解步骤的注释,看代码和注释更直观:

/*

使用方法

const int N=4;

double A[N][N + 1];

double X[N];

N代表N阶线性方程组

通过调用GaussFun函数,A为输入的线性方程的矩阵形式

| A00 A01 A02 A03 | | X0 | | A04 |

| A10 A11 A12 A13 | | X1 | = | A14 |

| A20 A21 A22 A23 | | X2 | | A24 |

| A30 A31 A32 A33 | | X3 | | A34 |

行列式结构如上所示 x0,x1,x2,x3为所求的值

A00-A03、A10-A13、A20-A23、A30-A33 为行列式系数

A04、A14、A24、A34 为常数项

*/

// 高斯消去法一般步骤:

// 按照左上角开始,按照对角线进行循环:

// 1、将列的绝对值最大的数作为主元,并且将该行调整到对角线上(提高精度);

// 2、主元所在的行除以主元,使得主元=1;

// 3、进行高斯消元,将主元所在的列的其他行的数变为0(消元),这个过程按照下式对非主元的其他行的系数进行更新;

#include <iostream>

#include <locale.h>

#include <string>

#include <vector>

#include <stdio.h>

#include <sstream>

#include<math.h>

using namespace std;

const int MAXN = 100;//最大求解方程数

int N; //实际求解方程数

double A[MAXN][MAXN + 1];//增广矩阵

double arr[4][5] = { {8,2,1,2.5,1.5},{1,8,-0.5,2,-3},{1.5,2,8,-1,-4.5},{1,0.5,0.7,8,3.2} };//测试数据

double X[MAXN];//解

char equation;

//要完成的工作

void Input(); //输入方程组

void InputTest();//使用测试数据

void Display();//显示求解方程组

void DisplayResult();//输出解

void FindMain(int i);//寻找第i列主元,并将其所在的行交换到当前处理行位置上

void DivMain(int i); //将主元所在的行的各个系数除以主元,当前主元为1

void Del(int i);//进行第i列消元

void GaussFun();//高斯消元

void print2D(double a[100][101],int row,int col); //矩阵打印

//====================主函数===========================

int main()

{
char ch;

while (1) {

//Input(); //手动输入时放开该行

InputTest();//使用测试数据(需要手动输入时注释掉该行)

Display();

GaussFun();

DisplayResult();

cout << "是否要继续求解其他方程组?(Y/N)";

cin >> ch;

if (ch == 'N') break;

}

return 0;

}
void InputTest() //使用测试数据

{
N = 4;

for (int i = 0; i < N; i++)

for (int j = 0; j < N + 1; j++)

A[i][j] = arr[i][j];
}

void Input()//输入基本数据
{
cout << "请输入实际求解方程数:";
cin >> N ;

cout << "开始输入方程组(每个方程组元素用英文逗号分隔,回车输入下一个方程,输完最后一个方程组自动结束,进行计算):" << endl;

vector<double> nums;

string str_input;

stringstream ss;

for (int i = 0; i < N; i++)

{

ss << i+1;//int值传给stringstream

string out_string = ss.str();//stringstream转string类型

printf("输入第 %s 个方程组:",out_string.c_str());

ss.str("");

cin >> str_input;

char *s_input = (char *)str_input.c_str();

const char * split = ",";

// 以逗号为分隔符拆分字符串

char *p = strtok(s_input, split);

int a;

while(p != NULL)

{

// char * -> int

sscanf(p, "%d", &a);

nums.push_back(a);

p=strtok(NULL, split);

}

//将输入值放进增广矩阵

//cout<<"输出得到的数字:"<<endl;

for(a = 0; a < nums.size(); a++)

{

A[i][a] = nums[a];

// cout << A[i][a] << endl;

}

nums.clear();

}

}

  
void print2D(double a[100][101],int row,int col)//矩阵打印

{

int i,j;

for(i = 0; i < row;i++)

{

for(j = 0;j < col;j++)

cout<<a[i][j]<<" ";

cout<<endl;

}

}

  
void GaussFun()//高斯消元

{

for (int i = 0; i < N; i++) //按行处理

{

if (i < N - 1) //寻找主元,交换到适应位置上

FindMain(i);

DivMain(i);

if (i < N - 1) //进行消元处理

Del(i);

}

for (int i = N - 2; i >= 0; i--) //回代过程

for (int j = N - 1; j > i; j--)

A[i][N] -= A[i][j] * A[j][N];

for (int i = 0; i < N; i++)

X[i] = A[i][N];

cout << "求解完毕!" << endl;

}

void GaussFunWhd()//无回代高斯消元

{

for(int i = 0; i < N; ++i) //i:行

{

if(i < N - 1) FindMain(i);

divmain(i);

Del(i);

}

for(int i = 0; i < N; ++i) X[i] = A[i][N];//保存解

cout << "求解完毕!" << endl;

}

void divmain(int i) //主元所在系数行除以主元,使得主元=1

{

int j;

float c;

c = A[i][i];

A[i][i] = 1.0;

for(j = i+1; j < N+1; j++) A[i][j] /= c;

}

void Display() //显示求解方程组

{
cout << "求解方程组为:" << endl;

print2D(A,N,N+1);

}

void DisplayResult()//输出解

{

cout << "求解结果为:" << endl;

for(int i = 0; i < N;i++)

{

cout << "X"+to_string(i+1)+"="+ to_string(X[i]);

if (i+1!=N)

{

cout << ",";

}else{

cout << endl;

}

}

//X[MAXN]

}

void FindMain(int i)//寻找第i列主元,并将其所在的行交换到当前处理行位置上

{

int j,k;

float c;

c = fabs(A[i][i]); k=i;//初始化主元

for(j=i+1; j<N; j++) //向下寻找绝对值最大的行

{

if(fabs(A[j][i]>c))

{

c = fabs(A[j][i]);

k = j;

}

}

if(k!=i)

{

for(j = 0; j <= N; j++) //将主元所在行交换到当前处理行位置

{

c = A[k][j];

A[k][j] = A[i][j];

A[i][j] = c;

}

}

  
  


}

void DivMain(int i) //将x

{

int j;

float c;

c = A[i][i];

A[i][i] = 1.0;

for(j = i+1; j < N+1; j++){

A[i][j] /= c;

}

}

void Del(int i)//进行第i列消元

{

int j, k;

float c;

for(j=0; j < N; j++)

{

if(j != i && A[j][i] != 0)//只处理i行外不等于0的行(j:行坐标)

{

c = A[j][i];

A[j][i] = 0;

for(k = i+1; k < N+1; k++){

A[j][k] -= c*A[i][k];//调整同行的其他系数

}

}

}

}

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
高斯消元算法是一种线性方程组求解方法,可以通过将系数矩阵化为一个上三角矩阵,从而求解出未知数的值。 以下是使用C++实现高斯消元算法的示例代码: ```c++ #include <iostream> using namespace std; const int N = 100; int main() { int n; // 系数矩阵的行数(也是列数) double a[N][N], b[N]; // 系数矩阵和常数向量 double ans[N]; // 存储解向量 // 输入系数矩阵和常数向量 cout << "请输入系数矩阵和常数向量:" << endl; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) cin >> a[i][j]; cin >> b[i]; } // 高斯消元 for (int k = 0; k < n; k++) // 第k列 { int p = k; for (int i = k; i < n; i++) // 选主元 if (abs(a[i][k]) > abs(a[p][k])) p = i; if (p != k) // 交换第k行和第p行 { for (int j = k; j < n; j++) swap(a[k][j], a[p][j]); swap(b[k], b[p]); } for (int i = k + 1; i < n; i++) // 消元 { double f = a[i][k] / a[k][k]; for (int j = k + 1; j < n; j++) a[i][j] -= f * a[k][j]; b[i] -= f * b[k]; } } // 回带求解 for (int i = n - 1; i >= 0; i--) { ans[i] = b[i]; for (int j = i + 1; j < n; j++) ans[i] -= a[i][j] * ans[j]; ans[i] /= a[i][i]; } // 输出解向量 cout << "解向量为:" << endl; for (int i = 0; i < n; i++) cout << ans[i] << " "; return 0; } ``` 在上面的代码中,我们首先输入系数矩阵和常数向量,然后执行高斯消元算法,将系数矩阵化为一个上三角矩阵。接着,我们使用回带法求解未知数的值,并将结果输出。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mldxxxxll5

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值