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

私はこれまでのところ最善を尽くしてきましたが、誰かが私のdoが機能しない理由を理解できれば、それは素晴らしいことです. ありがとう!

4

3 に答える 3

1

ここに 1 つの問題があります。tempValue、tempRHS、newValue、および neRHS をすべて int として宣言しています。マトリックスがすべて整数値で始まったとしても、消去に入ると、それらはそのままでは長く続きません。これらはすべて double として宣言する必要があります - int として、小数部分を常に捨てることになります。

于 2011-10-09T06:45:39.197 に答える
0

コードを1行ずつ調べていませんが、最も可能性の高い問題は、C++実装とウィキペディアアルゴリズムの配列インデックス規則の違いにあります。C ++は0ベースの配列(つまり、最初の配列要素のインデックスは0)を使用しますが、ウィキペディアのアルゴリズムは1ベース(つまり、最初の配列要素のインデックスは1)です。どこかで変換を逃した可能性があります。

アルゴリズムが何をしようとしているのかを理解していると仮定すると、最善の策は、アルゴリズムとC ++の理解に基づいて、コードを廃棄して最初からやり直すことです。

アルゴリズムの理解に問題がある場合は、Cの数値レシピのコピーを確認することをお勧めします(この点では、第2章が最も役立ちます)。CとC++はどちらも0ベースの配列言語であるため、実装の基礎としてWikipediaバージョンを使用する場合と比較して、必要な変更は比較的小さいはずです。

于 2011-10-09T05:10:27.067 に答える
0

正しいピボット要素で分割していません。アルゴリズムの各ステップで、ピボット要素はA(maxi、j)です。ただし、コードでは、ピボット要素によるスワッピングと除算の2つのステップをマージしようとします。結果としてあなたは言う

  current = equationMatrix.get_element(i,j) 

これは読む必要があります

  current = equationMatrix.get_element(maxi,j) 

それがお役に立てば幸いです。さらにバグがあるかもしれません。これは私が最初に見たものです。デバッグ時に、アルゴリズムの各ステップで現在の行列を出力すると役立つ場合があります。ガウスの消去法が正しく機能している場合、アルゴリズムは対角線上に1が付いた上三角行列を生成します。(詳細については、ウィキペディアのページを参照してください。)

このコードが教育目的であることを願っています。そこには多くの細かい線形代数ライブラリ(LAPACKなど)があります。線形システムを解く必要がある場合は、独自のライブラリを作成するのではなく、これらの優れたライブラリの1つを使用することを強くお勧めします。

于 2011-10-09T06:12:40.070 に答える