本网页所有文字内容由 imapbox邮箱云存储,邮箱网盘, iurlBox网页地址收藏管理器 下载并得到。
ImapBox 邮箱网盘 工具地址: https://www.imapbox.com/download/ImapBox.5.5.1_Build20141205_CHS_Bit32.exe
PC6下载站地址:PC6下载站分流下载
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox 网页视频 工具地址: https://www.imapbox.com/download/ImovieBox4.7.0_Build20141115_CHS.exe
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
/// <summary> /// 行列式计算,本程序属于MyMathLib的一部分,欢迎使用,参考,提意见。 /// 有时间用函数语言改写,做自己得MathLib,里面的算法经过验证,但没经过 /// 严格测试,如需参考,请慎重. /// </summary> public static partial class LinearAlgebra { /// <summary> /// 获取指定i,j的余子式 /// </summary> /// <param name="Determinants">N阶行列式</param> /// <param name="i">第i行</param> /// <param name="j">第j列</param> /// <returns>计算结果</returns> public static T[,] GetDeterminantMij<T>(T[,] Determinants, int i, int j) { var theN = Determinants.GetLength(0); var theNewDeter = new T[theN - 1, theN - 1]; int theI = -1; for (int k = 0; k < theN; k++) { if (k == i - 1) { continue; } theI++; int theJ = -1; for (int l = 0; l < theN; l++) { if (l == j - 1) { continue; } theJ++; theNewDeter[theI, theJ] = Determinants[k, l]; } } return theNewDeter; } /// <summary> /// 获取指定i,j的余子式 /// </summary> /// <param name="Determinants">N阶行列式</param> /// <param name="Rows">要取得行</param> /// <param name="Cols">要取得列</param> /// <returns>计算结果</returns> public static T[,] GetDeterminantMij<T>(T[,] Determinants, int[] Rows, int[] Cols) { if (Rows.Length != Cols.Length) { throw new Exception("所取行数和列数必须相等!"); } var theN = Determinants.GetLength(0); var theNewN = theN - Rows.Length; var theNewDeter = new T[theNewN, theNewN]; int theI = -1; for (int k = 0; k < theN; k++) { if (Rows.Contains(k + 1)) { continue; } theI++; int theJ = -1; for (int l = 0; l < theN; l++) { if (Cols.Contains(l + 1)) { continue; } theJ++; theNewDeter[theI, theJ] = Determinants[k, l]; } } return theNewDeter; } /// <summary> /// 获取指定k阶子式N /// </summary> /// <param name="Determinants">N阶行列式</param> /// <param name="Rows">要取得行</param> /// <param name="Cols">要取得列</param> /// <returns>计算结果</returns> public static T[,] GetDeterminantKN<T>(T[,] Determinants, int[] Rows, int[] Cols) { if (Rows.Length != Cols.Length) { throw new Exception("所取行数和列数必须相等!"); } var theNewN = Rows.Length; var theNewDeter = new T[theNewN, theNewN]; for (int k = 0; k < Rows.Length; k++) { for (int l = 0; l < Cols.Length; l++) { theNewDeter[k, l] = Determinants[Rows[k] - 1, Cols[l] - 1]; } } return theNewDeter; } /// <summary> /// 计算余子式的符号。 /// </summary> /// <param name="i"></param> /// <param name="j"></param> /// <returns></returns> public static int CalcDeterMijSign(int i, int j) { int theSign = 1; if ((i + j) % 2 == 1) { theSign = -1; } return theSign; } /// <summary> /// 计算余子式的符号。 /// </summary> /// <param name="i"></param> /// <param name="j"></param> /// <returns></returns> public static int CalcDeterMijSign(int[] Rows, int[] Cols) { int theSign = 1; var theSum = Rows.Sum() + Cols.Sum(); if (theSum % 2 == 1) { theSign = -1; } return theSign; } /// <summary> /// 降阶法计算行列式 /// </summary> /// <param name="Determinants">N阶行列式</param> /// <param name="ZeroOptimization">是否0优化</param> /// <returns>计算结果</returns> public static decimal CalcDeterminantAij(decimal[,] Determinants, bool ZeroOptimization = false) { var theN = Determinants.GetLength(0); //如果为2阶,直接计算 if (theN == 2) { return Determinants[0, 0] * Determinants[1, 1] - Determinants[0, 1] * Determinants[1, 0]; } if (ZeroOptimization) { //找0最多的行 int theRowIndex = 0; int theMaxZeroCountR = -1; for (int i = 0; i < theN; i++) { int theZeroNum = 0; for (int j = 0; j < theN; j++) { if (Determinants[i, j] == 0) { theZeroNum++; } } if (theZeroNum > theMaxZeroCountR) { theRowIndex = i; theMaxZeroCountR = theZeroNum; } } //找0最多的列 int theColIndex = 0; int theMaxZeroCountC = -1; for (int i = 0; i < theN; i++) { int theZeroNum = 0; for (int j = 0; j < theN; j++) { if (Determinants[j, i] == 0) { theZeroNum++; } } if (theZeroNum > theMaxZeroCountC) { theColIndex = i; theMaxZeroCountC = theZeroNum; } } if (theMaxZeroCountR >= theMaxZeroCountC) { decimal theRetDec = 0; //第i=theRowIndex+1行展开 int i = theRowIndex + 1; for (int j = 1; j <= theN; j++) { var theSign = CalcDeterMijSign(i, j); var theNewMij = GetDeterminantMij(Determinants, i, j); theRetDec += theSign * Determinants[i - 1, j - 1] * CalcDeterminantAij(theNewMij, ZeroOptimization); } return theRetDec; } else { decimal theRetDec = 0; //第j=theColIndex+1列展开 int j = theColIndex + 1; for (int i = 1; i <= theN; i++) { var theSign = CalcDeterMijSign(i, j); var theNewMij = GetDeterminantMij(Determinants, i, j); theRetDec += theSign * Determinants[i, j] * CalcDeterminantAij(theNewMij, ZeroOptimization); } return theRetDec; } } else { //采用随机法展开一行 var i = new Random().Next(1, theN); decimal theRetDec = 0; for (int j = 1; j <= theN; j++) { var theSign = CalcDeterMijSign(i, j); var theNewMij = GetDeterminantMij(Determinants, i, j); theRetDec += theSign * Determinants[i, j] * CalcDeterminantAij(theNewMij, ZeroOptimization); } return theRetDec; } } /// <summary> /// 计算范德蒙行列式 /// </summary> /// <param name="Determinants">范德蒙行列式简记序列</param> /// <returns>计算结果</returns> public static decimal CalcVanDerModeDeter(decimal[] VanDerModeDeter) { var theN = VanDerModeDeter.Length; if (theN == 1) { return 1; } decimal theRetDec = 1; for (int i = 0; i < theN; i++) { for (int j = i + 1; j < theN; j++) { theRetDec *= (VanDerModeDeter[j] - VanDerModeDeter[i]); } } return theRetDec; } /// <summary> /// 获取奇数序列 /// </summary> /// <param name="N"></param> /// <returns></returns> private static int[] GetLaplaceRowsOdd(int N) { var theRet = new List<int>(); for (int i = 0; i < N; i = i + 2) { theRet.Add(i + 1); } return theRet.ToArray(); } /// <summary> /// 根据拉普拉斯定理计算行列式值。 /// </summary> /// <param name="Determinants">N阶行列式</param> /// <param name="Rows">初始展开行,里面采用奇数行展开</param> /// <returns>计算结果</returns> public static decimal CalcDeterByLaplaceLaw(decimal[,] Determinants, int[] Rows) { var n = Determinants.GetLength(0); var k = Rows.Length; //如果阶数小于3,则没必要采用拉普拉斯展开 if (n <= 3) { return CalcDeterminantAij(Determinants, false); } //从P(theN,theK) var theRetList = GetCombination(n, k); decimal theRetDec = 0; foreach (var theCols in theRetList) { var theSign = CalcDeterMijSign(Rows, theCols.ToArray()); var theKN = GetDeterminantKN(Determinants, Rows, theCols.ToArray()); var theN = GetDeterminantMij(Determinants, Rows, theCols.ToArray()); decimal theRetKN = 0; //如果剩余阶数>4则采用随机半数处理. if (n - k >= 4) { var theRows = GetLaplaceRowsOdd(n - k); theRetKN = CalcDeterByLaplaceLaw(theKN, theRows); } else { theRetKN = CalcDeterminantAij(theKN); } decimal theRetAk = 0; if (k >= 4) { var theRows = GetLaplaceRowsOdd(k); theRetAk = CalcDeterByLaplaceLaw(theN, theRows); } else { theRetAk = CalcDeterminantAij(theN); } theRetDec += theSign * theRetKN * theRetAk; } return theRetDec; } /// <summary> /// 从N个数中取k个数的组合结果,考虑到组合数没有顺序区分,因此只要考虑从小 /// 到大的排列下的组合情况即可,另外,如果组合也不用考虑元素重复的 /// 问题,如果有重复数,只要除重即可。 /// </summary> /// <param name="N">N个数1-N</param> /// <param name="k">取K个</param> /// <returns></returns> public static List<List<int>> GetCombination(int N, int k) { var theList = new List<int>(); for (int i = 1; i <= N; i++) { theList.Add(i); } return GetCombination(theList, k); } /// <summary> /// 从N个中取k个数,算法原理C(N,k)=C(N-1,k)+ (a + C(Na-1,k-1));其中Na是N中去掉a后的集合. /// </summary> /// <param name="N">元素总个数</param> /// <param name="k">取k个</param> /// <returns></returns> public static List<List<int>> GetCombination(List<int> N, int k) { if (k==0) { return null; } if (N.Count < k) { return null; } if (k == 1) { var theResultsList = new List<List<int>>(); foreach (var theN in N) { var theList = new List<int>(); theList.Add(theN); theResultsList.Add(theList); } return theResultsList; } if (N.Count == k) { var theResultsList = new List<List<int>>(); var theList = new List<int>(); theList.AddRange(N); theResultsList.Add(theList); return theResultsList; } var theRet3 = new List<List<int>>(); int theLeft = N[0]; var theRight = new List<int>(); theRight.AddRange(N); theRight.Remove(N[0]); var theRet2 = GetCombination(theRight, k); theRet3.AddRange(theRet2); theRet2 = GetCombination(theRight, k - 1); for (int n = 0; n < theRet2.Count; n++) { var theList = new List<int>(); theList.Add(theLeft); theList.AddRange(theRet2[n]); theRet3.Add(theList); } return theRet3; } } }
阅读和此文章类似的: 程序员专区