矩阵规模如何?
创新互联专注于企业营销型网站建设、网站重做改版、平遥网站定制设计、自适应品牌网站建设、H5高端网站建设、成都做商城网站、集团公司官网建设、成都外贸网站制作、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为平遥等各大城市提供网站开发制作服务。
如果矩阵比较小 (~10), 可以直接按照定义来计算, P[x] = det( x*I - A); 其中det是一个矩阵的行列式; 可以按照定义直接迭代求;
如果矩阵比较大(100), 可以先求特征值, 然后构造矩阵特征多项式 P[x] = (x-x1)*(x-x2)... (x-xn), 其中xi为矩阵的第i个特征值.
可能是计算过程中数据溢出了,我用Java算,如果用double类型算出的结果也是不对的,换成BigDecimal算,就对了
这是我写的程序:
用double:
public static double mdeterm(double[][] matrix) {
for (int i = 0; i matrix.length; i++) {
if (matrix.length != matrix[i].length)
throw new IllegalArgumentException("矩阵行列式的行和列必须相等");
}
int[] row = new int[matrix.length];
int[] col = new int[matrix.length];
for (int i = 0; i matrix.length; i++) {
row[i] = i;
col[i] = i;
}
return mdeterm(matrix, row, col);
}
private static double mdeterm(double[][] matrix, int[] row, int[] col) {
if (row.length == 1) {
return matrix[row[0]][col[0]];
}
double result = 0;
for (int i = 0; i row.length; i++) {
int[] sub_row = new int[row.length - 1];
int[] sub_col = new int[col.length - 1];
for (int j = 0, row_index = 0, col_index = 0; j sub_col.length; j++, row_index++, col_index++) {
sub_row[j] = row[row_index + 1];
if (col_index == i)
col_index++;
sub_col[j] = col[col_index];
}
double temp = matrix[row[0]][col[i]]
* mdeterm(matrix, sub_row, sub_col);
if ((i % 2) != 0)
temp = -temp;
result += temp;
}
return result;
}
用BigDecimal:
public static BigDecimal mdeterm(BigDecimal[][] matrix) {
for (int i = 0; i matrix.length; i++) {
if (matrix.length != matrix[i].length)
throw new IllegalArgumentException("矩阵行列式的行和列必须相等");
}
int[] row = new int[matrix.length];
int[] col = new int[matrix.length];
for (int i = 0; i matrix.length; i++) {
row[i] = i;
col[i] = i;
}
return mdeterm(matrix, row, col);
}
private static BigDecimal mdeterm(BigDecimal[][] matrix, int[] row, int[] col) {
if (row.length == 1) {
return matrix[row[0]][col[0]];
}
BigDecimal result = BigDecimal.ZERO;
for (int i = 0; i row.length; i++) {
int[] sub_row = new int[row.length - 1];
int[] sub_col = new int[col.length - 1];
for (int j = 0, row_index = 0, col_index = 0; j sub_col.length; j++, row_index++, col_index++) {
sub_row[j] = row[row_index + 1];
if (col_index == i)
col_index++;
sub_col[j] = col[col_index];
}
BigDecimal temp = matrix[row[0]][col[i]].multiply(mdeterm(matrix, sub_row, sub_col));
if((i % 2) != 0)
temp = temp.negate();
result = result.add(temp);
}
return result;
}
Option Explicit Option Base 1 Private Sub Form_Load() Dim i As Long n = Val(InputBox("请输入行列式的阶数!", "输入框")) If n 2 Then MsgBox "输入错误阶数必须大于1!" vbCrLf "请单击重试重新输入!", vbCritical, "系统提示" Exit Sub Command2.TabIndex = 1 End If If n 9 Then MsgBox "输入错误本程序只能计算10阶以下的行列式!" "请单击重试重新输入!", vbCritical, "系统提示" Exit Sub Command2.TabIndex = 1 End If str2 = "1" For i = 2 To n str2 = str2 i '组成1到n组成的字符串123456.....n Next i s = n MsgBox "请在文本框里按行排列输入行列式" vbCrLf "注意用一个空格隔开!", vbOKOnly, "信息提示" Text1.TabIndex = 1 Text1.Text = "" End Sub Private Sub Command1_Click() Dim i As Long, j As Long, k As Long, m As Long, sum As Long, w As Long Dim strb As String, sz1() As String, sz2() As Long, sz3() As Long Dim str1 As String, str3 As String, st() As String ReDim sa(n) As Long, sz2(n) As Long '//st() 为输入行列式的字符串数组 '//sz3()为二维行列式数组 '//str2为1到n组成的字符串123456.....n 为全局变量 '//str3为str2的全排列所组成的字符串每种排列以“,”隔开 str1 = Text1.Text If Len(str1) 2 * n ^ 2 - 1 Then MsgBox "输入错误!" vbCrLf n "阶行列式中元素个数应为" n ^ 2 "!" vbCrLf "请查看是否个元素之间都用空格隔开及个数是否正确!" vbCrLf "请点击重试重新输入!", vbCritical, "系统提示" Text1.Text = "" Exit Sub End If st() = Split(str1) '取得行列式的数据 ReDim sz3(n, s) As Long For i = 1 To n For j = 1 To s k = (i - 1) * s + j '按行排列行列式中第k个数,k与i,j的关系 sz3(i, j) = Val(st(k - 1)) '把原数组按行排列存入一个二维数组 Next j Next i Permutation "", str2, str3 sz1() = Split(str3, ",") '取n!个全排列存入 数组 sz1() For j = 1 To JC(n) m = 1 '每次都降m初始为1 strb = sz1(j) '每次取出一种排列存入strb For i = 1 To n sz2(i) = Val(Mid(strb, i, 1)) '顺序取每个全排列中的数字存入数组sz2() Next i For i = 1 To n m = m * sz3(sz2(i), i) '求元素之积 Next i sum = sum + arr(sz2(), n) * m 'n!个积相加并相应冠上正负号 Next j Text2.Text = sum End Sub Private Sub Command2_Click() Dim i As Long n = Val(InputBox("请输入行列式的阶数!", "输入框")) If n 2 Then MsgB 行列式ox "输入错误阶数必须大于1!" vbCrLf "请单击重试重新输入!", vbCritical, "系统提示" Exit Sub Command2.TabIndex = 1 End If If n 9 Then MsgBox "输入错误本程序只能计算10阶一下的行列式!" "请单击重试重新输入!", vbCritical, "系统提示" Exit 行列式Sub Command2.TabIndex = 1 End If str2 = "1" For i = 2 To n str2 = str2 i '组成1到n组成的字符串123456.....n Next i s = n MsgBox "请在文本框里按行排列输入行列式" vbCrLf "注意用一个空格隔开!", vbOKOnly, "信息提示" Text1.Text = "" End Sub 模块1递 行列式归法求全排列 Option Explicit Option Base 1 '递归求全排列并返回全排列所组成的字符串 '算法描述: '以8位为例,求8位数的全排列,其实是8位中任取一位 '在后加上其余7位的全排列 '7 位:任取一位,其后跟剩下6位的全排列 '…… '这样就有两部分,一部分为前面的已经取出来的串,另一部分为后面即将进行的全排列的串 '参数pre即为前面已经取出来的串 '参数s 行列式即为将要进行排列的串 '参数str即为返回全排列所组成的字符串,每种排列以“,”隔开 Public Sub Permutation(pre As String, s As String, str As String) Dim i As Long '// 如果要排列的串长度为1,则返回 If Len(s) = 1 Then '//将排列数以“,”隔开存入一个字符串 str = str "," pre s Exit 行列式Sub End If '// for循环即是取出待排列的串的任一位 For i = 1 To Len(s) '// 递归,将取出的字符并入已经取出的串 '// 那么剩下的串即为待排列的串 Permutation pre Mid$(s, i, 1), Left$(s, i - 1) Mid$(s, i + 1), str Next i End Sub 模块2求逆序数 Option Explicit Opt 行列式ion Base 1 Public n As Long, s As Long, str2 As String '//求存入a()数组排列为奇排列还偶排列如果为奇排列返回-1,偶排列返回1 Public Function arr(a() As Long, ByVal n As Long) As Integer Dim i As Long, j As Long, k As Long, m As Long For i = 1 To n - 1 m = i For j = m + 1 To n If a(i) a(j) Then k = k + 1 Next Next arr = (-1) ^ k End Function 模块3递归法求阶乘 Option Explicit '//递归法求阶乘 Public Function JC(n As Long) As Double If n 2 Then JC = 1: Exit Function JC = n * JC(n - 1) End Function
public class Arranger {
private double[][] arrangerMatrix;
private double arrangerResult=1.0;
public static void main(String args[]){
double[][] a={{4,1,4,8},{1,1,3,2},{2,2,5,1},{2,2,1,4}};
Arranger ar=new Arranger();
ar.arrFunction(a);//把行列式变成上三角行列式
ar.displayMatrix();//显示得出的上三角行列式
ar.displayResult(); //显示行列式计算结果
}
public void arrFunction(double[][] a){//Guass 消去
double k=0;
for (int p = 0; pa[0].length-1; p++) {
for (int r =p+1; ra.length; r++) {
k=a[r][p]/a[p][p];
a[r][p]=0;
for (int c = p+1; ca[0].length; c++) {
a[r][c]=a[r][c]-k*a[p][c];
}//u
}//r
}//c
arrangerMatrix=new double[a.length][a[0].length];
for (int i = 0; ia.length; i++) {
for (int j = 0; ja[0].length; j++) {
arrangerMatrix[i][j]=a[i][j];
if (i==j) {arrangerResult=arrangerResult*a[i][j];}//计算主对角线相乘的结果
//System.out.println (a[i][j]+" ");
}//j
}//i
}
public void displayMatrix(){
for (int i = 0; iarrangerMatrix.length; i++) {
for (int j = 0; jarrangerMatrix[0].length; j++) {
System.out.print (arrangerMatrix[i][j]+" ");
}//j
System.out.println ();
}//i
}
public void displayResult(){
System.out.println ("The result is "+arrangerResult);
}
}
思路应该很简单,考虑如何抽象类,矩阵如何存储的数据结构如何表示(此处不建议使用数组,建议使用相关的容器,比如嵌套的ArrayListArrayListDouble, 类存储数据),容器类更方便的实现你说的3中的删除一行,不过删除列需要一些额外处理。
目标函数,应该不多,建议百度一下,有没有java实现的关于数学运算的第三方jar包,这样的话,你只要稍微封装一下即可。
见第一
如果使用容器,因为容器是动态的,不是数组的静态,也即是说,数据的多少对程序的影响是微小的。
希望上边的答复可以帮助到你。