### 求解线性方程

``````-44.3940 = a * 50.0 + b * 37.0 + tx
-45.3049 = a * 43.0 + b * 39.0 + tx
-44.9594 = a * 52.0 + b * 41.0 + tx
``````

#### 10 个答案:

Cramer's RuleGaussian Elimination 是两个很好的通用算法（另见Simultaneous Linear Equations）。如果您正在寻找代码，请查看GiNaCMaximaSymbolicC++（当然，取决于您的许可要求）。

``````-44.3940 = 50a + 37b + c (A)
-45.3049 = 43a + 39b + c (B)
-44.9594 = 52a + 41b + c (C)

(A-B): 0.9109 =  7a -  2b (D)
(B-C): 0.3455 = -9a -  2b (E)

(D-E): 1.2564 = 16a (F)

(F/16):  a = 0.078525 (G)

Feed G into D:
0.9109 = 7a - 2b
=> 0.9109 = 0.549675 - 2b (substitute a)
=> 0.361225 = -2b (subtract 0.549675 from both sides)
=> -0.1806125 = b (divide both sides by -2) (H)

Feed H/G into A:
-44.3940 = 50a + 37b + c
=> -44.3940 = 3.92625 - 6.6826625 + c (substitute a/b)
=> -41.6375875 = c (subtract 3.92625 - 6.6826625 from both sides)
``````

``````a =   0.0785250
b =  -0.1806125
c = -41.6375875
``````

`````` 7a + 2b =  50
14a + 4b = 100
``````

``````0 = 0 + 0
``````

``````#include <stdio.h>

typedef struct { double r, a, b, c; } tEquation;
tEquation equ1[] = {
{ -44.3940,  50, 37, 1 },      // -44.3940 = 50a + 37b + c (A)
{ -45.3049,  43, 39, 1 },      // -45.3049 = 43a + 39b + c (B)
{ -44.9594,  52, 41, 1 },      // -44.9594 = 52a + 41b + c (C)
};
tEquation equ2[2], equ3[1];

static void dumpEqu (char *desc, tEquation *e, char *post) {
printf ("%10s: %12.8lf = %12.8lfa + %12.8lfb + %12.8lfc (%s)\n",
desc, e->r, e->a, e->b, e->c, post);
}

int main (void) {
double a, b, c;
``````

``````    // First step, populate equ2 based on removing c from equ.

dumpEqu (">", &(equ1[0]), "A");
dumpEqu (">", &(equ1[1]), "B");
dumpEqu (">", &(equ1[2]), "C");
puts ("");

// A - B
equ2[0].r = equ1[0].r * equ1[1].c - equ1[1].r * equ1[0].c;
equ2[0].a = equ1[0].a * equ1[1].c - equ1[1].a * equ1[0].c;
equ2[0].b = equ1[0].b * equ1[1].c - equ1[1].b * equ1[0].c;
equ2[0].c = 0;

// B - C
equ2[1].r = equ1[1].r * equ1[2].c - equ1[2].r * equ1[1].c;
equ2[1].a = equ1[1].a * equ1[2].c - equ1[2].a * equ1[1].c;
equ2[1].b = equ1[1].b * equ1[2].c - equ1[2].b * equ1[1].c;
equ2[1].c = 0;

dumpEqu ("A-B", &(equ2[0]), "D");
dumpEqu ("B-C", &(equ2[1]), "E");
puts ("");
``````

``````    // Next step, populate equ3 based on removing b from equ2.

// D - E
equ3[0].r = equ2[0].r * equ2[1].b - equ2[1].r * equ2[0].b;
equ3[0].a = equ2[0].a * equ2[1].b - equ2[1].a * equ2[0].b;
equ3[0].b = 0;
equ3[0].c = 0;

dumpEqu ("D-E", &(equ3[0]), "F");
puts ("");
``````

``````    // Finally, substitute values back into equations.

a = equ3[0].r / equ3[0].a;
printf ("From (F    ), a = %12.8lf (G)\n", a);

b = (equ2[0].r - equ2[0].a * a) / equ2[0].b;
printf ("From (D,G  ), b = %12.8lf (H)\n", b);

c = (equ1[0].r - equ1[0].a * a - equ1[0].b * b) / equ1[0].c;
printf ("From (A,G,H), c = %12.8lf (I)\n", c);

return 0;
}
``````

``````         >: -44.39400000 =  50.00000000a +  37.00000000b +   1.00000000c (A)
>: -45.30490000 =  43.00000000a +  39.00000000b +   1.00000000c (B)
>: -44.95940000 =  52.00000000a +  41.00000000b +   1.00000000c (C)

A-B:   0.91090000 =   7.00000000a +  -2.00000000b +   0.00000000c (D)
B-C:  -0.34550000 =  -9.00000000a +  -2.00000000b +   0.00000000c (E)

D-E:  -2.51280000 = -32.00000000a +   0.00000000b +   0.00000000c (F)

From (F    ), a =   0.07852500 (G)
From (D,G  ), b =  -0.18061250 (H)
From (A,G,H), c = -41.63758750 (I)
``````

``````  SolverContext context = SolverContext.GetContext();
Model model = context.CreateModel();

Decision a = new Decision(Domain.Real, "a");
Decision b = new Decision(Domain.Real, "b");
Decision c = new Decision(Domain.Real, "c");
model.AddDecisions(a,b,c);
model.AddConstraint("eqA", -44.3940 == 50*a + 37*b + c);
model.AddConstraint("eqB", -45.3049 == 43*a + 39*b + c);
model.AddConstraint("eqC", -44.9594 == 52*a + 41*b + c);
Solution solution = context.Solve();
string results = solution.GetReport().ToString();
Console.WriteLine(results);
``````

=== Solver Foundation Service Report ===

Microsoft.SolverFoundation.Services.Directive

===解决方案详情===

a：0.0785250000000004
b：-0.180612500000001
c：-41.6375875

Template Numerical Toolkit拥有实现这一目标的工具。

``````void GetInverse(const Array2D<double>& A, Array2D<double>& invA)
{
QR<double> qr(A);
invA = qr.solve(I);
}
``````

Array2D在库中定义。

``````> y <- c(-44.394, -45.3049, -44.9594)
> a <- c(50.0, 43.0, 52.0)
> b <- c(37.0, 39.0, 41.0)
> regression = lm(y ~ a + b)
> regression

Call:
lm(formula = y ~ a + b)

Coefficients:
(Intercept)            a            b
-41.63759      0.07852     -0.18061
``````

``````function x = LinSolve(A,y)
%
% Recursive Solution of Linear System Ax=y
% matlab equivalent: x = A\y
% x = n x 1
% A = n x n
% y = n x 1
% Uses stack space extensively. Not efficient.
% C allows recursion, so convert it into C.
% ----------------------------------------------
n=length(y);
x=zeros(n,1);
if(n>1)
x(1:n-1,1) = LinSolve( A(1:n-1,1:n-1) - (A(1:n-1,n)*A(n,1:n-1))./A(n,n) , ...
y(1:n-1,1) - A(1:n-1,n).*(y(n,1)/A(n,n)));
x(n,1) = (y(n,1) - A(n,1:n-1)*x(1:n-1,1))./A(n,n);
else
x = y(1,1) / A(1,1);
end
``````