ĐẠI HỌC ĐÀ NẴNG
TRƯỜNG ĐẠI HỌC BÁCH KHOA
KHOA CÔNG NGHỆ THÔNG TIN
BÀI BÁO CÁO:
Thực hành
PHƯƠNG PHÁP TÍNH
Giáo Viên hướng dẫn: Nguyễn Văn Nguyên
Sinh Viên Thực Hiện: Phạm Duy Dy
Lớp: 11T4
Nhóm: 91
Bài số 1:
1. Viết chương trình tính giá trị đa thức p(x) bậc n tổng quát theo sơ đồ Hoocner.
Thuật toán:
- Nhập : bậc đa thức n, giá trị cần tính c, các hệ số a
i
()
- Xử lý: Gán p = a
0
Lặp i = 1 n : p = p * c + a
i
- Xuất kết quả: p
CODE
#include <conio.h>
#include <stdio.h>
void nhap(float a[100], int n)
{int i;
printf("\n");
for(i=1;i<=n+1;i++)
{
printf(" Nhap he so cua X^%d : ",n-i+1);
scanf("%f",&a[i]);
}
}
float tinh(float a[100], int n, float c)
{
int i;
float p;
p=a[1];
for(i=2;i<=n+1;i++)
p=p*c+a[i];
return p;
}
main()
{
int i, n;
float c,a[100];
printf("Nhap bac cua da thuc: ");
scanf("%d",&n);
nhap(a,n);
printf("\nNhap gia tri can tinh: ");
scanf("%f",&c);
printf("Ket qua: %0.3f ",tinh(a,n,c));
getch();
}
Kết quả chương trình:
2. Viết chương trình thực hiện:
a. Khai báo (định nghĩa) hàm tính giá trị đa thức p(x) bậc n tổng quát theo sơ đồ
Hoocner
b. Nhập vào đa thức p(x) bậc n và 2 giá trị thực y, z. Tính:
S1 = p(y) + p(z)
S2 = p(1) + p(2) + … + p(n)
CODE
#include <conio.h>
#include <stdio.h>
void nhap(float a[100], int n)
{
int i;
printf("\n");
for(i=1;i<=n+1;i++)
{
printf(" Nhap he so cua X^%d : ",n-i+1);
scanf("%f",&a[i]);
}
}
float tinh(float a[100], int n, float c)
{
int i;
float p;
p=a[1];
for(i=2;i<=n+1;i++)
p=p*c+a[i];
return p;
}
main()
{
int i, n;
float c,a[100],y,z,s1,s2;
printf("Nhap bac cua da thuc: ");
scanf("%d",&n);
nhap(a,n);
for(i=1;i<=n;i++)
s2= s2 + tinh(a,n,i);
printf("\nKet qua S2=f(1)+f(2)+ +f(n) la: %0.3f ",s2);
printf("\n\nNhap gia tri y: ");
scanf("%f",&y);
printf("Nhap gia tri z: ");
scanf("%f",&z);
printf("\nKet qua S1=f(y)-f(z) la: %0.3f ",tinh(a,n,c));
getch();
}
Kết quả chương trình:
3. Nhập vào 2 đa thức pn(x) bậc n, pm(y) bậc m và giá trị c. Tính pn(c) + pm(c)
CODE
#include <conio.h>
#include <stdio.h>
void nhap(float a[100], int n)
{
int i;
printf("\n");
for(i=1;i<=n+1;i++)
{
printf(" Nhap he so cua X^%d : ",n-i+1);
scanf("%f",&a[i]);
}
}
float tinh(float a[100], int n, float c)
{
int i;
float p;
p=a[1];
for(i=2;i<=n+1;i++)
p=p*c+a[i];
return p;
}
main()
{
int i,n1,n2;
float c,a[100],b[100];
printf("Nhap bac cua da thuc Pn(x): ");
scanf("%d",&n1);
nhap(a,n1);
printf("\nNhap bac cua da thuc Pm(y): ");
scanf("%d",&n2);
nhap(b,n2);
printf("\nNhap gia tri can tinh: ");
scanf("%f",&c);
printf("Ket qua Pn(%.3f)-Pm(%.3f): %.3f ",c,c,tinh(a,n1,c)-tinh(b,n2,c));
getch();
}
Kết quả chương trình:
4. Cho đa thức p(x) bậc n, viết chương trình xác định các hệ số của đa thức p(y+c)
theo sơ đồ Hoocner tổng quát.
Thuật toán:
- Nhập : n, c, a
i
(i = )
- Lặp k = n → 1
Lặp i = 1 → k : a
i
= a
i-1
* c + a
i
- Xuất : a
i
(i = )
CODE
#include <conio.h>
#include <stdio.h>
void nhap(float a[100], int n)
{
int i;
printf("\n");
for(i=1;i<=n+1;i++)
{
printf(" Nhap he so cua X^%d : ",n-i+1);
scanf("%f",&a[i]);
}
}
float tinh(float a[100], int n, float c)
{
int i,k;
for(k=n+1;k>=1;k )
for(i=2;i<=n+1;i++)
a[i]=a[i-1]*c+a[i];
printf("\n");
for(i=1;i<=n+1;i++)
printf(" He so X^%d cua da thuc f(x+%.3f): %.3f \n",n-i+1,c,a[i]);
}
main()
{
int n;
float c,a[100];
printf("Nhap bac cua da thuc: ");
scanf("%d",&n);
nhap(a,n);
printf("\nNhap gia tri c: ");
scanf("%f",&c);
tinh(a,n,c);
getch();
}
Kết quả chương trình:
5. Viết chương trình tìm nghiệm gần đúng cho phương trình có dạng tổng quát:
f(x) = a0xn + a1xn-1 + … + an-1x + an = 0 bằng phương pháp chia đôi
Thuật toán:
- Khai báo f(x) là hàm tính giá trị đa thức bậc n
- Nhập khoảng nghiệm a, b sao cho f(a)<0 và f(b)>0
- Lặp
c = (a+b)/2
nếu f(c) > 0 b = c
ngược lại a = c
trong khi (f(c)> ) /* a - b > và f(c) != 0 */
- Xuất nghiệm: c
CODE
#include <conio.h>
#include <stdio.h>
void nhap(float h[100], int n)
{
int i;
printf("\n");
for(i=1;i<=n+1;i++)
{
printf(" Nhap he so cua X^%d : ",n-i+1);
scanf("%f",&h[i]);
}
}
float f(float h[100], int n, float ab)
{
int i;
float p;
p=h[1];
for(i=2;i<=n+1;i++)
p=p*ab+h[i];
return p;
}
main()
{
int i, n;
float h[100],a,b,c;
printf("Nhap bac cua da thuc: ");
scanf("%d",&n);
nhap(h,n);
printf("\nNhap khoang nghiem (a,b) cua da thuc voi Fa*Fb < 0 ");
printf("\n");
do
{ printf("Nhap khoang nghiem (a,b) cua da thuc: ");
scanf("%f%f",&a,&b);
}
while( f(h,n,a)*f(h,n,b) >= 0 );
do
{ c=(a+b)/2;
if ( f(h,n,c)>0 ) b=c;
else a=c;
}
while( ( -0.001 <= f(h,n,c)) && (f(h,n,c) >= 0.001) );
printf("\nNghiem gan dung cua da thuc la: %.3f",c);
getch();
}
Kết quả chương trình:
Bài số 2:
1. Viết chương trình tìm nghiệm gần đúng cho phương trình có dạng tổng quát:
f(x) = a0xn + a1xn-1 + … + an-1x + an = 0 bằng phương pháp dây cung
Thuật toán:
- Khai báo hàm f(x) là hàm tính giá trị đa thức bậc n
- Nhập khoảng nghiệm a, b
- Tính x = a – (b-a)f(a) / (f(b)-f(a))
- Nếu f(x)*f(a) <0
Lặp b = x
x = a – (b-a)f(a) / (f(b)-f(a))
trong khi x - b>
Ngược lại
Lặp a = x
x = a – (b-a)f(a) / (f(b)-f(a))
trong khi x - a>
- Xuất nghiệm: x
CODE
#include<stdio.h>
#include<conio.h>
#include<math.h>
#define eps 0.0001
float heso[50], a, b, c;
int n;
double p(float x)
{
double k=heso[0];
int i;
for (i=1;i<=n;i++) k=k*x+heso[i];
return k;
}
void nhap()
{
printf("Nhap bac cua phuong trinh: "); scanf("%d", &n);
printf("\nNhap cac he so: ");
for (int i=0;i<=n;i++) scanf("%f", &heso[i]);
do
{ printf("\nNhap khoang nghiem: ");
scanf("%f%f", &a, &b);
if (p(a)*p(b)>0) printf("\n%.3f x %.3f > 0 > nhap sai khoang nghiem. \n", p(a), p(b));
}
while(p(a)*p(b)>0);
}
main()
{
nhap();
c=a-(b-a)/(p(b)-p(a));
if (p(a)*p(c)<0)
do
{
b=c;
c=a-(b-a)/(p(b)-p(a));
}
while (c-b>=eps);
else
do
{
a=c;
c=a-(b-a)/(p(b)-p(a));
}
while (c-a>=eps);
printf("\nNghiem cua pt la x= %.3f", c);
getch();
}
Kết quả chương trình:
2. Viết chương trình tìm nghiệm cho phương trình e^x - 10x + 7 = 0 bằng phương
pháp tiếp tuyến.
Thuật toán:
- Khai báo hàm f(x), hàm fdh(x) tính f’(x)
- Nhập xấp xỉ nghiệm ban đầu x ϵ khoảng nghiệm a,b
- Lặp y= x
x = y – f(y)/fdh(y)
trong khi x - y>
- Xuất nghiệm: x (hoặc y)
CODE
#include<conio.h>
#include<stdio.h>
#include<math.h>
float fx(float x)
{ float p;
p = exp(x) - 10*x + 7;
return p;
}
float fxdh(float x)
{ float p;
p = exp(x) - 10;
return p;
}
main()
{ float x,y;
printf("Phuong trinh: e^x - 10x + 7 = 0");
printf("\n\nNhap xap xi nghiem ban dau x thuoc (0;1): ");
scanf("%f",&x);
do
{ y=x;
x=y-fx(y)/fxdh(y);
}
while( (x-y)>10e-3 || (x-y)<-10e-3 );
printf("\nNghiem gan dung cua phuong trinh: %.3f",x);
getch();
}
Kết quả chương trình:
3. Viết chương trình giải hệ đại số tuyến tính bằng phương pháp Gauss
Thuật toán:
- Nhập n, a
ij
() (nhập trực tiếp hoặc từ file)
- Biến đổi A A’ (ma trận tam giác trên)
Lặp i = 1 n -1
Tìm j sao cho a
ji
# 0 , j = i+1n
• Nếu a
ii
= 0
Nếu j<=n thì hoán đổi dòng i và dòng j cho nhau
ngược lại thì kết thúc (vì dữ liệu ko hợp lệ)
• Lặp j = i + 1 n
m = -a
ji
/a
ii
Lặp k = i n +1 a
jk
= a
jk
+ a
ik
* m
- Tìm nghiệm
( i =n 1)
Lặp i = n 1
s = 0
lặp j = i + 1 n s = s + a
ij
* x
j
x
i
= (a
in+1
- s)/a
ii
- Xuất vectơ nghiệm: x
i
(i=1n)
CODE:
# include <stdio.h>
# include <conio.h>
# include <math.h>
# define eps 1e-3
# define max 100
void hoandoi(float *a, float *b)
{ float t;
t = *a;
*a = *b;
*b = t;
}
void doidong(float a[][max], int n, int p, int q)
{ int k;
if (p<=n && q<=n && p!=q)
for (k=1; k<=n+1; k++) hoandoi(&a[p][k], &a[q][k]);
}
/* Ham xuat mang a(n,n+1)*/
void xuatmt(float a[][max], int n)
{
int i,j;
for (i=1; i<=n; i++)
{ printf("\n");
for (j=1; j<=n+1; j++) printf(" %.2f ", a[i][j]);
}
}
int main()
{
float a[max][max];
float s,m,x[max];
int n, i, j, k;
FILE *f;
char tt;
f=fopen("Gauss_Siedel.txt","r"); /* mo file de doc so lieu */
fscanf(f,"%d",&n);
for (i=1; i<=n; i++)
for (j=1; j<=n+1; j++)
if (!feof(f)) fscanf(f, "%f", &a[i][j]);
else
{ printf("\n So lieu ko hop le");
getch();
return 0;
}
fclose(f);
printf("\nCac he so cua he phuong trinh: \n");
xuatmt(a,n);
/* bien doi A ve ma tran tam giac tren */
for(i=1; i<n; i++)
{ if (a[i][i]==0)
{ for (k=2;k<=n;k++)
if (a[k][i]!=0) break;
doidong(a,n,i,k);
if (k>n) return 0;
}
for(j=i+1;j<=n;j++)
{ m = -a[j][i]/a[i][i];
for (k=i;k<=n+1;k++) a[j][k]+=a[i][k]*m;
}
}
printf("\n\nHe phtrinh sau khi bien doi: \n");
xuatmt(a, n);
for(i=n; i>=1; i )
{ s=a[i][n+1];
for (k=i+1; k<=n; k++) s-=a[i][k]*x[k];
if (a[i][i]!=0) x[i] = s/a[i][i];
}
printf("\n\nNghiem he phtrinh: ");
for(i=1; i<=n; i++) printf("%.2f ", x[i]);
getch();
}
Kết quả chương trình:
4. Viết chương trình giải hệ đại số tuyến tính bằng phương pháp lặp Gauss Siedel
Thuật toán:
- Nhập n, a
ij
(i=1 n, j=1 n+1) (nhập trực tiếp hoặc từ file)
- Nhập xấp xỉ nghiệm ban đầu: x
i
(i =1n)
- Lặp
t = 0 /* cho thoat */
lap i = 1 n
{ s = 0
lap j = 1 n do
if (j i) s = s + a
ij
* x
j
y
i
= (a
in + 1
- s ) / a
ii
if ( | y
i
– x
i
| > = ) t =1 /* cho lap */
x
i
= y
i
}
trong khi (t)
- Xuất vectơ nghiệm: x
i
hoặc y
i
(i =1n)
CODE
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define max 100
#define eps 1e-3
void xuatmt(int a[][max], int n)
{
for(int i=1;i<=n;i++)
{
printf("\n");
for( int j=1;j<=n+1;j++) printf("%5d",a[i][j]);
}
}
void nhap(float *a,int n)
{
int i;
for(i=1;i<=n;i++)
scanf("%f",a+i);
}
void xuat(float a[], int n)
{
int i;
for(i=1;i<=n;i++) printf("%8.3f",a[i]);
}
int main()
{
float x[max], y[max];
int a[max][max];
int n, i, j, t, dem;
FILE *f;
char tt;
f=fopen("Gauss_Siedel.txt","r");
fscanf(f,"%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=n+1;j++)
{
if(!feof(f)) fscanf(f,"%d",&a[i][j]);
else
{
printf("Co loi");
getch();
return 0;
}
}
fclose(f);
printf("\nCac he so cua phuong trinh la: \n");
xuatmt(a,n);
while(1)
{
printf("\n\nNhap nghiem xap xi ban dau: \n");
nhap(x,n);
dem=0;
do
{
t=0; dem++;
for(i=1;i<=n;i++)
{
float s=0;
for(j=1;j<=n;j++)
if(j!=i) s=s+a[i][j]*x[j];
y[i]=(a[i][n+1]-s)/a[i][i];
if (a[i][i]!=0) y[i] = y[i]/a[i][i];
else return 0;
if(fabs(y[i]-x[i])>eps && dem<30) t=1;
}
for (i=1; i<=n; i++) x[i] = y[i];
}
while(t);
if (dem<30)
{ printf("\n Nghiem cua he phuong trinh : ");
xuat(y,n);
}
else printf(" \n He phuong trinh ko giai duoc bang phuong phap nay");
}
getch();
}
Kết quả chương trình:
Bài tập 3:
1. Cho hàm f(x) thoả mãn bảng giá trị:
x x0 x1 x2 … … xn
f(x) y0 y1 y2 … … yn
Viết chương trình tính giá trị hàm f(x) tại điểm x=t cho trước (t ϵ [x0, xn], dùng bảng
nội suy Ayken dạng 1)
Thuật toán:
- Nhập: n, x
i
, y
i
(i = 0n), t
- w = 1; s = 0;
- Lặp i = 0 n
{ w = w*(t - x
i
)
d = t - x
i
Lặp j = 0 n
Nếu j != i thì d = d * (x
i
- x
j
)
s = s + y
i
/d }
- Xuất kết qủa: w*s
CODE
//bang noi suy ayken dang 1
#include<stdio.h>
#include<conio.h>
main()
{
float x[50], y[50], c, d, w=1, s=0;
int n, i, j;
printf("nhap n: "); scanf("%d", &n);
printf("nhap x: ");
for (i=0;i<=n;i++) scanf("%f", x+i);
printf("nhap y: ");
for (i=0;i<=n;i++) scanf("%f", y+i);
printf("nhap c: "); scanf("%f", &c);
for (i=0;i<=n;i++)
{
d=1;
for (j=0;j<=n;j++)
if (j==i)
{
d*=(c-x[j]);
printf("%10.3f", c-x[j]);
}
else
{
d*=(x[i]-x[j]);
printf("%10.3f", x[i]-x[j]);
}
w*=(c-x[i]);
s+=y[i]/d;
printf("%10.3f\n", d);
}
printf("L(%.2f)= %.2f",c, w*s);
getch();
}
Kết quả chương trình:
2. Viết chương trình tính gần đúng tích gần đúng phân xác định của hàm f(x)
trên đoạn [a, b] trong 3 trường hợp:
a. Áp dụng công thức Hình thang
Thuật toán:
• Khai báo hàm f(x)
• Nhập a, b, n (số đoạn cần chia)
• Tính h = (b-a)/n, J = (f(a) + f(b))/2
• Lặp i = 1 n-1 : J+ = f(a+i*h)
• Xuất kết quả : h*J
CODE
#include<conio.h>
#include<stdio.h>
#include<math.h>
float a, b;
double f(float x)
{
return 1/(1+x*x);
}
void nhap()
{
printf("nhap can tinh tich phan:\n");
printf("a= "); scanf("%f", &a);
printf("b= "); scanf("%f", &b);
}
double tp(double (*f)(float), float a, float b)
{
double j, h;
h=(b-a)/1200;
j=(f(a)+f(b))/2;
for (int i=1;i<=1200;i++) j+=f(a+i*h);
return j*h;
}
main()
{
nhap();
printf("ket qua = %.3lf", tp(f,a, b));
getch();
}
Kết quả chương trình:
b. Áp dụng công thức Parabol
Thuật toán:
• Khai báo hàm f(x)
• Nhập a, b, n (số đoạn cần chia)
• Tính h = (b-a)/2n, J = f(a) + f(b)
• Lặp i = 1 2n-1
if (i%2) J+ = 4*f(a+i*h)
else J+ = 2*f(a+i*h)
• Xuất kết quả : h*J /3
CODE
#include<conio.h>
#include<stdio.h>
#include<math.h>
float a, b;
double f(float x)
{
return 1/(1+x*x);
}
void nhap()
{
printf("nhap can tinh tich phan:\n");
printf("a= "); scanf("%f", &a);
printf("b= "); scanf("%f", &b);
}