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定理、行列式计算 )
题目链接 题意 : 给定方格中第一行的各个起点.再给定最后一行与起点相对应的终点.问你从这些起点出发到各自的终点.不相交的路径有多少条.移动方向只能向下或向右 分析 : 首先对于多起点和多终点的不相交 ...
随机推荐
- win7如何不用点击用户名 直接自动登录桌面
win7如何不用点击用户名 直接自动登录桌面 在win7系统中开机时必须点击相应的用户名才能登陆系统桌面那么如何取消这一功能使当前账户自动登录到系统桌面呢? 1 .在开始菜单搜索框输入 “netplw ...
- [MyBean说明书]-如何制作BPL插件
DEMO位置: samples\simpleConsole\Lib-bpl [步骤]: 1. 首先新建一个BPL工程. 2. 添加一个窗体,实现IPluginForm接口(simpleCons ...
- 【Java】Java复习笔记-三大排序算法,堆栈队列,生成无重复的随机数列
冒泡排序 package com.lcw.bubble; public class BubbleSort { /** * 冒泡排序 * @param args * @author 成鹏致远 */ pu ...
- axios 的应用
vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios,前一段时间用了一下,现在说一下它的基本用法. 首先就是引入axios,如果你使用es6,只需要安装axios ...
- LeetCode: Palindrome 回文相关题目
LeetCode: Palindrome 回文相关题目汇总 LeetCode: Palindrome Partitioning 解题报告 LeetCode: Palindrome Partitioni ...
- 【Python学习笔记】-冒泡排序、插入排序、二分法查找
原文出处:https://blog.csdn.net/yort2016/article/details/68065728 冒泡排序 主要是拿一个数与列表中所有的数进行比对,若比此数大(或者小),就交换 ...
- spring batch中控制step的走向
1.顺序执行step: <job id="job"> <step id="stepA" parent="s1" next= ...
- oracle本月、上月、去年
select trunc(sysdate, 'month') 本月第一天, trunc(last_day(sysdate)) 本月最后一天, trunc(add_month ...
- cas单点登录-CAS5.1.3 overlay服务器搭建(二)
前言 本节主要讲解怎么搭建cas服务端,并且在浏览器中使用https访问cas服务端 1.通过cas代码生成工具(https://casinitializr.herokuapp.com/),生成 ...
- Java中的守护线程——daemon
絮叨 Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 定义:守护线程(aka:服务线程),在没有用户线程可服务时会自动离开. 优先级:守护线程的优先级 ...