高斯消元法求解方程组

来源:互联网 发布:淘宝夜店装 编辑:程序博客网 时间:2024/05/23 16:41

    • 引子
      • 高斯消元法简介
      • 引例
    • 求解过程
    • 编程实现高斯消元法C

1. 引子

1. 高斯消元法简介

数学上,高斯消元法(Gaussian Elimination),是线性代数规划中的一个算法,可用来为线性方程组求解。

2. 引例

求解如下方程组:

2x+3y+z=4x2y+4z=53x+8y2z=13

2. 求解过程

可以将方程组和矩阵联系起来。如下:

2x+3y+z=11x2y+3z=63x+8y2z=13(1)(2)(3)

21332813211613(广)

(1)2(2)33(2) 得:

x2y+3z=67y5z=114y11z=5(4)(5)(6)

10027143511615

(6)2(7) 得:

x2y+3z=67y5z=1z=3(7)(8)(9)

100270351613()

还可以进一步简化:

x2y+3z=6y57z=17z=3(7)(8)(9)

10021035716173()

(7)+2(8)(8)+57(9) 继续进行化简:

x=1y=2z=3(7)(8)(9)

100010001123()

可见,当增广矩阵简化为标准形后,解即为矩阵最后一列的值。因此,我们可以脱离原方程组,对矩阵进行化简,得到方程组的解。

3. 编程实现高斯消元法(C#)

    using System.Collections.Generic;    using System.Linq;    namespace GaussianEliminationLib    {        public static class GaussianElimination        {            public static List<double> Resolve(IEnumerable<IEnumerable<double>> equationSet)            {                // 存储方程组矩阵                List<List<double>> equationSetList = new List<List<double>>();                foreach(IEnumerable<double> equation in equationSet)                {                    equationSetList.Add(equation.ToList());                }                for (int i = 0; i < equationSetList.Count; ++i)                {                    // 化简成行最简形                    Simplitify(equationSetList, i, i);                }                // 化简成标准形                return SimplitifyAgain(equationSetList);            }            private static void Simplitify(List<List<double>> equationSet, int rowStart, int colStart)            {                // 选择当前列最大行                int pivotRow = FindPivotRow(equationSet, rowStart, colStart);                SwapRows(equationSet, rowStart, pivotRow);                int cols = equationSet[rowStart].Count;                double maxValue = equationSet[rowStart][colStart];                for (int i = rowStart; i < equationSet.Count; ++i)                {                    for (int j = colStart; j < cols; ++j)                    {                        equationSet[i][j] /= maxValue;                    }                }                for (int i = rowStart + 1; i < equationSet.Count; ++i)                {                    double primer = equationSet[i][colStart];                    for (int j = colStart; j < cols; ++j)                    {                        equationSet[i][j] -= primer * equationSet[rowStart][j];                    }                }            }            private static List<double> SimplitifyAgain(List<List<double>> equationSet)            {                int solutionsCount = equationSet.Count;                List<double> solutions = new List<double>(solutionsCount);                for (int i = 0; i < equationSet.Count; ++i)                {                    solutions.Add(0.0);                }                for (int i = equationSet.Count - 1; i >= 0; --i)                {                    double value = 0.0;                    for (int j = 0; j < solutionsCount; ++j)                    {                        value += solutions[j] * equationSet[i][j];                    }                    solutions[i] = equationSet[i][equationSet.Count] - value;                }                return solutions;            }            private static int FindPivotRow(List<List<double>> equationSet, int rowStart, int col)            {                int row = rowStart;                double value = equationSet[rowStart][col];                for (int i = rowStart; i < equationSet.Count(); ++i)                {                    if (value < equationSet[i][col])                    {                        row = i;                        value = equationSet[i][col];                    }                }                return row;            }               private static void SwapRows(List<List<double>> equationSet, int currentRow, int pivotRow)            {                List<double> row = equationSet[currentRow];                equationSet[currentRow] = equationSet[pivotRow];                equationSet[pivotRow] = row;            }        }    }