C# 列主元素(Gauss)消去法 计算一元多次方程组

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6
  7 namespace zblGauss1
  8 {
  9     class Program
 10     {
 11         static void Main(string[] args)
 12         {
 13             //double[,] a = { { 8.1, 2.3, -1.5, 6.1 }, { 0.5, -6.23, 0.87, 2.3 }, { 2.5, 1.5, 10.2, 1.8 } };
 14             //double[,] a = { { 2, -1, 3, 1 }, { 4, 2, 5, 4 }, { 1, 2, 0, 7 } };
 15             double[,] a = { { 0.01200, 0.01000, 0.1670, 0.6781 }, { 1.000, 0.8334, 5.910, 12.10 }, { 3200, 1200, 4.200, 981.0 } };
 16             int n = a.GetLength(0);//数组a的第一维长度,即行数,3
 17             double[] x = new double[n];//存放解的数组,初始值为0
 18
 19             // Gauss1(n, a, x);//调用Gauss1 方法计算,用顺序高斯消去法计算一元多次方程组
 20             Gauss2(n, a, x);//列主元Gauss消去法
 21             Console.WriteLine("方程的{0}个根为:",n);//输出方程组的根
 22             for (int i = 0; i < n; i++)
 23             {
 24                 Console.Write("x{0}={1,10:F10}, ", i+1, x[i]);
 25             }
 26         }
 27
 28         //利用顺序高斯Gauss消元法求一元多次线性方程组的解
 29         public static void Gauss1(int n, double[,] a, double[] x)//写了一个静态方法,方法可以在别的方法中直接调用,不必声明对象然后调用对象中的方法了
 30         {
 31             Console.WriteLine("-----------利用顺序高斯Gauss消元法求线性方程组的解----------");
 32             Console.WriteLine("要计算的增广矩阵a为:");
 33             printArray(n, a);
 34
 35             //消元过程
 36             for (int k = 0; k < n - 1; k++)//k=0 1 ,弄出来两个主元即可 ,两次大循环,此称为1层循环  ---主元---
 37             {
 38                 for (int i = k; i < n - 1; i++)//每个大循环中   要对主元素下面所有元素变化为零,,  ---行---  ,i= 0 1 ,此称为2层循环
 39                 {
 40                     double m = a[i + 1, k] / a[k, k];//可能用到多次,在此将化零因子放入m中
 41                     for (int j = k; j <= n; j++) //2层循环中要对每行所有元素都做相同变化,   ---列---    ,  j=
 42                     {
 43                         a[i + 1, j] = a[i + 1, j] - m * a[k, j];//由于第一行第一列元素不用化零,故首先从i+1开始,同列所以后面都是j,k处为主元行处
 44                     }
 45                     Console.WriteLine("第{0}个主元第{1}次变换后增广矩阵为:", k, i);
 46                     printArray(n, a);
 47                 }
 48                 Console.WriteLine();
 49             }
 50
 51             //回代过程
 52             for (int k = n - 1; k >= 0; k--) //k=2 1 0 从最后一行开始往前迭代
 53             {
 54                 double addResult = 0.0;//用于存放已知的未知数代入相应式子中之和,换一行计算时需要清零,故放在此处
 55                 for (int j = k; j < n - 1; j++)//j=2   j 最大值为2,每行未知数可能不止一个,故需要遍历已知的未知数并代入
 56                 {
 57                     addResult = addResult + x[j + 1] * a[k, j + 1];//k代表计算的行,j+1代表的列,系数与解要对应,故都为 j+1
 58                 }
 59                 x[k] = (a[k, n] - addResult) / a[k, k];//本行的未知数用本行最右边数-本行已知未知数代入系数之差 再除以本未知数系数
 60             }
 61
 62         }
 63
 64         public static void Gauss2(int n, double[,] a, double[] x)//写了一个静态方法,方法可以在别的方法中直接调用,不必声明对象然后调用对象中的方法了
 65         {
 66             Console.WriteLine("-----------利用顺序高斯Gauss消元法求线性方程组的解----------");
 67             Console.WriteLine("要计算的增广矩阵a为:");
 68             printArray(n, a);
 69
 70             //消元过程
 71             for (int k = 0; k < n - 1; k++)//k=0 1 ,弄出来两个主元即可 ,两次大循环,此称为1层循环  ---主元---
 72             {
 73                 selectMainElement(n, k, a); // 选择主元素
 74                 Console.WriteLine("------------第{0}个主元选择主元素后的增广矩阵为:---------------",k,a);
 75                 printArray(n, a);
 76                 Console.WriteLine();
 77                 for (int i = k; i < n - 1; i++)//每个大循环中   要对主元素下面所有元素变化为零,,  ---行---  ,i= 0 1 ,此称为2层循环
 78                 {
 79                     double m = a[i + 1, k] / a[k, k];//可能用到多次,在此将化零因子放入m中
 80                     for (int j = k; j <= n; j++) //2层循环中要对每行所有元素都做相同变化,   ---列---    ,  j=
 81                     {
 82                         a[i + 1, j] = a[i + 1, j] - m * a[k, j];//由于第一行第一列元素不用化零,故首先从i+1开始,同列所以后面都是j,k处为主元行处
 83                     }
 84                     Console.WriteLine("第{0}个主元第{1}次变换后增广矩阵为:", k, i);
 85                     printArray(n, a);
 86                 }
 87                 Console.WriteLine();
 88             }
 89
 90             //回代过程
 91             for (int k = n - 1; k >= 0; k--) //k=2 1 0 从最后一行开始往前迭代
 92             {
 93                 double addResult = 0.0;//用于存放已知的未知数代入相应式子中之和,换一行计算时需要清零,故放在此处
 94                 for (int j = k; j < n - 1; j++)//j=2   j 最大值为2,每行未知数可能不止一个,故需要遍历已知的未知数并代入
 95                 {
 96                     addResult = addResult + x[j + 1] * a[k, j + 1];//k代表计算的行,j+1代表的列,系数与解要对应,故都为 j+1
 97                 }
 98                 x[k] = (a[k, n] - addResult) / a[k, k];//本行的未知数用本行最右边数-本行已知未知数代入系数之差 再除以本未知数系数
 99             }
100
101         }
102         public static void printArray(int n, double[,] a)
103         {
104             for (int i = 0; i < n; i++)
105             {
106                 for (int j = 0; j <= n; j++)
107                 {
108                     Console.Write("{0,15:F6}", a[i, j]);
109                 }
110                 Console.WriteLine();
111             }
112         }
113
114         /// <summary>
115         /// selectMainElement 用来选择出第k个主元及其所在列下面所有元素中最大的元素作为主元
116         /// </summary>
117         /// <param name="n">传递过来的矩阵a的行数</param>
118         /// <param name="k">现在主元所在行数</param>
119         /// <param name="a">传递过来的用来处理的矩阵</param>
120         public static void selectMainElement(int n, int k, double[,] a)
121         {
122             double t, mainElement;// mainElement用于保存主元素的值
123             int l;// 用于保存主元素所在的行号
124             mainElement = Math.Abs(a[k, k]);  // 注意别忘了取绝对值
125             // 从第k行到第n行寻找第k列的主元素,记下主元素mainElement和所在的行号l
126             l = k;
127             for (int i = k + 1; i < n; i++)
128             {
129                 if (mainElement < Math.Abs(a[i, k]))
130                 {
131                     mainElement = Math.Abs(a[i, k]);
132                     l = i;                        // 记下主元素所在的行号
133                 }
134             }
135             // l是主元素所在的行。将l行与k行交换,每行前面的k个元素都是0,不必交换
136             if (l != k)
137             {
138                 for (int j = k; j <= n; j++)
139                 {
140                     t = a[k, j]; a[k, j] = a[l, j]; a[l, j] = t;
141                 }
142             }
143         }
144
145
146     }
147 }

方法是在第k次消元之前,先对增广矩阵作第一种初等行变换,目的是把此主元所在列中找到包括主元在内及其下面元素中最大值作为新的主元,新主元与原先主元所在行交换,然后再用消去法,然后再计算。

时间: 2024-10-02 22:16:12

C# 列主元素(Gauss)消去法 计算一元多次方程组的相关文章

高斯列主元素消去法解多元一次方程组

1.Gauss消去法及列主元素消去法算法介绍 2.c#源码 1 /******************************** 2 高斯列主元素消去法解多元一次方程组 3 * 4 * 例如 方程组 5 * x+y+z=7 6 * 2x+y-z=6 7 * x-y-2z=4 8 * 9 * 矩阵阶数N=3 10 * a[N,N]为1 1 1 11 * 2 1 -1 12 * 1 -1 -2 13 * b[N]为 7 14 * 6 15 * 4 16 **********************

Gauss消去法求线性方程组

给定线性方程组的系数,求解方程组是否有解. 1,找到系数矩阵行列为(k, k)的块绝对值最大的数作为主元,记下行和列,分别与第k列交换,与第k行交换,(行跟行交换,列跟列交换). 2,交换后,主元所在的行每一个元除以主元的值,使得主元所在的位置为1,常数列也除以主元的值. 3,进行初等行变换,使得主元所在的列的其他元为0. 4,判断系数矩阵和增广矩阵的秩是否相同,相同,有解,不相同,无解. 下面的是代码: #include <cmath> #include <iostream> #

解一元同余方程组

2016.1.26 试题描述 给定n个一次同余方程x mod mi=ai,这里i=0,1,2,……,n-1,给定数据保证所有的mi两两互素.求该方程组的解. 输入 第一行包含一个正整数n,接下来的n行,每行包括两个整数,对应一个同余方程,第一个数为mi,第二个数为ai,两数间用一个空格分隔. 输出 一个数,表示方程组的解. 输入示例 33 25 37 2 输出示例 23 其他说明 数据范围:所有给定的数据均在int32范围内,且保证所有的数据都符合题目描述的要求,结果在long long范围内.

高斯消去、追赶法 matlab

1. 分别用Gauss消去法.列主元Gauss消去法.三角分解方法求解方程组 程序: (1)Guess消去法: function x=GaussXQByOrder(A,b) %Gauss消去法 N = size(A); n = N(1); x = zeros(n,1); for i=1:(n-1) for j=(i+1):n if(A(i,i)==0) disp('对角元不能为0'); return; end m = A(j,i)/A(i,i); A(j,i:n)=A(j,i:n)-m*A(i,

弦截法求一元三次方程的近似解

1 #include<stdio.h> 2 #include<math.h> 3 4 //计算一元三次方程的根大致分布位置 5 6 //计算的方程为 x*x*x-8*x*x+12*x-30=0 7 8 //计算函数值 9 float f(float x) 10 { 11 return ((x-8.0)*x+12.0)*x-30.0; 12 } 13 14 //计算弦与坐标x轴的交点 15 16 float xpoint(float x1,float x2) 17 { 18 retu

ffmpeg文档08-表达式计算/求值

8 表达式计算/求值 在计算表达式时,ffmpeg通过libavutil/eval.h接口调用内部计算器进行计算. 表达式可以包含一元运算符.运算符.常数和函数 两个表达式expr1和expr2可以组合起来成为"expr1;expr2" ,两个表达式都会被计算,但是新表达式(组合起来的)值实为表达式expr2的值. 表达式支持的二元运算符有:+,-,*,/,^ 一元运算符:+,- 以及下面的函数: abs(x) 返回x的绝对值. acos(x) 计算x反余弦 . asin(x) 计算x

计算圆周率的C程序

这是很早以前用C语言写的一个计算圆周率的程序,  算法是用泰勒公式计算反正切值.在命令行不跟参数执行该程序则使用Gauss公式计算前1000位圆周率的值,如果带一个命令行参数,则该值为要计算的位数.如果还有第二个命令行参数,则使用Stomer公式计算,可作为验算.因为该程序只涉及到纯数学计算,可以在Linux.Unix.Windows等操作系统下编译并运行.当时写这个程序时,int是2个字节的,现在大多数的C编译器int都是4个字节,不过这不影响程序的正确性. #include <stdio.h

Python一日一练03----一元二次方程的计算

要求 由用户随意给定一元二次方程系数a.b.c,计算一元二次方程的解 源码 import cmath #包含复数运算 import math import sys def get_float(msg, allow_zero): x = None while x is None: try: x = float(input(msg)) if not allow_zero and abs(x) < sys.float_info.epsilon: #sys.float_info.epsilon是浮点数0

一元N次方程的字符串形式导数输出

代码如下  .........网上给出的求导数的方法是数值方法,这个方法是字符串方法 public class SystemMathTools { /* *  还不是很完善,需要进一步修改...     *      *  x*x+3*x+1      *  一元N次方程组的导数,给出字符串变量的导数形式,用导数公式来生成导数     *     *  DerivedFunction(原函数)     *  输出 导数函数     *  n*x*x+n*x+1 类似这种一元N次方程的导数,先计算