C# 多元一次方程算法,高斯消元列主消元法比較

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章