1:高斯消元法算法步骤
1:选择主元;即选择对角元素,保证其为所在列的最大,避免大数除以小数出现溢出,其实是避免其值为0;
2:当前主元不为最大值,交换两行;
3:判断主元是否为0,若是则不是唯一解;
4:逐行消元;
5:对角线元素归一化;
6:回代消除对角线之上的元素。
2:算法结果展示
百度知道上的一道题目,用来测试
图中是原题给出的答案:
下图是算法给出的答案
这样看来结果还是很不错的。
3:代码
这个是主方法,主要是使用一维数组实现,对应的方法参数要给出方程增广矩阵的每一行的个数。
内部方法将在后面给出,这个方法可以直接使用。
/**
*
* @param array 系数矩阵 增广矩阵
* @param colNum 列向量个数(从第0列开始)
* @return boolean 是否得出结果
*/
public boolean Resolve(float[] array, int colNum){
//行数
int rows = array.length / colNum ;
//逐行选择主元 第 i 行 ,第i列 的元素(i,i)
for (int i = 0; i < rows; i++) {
//按列选择主元
int pivotRow = SelectPivotalElement(array,colNum,i);
//如果主元不是目前所在的i列,则交换
if(pivotRow!=i){
swapCol(array,pivotRow,i,colNum);
}
if(array[i*colNum+i]==0){
System.out.println("不含有唯一解");
return false ;
}
//消元得到上三角
for (int j = 0; j < colNum; j++) {
emissElement(array,j,colNum);
}
}
//主元素归一化
for (int i = 0; i < rows; i++) {
ElementBack(array,i,colNum);
}
//回代消元,从最后一行开始
for (int i = rows-1; i > 0; i--) {
backEmiss(array,i,colNum);
}
return true ;
}
用于内部实现的各个方法
/**
* 回代消元
* @param array
* @param i 第i行之上的开始消除
* @param colNum 矩阵每一行的个数
*/
private static void backEmiss(float[] array, int i, int colNum) {
for (int j = i; j >0; j--) {
float fractor = array[(j-1)*colNum+i] ;
array[(j-1)*colNum+i] = 0 ;
array[j*colNum-1] = array[j*colNum-1] - array[(i+1)*colNum-1]*fractor ;
}
}
/**
* 元素归一化处理
* @param array
* @param i 第 i 行 归一化处理
* @param colNum 矩阵列数 ,每行元素个数
*/
private static void ElementBack(float[] array, int i, int colNum) {
//每行的长度
int len = array.length / colNum ;
float factor = array[i * colNum + i] ;
for (int j = i * colNum + i; j < (i+1)*colNum; j++) {
array[j] = array[j] / factor ;
}
}
/**
* 逐行消元
* @param array
* @param i 标示第 i 行的主元
* @param colNum
*/
private static void emissElement(float[] array, int i, int colNum) {
//矩阵行数
int len = array.length / colNum ;
//第i+1行开始消元
for (int j = (i+1); j <len; j++) {
//int j = 1 ;
//消元系数
float index = array[j*colNum+i] / array[i * colNum + i] ;
int ii = i * colNum + i ;
for (int k = j*colNum + i; k < (j+1)*colNum ; k++,ii++) {
array[k] = array[k] - array[ii]*index ;
}
}
}
/**
* 交换两行
* @param array
* @param dist 目标行
* @param src 原来的行
* @param colNum 行向量的长度
*/
private static void swapCol(float[] array, int dist, int src,int colNum) {
int distance = (dist - src)*colNum ;
for (int j = src*colNum; j < (src+1)*colNum; j++) {
float temp = array[j] ;
array[j] = array[j+distance] ;
array[j+distance] = temp ;
}
}
/**
*
* @param array
* @param colNum
* @param i 第i行的主元
* @return 主元所在的列
*/
private static int SelectPivotalElement(float[] array,int colNum,int i) {
//返回的所选择的主元所在列的索引
int pivotColIndex = 0 ;
//中间变量
float max = 0 ;
for (int j = i*colNum + i; j < array.length; j+=colNum) {
if(Math.abs(max)<Math.abs(array[j])){
max = array[j];
pivotColIndex = j ;
}
}
//返回主元所在的行
return pivotColIndex/colNum;
}
本文介绍了高斯消元法的算法步骤,包括选择主元、行交换、判断主元、逐行消元、归一化和回代。通过一个具体的例子展示了算法结果,并提供了Java代码实现,使用一维数组处理方程的增广矩阵。
&spm=1001.2101.3001.5002&articleId=50471115&d=1&t=3&u=2adab58dd7464db39479f9e5e9f85696)
332

被折叠的 条评论
为什么被折叠?



