上一個隨筆,我介紹了全排列的遞回求解,其中還有排列的逆序數等代碼,這次我來介紹如何使用全排列計算行列式的值,
使用全排列求行列式的值,簡單的描述就是:
- 對這個行列式每一行選取一個數,這些數處于行列式的不同的列,將這些數相乘,結果記為A_1
- 將這些數的列標按行標從上到下的順序排列,如果這個排列的逆序數為偶數,A_1加個正號+A_1,否則加個負號-A_1
- 由排列組合知識我們知道我們一共能從行列式中取出n!種情況,他們的和就是行列式的值
(剛開始用博客園,沒找到插入latex的地方,我就截個圖了,,,)

可見,我們需要實作以下功能:
1. 定義矩陣類
2. 獲得矩陣列標的全排列
3. 對每個排列,在矩陣的每一行取一個數,并計算這個排列的逆序數,決定符號
4. 計算取出的數的求積,綜合以上操作,求出行列式的值
逐個實作!
1. 首先,類定義的代碼分別如下(成員函式逐一介紹):
public class Matrix { /** * author:ZhaoKe * college: CUST */ public int row; public int column; public double[][] elements; public Matrix() { this.elements = new double[this.row][this.column]; for (int i = 0; i < this.row; i++) { for (int j = 0; j < this.column; j++) { this.elements[i][j] = 0; } } } public Matrix(double[][] elements) { this.row = elements.length; this.column = elements[0].length; this.elements = new double[this.row][this.column]; for (int i = 0; i < this.row; i++) { for (int j = 0; j < this.column; j++) { this.elements[i][j] = elements[i][j]; } } } }
2. 然后我們要獲得全排列,這部分上一次已經講過,完整代碼請看一下 https://www.cnblogs.com/zhaoke271828/p/12530031.html
3. 根據排列從矩陣中取數,所謂排列,我們用陣串列示,那么功能也很好實作,大家可以自己試一下,注意這是Matrix類的成員函式
public double[] getArrayByColumnIndex(int[] index) { double[] array = new double[index.length]; for (int i = 0; i < this.row; i++) { array[i] = this.elements[i][index[i]]; } return array; }
4. 然后直接求行列式的值:
根據逆序數判斷正負號:
this.isOdd(perm.against(result[i]))?1:-1
這個perm表示Permutation類的實體,這個類的定義參考我的另一個博客 全排列的Java實作 https://www.cnblogs.com/zhaoke271828/p/12530031.html
public boolean isOdd(int number) { return number %2==0; } public double det() throws Exception { if (this.row != this.column) { throw new Exception("該矩陣不是方陣,不可求行列式,考慮求廣義行列式吧!"); } int[] index = new int[this.column]; for (int i = 0; i < index.length; i++) { index[i] = i; } Permutation perm = new Permutation(index); perm.perm(index, 0); int[][] result = perm.getResult(); double sum = 0; for (int i = 0; i < result.length; i++) { // System.out.println("本次運算的陣列:" + Arrays.toString(getArrayByColumnIndex(result[i]))); // System.out.println("符號是:" + (this.isOdd(perm.against(result[i]))?1:-1)); sum += Array.prod(getArrayByColumnIndex(result[i]))*(this.isOdd(perm.against(result[i]))?1:-1); } return sum; }
其中涉及到對一個陣列求連乘積,這個大家可以自己實作以下,我這里又定義了陣列類Array,代碼如下:
其實變麻煩了,不過博主習慣這種操作hhhhh~如果還需要關于陣列的操作,方便添加功能
public class Array { public double[] elements; public Array(double[] elements) { this.elements = elements; } public static double prod(double[] array) { double prod = 1; for (int i = 0; i < array.length; i++) { prod *= array[i]; } return prod; } }
以上就是全部代碼了,可以試一下效果:
public static void main(String[] args) { double[][] matrix = { {1, 2, 4, 8}, {1,1,1,1}, {1, 4, 16, 64}, {1,5,25,125} }; Matrix m = new Matrix(matrix); try { System.out.println(m.det()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
結果正是 -72.0
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/71901.html
標籤:其他
上一篇:Silvaco中的光電仿真
