行列式:
行列式在数学中,是一个函数,其定义域为det的矩阵A,取值为一个标量,写作det(A)或 | A | 。无论是在线性代数、多项式理论,还是在微积分学中(比如说换元积分法中),行列式作为基本的数学工具,都有着重要的应用。
——来自百度百科
举个例子,这样一个行列式,n=3:
它的值为1*5*0 + 4*8*3 + 7*2*6 -7*5*3 - 8*6*1 -0*4*2=27.
下面的才是重点,高斯消元要用的行列式的性质:
-
行列式与它的转置行列式相等
比如上例的转置行列式就这:
显然。不证。
-
交换行列式的两行,行列式取相反数
这个就是高斯消元的重点之一了,每次转换相邻两行,值相应地取相反数。
因为转换后顺逆序会相反。既然相反就求相反数喽。
-
行列式的某一行的所有元素都乘以同一数k,等于用数k乘此行列式
注意是只乘一行而不是全部。因为这一行的数字在每个项都出现提出来就行了。
-
行列式如果有两行元素成比例,则此行列式等于零
很神奇,要用到上面两个性质:
记f[i]=f[j]*k,那么行列式的值就等于转换后的行列式*k,交换f[i]和f[j]该行列式等于相反数,但显然值不变,所以它=0,0*k=0,得证。
-
把行列式的某一行的各元素乘以同一数然后加到另一行对应的元素上去,行列式不变
高斯消元的重点。
-
若行列式的某一行每一个元素都可以由两个数相加得到,则这个行列式是对应两个行列式的和。
举个例子:
这个性质由乘法分配律可以容易得出,自行脑补。
高斯消元(Gauss)求行列式
高斯消元只需要上述强调过的两个性质。
它把行列式下三角全变为0.依据性质,我们知道此时行列式的值就是对角线的积。
int Gauss() { double t; double ans; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { t=f[i][i]/f[i][j]; for(int k=i;k<=m+1;k++) f[i][k]-=f[j][k]*t; swap(f[i],f[j]); ans*=-1; } }
for(int i=1;i<=n;i++)ans*=f[i][i]; return (int)(ans+0.5); }
我们发现,如果行列式要遍历的行本来就是0,我们直接跳过就行了不用再遍历;
int Gauss1() { for(int i=1;i<=n;i++){ int p=i; while(!f[p][i] and p<=n)p++; if(p>=n+1)return 0; if(p!=i)swap(f[i],f[p]); for(int j=i+1;j<=n;j++) { double tmp=f[j][i]/f[i][i]; for(int k=i;k<=n;k++) f[j][k]-=f[i][k]*tmp; } } double ans=1; for(int i=1;i<=n;i++) ans*=f[i][i]; return (int)(ans+0.5); }