我有一个相当基本的数学问题,但诀窍是我需要用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
到目前为止,我已经完成了我最好的比赛,但是如果有人能够弄清楚为什么我的母鹿不起作用,那就太可爱了。谢谢!
答案 0 :(得分:1)
这是一个问题:你将tempValue,tempRHS,newValue和neRHS全部声明为int。即使你的矩阵以所有整数值开始,一旦你进入淘汰,它们也不会那么长。这些都应该被宣布为双重 - 就像整数一样,你将不断丢弃分数部分。
答案 1 :(得分:0)
我没有逐行检查你的代码,但最可能的问题在于你的C ++实现和Wikipedia算法之间的数组索引约定的差异。 C ++使用基于0的数组(即第一个数组元素的索引是0),而维基百科算法是基于1的(即第一个数组元素的索引是1)。你很可能错过了某些转换。
假设您了解该算法正在尝试做什么,最好的办法是废弃您的代码并根据您对算法和C ++的理解重新开始。
如果您在理解算法时遇到一些困难,可能需要查看Numerical Recipes in C的副本(第2章在这方面最有用)。由于C和C ++都是基于0的数组语言,与使用维基百科版本作为实现基础相比,您所需的更改应该相对较小
答案 2 :(得分:0)
您没有使用正确的枢轴元素进行划分。在算法的每个步骤中,枢轴元素是A(maxi,j)。但是,在您的代码中,您尝试合并交换元素交换和分割的两个步骤。结果你说
current = equationMatrix.get_element(i,j)
这应该是
current = equationMatrix.get_element(maxi,j)
我希望有所帮助。可能会有更多错误。这只是我看到的第一个。 调试在每一步打印出当前矩阵时可能会有所帮助 算法。当您的高斯消元正常工作时,您的算法将生成一个上三角矩阵,对角线上有1。 (有关更多详细信息,请参阅维基百科页面。)
我希望此代码用于教育目的。那里有很多精细的线性代数库(比如LAPACK)。如果您需要解决线性系统,我强烈建议您使用其中一个漂亮的库,而不是尝试自己动手。