Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 21

TRƯỜNG ĐẠI HỌC BÁCH KHOA

KHOA CÔNG NGHỆ THÔNG TIN


ĐỀ THI VÀ BÀI LÀM
Tên học phần: Toán ứng dụng CNTT
Mã học phần: Hình thức thi: Tự luận có giám sát
Đề số: T0000.02 Thời gian làm bài: 90 phút (không kể thời gian chép/phát đề)
Được sử dụng tài liệu khi làm bài.

Họ tên: Nguyễn Đình Thúy Vy Lớp: 20TCLC_DT1 MSSV:102200080


Sinh viên làm bài trực tiếp trên tệp này, lưu tệp với định dạng MSSV_HọTên.pdf và nộp bài thông qua
MS Teams.
Câu 1 (2 điểm): Cho hệ đồng dư sau:

a) (1 điểm) Trình bày phương pháp giải hệ phương trình đồng dư đã cho.
# Trả lời: trình bày sơ đồ khối hoặc ngôn ngữ tự nhiên:
Với phương trình 

,   
Hệ phương trình có nghiệm duy nhất với   
Trong đó:  
   

   
   
Input: Các hệ số   với   
Thuật toán: 
Bước 1: Khởi tạo   
Bước 2: Lặp   đến   
· Tính   
· Nếu thì continue đến vòng lặp tiếp theo  
· Lặp tìm   đến   
 Nếu   thì và thoát khỏi vòng lặp j 
  x = x % M;  
Bước 4: Trả về (nghiệm của hệ phương trình) 

b) (1 điểm) Viết chương trình giải hệ phương trình đồng dư trên.


# Trả lời: Dán code vào bên dưới:
#include <iostream>
using namespace std;
int findInverseX(int m, int X) {
int i = 0;
while (true) {
if ((i * m + 1) % X == 0) {
return (i * m + 1) / X;
}
i++;
}
}
void solve(int a[], int m[], int n) {
int M = 1;
for (int i = 0; i < n; i++) {
M *= m[i];
}
int X[n];
int iX[n];
for (int i = 0; i < n; i++) {
X[i] = M / m[i];
iX[i] = findInverseX(m[i], X[i]);
}
int result = 0;
for (int i = 0; i < n; i++) {
result += a[i] * X[i] * iX[i];
}
cout << "Result: " << result << endl;
cout << "Short: " << (result % M) << " (mod "<< M <<") " <<endl;
}
int main() {
int n;
cout << "Number of equation: ";
cin >> n;
int a[n];
int m[n];
for (int i = 0; i < n; i++) {
cout << "Input a[" << i << "]: ";
cin >> a[i];
cout << "Input m[" << i << "]: ";
cin >> m[i];
}
solve(a, m, n);
}
# Trả lời: Dán kết quả thực thi vào bên dưới:
Câu 2 (2 điểm): Cho ma trận A. Viết chương trình phân rã ma trận A bằng phương pháp SVD.
# Trả lời: Dán code vào bên dưới (bao gồm điều kiện của ma trận A nếu có):
#include <iostream>
#include <Eigen/Eigenvalues>
#include <typeinfo>
#include <Math.h>
using Eigen::MatrixXd;
using Eigen::EigenSolver;
using namespace std;

// Nhan 2 ma tran lai voi nhau


MatrixXd mulMatrixAndMatrix(MatrixXd A,MatrixXd B){
MatrixXd temp(A.rows(),B.cols());
if(A.cols() != B.rows()) return temp;
for(int i =0;i<temp.rows();i++){
for(int j =0;j<temp.cols();j++){
double sum = 0;
for(int k=0;k<A.cols();k++){
sum += A(i,k)*B(k,j);
}
temp(i,j) = sum;
}
}
return temp;
}

// Nhan mot so voi mot ma tran


MatrixXd mulNumberAndMatrix(double val, MatrixXd A){
MatrixXd temp(A.rows(),A.cols());
for(int i =0;i<temp.rows();i++){
for(int j =0;j<temp.cols();j++){
temp(i,j) = val*A(i,j);
}
}
return temp;
}

// Ma tran chuyen vi
MatrixXd transport(MatrixXd A){
// Khai bao va khoi tao 1 ma tran n hang m cot ( so voi ma tran ban dau m hang n cot)
MatrixXd temp(A.cols(),A.rows());
for(int i =0;i<temp.rows();i++){
for(int j=0;j<temp.cols();j++){
temp(i,j) = A(j,i);
}
}
return temp;
}

MatrixXd calSigmaMatrix(MatrixXd EigenVals){


MatrixXd temp(EigenVals.rows(),EigenVals.rows());
for(int i=0;i<temp.rows();i++){
for(int j=0;j<temp.cols();j++){
if(i==j) temp(i,j) = sqrt(EigenVals(i,0));
else temp(i,j) = 0;
}
}
return temp;
}

MatrixXd calU(MatrixXd A,MatrixXd EigenVecs,MatrixXd EigenVals){


MatrixXd temp(A.rows(),EigenVecs.cols());
for(int i = 0 ;i<temp.cols();i++){
temp.col(i) =
mulNumberAndMatrix(1.0/sqrt(EigenVals(i,0)),mulMatrixAndMatrix(A,EigenVecs.col(i)));
}
return temp;
}
int main() {
int row =0 ,col = 0;
cout << "Row=";
cin >>row;
cout <<"Col =";
cin >> col;
int max = row>col ? row:col;
MatrixXd A(max,max);
for(int i=0;i<max;i++){
for(int j=0;j<max;j++){
if(i >= row || j>=col) A(i,j) = 0;
else {
cout<<"A["<<i<<","<<j<<"] = ";
cin >> A(i,j);
}
}
}

cout << "Matrix A:" << endl << A << endl << endl;
MatrixXd S = mulMatrixAndMatrix(transport(A),A);
cout << "Matrix S: (with S= A^T * A ) " << endl << S << endl << endl;

// In ra cac gia tri rieng


EigenSolver<MatrixXd> es(S);
cout << "The eigenvalues of S are:" << endl << es.eigenvalues().real()<< endl;
// In ra cac vecto rieng
cout << "The matrix of eigenvectors" << endl << es.eigenvectors().real() << endl <<
endl;

MatrixXd V = es.eigenvectors().real();
cout << "Matrix V: ( with per col is an eigenvector)" << endl << V << endl << endl;
MatrixXd V_T = transport(V);
cout << "Matrix V^T:" << endl << V_T << endl << endl;

MatrixXd Sigma = calSigmaMatrix(es.eigenvalues().real());


cout << "Matrix Sigma Of Sum:"<< endl << Sigma << endl << endl;

MatrixXd U = calU(A,es.eigenvectors().real(),es.eigenvalues().real());
cout << "Matrix U: "<< endl << U << endl << endl;

cout << "A = U*Sigma*V^T = " <<endl<<U<<endl<<" * "<<endl<<Sigma<<endl<<" *


"<<endl<<V_T;
}
# Trả lời: Dán kết quả thực thi vào bên dưới biết rằng , sai số .
Câu 3 (2 điểm): Cho mười điểm trong không gian Oxy như sau: (6, 7); (8,6); (9,8); (10,9); (11,10);
(7,12); (6,11); (7,11); (10,13); (10,7)
a) (1.0 điểm) Mô tả thuật toán xác định bao lồi và xác định bao lồi
# Trả lời: dán sơ đồ khối hoặc ngôn ngữ tự nhiên vào bên dưới:

Điều kiện
-n là số nguyên lớn hơn 0

Thuật toán (input, output, solve)


-input: nhập vào n và tọa độ x,y của n điểm
-ouput: bao lồi của n điểm
-solve:
- Trước tiên ta loại bỏ các điểm trùng nhau
- Để xác định bao trên :
+ Sắp xếp các điểm theo thứ tự tăng dần
+ Tạo mảng bao trên và thêm 2 điểm đầu tiên
+ Tiếp tục thêm các điểm đồng thời kiểm tra liên tục nếu 3 điểm cuối (trong mảng bao) không
tạo thành rẽ phải thì xóa điểm giữa
- Để xác định bao dưới:
+Sắp xếp các điểm theo thứ tự giảm dần và làm tương tự như bao trên
+Xóa điểm đầu và điểm cuối trong báo dưới để chèn vào sau bao trên
=> Convex Hull (theo chiều kim đồng hồ):

b) (1.0 điểm) Viết hàm xác định bao lồi và tính diện tích bao lồi tìm được.
# Trả lời: Dán code bên dưới:
#include <bits/stdc++.h>
using namespace std;
pair<int, int> mid;
int quad(pair<int, int> p)
{
if (p.first >= 0 && p.second >= 0)
return 1;
if (p.first <= 0 && p.second >= 0)
return 2;
if (p.first <= 0 && p.second <= 0)
return 3;
return 4;
}
int calc_line(pair<int, int> a, pair<int, int> b,
pair<int, int> c)
{
int res = (b.second - a.second) * (c.first - b.first) -
(c.second - b.second) * (b.first - a.first);
if (res == 0)
return 0;
if (res > 0)
return 1;
return -1;
}
bool compare(pair<int, int> p1, pair<int, int> q1)
{
pair<int, int> p = make_pair(p1.first - mid.first,
p1.second - mid.second);
pair<int, int> q = make_pair(q1.first - mid.first,
q1.second - mid.second);
int one = quad(p);
int two = quad(q);
if (one != two)
return (one < two);
return (p.second * q.first < q.second * p.first);
}
vector<pair<int, int>> merger(vector<pair<int, int>> a,
vector<pair<int, int>> b)
{
int n1 = a.size(), n2 = b.size();
int ia = 0, ib = 0;
for (int i = 1; i < n1; i++)
if (a[i].first > a[ia].first)
ia = i;
for (int i = 1; i < n2; i++)
if (b[i].first < b[ib].first)
ib = i;
int inda = ia, indb = ib;
bool done = 0;
while (!done)
{
done = 1;
while (calc_line(b[indb], a[inda], a[(inda + 1) % n1]) >= 0)
inda = (inda + 1) % n1;
while (calc_line(a[inda], b[indb], b[(n2 + indb - 1) % n2]) <= 0)
{
indb = (n2 + indb - 1) % n2;
done = 0;
}
}
int uppera = inda, upperb = indb;
inda = ia, indb = ib;
done = 0;
int g = 0;
while (!done)
{
done = 1;
while (calc_line(a[inda], b[indb], b[(indb + 1) % n2]) >= 0)
indb = (indb + 1) % n2;
while (calc_line(b[indb], a[inda], a[(n1 + inda - 1) % n1]) <= 0)
{
inda = (n1 + inda - 1) % n1;
done = 0;
}
}
int lowera = inda, lowerb = indb;
vector<pair<int, int>> ret;
int ind = uppera;
ret.push_back(a[uppera]);
while (ind != lowera)
{
ind = (ind + 1) % n1;
ret.push_back(a[ind]);
}
ind = lowerb;
ret.push_back(b[lowerb]);
while (ind != upperb)
{
ind = (ind + 1) % n2;
ret.push_back(b[ind]);
}
return ret;
}
vector<pair<int, int>> bruteHull(vector<pair<int, int>> a)
{
set<pair<int, int>> s;
for (int i = 0; i < a.size(); i++)
{
for (int j = i + 1; j < a.size(); j++)
{
int x1 = a[i].first, x2 = a[j].first;
int y1 = a[i].second, y2 = a[j].second;
int a1 = y1 - y2;
int b1 = x2 - x1;
int c1 = x1 * y2 - y1 * x2;
int pos = 0, neg = 0;
for (int k = 0; k < a.size(); k++)
{
if (a1 * a[k].first + b1 * a[k].second + c1 <= 0)
neg++;
if (a1 * a[k].first + b1 * a[k].second + c1 >= 0)
pos++;
}
if (pos == a.size() || neg == a.size())
{
s.insert(a[i]);
s.insert(a[j]);
}
}
}
vector<pair<int, int>> ret;
for (auto e : s)
ret.push_back(e);
mid = {0, 0};
int n = ret.size();
for (int i = 0; i < n; i++)
{
mid.first += ret[i].first;
mid.second += ret[i].second;
ret[i].first *= n;
ret[i].second *= n;
}
sort(ret.begin(), ret.end(), compare);
for (int i = 0; i < n; i++)
ret[i] = make_pair(ret[i].first / n, ret[i].second / n);
return ret;
}
vector<pair<int, int>> divide(vector<pair<int, int>> a)
{
if (a.size() <= 5)
return bruteHull(a);
vector<pair<int, int>> left, right;
for (int i = 0; i < a.size() / 2; i++)
left.push_back(a[i]);
for (int i = a.size() / 2; i < a.size(); i++)
right.push_back(a[i]);
vector<pair<int, int>> left_hull = divide(left);
vector<pair<int, int>> right_hull = divide(right);
return merger(left_hull, right_hull);
}
double polygonArea(vector<pair<int, int>> a)
{
double area = 0.0;
int j = a.size() - 1;
for (int i = 0; i < a.size(); i++)
{
area += (a[j].first + a[i].first) * (a[j].second - a[i].second);
j = i;
}
return abs(area / 2.0);
}
int main()
{

vector<pair<int, int>> points;


points.push_back({ 6, 7 });
points.push_back({ 8, 6 });
points.push_back({ 9, 8 });
points.push_back({ 10, 9 });
points.push_back({ 11, 10 });
points.push_back({ 7, 12 });
points.push_back({ 6, 11 });
points.push_back({ 7, 11 });
points.push_back({ 10, 13 });
points.push_back({ 10, 7 });

sort(points.begin(), points.end());
vector<pair<int, int>> ans = divide(points);

cout << "Convex Hull: \n";


for (auto e : ans)
cout << "(" << e.first << ", "
<< e.second << ")" << endl;
cout << "Area of the convex hull is :" << polygonArea(ans);
return 0;
}

# Trả lời: Dán kết quả thực thi vào bên dưới:
Câu 4 (3 điểm): Cho hàm số .
a) (1 điểm) Khai triển đạo hàm cấp 1 của f(x)

# Trả lời: Khai triển đạo hàm:

F(x)=
- Điều kiện dừng
của Gradient descent:
+ Giới hạn số bước lặp
+ So sánh giá trị hàm của nghiệm tại 2 lần cập nhật
+ Kiểm tra giá trị tuyệt đối của gradient
- Tốc độ hội tụ của Gradient descent:
+ Phụ thuộc vào điểm khởi tạo
+ Phụ thuộc vào chỉ số alpha

Input: Hàm số
Thuật toán:

- Dự đoán một điểm khởi tạo


- Cập nhật đến đạt kết quả chấp nhận:

b) (2 điểm) Viết chương trình (có dùng hàm) tính giá trị bé nhất của f(x) sử dụng phương pháp
gradient descent với momentum với tham số học (learning rate) , hệ số động lượng là , số
bước lặp N và sai số :
# Trả lời: Dán code vào bên dưới:
#include <bits/stdc++.h>

using namespace std;

float giatriham(float x)

    // return pow((exp(2*x) + 3*x - 10), 2) + 2*pow((x + 1), 2);

    return pow((exp(4 * x) - 2 * pow(x, 2) - 5 * pow(x, 3)), 2) + 2 * pow(x, 4);


}

float grad(float x)
{
    return 2 * (exp(4 * x) - 2 * pow(x, 2) - 5 * pow(x, 3)) * (4 * exp(4 * x) - 4 * x - 15 * pow(x, 2)) + 8
* pow(x, 3);
}

float GD(float x, float gamma, int N_loop) // N so lan lap

    float x_new = 0;

    for (int i = 1; i < N_loop; i++)

  {

        x_new = x - gamma * grad(x);

        printf("Vong lap thu %d: gia tri x = %f, gia tri cua ham la: %1.5f \n", i, x, giatriham(x));

        cout << "|x - x_new| = " << fabs(x - x_new) << endl;

        if (fabs(x - x_new) < 0.00001)

    {

            cout << "i = " << i << endl;

            break;
    }

        else

    {

            x = x_new;
    }
  }

    cout << "x = " << x << endl;

    return (giatriham(x));
}

int main()

    double fmin = GD(-0.5, 0.01, 10000);

    cout << "Min f(x) =  " << fmin;

    return 0;
}

# Trả lời: Dán kết quả thực thi với điểm khởi , tham số học học (learning

rate) , hệ số động lượng (momentum coefficient) là , số bước lặp N


= 10000 và sai số :
Câu 5 (1 điểm): Một hệ thống có chế độ làm việc ở mỗi giai đoạn vận hành chỉ với các trạng thái từ 0 đến 3.
Chế độ làm việc của hệ thống này được mô tả bằng chuỗi Markov như hình vẽ.

a) (0.5 điểm) Xác định ma trận chuyển đổi trạng thái P của hệ.

# Trả lời: dán kết quả vào bên dưới:


0 1 2 3
0 0.6 0.4 0 0
1 0.3 0.3 0.3 0.1
2 0 0.3 0.7 0
3 0 0.5 0.5 0
b) (0.5 điểm) Tìm xác suất (lớn nhất) khi hệ thống làm việc ở trạng thái 3 sau ba giai đoạn vận hành biết
rằng hệ thống bắt đầu làm việc ở trạng thái 1.
# Trả lời: Dán kết quả tính toán vào bên dưới:
Đà Nẵng, ngày 01 tháng 12 năm 2022
GIẢNG VIÊN BIÊN SOẠN ĐỀ THI KHOA CÔNG NGHỆ THÔNG TIN
( đã duyệt)

You might also like