2

我必须设计一个算法作为前向消除的扩展,它在矩阵上进行高斯乔丹消除。我的程序正在执行和创建数字的对角线,但它们并不全是 1。它也不会访问第一行和第一列以将它们更改为 0。最后一列,答案应该在的那一列,没有改变。有什么想法可以让我更接近解决方案吗?

#include <cmath>

using namespace std;

double BetterForwardElimination(double A[8][9])
{

//Implements Gaussian elimination with partial pivoting
//Input: Matrix A[1..n,1..n] and column-vector b[1..n]
//Output: An equivalent upper-triangular matrix in place ofAand the
//corresponding right-hand side values in place of the (n+1)st column

    //size of array
    int n = 8;
    //int n = sizeof(A)/sizeof(A[0]);

for (int i = 1; i<n; i++)
{
    int pivotrow = i;
    for (int j=i+1; j<n; j++)
    {
        if (A[j][i] > A[pivotrow][i])
        {
            pivotrow = j;
        }
    }

    for (int k=i; k<n-1; k++)
    {
        swap(A[i][k], A[pivotrow][k]);
    }

    for (int j=i+1; j<n; j++)
    {
        //int temp = A[j][i]/A[i][i];
        for (int k = i; k<n; k++)
        {
            A[j][k] = A[j][k] - A[i][k]*(A[j][i]/A[i][i]);
        }
        A[i][j] = 0;
    }
}

return A[n][n];
}

我的输出是这样的:

1   1   1   1   1   1   1   1   0   
1   2   0   0   0   0   0   0   0   
1   0   3   0   0   0   0   0   0   
1   0   0   4   0   0   0   0   0   
11  0   0   0   5   0   0   0   20  
1   0   0   0   0   1   0   0   34  
1   0   0   0   0   0   1   0   -51 
1   0   0   0   0   0   0   -1  -6

预期输出应该是:

1   0   0   0   0   0   0   0   2   
0   1   0   0   0   0   0   0   3   
0   0   1   0   0   0   0   0   5   
0   0   0   1   0   0   0   0   7   
0   0   0   0   1   0   0   0   -7  
0   0   0   0   0   1   0   0   -5  
0   0   0   0   0   0   1   0   -3  
0   0   0   0   0   0   0   1   -2
4

2 回答 2

1

根据算法,A[j][i] > A[pivotrow][i]应该是|A[j][i]| > |A[pivotrow][i]|,两者都是绝对值。你的交换功能在哪里?我不认为 C++ 有它自己的swap(int[][] a, int[][]b).

于 2013-10-09T05:28:04.887 回答
1

我刚刚创建了一个QMatrix类。它使用内置的矢量 > 容器。

您可以按如下方式使用它:

#include "QMatrix.h"
#include <iostream>

int main(){
QMatrix<double> A(3,3,true);
QMatrix<double> Result = A.inverse()*A; //should give the idendity matrix

std::cout<<A.inverse()<<std::endl;
std::cout<<Result<<std::endl; // for checking
return 0;
}

如果你想看看它是如何工作的,反函数的实现如下:

该类具有以下字段:

template<class T> class QMatrix{
public:
int rows, cols;
std::vector<std::vector<T> > A;

逆()函数:

template<class T> 
QMatrix<T> QMatrix<T>:: inverse(){
Identity<T> Id(rows); //the Identity Matrix as a subclass of QMatrix.
QMatrix<T> Result = *this; // making a copy and transforming it to the Identity matrix
T epsilon = 0.000001;
for(int i=0;i<rows;++i){
    //check if Result(i,i)==0, if true, switch the row with another

    for(int j=i;j<rows;++j){
        if(std::abs(Result(j,j))<epsilon) { //uses Overloading()(int int) to extract element from Result Matrix
            Result.replace_rows(i,j+1); //switches rows i with j+1
        }
        else break;
    }
    // main part, making a triangular matrix
    Id(i)=Id(i)*(1.0/Result(i,i));
    Result(i)=Result(i)*(1.0/Result(i,i));  // Using overloading ()(int) to get a row form the matrix
    for(int j=i+1;j<rows;++j){
        T temp = Result(j,i);
        Result(j) = Result(j) - Result(i)*temp;
        Id(j) = Id(j) - Id(i)*temp; //doing the same operations to the identity matrix
        Result(j,i)=0; //not necessary, but looks nicer than 10^-15
    }
}

// solving a triangular matrix 
for(int i=rows-1;i>0;--i){
    for(int j=i-1;j>=0;--j){
        T temp = Result(j,i);
        Id(j) = Id(j) - temp*Id(i);
        Result(j)=Result(j)-temp*Result(i);
    }
}

return Id;
}

它工作得很好......但应该有办法在不影响灵活性的情况下提高它的速度。

于 2015-04-16T22:08:48.643 回答