1

我有一个相当基本的数学问题,但诀窍是我在 C++ 中需要它。我现在正在关注维基百科上给出的伪代码。这是我的尝试:

createMatrixForAllSolutions(*this);
std::cout << equationMatrix.to_string() << endl;
bool solved = false;
int rows = equationMatrix.getRows();
int cols = equationMatrix.getCols();
int i = 0;
int j = 0;
int maxi = 0;
double current = 0;
double eqnValue = 0;
double solValue = 0;
std::vector<char> reversedVars;
int sum = 0;
int tempValue;
int tempRHS;
int newValue;
int neRHS;

while (i < rows && j < cols) {
    maxi = i;
    for (int k = i + 1; k < rows; k++) {
        if (abs(equationMatrix.get_element(k, j)) > abs(equationMatrix.get_element(maxi, j)))
            maxi = k;
    }
    if (equationMatrix.get_element(maxi, j) != 0) {
        current = equationMatrix.get_element(i, j);
        for (int x = 0; x < cols; x++) {
            tempValue = equationMatrix.get_element(i, x);
            newValue = equationMatrix.get_element(maxi, x);
            equationMatrix.set_element(i, x, newValue/current);
            equationMatrix.set_element(maxi, x, tempValue);
        }
        tempRHS = solutionMatrix.get_element(i, 0);
        neRHS = solutionMatrix.get_element(maxi, 0);
        solutionMatrix.set_element(i, 0, neRHS/current);
        solutionMatrix.set_element(maxi, 0, tempRHS);
        //SWAP rows i and maxi
        //SWAP RHS i and maxi
        //DIVIDE each entry in row i by current
        //DIVIDE RHS i by current
        for (int u = i + 1; u < rows; u++) {
            eqnValue = equationMatrix.get_element(u, j) - equationMatrix.get_element(i, j) * equationMatrix.get_element(u, j);
            std::cout << "Equation Value: " << eqnValue << endl;
            equationMatrix.set_element(u, j, eqnValue);
            solValue = solutionMatrix.get_element(u, 0) - solutionMatrix.get_element(i, 0) * solutionMatrix.get_element(u, 0);
            std::cout << "Solution Value: " << solValue << endl;
            solutionMatrix.set_element(u, 0, solValue);
        }
        i++;
    }
    j++;
}

我关注的伪代码来自维基百科:

i := 1
j := 1
while (i ≤ m and j ≤ n) do
  Find pivot in column j, starting in row i:
  maxi := i
  for k := i+1 to m do
    if abs(A[k,j]) > abs(A[maxi,j]) then
      maxi := k
    end if
  end for
  if A[maxi,j] ≠ 0 then
    swap rows i and maxi, but do not change the value of i
    Now A[i,j] will contain the old value of A[maxi,j].
    divide each entry in row i by A[i,j]
    Now A[i,j] will have the value 1.
    for u := i+1 to m do
      subtract A[u,j] * row i from row u
      Now A[u,j] will be 0, since A[u,j] - A[i,j] * A[u,j] = A[u,j] - 1 * A[u,j] = 0.
    end for
    i := i + 1
  end if
  j := j + 1
 end while

到目前为止,我已经做到了最好的匹配,但是如果有人能够弄清楚为什么我的母鹿不工作,那就太好了。谢谢!

4

3 回答 3

1

这是一个问题:您将 tempValue、tempRHS、newValue 和 neRHS 都声明为整数。即使您的矩阵以所有整数值开始,一旦您进入消除,它们也不会保持那么长时间。这些都应该声明为 double - 作为整数,您将不断丢弃小数部分。

于 2011-10-09T06:45:39.197 回答
0

我没有逐行浏览您的代码,但最可能的问题在于您的 C++ 实现和 Wikipedia 算法之间的数组索引约定的差异。C++ 使用从 0 开始的数组(即第一个数组元素的索引是 0),而 Wikipedia 算法是从 1 开始的(即第一个数组元素的索引是 1)。您可能在某处错过了一些转换。

假设您了解算法试图做什么,最好的选择是废弃您的代码并根据您对算法和 C++ 的理解重新开始。

如果你在理解算法上有一些困难,你可能想看一份C 语言中的数值食谱(第 2 章在这方面最有用)。由于 C 和 C++ 都是基于 0 的数组语言,因此与使用 Wikipedia 版本作为实现的基础相比,您需要的更改应该相对较小

于 2011-10-09T05:10:27.067 回答
0

您没有除以正确的枢轴元素。在算法的每一步,枢轴元素都是 A(maxi,j)。但是,在您的代码中,您尝试合并交换和除以枢轴元素的两个步骤。结果你说

  current = equationMatrix.get_element(i,j) 

这应该读

  current = equationMatrix.get_element(maxi,j) 

我希望这会有所帮助。可能有更多的错误。这只是我看到的第一个。在调试时在算法的每一步打印出当前矩阵可能会有所帮助。当您的高斯消除正常工作时,您的算法将产生一个对角线上为 1 的上三角矩阵。(有关更多详细信息,请参阅维基百科页面。)

我希望此代码用于教育目的。那里有许多很好的线性代数库(例如 LAPACK)。如果您需要解决线性系统,我强烈建议您使用这些不错的库之一,而不是尝试自己动手。

于 2011-10-09T06:12:40.070 回答