n阶行列式的全排列求解(Java)
上一个随笔,我介绍了全排列的递归求解,其中还有排列的逆序数等代码,这次我来介绍如何使用全排列计算行列式的值。
使用全排列求行列式的值,简单的描述就是:
- 对这个行列式每一行选取一个数,这些数处于行列式的不同的列,将这些数相乘,结果记为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
n阶行列式的全排列求解(Java)的更多相关文章
- TOJ4537: n阶行列式
4537: n阶行列式 Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByteTotal Submit: 28 ...
- 行列式(三):n阶行列式
1.数学定义 n阶行列式定义如下: 2.算法实现 函数名: GetValue() 功能:返回一个行列式的值 Private Function GetValue() Dim gValue As Do ...
- n阶行列式计算----c语言实现(完结)
花了半天时间,写了这个n阶行列式计算的程序,应该算是比较优美吧,有很多地方多次做了优化,程序占用内存不是很大,要是说小吧,也不合适,因为里边有一个递归,而且递归的深度还比较深.时间复杂度具体没有细看, ...
- 基于上三角变换或基于DFS的行(列)展开的n阶行列式求值算法分析及性能评估
进入大一新学期,看完<线性代数>前几节后,笔者有了用计算机实现行列式运算的想法.这样做的目的,一是巩固自己对相关概念的理解,二是通过独立设计算法练手,三是希望通过图表直观地展现涉及的两种算 ...
- 线代: N阶行列式
线性变换 将 (x, y) 变成 (2 x + y, x - 3 y) 就叫做线性变换, 这就是矩阵乘法, 用于表示一切线性变换. 几何上看, 把平面上的每个点 (x, y) 都变到 (2 x + y ...
- C#程序计算N阶行列式的值及N元一次方程组
C#程序计算N阶行列式的值及N元一次方程组 用了挺长时间自行完成了C#程序计算N阶行列式的值及N元一次方程组.由于自己没有在网上查阅其他资料,所以只能硬着头皮用最朴素的思想和基础的算法进行编程.在给出 ...
- 全排列(java版)
适用于不同数字的全排列,其实也适用于有重复数字的全排列,只不过的出来的结果有重复,需手动删减掉重复的组合. package testFullPermutation; import java.util. ...
- 两种常用的全排列算法(java)
问题:给出一个字符串,输出所有可能的排列. 全排列有多种算法,此处仅介绍常用的两种:字典序法和递归法. 1.字典序法: 如何计算字符串的下一个排列了?来考虑"926520"这个字符 ...
- 字典序全排列(java实现)
import java.util.Arrays; /** *字典序全排列 *字符串的全排列 *比如单词"too" 它的全排列是"oot","oto&q ...
随机推荐
- 返回头添加cookie信息
返回类型 HttpResponseMessage //构建返回对象 var res= Request.CreateResponse(HttpStstusCode.Ok,返回体) //创建cookie对 ...
- rxjs入门4之rxjs模式设计
观察者模式 (Observer Pattern) 观察者模式其实在日常编码中经常遇到,比如DOM的事件监听,代码如下 function clickHandler(event) { console.lo ...
- C++单链表操作
#include <stdio.h> typedef struct _Node{ int value; _Node *next;}Node; void AddNodeTail(No ...
- 多测师讲解python函数 _open_高级讲师肖sir
open()函数 #open() 函数用于打开一个文件,创建一个 file 对象 #Python open() 函数用于打开一个文件,并返回文件对象, # 在对文件进行处理过程都需要使用到这个函数,如 ...
- MeteoInfoLab脚本示例:LaTeX写数学公式
LaTeX是排版常用的语法,科学计算软件中也常用它来写数学公式(比如MatLab, Matplotlib等),MeteoInfo通过调用JMathLaTeX库也可以实现这样的功能.LaTeX的语法介绍 ...
- C++虚函数与多继承
虚函数 C++用虚函数实现运行时多态,虚函数的实现是由两个部分组成的,虚函数指针与虚函数表. 虚函数指针(vptr)是指向虚函数表的指针,在一个被实例化的对象中,它总是被存放在该对象的地址首位.而虚函 ...
- linux(centos8):安装配置consul集群(consul 1.8.4 | centos 8.2.2004)
一,什么是consul? 1,Consul 是 HashiCorp 公司推出的开源软件,用于实现分布式系统的服务发现与配置. Consul 是分布式的.高可用的. 可横向扩展的 2,官方网站: h ...
- spring boot:用redis+lua实现基于ip地址的分布式流量限制(限流/简单计数器算法)(spring boot 2.2.0)
一,限流有哪些环节? 1,为什么要限流? 目的:通过对并发请求进行限速或者一个时间单位内的的请求进行限速,目的是保护系统可正常提供服务,避免被压力太大无法响应服务. 如果达到限制速率则可以采取预定的处 ...
- linux(centos8):用sort对文本内容排序
一,sort的用途 1,作用: sort命令用于将文本文件内容加以排序. 它能够以行为单位来排序 2,sort常与uniq搭配使用,原因: 用uniq命令去重时, 需要相同的每行位置相邻才能生效, 所 ...
- Centos定时备份 MySQL数据库
一.编写数据库备份脚本 backupmysql.sh #!/bin/bash # Name:bakmysql.sh # This is a ShellScript For Auto DB Backup ...