MyMathLib系列(行列式计算)
靠人不如靠己,准备做自己得MathLib,在学校的时候,就想过把数学数理的东西都计算机化。但一直没有时间去做这件事情,如今认为空余 时间比較闲,就做做这件事情,先从线性代数開始,毕竟这里面的非常多算法。实际共走中都实用到。
在做这些算法的过程中。也体会到了:数学中的东西不是没实用,而是你没用到。以下的算法(除全排列外)都是自己原创想得,做的不够效率的地方,也请大家分享更好的东西。好了。啰嗦这么多,让代码说话吧:
/// <summary>
/// 行列式计算,本程序属于MyMathLib的一部分。欢迎使用,參考。提意见。 /// 有时间用函数语言改写,做自己得MathLib,里面的算法经过验证,但没经过
/// 严格測试,如需參考,请谨慎.
/// </summary>
public static partial class LinearAlgebra
{
/// <summary>
/// 求逆序数
/// </summary>
/// <param name="Numbers">数字序列</param>
/// <returns></returns>
public static int CalcInverseNumber(string Numbers)
{
int theRet = 0;
if (string.IsNullOrWhiteSpace(Numbers))
{
return theRet;
}
else
{
string[] theNumbers = Numbers.Split(new string[] { ",", " " }, StringSplitOptions.RemoveEmptyEntries);
return CalcInverseNumber(theNumbers);
}
}
/// <summary>
/// 求逆序数
/// </summary>
/// <param name="Numbers">数字序列</param>
/// <returns></returns>
public static int CalcInverseNumber(string[] Numbers)
{
var theRet = 0;
if (Numbers.Count() <= 0)
{
return theRet;
}
else
{
string[] theNumbers = Numbers.ToArray(); int[] theNums = new int[theNumbers.Count()];
for (int i = 0; i < theNumbers.Count(); i++)
{
theNums[i] = Convert.ToInt32(theNumbers[i]);
}
for (int theI = 0; theI < theNums.Count() - 1; theI++)
{
for (int theJ = theI + 1; theJ < theNums.Count(); theJ++)
{
if (theNums[theI] > theNums[theJ])
{
theRet++;
}
}
}
}
return theRet;
}
private static string HandlingMultiExp(string Exp, int Sign)
{
decimal theRetNum = Sign;
var theRetLine = "";
var theDigits = Exp.Split('*');
foreach (var theD in theDigits)
{
decimal theDec = 0;
if (decimal.TryParse(theD, out theDec))
{
theRetNum *= theDec;
}
else
{
if (theRetLine == "")
{
theRetLine = theD;
}
else
{
theRetLine += "*" + theD;
}
}
}
if (theRetNum == 0)
{
return "";
}
else
{
if (theRetNum == 1)
{
return theRetLine;
}
if (theRetNum == -1)
{
return "-" + theRetLine;
}
return theRetNum.ToString() + theRetLine;
}
}
/// <summary>
/// 行列式表达式展开
/// </summary>
/// <param name="Determinants">N阶行列式</param>
/// <returns></returns>
public static string DeterminantToExpression(string[,] Determinants)
{
int theR = Determinants.GetLength(0);
int theC = Determinants.GetLength(1);
if (theR != theC)
{
throw new Exception("不是N阶行列式!");
}
var theResults = new List<string>();
List<string> theNs = new List<string>();
for (int i = 1; i <= theC; i++)
{
theNs.Add(i.ToString());
}
FullPermutation(theNs, 0, theC - 1, theResults);
var theNExp = "";
var thePExp = "";
foreach (var theAL in theResults)
{
var theInverseNum = Convert.ToInt32(Math.Pow(-1, CalcInverseNumber(theAL)));
var theLine = "";
string[] theNums = theAL.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 1; i <= theC; i++)
{
var theV = Determinants[i - 1, int.Parse(theNums[i - 1]) - 1];
theLine += "*" + theV;
}
theLine = HandlingMultiExp(theLine.Substring(1), theInverseNum);
if (!string.IsNullOrEmpty(theLine))
{
if (theLine[0] == '-')
{
theNExp += "" + theLine;
}
else
{
thePExp += "+" + theLine;
}
}
}
return thePExp.Substring(1) + theNExp;
}
/// <summary>
/// 对数组进行全排列
/// </summary>
/// <param name="lsArray">要进行全排列的数组</param>
/// <param name="begin">进行全排列的開始下标</param>
/// <param name="end">进行全排列的结束下标</param>
public static void FullPermutation(List<string> lsArray, int begin, int end, List<string> Result)
{
if (begin == end)
{
string theLine = "";
for (int i = 0; i <= end; i++)
{ theLine += "," + lsArray[i];
}
Result.Add(theLine.Substring(1));
} for (int i = begin; i <= end; i++)
{
Swap(lsArray, begin, i);
FullPermutation(lsArray, begin + 1, end, Result);
Swap(lsArray, begin, i);
} }
/// <summary>
/// 交换数组中的下标为x,y的值
/// </summary>
/// <param name="lsArray">该数组</param>
/// <param name="x"></param>
/// <param name="y"></param>
private static void Swap(List<string> lsArray, int x, int y)
{
string t = lsArray[x];
lsArray[x] = lsArray[y];
lsArray[y] = t;
}
/// <summary>
/// 化三角法行列式计算,
/// </summary>
/// <param name="Determinants">N阶行列式</param>
/// <returns>计算结果</returns>
public static decimal CalcDeterminant(decimal[,] Determinants)
{
int theSign = 1;//正负符号。假设须要变换,将记录变换后的符号.
int theN = Determinants.GetLength(0);
//从第1列到第theN-1列
for (int i = 0; i < theN - 1; i++)
{
//从第theN-1行到第i+1行。将D[j,i]依次变为0
for (int j = theN - 1; j > i; j--)
{
//假设为当前值为0,则不处理,继续处理上一行
if (Determinants[j, i] == 0)
{
continue;
} //假设[j,i]的上一行[j-1, i]的值为0则交换
if (Determinants[j - 1, i] == 0)
{
//每次交换,行列式的值大小不变。符号取反
theSign = 0 - theSign;
for (int k = 0; k < theN; k++)
{
decimal theTmpDec = Determinants[j, k];
Determinants[j, k] = Determinants[j - 1, k];
Determinants[j - 1, k] = theTmpDec;
}
}
else
{
//将当前行减去上一行与theRate的积。 var theRate = Determinants[j, i] / Determinants[j - 1, i];
for (int k = 0; k < theN; k++)
{
Determinants[j, k] = Determinants[j, k] - Determinants[j - 1, k] * theRate;
}
}
}
}
//结果为对角线上的元素的乘积,注意符号的处理。
decimal theRetDec = theSign;
for (int i = 0; i < theN; i++)
{
theRetDec *= Determinants[i, i];
}
return theRetDec;
}
}
MyMathLib系列(行列式计算)的更多相关文章
- MyMathLib系列(行列式计算2)
/// <summary> /// 行列式计算,本程序属于MyMathLib的一部分.欢迎使用,參考,提意见. /// 有时间用函数语言改写,做自己得MathLib,里面的算法经过验证,但 ...
- 行列式计算(C#)
最近几天学习高等代数老师说要写个程序算行列式的结果,闲来无事就简单写了一下. 不多说了,上代码 using System; using System.Collections.Generic; usin ...
- n阶行列式计算----c语言实现(完结)
花了半天时间,写了这个n阶行列式计算的程序,应该算是比较优美吧,有很多地方多次做了优化,程序占用内存不是很大,要是说小吧,也不合适,因为里边有一个递归,而且递归的深度还比较深.时间复杂度具体没有细看, ...
- Java实现行列式计算
前天我看线代书,看到行列式,发现是个递归的式子,恰巧又正在学java,产生写程序实现的想法.写了两个小时,觉得实现了,写了个行列式放进去测试,我放的是 这个行列式,经过程序计算后发现结果是0.我以为我 ...
- 辛巴学院-Unity-剑英陪你零基础学c#系列(三)计算与类型
辛巴学院:正大光明的不务正业. 中秋节快乐,每逢佳节倍思亲,尤其是那素未谋面的老婆,对吧,屌丝们. 今天我们来探索一下C#里面奇怪的计算,奇怪的类型. 奇怪的计算 当我刚刚接触计算机编程的时候,一 ...
- JavaScript系列:计算一个结果为30的加法智力题
用下面这段JavaScript代码可以计算出来 function findTheThreeNum(numFix) { var a = ["1", "3", &q ...
- Vue.js系列之四计算属性和观察者
一.计算属性 1.模版内的表达式非常便利,但是设计它们的初衷是用于简单计算的.在模版中放入太多的逻辑运算会让模版过重且难以维护,例如如下代码: <div id="example&quo ...
- python 行列式计算
N= #声明2x2的数组arr并将所有元素赋值为 None arr=[[None] * N for row in range(N)] print('|a1 b1|') print('|a2 b2|') ...
- HDU 5852 Intersection is not allowed! ( 2016多校9、不相交路径的方案、LGV定理、行列式计算 )
题目链接 题意 : 给定方格中第一行的各个起点.再给定最后一行与起点相对应的终点.问你从这些起点出发到各自的终点.不相交的路径有多少条.移动方向只能向下或向右 分析 : 首先对于多起点和多终点的不相交 ...
随机推荐
- MSSQL 的Top 和 MAX 效率测试
环境: MSSQL 2008, 都在没有使用缓存的情况下面执行 表中有8W 条记录 分类1有134条记录 分别测试了3个语句 -- A select 字段1 from 表1 WHERE Ftype=' ...
- Asp.Net发送手机验证码
C#发送手机验证码,平台有很多,我就说说其中的1个平台 测试环境:.net2.0 测试效果:速度还可以,10秒内接收短信 1.去http://www.yuntongxun.com注册,会送8元测试金额 ...
- 双重检验的单例模式,为什么要用volatile关键字
双重检验的单例模式是比较推荐的单例写法,在该代码中的单例对象的是用volatile关键字修饰的.这时就产生的一个疑问,为什么需要volatile来修饰呢?上网查看多个博客,下面简单通俗分析一下当中的原 ...
- python 发送邮件 带附件
# coding:utf-8 # __author__ = 'Mark sinoberg' # __date__ = '2016/5/26' # __Desc__ = 实现发送带有各种附件类型的邮件 ...
- Vmware 注册服务 开机自启
现在的服务器性能往往过剩,利用虚拟机可以提高服务器的利用效率.VMware是一款很好的虚拟机软件,但是其WorkSation版本并不支持开机自动启动,支持开机自启的Server又长年没有更新,已经无法 ...
- JAVA-JSP内置对象之request范围
相关资料:<21天学通Java Web开发> request范围1.在一次请求内有效.2.如果页面从一个页面跳转到另一个页面,那么属性就失效了.3.如果使用服务器端跳转<jsp:fo ...
- 基于HTML5手机上下滑动翻页特效
基于HTML5手机上下滑动翻页特效.这是一款手机移动端触屏滑动翻页代码下载.效果图如下: 在线预览 源码下载 实现的代码. html代码: <section class="u-al ...
- zip伪加密
简单的话来阐述 zip伪协议的意思是说本来不需要密码的zip文件然后通过修改标志位,然后就可以达到有密码的效果对吗?但是他实际是没有密码. 一个 ZIP 文件由三个部分组成: 压缩源文件数据区+压缩源 ...
- 用Total Commander for Android管理应用程序
用Total Commander for Android管理应用程序 前不久安装了一个Total Commander的Anroid版本,除了用它来管理文件之外,我发现用它管理已安装程序挺不错的. 可以 ...
- Python 创建线程的方法
使用的是 threading 模块 代码如下: 1 #!/usr/bin/python3 2 3 import threading 4 import time 5 6 exitFlag = 0 7 / ...