BÀI TẬP TIN HỌC ỨNG DỤNG GVHD: Ths.GVC... void xulymatranbangint nb,int mb,int n else printf"\nhe phuong trinh vo so nghiem"; }else { printf"\nhe phuong trinh co nghiem";... Theo GAUS
Trang 1BÀI TẬP TIN HỌC ỨNG DỤNG
GVHD: Ths.GVC Lê Văn Hợi
Đà Nẵng , tháng 10 năm 2017
Trang 52 Giải hệ phương trình:
2.1 Hệ phương trình có ma trận hệ số đầy đủ, không đối xứng:
Giải thuật phương pháp khử Gauss:
Để đơn giản khi lập giải thuật ta mở rộng ma trận A[n,n] thêm
1 phần tử (n+1) Cột thứ (n+1) chính là cột tự do ( vế phải của HPT )
M
M M M M
L
Bước 1 Khử về dạng tam giác :
Cho i = 1 -> (n-1) để khử (n-1) cột
Tại lần khử thứ i, đưa các phần tử cột i dưới đường chéo về 0:
+ Đặt P = aij( giả thiết P � 0)
+ Chia hàng i cho P:
Aij /= P; j=i->(n+1);
+ Dùng hàng i làm chuẩn để khử cột i dưới đường chéo về 0;
+ Cho k = i+1 -> n
Đặt Q= Aki
Nhân Q với hàng i rồi trừ vào hàng k: (j = i -> (n+1)) Akj = Aij Q;
Bước 2 Lấy nghiệm:
Sau quá trình khử xuôi ở bước 1 ma trận hệ số có dạng:
1( 1)
2( 1) 2
n n nn
a
a a A
a a
M
M M M M
L
Trang 6Bắt đầu lấy nghiệm từ phương trình thứ n ngược về phương trình đầu tiên: + Nếu a nn = 0 thì vô số nghiệm khi a n n( 1) 0 và vô nghiệm khi a n n( 1) �0
+ Nếu a nn �0thì
( 1)
n n n nn
a x a
Trang 8printf("\nNghiem he phuong trinh : ");
for(int i=1;i<=n;i++) printf("%5.2f ",X[i]);
Nguyên tắc: chỉ xử lý các phần tử thuộc phạm vi băng:
Khi chia hàng i cho P – chỉ cần cho j = i -> c1;
Xử lý riêng cho phần tử tự do: khi khử 1 cột i, chỉ cần cho k = i+1-c2( vì các phần tử ngoài băng đã bằng 0, không cần khử)
Chạy ngang để tính a[k][j] = a[i][j] – Q.a[i][j] (j chỉ cần chạy từ i -> c1) Xử lý riêng chophần tử tự do Khi lấy nghiệm: Tổng a[i][j].x[j] chỉ lấy trên phạm vi băng( j = c1-> i+1)
Trang 9void xulymatranbang(int nb,int mb,int n)
else printf("\nhe phuong trinh vo so nghiem");
}else {
printf("\nhe phuong trinh co nghiem");
Trang 10X[i] = A[i][n+1] - sum;
printf("X[%d] = %0.3f",i, X[i]);
}
}
Yêu cầu 2: Lưu băng trong 1 vector:
Code như sau:
Trang 13+ Giải hệ phương trình với ma trận mở rộng An,n+1 sẽ tìm được vector nghiệm X(n)
+ Đưa vector nghiệm X(n) vào cột thứ l của ma trận A-1
Cho i = 1 -> n : A-1(i,l) = X(i);
Xuất ma trận A-1 cần tìm
ĐỀ XUẤT THUẬT TOÁN TỐI ƯU:
Giảm thời gian bằng cách thay việc giải n lần n hệ phương trình bởi việc giải 1 lần n hệ phương trình( dùng 3 mảng 2 chiều)
Trang 14Hoặc có thể thay bằng cách giải 1 lần n hệ phương trình ( dùng 2 mảng và 1 vector).
Ax[i][j]=A[i][j];
}}
//dua cot tu do ve 0
for(int i=1;i<=n;i++)
Trang 15}}
Trang 16for(int j=i+1;j<=n;j++){
x[i]=x[i]-(Ax[i][j]*x[j]);
}}
//dua x[n] vao cot L trong ma tran Ao
Trang 17Theo GAUSS- JOOCDANG
Lập ma trận A0 bằng ma trận ban đầu cần nghịch đảo Tính truy hồi Ak từ Ak-1 theo công thức:
, ( 1) ,
( 1) ,
.( , )( , )( , )1
( )
k k
i k k j k
k k k
k j k
k k k
i k k
i k j k A
A
A
i k j k A
Xuất A1 ở bước tính thứ n – đó chính là ma trận nghịch đảo A-1 cần tìm
(thuật toán này cần đến 2 mảng 2 chiều)
Đề xuất thuật toán tối ưu để tiết kiệm bộ nhớ:
Chỉ dùng 1 mảng 2 chiều và một mảng 1 chiều phụ trợ Lưu giá trị của bước tính thứ k trên 1 mảng 2 chiều duy nhất
Trong mỗi lần tính truy hồi ở bước k cần phải:
+ Lưu giá trị của Ak,k vào biến P
+ Lưu giá trị của Ai,k vào biến Q
+ Lưu giá trị của hàng k Ak,j vào vector D(j=1->n)
Lý do: nếu không lưu giữ riêng các giá trị này thì chúng sẽ bị thay đổi ngay trong lần đầu tiên của 1 bước lặp( khi j = 1-> n) và các vòng tính tiếp theo ( khi i,j thay đổi) không còn đúng nữa
b Chương trình :
Trang 18{if(i!=k && j!=k) A[i][j] = A[i][j] – Q*D[j]/P;
if(i==k && j!=k) A[i][j] = D[j]/P;
if(i!=k && j==k) A[i][j] = -Q/P;
if(i==k && j==k) A[i][j] = 1/P;
}
}
}
Có thể sử dụng đệ qui:
float Aij(int k,int i,int j)//tim ma tran nghich dao theo jordand
if(i==k && j != k) return A[i][j] = 1.0*Aij(k-1,k,j)/Aij(k-1,k,k);
if(i != k && j == k) return A[i][j] = -1.0*Aij(k-1,i,k)/Aij(k-1,k,k);
if(i==k && j==k) return A[i][j] = 1.0/Aij(k-1,k,k);
}
}
Trang 19CHƯƠNG 3
1 Thuật toán nội suy bậc nhất 1 chiều :
a Thuật toán :
- Đọc giá trị bảng tra X(x) và Y(n)
- Cho giá trị xo
- Tìm i thõa mãn điều kiện xi-1 ≤ xo ≤ xi
- Tính yo theo công thức :
Trang 20//xuat yprintf("y = %0.2f\n",y);
break;
}}
}while(1);
}
Trang 212 Thuật toán nội suy bậc nhất 2 chiều :
a Thuật toán :
- Nhập các bảng tra vào mảng
- Tìm vị trí x0và yo trong bảng tra , tức là i và j thỏa mãn :
xi-1 ≤ xo ≤ xi
yj-1 ≤ yo ≤ yj
- Thực hiện các bước tính nội suy như sau :
+ Trên cột j-1 , nội suy theo xo để tìm ra Z1
Z1 = Zi-1,j-1 ++ Trên cột j , nội suy theo xo để tìm ra Z2
Z2 = Zi-1,j ++ Từ Z1 và Z2 nội suy theo yo để tìm ra Zo
Trang 24Z1 = z[i-1][j-1] + (1.0 * (z[i][j-1] - z[i-1][j-1]) * (x0 - x[i-1]) / (x[i] - x[i-1]));Z2 = z[i-1][j] + (1.0 * (z[i][j] - z[i-1][j]) * (x0 - x[i-1]) / (x[i] - x[i-1]));
Z0 = Z1 + (1.0 * (y0 - y[j-1]) * (Z2-Z1) / (y[j] - y[j-1]));
printf("x = %0.2f & y = %0.2f => z = %0.2f\n",x0,y0,Z0);
}while(true);
}
Trang 25c Phương pháp chia đôi
Nhập bậc phương trình n, và các hệ số ai (i= 0,n)
Định nghĩa hàm Hoocner để tính giá trị hàm f(x)
Truyền vào hàm bậc đa thức n, các hệ số ai (i= 0,n)
void Nhaptt(float *d, int &n);
void Nhapf(float *d, int &n);
void Xuat(float *d, int n);
Trang 26float f(float *d, int n, float c);
float PP_Chiadoi(float *d, int n, float a, float b);
void ghifile(float *d, int n, float a, float b);
printf("Chon kieu nhap du lieu:\n");
printf("\t1.Nhap truc tiep.\n");
Trang 31Khai báo hàm Hoocner để tính giá trị của đa thức f(x) 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(a)*f(b)<0 thì tiến hành lặp
void Nhaptt(float *d, int &n);
void Nhapf(float *d, int &n);
Trang 32void Xuat(float *d, int n);
float f(float *d, int n, float c);
float PP_Daycung(float *d, int n, float a, float b);
void ghifile(float *d, int n, float a, float b);
printf("Chon kieu nhap du lieu:\n");
printf("\t1.Nhap truc tiep.\n");
Trang 33printf("\nNhap khoang nghiem (a,b): ");
Trang 34void Nhapf(float *d, int &n)
Trang 37CHƯƠNG 5 : GIẢI THUẬT MỘT SỐ BÀI TOÁN CHUYÊN NGÀNH XÂY DỰNG 5.1 Tính toán cột chịu nén lệch tâm
a Thuật toán :
- Lập thủ tục xác định µmin
- Lập thủ tục tính đọ lệch tâm e
- Lập thủ tục tính cốt thép – trường hợp lệch tâm bé
- Lập thủ tục tính cốt thép – trường hợp lệch tâm lớn
- Nhập các số liệu đầu vào
- Xác định các thông số tính toán và gọi thủ tục xác định µmin
- Giải thiết µ=µmin
Lặp để tính cốt thép :
- Gọi thủ tục TINH_E
- Tùy theo e-Gọi LTAM_BE hay LTAM_LON
- Tính
- Tính sai số SS=
- Giải thiết lại µ=
Xuất kết quả và kết thúc
SS<0.05
Trang 385.2 Bài toán tính toán đường mực nước trên kênh :
a Thuật toán :
Nhập các số liệu đầu vào :
- Lưu lượng qua kênh : Q - Độ nhám : n
- Bề rộng và mái dốc : b,m - Độ dốc kênh : i
- Độ sâu mực nước đầu kênh : ho
Xác định dạng đường mực nước đầu kệnhNếu đường mực nước là đường dâng :
Chọn Δh > 0Ngược lại – đường nước hạ
Tính các thông số của mặt cắt 2 :
ω1 , χ1 , J1 , và ϶1 (theo công thức đã nêu)
Tính ΔL =
Cộng dồn ΔL vào L : L = L + ΔL
- Nếu L < L+Lo : gán tham số của mặt cắt 2 cho mặt cắt 1 :
- Ngược lại nếu L > Lo thì phải chia nhỏ Δh và định vị L tại mặt cắt 1 :
Δh = Δh/10 ; L = L – ΔL
Trang 39END
Trang 405.4 Tính toán kích thước bể tiêu năng
a Thuật toán :
Nhập các số liệu : Q , b , H , P , v , φ
Tạo bảng tra tc và t’’
- Tính lại E= Eo + d ; Có E và q Tính được F(t) ;
tra bảng được tc và t’’
c => tính được hc và h’’
c
- Tính ra lại được dtt = σ h’’
c - hh
- Tính sai số : SS = |dtt –d|/d
- Giả thiết lại d = (dtt + d)/2
Tính chiều dài bể và và xuất kết quả
SS >ε
Trang 41b Chương trình
include<conio.h>
include<stdio.h>
include<math.h>
void noi_suy( float Fe [100], *Tett, float Teett);{
float I,n,a,Fo,Te[100], Tee[100];
printf ("\nFe[%1.0f],=%5,4f i, Fe[i]);
scanf(f2 "%f", & Te [i]);
if (Te[i]!=EOF);
printf ("\t\tFe[%1.0f]=%5,4f,i.Te[i]);
Trang 42scanf(f2, "%f",& Tee[i]);
// chuong trinh noi suy
printf("\n nhap gia tri Fo: ");
scanf (F0= % 5.0 f & Fo);
Tett= Te[i-1]+ (Te[i]-Te[i-1])*(Te[i]-Te[i-1])/(Te[i]-Te[i-1]);
Teett= Te[i-1]+ (Te[i]-Te[i-1])*(Te[i]-Te[i-1])/(Te[i]-Te[i-1]);
Trang 43Float
b,m,Q,P,hh,deta,eps,eps1,phi,Fo,a,Fe[100],n,i,F,Tett,Te[100],Teett,Tee[100],Ho,Eo<hc,hee,d,E,he1,hee1,dtt,c;
scanf (f1 ,"%f"&b); printf("\nb=%2.0f",b);
scanf (f1 ,"%f"&m); printf("\nb=%2.0f",m);
scanf (f1 ,"%f"&Q); printf("\nb=%2.0f",Q);
scanf (f1 ,"%f"&P); printf("\nb=%2.0f",P);
scanf (f1 ,"%f"&phi); printf("\nb=%2.0f",phi);
scanf (f1 ,"%f"&hh); printf("\nb=%2.0f",hh);
scanf (f1 ,"%f"&eps); printf("\nb=%2.0f",eps);
fclose(f1);
// coot nuoc tren dinh tran
Ho= pow(Q/m*p* sqrt (19,62));
printf ( "\n Ho= %10,5 f", Ho);
// coot nuoc toan phan
Trang 465.5 Bài toán thấm qua đập đất bằng phương pháp thủy lực :
a Thuật toán :
Nhập số liệu đầu vào
Chọn ẩn số là h1 – giải thiết giá trị h1 (thuộc khoảng (H2 – H1)
Dùng thuật toán lặp chia đôi khoảng nghiệm tìm được h1 (đã nói ở chương 4 )
Tính các đại lượng qn , qđ , h2
Tính tọa độ đường bão hòa theo phương trình và vẽ được đường bão hòa
b Chương trình :
Trang 475.6 Bào toán ổn định mái dốc :
a Thuật toán :
Nhập số liệu vào :
+ Số đường ranh giới (SĐ = số lớp đất +1)
+ Tọa độ (x,y) mô tả các đường : Y1 : Mặt đặp ; Y2 : Đường bão hòa ; Y3 : Ranhgiới đáy đặp và nền ; Y4 : Ranh giới lớp nền 1 và lớp nền 2 …
+ Tính chất cơ lý : Lớp thứ I – φ,C,γ tương ứng
+ Các thông số bề rộng cột đất , lưới tâm trượt , và cách thay đổi bán kính cungtrượt
+Các mực nước TL , HL
+Xét một cung trượt tâm O(xo ,yo) bán kinh R bất kỳ ta có công thức xác định hẹsố ổn định như sau :
k = =
Giải thuật tìm 1 cung trượt bất kì :
- Phương trình cung trượt Yc được suy ra từ : R2 = X2 + Y2
- Gán giá trị các tổng ở tử số và mẫu số bằng 0 : ST1 ,ST2 , SM =0
- Định vị cột đất đầu tiên tại đường thẳng đúng qua tâm O : x = xo
- Lặp cho các cột đất bên trái truc OM :
Có x tính được αi , dαi , dSi
Có x tính được Y1 , Y2 ,Y3 , Y4 …
TÍNH Gi :
Gi = khi thỏa điều kiện : Yi+1 > Yc
Gi = khi thỏa mãn điều kiện Yi+1 < Yc < Yi
Gi = 0 khi Yi < Yc (đã xuống dưới cung trượt)
Tính h = Y2 – Yc (nếu Y2 > Yc) => Tính được Wi
Lấy φi , Ci của lớp đất thứ I thõa mãn điều kiện Yi+1 < Yc < Yi
Thế vào và cộng dồn vào ST1 , ST2 , SM
X= X – dx
Điều kiện kết thúc vòng lặp : Y1(x) < Yc
- Lặp tiếp cho các cột bên phải OM
- Lặp tỉ số k=(ST1 + ST2)/SM
Giải thuật tìm cung trượt nguy hiểm nhất :
- Nguyên tắc chung là : Tâm trượt di chuyển trên một lưới (được xác định bởi
hình chữ nhật có bước lưới dxo,dyo) , với 1 tâm trượt sẽ có các cung trượt với Rkhác nhau (bước thay đổi là dR – được xác định bởi các đoạn thẳng nằmngang )