• 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

  • 相关阅读:
    20200304(10)
    20200303Tuesday(9)
    词根词缀explicit(8)
    词根词缀(7)
    20200303(6)
    什么是ring0-ring3
    20200301a
    mark字体大全
    评估评价 提高专项(5)
    图的广度优先遍历算法
  • 原文地址:https://www.cnblogs.com/zhaoke271828/p/12540291.html
Copyright © 2020-2023  润新知