C#程式計算N階行列式的值及N元一次方程組 用了挺長時間自行完成了C#程式計算N階行列式的值及N元一次方程組。由於自己沒有在網上查閱其他資料,所以只能硬著頭皮用最朴素的思想和基礎的演算法進行編程。在給出代碼之前,我先簡單發表一些自己的粗鄙之見。。。 1.數學思想:有了線性代數中高斯提供的公式,我們很容 ...
C#程式計算N階行列式的值及N元一次方程組
用了挺長時間自行完成了C#程式計算N階行列式的值及N元一次方程組。由於自己沒有在網上查閱其他資料,所以只能硬著頭皮用最朴素的思想和基礎的演算法進行編程。在給出代碼之前,我先簡單發表一些自己的粗鄙之見。。。
1.數學思想:有了線性代數中高斯提供的公式,我們很容易就能得到N階方程的解的統一計算方法:即xn=Dn/D。其中D是繫數矩陣的行列式值,Dn是用每個方程的結果分別代替繫數矩陣中的每列值,所得新的行列式的值。 那麼我們的關鍵問題就是(1)如何計算一個N階行列式的值(2)如何得到N個新的行列式。下麵就對這兩個關鍵問題進行探討。
2.問題一:如何計算N階行列式的值。我沒有選用網上的一些諸如“加邊法”等一些方法。選用了N階行列式最基本的計算公式。即求任意一行或列的所有元素乘以他們的餘子式,進行降階,最後在二階用主對角線之積減副對角線之積進行計算。朴素的思想有著“易理解,難操作或性能低”的特點。選用這種方法的本質就是:遞歸。
3.問題二:問題二相對問題一而言更好解決,對每列進行遍歷,用方程值組代替列組,創建新的行列式放到問題一的函數中計算即可。
下麵附上代碼:
static void Main() { bool tap = true; while (tap) { //輸出標題並輸入階數 Console.SetCursorPosition(48, 3); Console.WriteLine("解N元一次方程組"); Console.Write("請輸入N元方程組的階數(未知數的個數):"); int n = Convert.ToInt32(Console.ReadLine()); //依次輸入每行方程的繫數和結果 double[,] Xishu = new double[n, n]; double[] zhi = new double[n]; double[] EachLineResult = new double[n]; Console.WriteLine("請依次輸入每行的繫數數和結果數:"); Console.WriteLine(); for (int i = 0; i < n; i++) { Console.WriteLine("請輸入第{0}行的繫數值和結果值", i + 1); for (int j = 0; j < n; j++) { Xishu[i, j] = Convert.ToDouble(Console.ReadLine()); } Console.WriteLine("請輸入第{0}行的結果值", i + 1); zhi[i] = Convert.ToDouble(Console.ReadLine()); } //計算行列式的值和用結果值代替繫數的行列式的值 double result = Hanglieshi(n, Xishu); //測試用句1: Console.WriteLine("計算出行列式的結果為:{0}", result); if (result == 0) Console.WriteLine("此方程無解!");//行列式值為0,方程無解 else { for (int i = 0; i < n; i++) { double[,] TempXishu = new double[n, n]; for (int ii = 0; ii < n; ii++) { for (int jj = 0; jj < n; jj++) { TempXishu[ii, jj] = Xishu[ii, jj]; } } EachLineResult[i] = Rexishu(i, TempXishu, zhi, n); //測試用句2: Console.WriteLine("第{0}個結果行列式的值為:{1}",i+1,EachLineResult[i]); } //輸出每一個結果的值 Console.WriteLine(); Console.WriteLine("{0}元一次方程組的解集如下:", n); for (int i = 0; i < n; i++) { Console.WriteLine("X{0}:{1}", i + 1, EachLineResult[i] / result); } } Console.WriteLine(); Console.WriteLine("你是否要繼續計算?回答:是或不是"); string choice = Console.ReadLine(); while (choice != "是"&& choice != "不是") choice = Console.ReadLine(); if (choice == "是") { Console.Clear(); } else tap = false; } //計算行列式函數:利用遞歸和行列式的數學計算式計算。時間複雜度為O(n三次方),性能較低。 double Hanglieshi (int N,double [,] xishu) { double Mo = 0; if (N == 0) return 0; else if (N == 1) return xishu[0, 0]; else if (N == 2) return xishu[0, 0] * xishu[1, 1] - xishu[0,1] * xishu[1,0]; else { for (int i = 0; i < N; i++) { double[,] NewXishu = new double[N - 1, N - 1]; for(int j = 0; j < N - 1; j++) { int mark = 0; for (int k = 0; k <N-1; k++) { if (k == i) { NewXishu[j, k] = xishu[j + 1, mark + 1]; mark++; } else NewXishu[j, k] = xishu[j + 1, mark]; //Console.WriteLine("k的值為:{0}\tmark的值為:{1}\t數組的值為:{2}",k,mark,NewXishu[j,k]); mark++; } } //Console.WriteLine("這是第{0}次迴圈",i+1); if(i%2==0) Mo += xishu[0,i]*Hanglieshi(N - 1, NewXishu); else Mo -= xishu[0, i] * Hanglieshi(N - 1, NewXishu); } return Mo; } } /*創建新的數組讓方程結果值代替列值,時間複雜度為O(n)主要問題在空間複雜度上,傳 參時,需要把原數組複製,所以要O(n三次方)。註意:正常函數傳參是按值傳參,函數內形參不 改變函數外部實參的值。但是數組比較特殊,會被更改。 */ double Rexishu(int lieshu,double [,]xishu,double[]Zhi,int Size) { Console.WriteLine(); for (int i = 0; i <Size; i++) { xishu[i, lieshu] = Zhi[i]; } double resulti=Hanglieshi(Size,xishu); return resulti; } }