using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Console.Title = "多元一次方程高斯消元列主消元计算";
Console.WindowWidth = 80;
Console.BufferHeight = 100;
//float[,] c = new float[,]
//{
//{ 1, 1, 1,6},
//{ 1, 3, -2 ,1},
//{ 2, -2, 1 ,1}
//};
//float[] res = LieZhuXiaoYuan(c);
while(true)
{
float[,] d = read();
Console.Write("\n\n高斯消元计算\n\n");
GaosiXiaoYuan(d);
Console.Write("\n\n列主消元计算\n\n");
LieZhuXiaoYuan(d);
}
}
private static float[,] read()
{
Console.Write("\n\n\n\n\n");
Console.Write("多元一次方程高斯消元列主消元计算\n");
Console.Write("|-----------------------------\n");
Console.Write("|1.1348 3.8326 1.1651 3.4017 9.5342\n");
Console.Write("|0.5301 1.7875 2.5330 1.5435 6.3941\n");
Console.Write("|3.4129 4.9317 8.7643 1.3142 18.4231\n");
Console.Write("|1.2371 4.9998 10.6721 0.0147 16.9237\n");
Console.Write("|-----------------------------\n");
Console.Write("|请输入系数0,计算例题,如:\n");
string ch = Console.ReadLine();
if(ch == "0")
{
float[,] exp = new float[,]
{
{ 1.1348F, 3.8326F, 1.1651F, 3.4017F, 9.5342F},
{ 0.5301F, 1.7875F, 2.5330F, 1.5435F, 6.3941F},
{ 3.4129F, 4.9317F, 8.7643F, 1.3142F, 18.4231F},
{ 1.2371F, 4.9998F, 10.6721F, 0.0147F, 16.9237F}
};
return exp;
}
else
{
Console.Write("|请输入系数矩阵行列数目,如:4 5\n");
string input = Console.ReadLine();
string[] inputnum = input.Split(' ');
int _rows = Int32.Parse(inputnum[0]);
int _cols = Int32.Parse(inputnum[1]);
float[,] data = new float[_rows, _cols];
Console.Write("|请输入系数矩阵行列,如:上面例子\n");
for (int i = 0; i < _rows; i++)
{
input = Console.ReadLine();
inputnum = input.Split(' ');
for (int j = 0; j < _cols; j++)
{
data[i, j] = float.Parse(inputnum[j]);
data[i, j] *= 1;
}
}
return data;
}
}
private static void PrintProc(float[,] a, int k)
{
Console.Write(string.Format("第{0}次消元结果如下:" + Environment.NewLine, k + 1));
for (int i = 0; i < a.GetLength(0); i++)
{
string tt = "";
for (int j = 0; j < a.GetLength(1); j++)
{
tt += string.Format("{0:N7}\t", a[i, j]);
}
Console.Write(tt);
}
}
private static void Print(float[] x)
{
Console.Write("结果为:" + Environment.NewLine);
for (int i = 0; i < x.GetLength(0); i++)
{
Console.Write(string.Format("x{0}= {1:N7}" + Environment.NewLine, i, x[i]));
}
}
static float[] GaosiXiaoYuan(float[,]c)
{
float[,] a = new float[c.GetLength(0),c.GetLength(1)];
Array.Copy(c, a, c.GetLength(0)*c.GetLength(1));
int _rows = a.GetLength(0);
int _cols = a.GetLength(1);
float[,] m = new float[_rows, _cols];
float[] x = new float[_rows];
//消元计算
for (int k = 0; k < _rows - 1; k++)
{
for (int i = k; i < _cols - 1; i++)
{
m[i,k] = a[i,k] / a[k,k];
for (int j = k; j < _cols; j++)
{
a[i,j] -= m[i,k] * a[k,j];
}
}
//for (int i = k + 1; i <= n; i++)
//{
// b[i] -= m[i,k] * b[k];
//}
PrintProc(a,k);//输出中间计算过程
}
//回代求解
//x[n] = b[n] / a[n,n];
for (int i = _rows - 1; i > 0; i--)
{
x[i] = a[i, _cols - 1];
for (int j = i + 1; j <_cols - 1; j++)
x[i] -= a[i,j] * x[j];
x[i] /= a[i,i];
}
//输出结果
Print(x);
return x;
}
static float[] LieZhuXiaoYuan(float[,] c)
{
float[,] a = new float[c.GetLength(0), c.GetLength(1)];
Array.Copy(c, a, c.GetLength(0) * c.GetLength(1));
const float e = 0.00001F;
int _rows = a.GetLength(0);
int _cols = a.GetLength(1);
float[] x = new float[_rows];
for (int k = 0; k < _rows - 1; k++)
{
//选主元[这一列的绝对值最大值]
float ab_max = -1;
int max_ik = 0;
for (int i = k; i < _cols - 1; i++)
{
if (Math.Abs(a[i, k]) > ab_max)
{
ab_max = Math.Abs(a[i, k]);
max_ik = i;
}
}
//交换行处理[先判断是否为0矩阵]
if (ab_max < e)
{//0矩阵情况
Console.Write("0矩阵情况");
break;
}
else if (max_ik != k)
{//是否是当前行,不是交换
float temp;
for (int j = 0; j < _cols; j++)
{
temp = a[max_ik, j];
a[max_ik, j] = a[k, j];
a[k, j] = temp;
}
}
//消元计算
for (int i = k + 1; i < _rows; i++)
{
float kk = a[i, k] / a[k, k];
for (int j = k; j < _cols; j++)
{
a[i, j] -= kk * a[k, j];
}
}
//输出中间计算过程
PrintProc(a, k);
if (k < _rows - 2)
continue;
else
{
if (Math.Abs(a[_rows - 1, _rows - 1]) < e)
{
Console.Write("0矩阵情况");
break;
}
else
{//回代求解
for (int i = _rows - 1; i >= 0; i--)
{
x[i] = a[i, _cols - 1];
for (int j = i + 1; j < _cols - 1; j++)
x[i] -= a[i, j] * x[j];
x[i] /= a[i, i];
}
}
}
}
//输出结果
Print(x);
return x;
}
}
}
/*
书上高斯消元的例子:
1 1 1
1 3 -2
2 -2 1
6 1 1
*/
/*
书上列主消元的例子:
-0.002 2 2
1 0.78125 0
3.996 5.5625 4
0.4 1.3816 7.4178
*/
列主元素消去法是为控制舍入误差而提出来的一种算法,在Gauss消去法的消元过程中,若出现a=0,则消元无法进行,即使其不为0,但很小,把它作为除数,就会导致其他元素量级的巨大增长和舍入误差的扩散,最后使计算结果不可靠.使用列主元素消去法计算,基本上能控制舍入误差的影响,并且选主元素比较方便.
参考:http://www.cnblogs.com/zjutlitao/p/3637411.html