2011-10-09 4 views
1

저는 수학에 관한 기본적인 질문을 가지고 있습니다. 그러나 트릭은 C++에서 필요합니다. 나는 현재 Wikipedia에 주어진 pseudocode를 따르고있다. 위키 백과에서가우스 제거 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 

그것은 지금까지하지만 아무도 그 이유를 알아낼 수 있다면 내 미상은 작동하지 않습니다. 사랑 스러울 것입니다. 감사!

+1

코드는 어떻게됩니까? 그것은 컴파일합니까? 그것은 추락합니까? 그것은 잘못된 대답을 제공합니까? –

+0

잘못된 답변을 제공합니다 ... 사실 매우 큰 숫자입니다. – Brandon

답변

0

줄마다 코드를 검토하지는 않았지만 C++ 구현과 위키 백과 알고리즘 간의 배열 인덱싱 규칙 차이가 가장 큰 문제입니다. Wikipedia 알고리즘은 1 기반 (즉, 첫 번째 배열 요소의 색인은 1) 인 반면 C++은 0 기반 배열 (즉, 첫 번째 배열 요소의 색인은 0)을 사용합니다. 어딘가에서 전환을 놓친 것 같습니다.

알고리즘이 무엇을 시도하는지 이해한다고 가정하면 알고리즘 및 C++에 대한 이해를 기반으로 코드를 스크랩하고 다시 시작하는 것이 가장 좋습니다.

알고리즘을 이해하는 데 어려움이있는 경우 Numerical Recipes in C 사본을 볼 수 있습니다 (2 장은이 점에서 가장 유용합니다). C와 C++ 모두 0 기반 배열 언어이기 때문에 위키 피디 어 버전을 구현의 기초로 사용할 때보 다 비교적 작은 변경이 필요합니다.

+0

코드에 인덱싱 오류가 있다고 생각하지 않습니다. – codehippo

0

올바른 피벗 요소로 나누지 않습니다. 알고리즘의 각 단계에서 피벗 요소는 A (maxi, j)입니다. 그러나 코드에서 스와핑과 피벗 요소로 나누는 두 단계를 병합하려고합니다. 그 결과 당신이 내가 희망이 도움이

current = equationMatrix.get_element(maxi,j) 

을 읽어야

current = equationMatrix.get_element(i,j) 

을 말한다. 더 많은 버그가있을 수 있습니다. 이것은 제가 처음 보았던 것입니다. 알고리즘의 각 단계 에서 현재 매트릭스를 인쇄하도록 디버깅 할 때 도움이 될 수 있습니다. 가우시안 제거가 올바르게 작동하면 알고리즘은 대각선에 1을 갖는 상 삼각 행렬을 생성합니다. 자세한 내용은 Wikipedia 페이지를 참조하십시오.

이 코드가 교육적 목적으로 사용되기를 바랍니다. LAPACK과 같은 많은 훌륭한 선형 대수 라이브러리가 있습니다. 선형 시스템을 해결해야 할 필요가 있다면 자신 만의 라이브러리를 사용하기보다는 멋진 라이브러리 중 하나를 사용하는 것이 좋습니다.

1

tempValue, tempRHS, newValue 및 neRHS를 모두 int로 선언하고 있습니다. 매트릭스가 모든 정수 값으로 시작하더라도, 일단 제거되면 그 길이 머물러 있지 않습니다. 이것들은 모두 int로 두 번 선언해야합니다, 당신은 끊임없이 분수 부분을 던져 버릴 것입니다.