Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 35 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
35
Dung lượng
151,64 KB
Nội dung
145
Chơng 10 : Giải hệ phơng trình đại số tuyến tính
Đ1.Phơng pháp Gauss
Có nhiều phơng pháp để giải một hệ phơng trình tuyến tính dạng AX = B. Phơng
pháp giải sẽ đơn giản hơn nếu ma trận A có dạng tam giác nghĩa là có dạng :
333231
2221
11
aaa
0aa
00a
hay
33
2322
131211
a00
aa0
aaa
Trong trờng hợp đầu tiên,ma trận đợc gọi là ma trận tam giác dới và trờng hợp
thứ hai ma trận đợc gọi là ma trận tam giác trên.Phơng trình tơng ứng với ma trận tam
giác dới có dạng tờng minh là :
11 1 2
3
1
21 1
2
32
31 1
23
3
0
0
0
22
32 33
ax x
x
b
ax
a
x
xb
ax
a
x
a
x
b
++ =
++=
++ =
Với phơng trình dạng này chúng ta sẽ giải phơng trình từ trên xuống.
Chơng trình giải phơng trình ma trận tam giác dới là :
Chơng trình 10-1
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define max 10
void main()
{
float a[max][max];
float b[max],x[max];
int i,j,k,n,t;
float s,c;
char tl;
clrscr();
printf("Cho so phuong trinh n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a\n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran a ma ban da nhap\n");
printf("\n");
146
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
t=1;
flushall();
while (t)
{
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
printf("Ma tran a ban dau\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
printf("Cho cac phan tu cua ma tran b\n");
for (i=1;i<=n;i++)
{
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
printf("\n");
printf("Ma tran b ma ban da nhap");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %10.5f\n",i,b[i]);
printf("\n");
flushall();
t=1;
while (t)
{
147
printf("Co sua ma tran b khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
if (toupper(tl)=='K')
t=0;
}
printf("\n");
printf("Ma tran b ban dau");
printf("\n");
for (i=1;i<=n;i++)
printf("%15.5f\n",b[i]);
{
if (a[1][1]==0)
if (b[1]!=0)
printf("He da cho vo nghiem\n");
else
{
printf("He da cho co vo so nghiem");
x[n]=c;
}
else
x[1]=b[1]/a[1][1];
for (i=2;i<=n;i++)
{
s=0;
for (k=1;k<=i-1;k++)
s=s+a[i][k]*x[k];
x[i]=(b[i]-s)/a[i][i];
}
printf("\n");
printf("Nghiem cua he da cho la");
printf("\n");
for (i=1;i<=n;i++)
printf("x[%d] = %10.5f\n",i,x[i]);
getch();
}
}
Phơng trình tơng ứng với ma trận tam giác trên có dạng tờng minh là :
11 1
2
3
1
1
23
2
1
2
3
3
12
13
22 23
33
0
0
0
ax
a
x
a
x
b
x
a
x
a
x
b
x
x
a
x
b
++ =
++ =
++ =
Với phơng trình này chúng ta giải từ dới lên.
148
Ch−¬ng tr×nh gi¶i ph−¬ng tr×nh ma trËn tam gi¸c trªn lµ :
Ch−¬ng tr×nh 10-2
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define max 10
void main()
{
float a[max][max];
float b[max],x[max];
int i,j,k,n,t;
float s,c;
char tl;
clrscr();
printf("Cho so phuong trinh n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a :\n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran a ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
t=1;
flushall();
while (t)
{
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
149
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
printf("Ma tran a ban dau");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
printf("Cho cac phan tu cua ma tran b : \n");
for (i=1;i<=n;i++)
{
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
printf("\n");
printf("Ma tran b ma ban da nhap");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %10.5f\n",i,b[i]);
printf("\n");
flushall();
t=1;
while (t)
{
printf("Co sua ma tran b khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
if (toupper(tl)=='K')
t=0;
}
printf("\n");
printf("Ma tran b ban dau\n");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %10.5f\n",i,b[i]);
150
printf("\n");
{
if (a[n][n]==0)
if (b[n]!=0)
printf("He da cho vo nghiem");
else
{
printf("He da cho co vo so nghiem");
x[n]=c;
}
else
x[n]=b[n]/a[n][n];
for (i=n-1;i>=1;i )
{
s=0;
for (k=i+1;k<=n;k++)
s=s+a[i][k]*x[k];
x[i]=(b[i]-s)/a[i][i];
}
printf("\n");
printf("Nghiem cua he da cho la\n");
printf("\n");
for (i=1;i<=n;i++)
printf("x[%d] = %10.5f\n",i,x[i]);
getch();
}
}
Tuy nhiên, các hệ phơng trình đơn giản hiếm khi gặp trong thực tế. Các hệ phơng
trình tuyến tính có thể biểu diễn dới dạng tam giác nếu định thức của nó khác không, nghĩa
là phơng trình có nghiệm.Chúng ta biết rằng các nghiệm của hệ không đổi nếu ta thay một
hàng bằng tổ hợp tuyến tính của các hàng khác.Nh vậy bằng một loạt các biến đổi ta có thể
đahệ ban đầu về dạng tam giác. Đó chính là nội dung của phơng pháp loại trừ Gauss.
Chúng ta hãy xét hệ phơng trình :
11 1
2
3
1
21 1
2
3
2
31 1
23
3
12
13
22
23
32 33
ax
a
x
a
x
b
ax
a
x
a
x
b
ax
a
x
a
x
b
++ =
++ =
++ =
Nhân hàng thứ nhất với a
21
/a
11
ta có :
21 1
21
11
12 2
21
11
13 3
21
11
1
ax
a
a
ax
a
a
ax
a
a
b
++=
Số hạng đầu của phơng trình bằng số hạng đầu của hàng thứ hai trong hệ phơng trình ban
đầu.Khi trừ hàng một đã đợc biến đổi cho hàng 2 ta nhận đợc hàng 2 mới
0
1
22
21
11
12
223
21
11
13
3
2
21
11
1
x
a
a
a
a
xa
a
a
a
x
b
a
a
b
+ + =
()()
Ta tiếp tục cách này để loại trừ x
1
ra khỏi hàng thứ 3.Phơng trình trở thành :
11 12 13
22 23
32 33
1
2
3
1
2
3
0
0
,, ,
,,
,,
,
'
,
aa a
aa
aa
x
x
x
b
b
b
ì=
151
với a
,
11
= a
11
; a
,
12
= a
12
; a
,
13
= a
13
; a
,
13
= a
13
; b
,
1
= b
1
22 22
21
11
12
,
aa
a
a
a
=
23 23
21
11
13
,
aa
a
a
a
=
32 32
31
11
12
,
aa
a
a
a
=
33 33
31
11
13
,
aa
a
a
a
=
22
21
11
1
,
bb
a
a
b
=
33
31
11
1
,
bb
a
a
b
=
Ta loại trừ số hạng chứa x
3
trong dòng thứ 3 bằng cách tơng tự.Ta nhân hàng thứ 2 trong hệ
A
'
X = B
'
với a
,
32
/a
,
22
và đem trừ đi hàng thứ 3 trong hệ mới.Nh vậy số hạng chứa x
3
biến
mất và ta nhận đợc ma trận tam giác trên.
11 12 13
22 23
33
1
2
3
1
2
3
0
0
0
,, ,, ,,
,, ,,
,,
,,
,,
,,
aa a
aa
a
x
x
x
b
b
b
ì=
với
11 11
,, ,
aa
=
12 12
,, ,
aa
=
13 13
,, ,
aa
=
11
,, ,
bb
=
22 22
,, ,
aa
=
23 23
,, ,
aa
=
22
,, ,
bb
=
33 33
32
22
23
,, ,
,
,
,
aa
a
a
a
=
33
33
22
2
,, ,
,
,
,
bb
a
a
b
=
Các phép tính này chỉ thực hiện đợc khi a
11
0 và a
,
11
0.
Với một hệ có n phơng trình,thuật tính hoàn toàn tơng tự.Sau đây là chơng trình
giải hệ phơng trình n ẩn số bằng phơng pháp loại trừ Gauss.
Chơng trình 10-3
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define max 10
void main()
{
float b[max],x[max];
float a[max][max];
int i,j,k,n,t;
float c,s,d;
char tl;
clrscr();
printf("Cho so phuong trinh n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a :\n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran a ma ban da nhap\n");
printf("\n");
152
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
t=1;
flushall();
while (t)
{
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
printf("Ma tran a ban dau\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
printf("Cho cac phan tu cua ma tran b : \n");
for (i=1;i<=n;i++)
{
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
printf("\n");
printf("Ma tran b ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %15.5f\n",i,b[i]);
printf("\n");
flushall();
t=1;
while (t)
{
153
printf("Co sua ma tran b khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%f",&i);
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
if (toupper(tl)=='K')
t=0;
}
printf("\n");
printf("Ma tran b\n");
for (i=1;i<=n;i++)
printf("b[%d] = %15.5f\n",i,b[i]);
printf("\n");
for (k=1;k<=n-1;k++)
{
for (i=k+1;i<=n;i++)
{
b[i]=b[i]-b[k]*a[i][k]/a[k][k];
for (j=k+1;j<=n;j++)
a[i][j]=a[i][j]-a[k][j]*a[i][k]/a[k][k];
}
}
{
if (a[n][n]==0)
if (b[n]==0)
printf("He da cho vo nghiem");
else
{
printf("He da cho co vo so nghiem");
x[n]=c;
}
else
x[n]=b[n]/a[n][n];
for (i=n-1;i>=1;i )
{
s=0;
for (k=i+1;k<=n;k++)
s=s+a[i][k]*x[k];
x[i]=(b[i]-s)/a[i][i];
}
printf("\n");
printf("Nghiem cua he da cho la\n");
printf("\n");
for (i=1;i<=n;i++)
printf("x[%d] = %15.5f\n",i,x[i]);
154
getch();
}
}
Đ2.Phơng pháp Gauss-Jordan
Xét hệ phơng trình AX=B. Khi giải hệ bằng phơng pháp Gauss ta đa nó về dạng
ma trận tam giác sau một loạt biến đổi. Phơng pháp khử Gauss-Jordan cải tiến khử Gauss
bằng cách đa hệ về dạng :
EX = B
*
và khi đó nghiệm của hệ chính là B
*
.Trong phơng pháp Gauss-Jordan mỗi bớc tính phải
tính nhiều hơn phơng pháp Gauss nhng lại không phải tính nghiệm.Để đa ma trận A về
dạng ma trận E tại bớc thứ i ta phải có a
ii
= 1 và a
ij
=0.Nh vậy tại lần khử thứ i ta biến đổi :
1.a
ij
= a
ij
/a
ii
(j=i+1,i+2, ,n)
2.k=1,2, ,n
a
kj
= a
kj
- a
ij
a
ki
(j=i+1,i+2, ,n)
b
k
= b
k
- b
i
a
ki
Ví dụ : Cho hệ
=
ì
21
26
32
24
x
x
x
x
9440
45.652
45104
0248
4
3
2
1
Biến đổi lần 1 : ta chia hàng 1 cho a
11
= 8;nhân hàng 1 vừa nhận đợc với 4 và lấy hàng 2
trừ đi; nhân hàng 1 vừa nhận đợc với 2 và lấy hàng 3 trừ đi;giữ nguyên hàng 4 vì phần tử
đầu tiên đã bằng 0 ta có
=
ì
21
20
20
3
x
x
x
x
9440
4640
4480
025.05.01
4
3
2
1
Biến đổi lần 2 : ta chia hàng 2 cho a
22
= 8;nhân hàng 2 vừa nhận đợc với 0.5 và lấy hàng 1
trừ đi; nhân hàng 2 vừa nhận đợc với 4 và lấy hàng 3 trừ đi; nhân hàng 2 vừa nhận đợc với
4 và lấy hàng 4 trừ đi ta có :
=
ì
11
10
5.2
75.1
x
x
x
x
7200
2400
5.05.010
25.0001
4
3
2
1
Biến đổi lần 3 : ta chia hàng 3 cho a
33
= 4;giữ nguyên hàng 1;nhân hàng 3 vừa nhận đợc
với 0.5 và lấy hàng 2 trừ đi; nhân hàng 3 vừa nhận đợc với 2 và lấy hàng 4 trừ đi ta có :
=
ì
6
5.2
25.1
75.1
x
x
x
x
6000
5.0100
25.0010
25.0001
4
3
2
1
[...]... phơng trình nh vậy c tên là hệ thống Cramer 172 Định lí Crame : Hệ thống Crame c nghiệm duy nhất đ c cho bởi c ng th c : xi = A ( i) A (i = 1, , n) trong đó A(i) là ma trận nhận đ c từ A bằng c ch thay c t thứ i bởi c t B=[ b1 , ,bn]T Nh vậy để giải hệ bằng phơng pháp Cramer chúng ta lần lợt tính cc định th c của ma trận và ma trận thay thế rồi tìm nghiệm theo c ng th c Cramer Chơng trình sau mô... đ c phân tích thành dạng A = RTR trong đó R là một ma trận tam gi c trên.Hệ phơng trình l c đó chuyển thành AX = RTRX = B.Nh vậy tr c hết ta phân tích ma trận A thành tích hai ma trận.Sau đó giải hệ phơng trình RTY = B và cuối c ng là hệ RX = Y.Chơng trình mô tả thuật toán này đ c cho dới đây : Chơng trình 10-5 #include #include #include #include #include ... trình ban đầu Chơng trình giải hệ phơng trình nh vậy cho ở dới đây : 176 Chơng trình 10-10 #include #include #include #include #include #define max 20 void main() { int i,j,k,l,n,m; float s,t,a[max][max],b[max][max],x[max]; clrscr(); printf("Cho so an so cua phuong trinh n = "); scanf("%d",&n); printf("Cho phan thuc cua cac he so,ke ca ve phai\n");... Chơng trình sau mô tả thuật toán này, Chơng trình 10-.9 // Cramer; #include #include #include #define max 50 void main() { float r[max][max],a[max][max]; float b[max],x[max]; float delta[max]; int i,j,k,l,t,n,ok1,ok2,t1; float c, d; char tl; clrscr(); printf("Cho so an cua phuong trinh n = "); scanf("%d",&n); printf("Cho cac phan tu cua ma tran a : \n"); for (i=1;i . trình c nghiệm.Chúng ta biết rằng c c nghiệm c a hệ không đổi nếu ta thay một
hàng bằng tổ hợp tuyến tính c a c c hàng kh c. Nh vậy bằng một loạt c c biến. float s ,c;
char tl;
clrscr();
printf("Cho so phuong trinh n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma