n阶行列式的全排列求解(Java)

上一个随笔,我介绍了全排列的递归求解,其中还有排列的逆序数等代码,这次我来介绍如何使用全排列计算行列式的值。

使用全排列求行列式的值,简单的描述就是:

  1. 对这个行列式每一行选取一个数,这些数处于行列式的不同的列,将这些数相乘,结果记为A_1
  2. 将这些数的列标按行标从上到下的顺序排列,如果这个排列的逆序数为偶数,A_1加个正号+A_1,否则加个负号-A_1
  3. 由排列组合知识我们知道我们一共能从行列式中取出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.cnblogs.com/zhaoke271828/p/12540291.html

时间: 2024-11-10 07:52:20

n阶行列式的全排列求解(Java)的相关文章

n阶行列式

1.首先,在学习n阶行列式定义前,我们先介绍一下排列.逆序数及对换的概念: (1)排列定义:由 1,2,-,n 组成的一个有序数组称为一个 n 级排列(也叫做这 n 个元素的一个全          排列). 例子:所有的 3 级排列: 123     132     213     231     312     321 排列的分类:分为奇排列和偶排列:逆序数是奇数的排列称为奇排列:逆序数是偶数或 0 的排列            称为偶排列 (2)逆序数的定义:在一个排列中,如果一对数的前后

行列式(三):n阶行列式

  1.数学定义   n阶行列式定义如下: 2.算法实现 函数名: GetValue() 功能:返回一个行列式的值 Private Function GetValue() Dim gValue As Double Dim tempResultList As New List(Of Array) Dim tempNumArray(RankLength - 1) As Integer '要进行全排列的序列 For i = 0 To RankLength - 1 tempNumArray(i) = i

两种常用的全排列算法(java)

问题:给出一个字符串,输出所有可能的排列. 全排列有多种算法,此处仅介绍常用的两种:字典序法和递归法. 1.字典序法: 如何计算字符串的下一个排列了?来考虑"926520"这个字符串,我们从后向前找第一双相邻的递增数字,"20"."52"都是非递增的,"26 "即满足要求,称前一个数字2为替换数,替换数的下标称为替换点,再从后面找一个比替换数大的最小数(这个数必然存在),0.2都不行,5可以,将5和2交换得到"956

十二:全排列-求解密码

问题:全排列-求解密码题目描述有某个系统需要密码才可以进入,现已知密码中的字符组合为字符串s中的字符(s<=6,s中的每一个字符都是英文字母,没有数字),但不知其排列顺序,请你编写程序,显示出该字符串中元素的所有组合(注意:会出现重复情况)如果您采用哈希函数来消除重复,请使用如下公式来计算哈希值:  result = s[i] + (result << 6) + (result << 16) - result;result = result & 0x7fffffff;

全排列算法-Java

第一步,排列的精髓是交换和顺序处理,比如,考虑[1,2,3,4]排列,实际上是,1和1,2,3,4分别交换得来 1和1交换:[1],[2,3,4] 1和2交换:[2],[1,3,4] 1和3交换:[3],[2,1,4] 1和4交换:[4],[2,3,1] 那么下面分别考虑上面的四个结果,比如,考虑 [1],[2,3,4] 第二步,我们把[1]固定不变,考虑[2,3,4],把它看成是2和2,3,4分别交换,得到如下结果: [1]固定,2和2交换:[1],[2],[3,4] [1]固定,2和3交换:

字典序全排列(java实现)

import java.util.Arrays; /** *字典序全排列 *字符串的全排列 *比如单词"too" 它的全排列是"oot","oto","too" *1,从右端开始扫描,若出现前一个比好一个小,记录前一个的元素下表index *2,再找出index以后比该元素大的中的最小值的下标,(实现见 下面的getMin方法) *3,index以后的元素实现反转(实现 见下面的reverse方法) *结束条件:前一个都比后一

分治法实现1-N的数字按字典序全排列组合 Java语言

package 分治法; import java.util.Arrays; /* * 将数字 1 - n进行全排列 按字典序从小到大输出 * 如 1 - 3 * 123 132 213 231 312 321 */ class GenerateP{ private int n; // 求 1-n所有数字的全排列 private final int maxn = 110;//最多可排列组合的长度 1-100 private boolean [] hashTable; private int []

计算n阶行列式的模板

之前在学习计数问题的时候也在网上找了很多关于行列式的资料 但是发现很多地方都只介绍2\3阶的情况 一些论文介绍的方法又看不懂 然后就一直耽搁着 今天恰好出到这样的题目 发现标算的代码简介明了 还挺开心的 function det(a:arr):int64; var i,j,k:longint; t,ans:int64; begin ans:=1; for i:=1 to n do begin for j:=i+1 to n do while a[j,i]<>0 do begin t:=a[i,

0/1背包问题的动态规划法求解 —— Java 实现

0/1背包问题的动态规划法求解,前人之述备矣,这里所做的工作,不过是自己根据理解实现了一遍,主要目的还是锻炼思维和编程能力,同时,也是为了增进对动态规划法机制的理解和掌握. 值得提及的一个问题是,在用 JAVA 实现时, 是按算法模型建模,还是用对象模型建模呢? 如果用算法模型,那么 背包的值.重量就直接存入二个数组里:如果用对象模型,则要对背包以及背包问题进行对象建模.思来想去,还是采用了对象模型,尽管心里感觉算法模型似乎更好一些.有时确实就是这样,对象模型虽然现在很主流,但也不是万能的,采用