ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

线性方程组求解

线性方程组求解 经典问题用高斯约当算法求解线性方程组。这里要求对任意形式的线性方程组都能够妥善处理不能只适用于方程个数和未知量数目相等的特殊情形。先用循环结构将增广矩阵转换为阶梯形矩阵循环结束时得到阶梯型矩阵非零行行数同时得到一个链表其中存放有各非零行主元的列标列标在链表中按从左到右的顺序依次递减。然后根据线性代数中线性方程组的解的情况及判别准则判断方程是否有解有多少个解。当线性方程组有解时需要用convert函数将其转换为简化行阶梯型矩阵然后输出唯一解或一般解更新:定义了新的有理数类,使得求解算法可以处理方程中常数项为有理数情形:C语言代码如下#include stdio.h #include malloc.h #include cmath #include vector #include RationalNumber.h using std::vector; struct maincol { int col; //存放各主元下标的结构体类型 struct maincol* next; }; typedef struct maincol mc1; int test(int s, int t, vectorvectorRationalNumber a, int _j, const RationalNumber zero); //判断增广矩阵的s行至M行与t列至N列相交形成的子矩阵是否为零矩阵若是返回0若不是返回第一个不为零的列的列标 void add(mc1* head, int col, mc1** tail); //函数用于新建一节点其中保存有主元col列标然后按递减顺序将其插入maincol类型的链表 void convert(vectorvectorRationalNumber a, int row, mc1* head); //函数用于将阶梯型矩阵转化为简化行阶梯形矩阵 #define N 5 //增广矩阵列数 #define M 3 //增广矩阵行数 int main() { int matrix[M][N] { {2, 1, -3, 5, 6}, {-3, 2, 1, -4, 5}, {-1, 3, -2, 1, 11} }; //增广矩阵 int i, j; int row, col; //子矩阵左上角元素行列下标,循环结束后row用于存放阶梯形矩阵非零行行数 RationalNumber swap; mc1* head, * tail, * psnew; vectorvectorRationalNumber a(M, vectorRationalNumber(N)); for (i 0; i M; i) { for (j 0; j N; j) { a[i][j] RationalNumber(matrix[i][j], 1); } } head (mc1*)malloc(sizeof(mc1)); head-next NULL; tail head; row col 1; //子矩阵即为增广矩阵本身用增广矩阵左上角元素行列标初始化s,t RationalNumber zero(0, 1); while ((col test(row, col, a, j, zero)) ! 0) //子矩阵不为零矩阵 { if (row M) //增广矩阵已化为阶梯形矩阵 { add(head, col, tail); //最后一个非零行主元列标放入maincol类型链表 break; //结束循环 } else { int temp_j j; for (i j 1; i M; i) { if (a[j][col - 1].abs() a[i][col - 1].abs()) //列选主元 j i; } if (row - 1 ! j) { for (i col - 1; i N; i) { swap a[j][i]; a[j][i] a[row - 1][i]; //列选主元 a[row - 1][i] swap; } } if (col N) //增广矩阵已经化为阶梯形矩阵 { add(head, col, tail); //最后一个非零行主元列标放入maincol类型链表 break; //结束循环 } if (temp_j row - 1) temp_j; for (j temp_j; j M; j) { if (a[j][col - 1] ! zero) { a[j][col - 1] -(a[j][col - 1] / a[row - 1][col - 1]); for (i col; i N; i) //消元 { if (a[row - 1][i] ! zero) { a[j][i] a[j][col - 1] * a[row - 1][i] a[j][i]; } } } } add(head, col, tail); //将消元后得到的主元列标col放入maincol类型链表 row; col; //更新s,t,使s,t成为消元后得到的新的子矩阵的左上角元素行列标,为test函数操作新的子矩阵作准备 } } if (col 0) //从循环控制条件退出循环 --row; //此时增广矩阵已成为阶梯形矩阵,非零行函数就是row-1 if (row 0) //利用线性方程组解的判别准则判断是否有解有多少个解 { printf(线性方程组有无穷多组解\n); //增广矩阵为零矩阵无穷多组解 printf(一般解:\n); for (i 1; i N; i) printf(x%dt%d\n, i, i); //输出解 } else { psnew head-next; if (psnew-col N) //阶梯形矩阵最后一主元在最后一列无解 printf(线性方程组无解\n); else { convert(a, row, head); //用convert函数将阶梯形矩阵进一步化为简化行阶梯形矩阵 if (row N - 1) //非零行行数等于未知量个数有唯一解 { printf(线性方程组有唯一解:\n); for (i 1; i row; i) std::cout x i a[i - 1][N - 1] std::endl;//输出唯一解 } else //非零行行数小于未知量个数有无穷多组解 { int* m; m (int*)malloc((N - 1 - row) * sizeof(int)); i N - 1 - row; for (j N - 1; j 1; j--) { if (j ! psnew-col) { m[--i] j; //从所有未知量标号中筛选出自由未知量标号 if (i 0) break; } else { if (psnew-next ! NULL) psnew psnew-next; } } printf(线性方程组有无穷多组解\n); printf(一般解:\n); i row; for (psnew head-next; psnew ! NULL; psnew psnew-next) { std::cout x psnew-col a[i - 1][N - 1]; //输出一般解 for (j 0; j N - 1 - row; j) { if (m[j] psnew-col) { printf(-%dx%d, 0, m[j]); } else { std::cout - a[i - 1][m[j] - 1] x m[j]; } } printf(\n); i--; } } } } return 0; } int test(int s, int t, vectorvectorRationalNumber a, int _j, const RationalNumber zero) //判断增广矩阵的s行至M行与t列至N列相交形成的子矩阵是否为零矩阵若是返回0若不是返回第一个不为零的列的列标 { int i, j; for (j t - 1; j N; j) { for (i s - 1; i M; i) { if (a[i][j] ! zero) { _j i; return (j 1); } } } return (0); } void add(mc1* head, int col, mc1** tail) //函数用于新建一节点其中保存有主元col列标然后按递减顺序将其插入maincol类型的链表 { mc1* psnew; psnew (mc1*)malloc(sizeof(mc1)); psnew-col col; if (head-next NULL) { psnew-next NULL; head-next psnew; *tail psnew; } else { psnew-next head-next; head-next psnew; } } void convert(vectorvectorRationalNumber a, int row, mc1* head) //函数用于将阶梯型矩阵转化为简化行阶梯形矩阵 { mc1* psnew, * pq; int i, j, k, m; RationalNumber one(1, 1); RationalNumber zero(0, 1); psnew head-next; for (i row - 1; i 0; i--) { if (a[i][psnew-col - 1] ! one) //各非零行主元化为1 { for (j psnew-col; j N; j) a[i][j] a[i][j] / a[i][psnew-col - 1]; } psnew psnew-next; } psnew head-next; //向上消元把除第一个主元外其余主元所在列中在主元上方的部分变为零 for (i row - 1; i 1; i--) { m N - psnew-col - (row - i - 1); //获取未知量标号1,2,--,N-1中位于i1非零行主元列标号右边的自由未知量标号个数 pq head-next; //pq指向存放最后一个非零行主元列标号的节点 for (k N; k psnew-col; k--) { if (k ! pq-col) { if (a[i][k - 1] ! zero) { for (j i - 1; j 0; j--) { if (a[j][psnew-col - 1] ! zero) { a[j][k - 1] -(a[i][k - 1] * a[j][psnew-col - 1]) a[j][k - 1]; //从右向左作初等行变换直至i1行主元所在列右边的列位置期间跳过i2----row行主元所在的列 } } } m--; if (m 0) break; } else { if (pq-next ! psnew) pq pq-next; } } psnew psnew-next; //递进至上一行主元为新一轮向上消元作准备 } }RationalNumber.h内容如下:#pragma once #include iostream #include cmath #include algorithm class RationalNumber { public: RationalNumber(long long m, long long d); RationalNumber() default; long long computeGCD(); bool operator(const RationalNumber opNum); bool operator(const RationalNumber opNum); bool operator(const RationalNumber opNum); bool operator(const RationalNumber opNum); bool operator(const RationalNumber opNum); bool operator!(const RationalNumber opNum); RationalNumber operator(const RationalNumber opNum); RationalNumber operator-(const RationalNumber opNum); RationalNumber operator*(const RationalNumber opNum); RationalNumber operator/(const RationalNumber opNum); RationalNumber operator-() { RationalNumber t *this; t.positive !t.positive; return t; } RationalNumber abs() { RationalNumber t *this; t.positive true; return t; } public: bool positive; long long molecule; long long denominator; }; std::ostream operator(std::ostream out, const RationalNumber output) { if (output.positive false output.molecule ! 0) out -; if (output.molecule 0) out 0; else { if (output.denominator 1) out output.molecule; else out output.molecule / output.denominator; } return out; } bool RationalNumber::operator(const RationalNumber opNum) { if (molecule 0) { if (opNum.molecule 0) { return false; } else { if (opNum.positive) return true; return false; } } else { if (opNum.molecule 0) { if (positive false) return true; return false; } else { if (!positive opNum.positive) { return true; } else if (positive !opNum.positive) { return false; } else if (positive) { if (denominator opNum.denominator) { return molecule opNum.molecule; } else { if (molecule opNum.molecule) return denominator opNum.denominator; if (molecule opNum.molecule denominator opNum.denominator) return true; if (molecule opNum.molecule denominator opNum.denominator) return false; return molecule * opNum.denominator opNum.molecule* denominator; } } else { if (denominator opNum.denominator) { return molecule opNum.molecule; } else { if (molecule opNum.molecule) return denominator opNum.denominator; if (molecule opNum.molecule denominator opNum.denominator) return false; if (molecule opNum.molecule denominator opNum.denominator) return true; return molecule * opNum.denominator opNum.molecule * denominator; } } } } } bool RationalNumber::operator(const RationalNumber opNum) { return !operator(opNum); } bool RationalNumber::operator(const RationalNumber opNum) { if (molecule 0) { if (opNum.molecule 0) { return false; } else { if (opNum.positive) return false; return true; } } else { if (opNum.molecule 0) { if (positive false) return false; return true; } else { if (!positive opNum.positive) { return false; } else if (positive !opNum.positive) { return true; } else if (positive) { if (denominator opNum.denominator) { return molecule opNum.molecule; } else { if (molecule opNum.molecule) return denominator opNum.denominator; if (molecule opNum.molecule denominator opNum.denominator) return false; if (molecule opNum.molecule denominator opNum.denominator) return true; return molecule * opNum.denominator opNum.molecule * denominator; } } else { if (denominator opNum.denominator) { return molecule opNum.molecule; } else { if (molecule opNum.molecule) return denominator opNum.denominator; if (molecule opNum.molecule denominator opNum.denominator) return true; if (molecule opNum.molecule denominator opNum.denominator) return false; return molecule * opNum.denominator opNum.molecule* denominator; } } } } } bool RationalNumber::operator(const RationalNumber opNum) { return !operator(opNum); } bool RationalNumber::operator(const RationalNumber opNum) { if (molecule 0) { if (opNum.molecule 0) { return true; } else { return false; } } else { if (opNum.molecule 0) { return false; } else { if (!positive opNum.positive || positive !opNum.positive) { return false; } else { if (denominator opNum.denominator) { return molecule opNum.molecule; } else if (molecule opNum.molecule) { return false; } else { return molecule * opNum.denominator opNum.molecule * denominator; } } } } } bool RationalNumber::operator!(const RationalNumber opNum) { return !operator(opNum); } RationalNumber RationalNumber::operator/(const RationalNumber opNum) { if (opNum.molecule 0) { std::cout Error,除数不能为零! std::endl; exit(-1); } if (molecule 0) return RationalNumber(0, 1); RationalNumber temp opNum; std::swap(temp.molecule, temp.denominator); return operator*(temp); } RationalNumber RationalNumber::operator*(const RationalNumber opNum) { if (molecule 0 || opNum.molecule 0) { return RationalNumber(0, 1); } if (positive !opNum.positive || !positive opNum.positive) { return RationalNumber(-(molecule * opNum.molecule), denominator * opNum.denominator); } else { return RationalNumber(molecule * opNum.molecule, denominator * opNum.denominator); } } RationalNumber RationalNumber::operator-(const RationalNumber opNum) { RationalNumber temp opNum; temp.positive !temp.positive; return operator(temp); } RationalNumber RationalNumber::operator(const RationalNumber opNum) { if (molecule 0) { return opNum; } if (opNum.molecule 0) { return *this; } if (denominator opNum.denominator) { if (positive) { if (opNum.positive) { return RationalNumber(molecule opNum.molecule, denominator); } else { return RationalNumber(molecule - opNum.molecule, denominator); } } else { if (opNum.positive) { return RationalNumber(opNum.molecule - molecule, denominator); } else { return RationalNumber(-(opNum.molecule molecule), denominator); } } } if (positive) { if (opNum.positive) { return RationalNumber(molecule * opNum.denominator opNum.molecule * denominator, denominator * opNum.denominator); } else { return RationalNumber(molecule * opNum.denominator - opNum.molecule * denominator, denominator * opNum.denominator); } } else { if (opNum.positive) { return RationalNumber(opNum.molecule * denominator - molecule * opNum.denominator, denominator * opNum.denominator); } else { return RationalNumber(-(opNum.molecule * denominator molecule * opNum.denominator), denominator * opNum.denominator); } } } long long RationalNumber::computeGCD() { long long d denominator; long long m molecule; while (m ! 0) { long long temp m; m d % m; d temp; } return d; } RationalNumber::RationalNumber(long long m, long long d) { if (d 0) { std::cout ERROR,分母不能为零! std::endl; exit(-1); } if (m 0 d0 || m 0 d 0) { positive false; } else { positive true; } denominator std::abs(d); molecule std::abs(m); if (molecule ! 0) { if (molecule 1 denominator 1) { unsigned long long gcd computeGCD(); denominator / gcd; molecule / gcd; } } }
返回列表