0% found this document useful (0 votes)
18 views10 pages

HoangGiaUy 20020014 VNUK en - 2024

Ok

Uploaded by

BM2T Band
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views10 pages

HoangGiaUy 20020014 VNUK en - 2024

Ok

Uploaded by

BM2T Band
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 10

DA NANG UNIVERSITY

VN-UK Institute for Research & Executive Education


QUESTIONS
Course Name: Math for Computer Science
Course code: Exam format:
Code : 000B Time: 150 minutes (not including time to copy/distribute questions)
Dont use materials when doing assignments.

Full name: …Hoàng Gia Uy………Class:………20CSE………….


Students work directly on this file, save the file in the format MSSV_FirstName.pdf
Question 1 (2 points): Given matrix A. Write a function to decompose matrix A using Cholesky
method.
# Answer: the condition of matrix A for decompose: Matrix A must be symmetric and positive
definite.

For a matrix A to be Cholesky decomposable, it must be:

1. Symmetric: The matrix must be equal to its transpose, i.e., A = A^T.


2. Positive-definite: All eigenvalues of the matrix must be positive. Equivalently, all leading
principal minors of the matrix must be positive.

# Answer: Paste the code below :

import numpy as np

def cholesky_decomposition(A):
"""
Performs Cholesky decomposition on a symmetric positive-definite matrix A.

Args:
A: A symmetric positive-definite matrix.

Returns:
L: The lower triangular matrix.
"""

n = A.shape[0]
L = np.zeros_like(A)

for i in range(n):
for j in range(i+1):
s = sum(L[i, k] * L[j, k] for k in range(j))
if i == j:
L[i, j] = np.sqrt(A[i, i] - s)
else:
L[i, j] = (1.0 / L[j, j]) * (A[i, j] - s)
return L

# Example usage:
A = np.array([[1, 2, 0, 0, 0, 0, 0, 0, 0],
[2, 5, 2, 0, 0, 0, 0, 0, 0],
[0, 2, 5, 2, 0, 0, 0, 0, 0],
[0, 0, 2, 5, 2, 0, 0, 0, 0],
[0, 0, 0, 2, 5, 2, 0, 0, 0],
[0, 0, 0, 0, 2, 5, 2, 0, 0],
[0, 0, 0, 0, 0, 2, 5, 2, 0],
[0, 0, 0, 0, 0, 0, 2, 5, 2],
[0, 0, 0, 0, 0, 0, 0, 2, 5]])

L = cholesky_decomposition(A)
print(L)
U, S, V = np.linalg.svd(A)
print(U, S, V)

# Answer: Paste the results of the SVD decomposition of the 9x9 matrix below.

U:
[[-0.05163034 0.10139725 0.14734538 -0.18724436 0.21811848 -0.2349018
0.22623037 -0.16221427 0.86604481]
[-0.200725 0.36129247 0.45110258 -0.45642105 0.38377818 -0.2589122
0.12232696 -0.02394212 -0.43301869]
[-0.32728485 0.46335307 0.33151438 -0.01247133 -0.31041938 0.46734938
-0.40473983 0.20656476 0.21650005]
[-0.41710142 0.36299273 -0.0991895 0.45096398 -0.3091205 -0.16066724
0.46830237 -0.35869933 -0.10823051]
[-0.46009127 0.10405499 -0.4368072 0.20979917 0.38476467 -0.32310469
-0.27864513 0.45789144 0.05407577]
[-0.45142805 -0.20034033 -0.36449526 -0.35916237 0.21658234 0.4507459
-0.0616807 -0.48950077 -0.02695867]
[-0.39208436 -0.41721476 0.04988386 -0.36695748 -0.43685399 -0.08156838
0.36865463 0.44886191 0.01332079]
[-0.28872254 -0.45182428 0.41744857 0.19859317 -0.1115164 -0.377515
-0.47629016 -0.34197299 -0.00634325]
[-0.1529467 -0.28904935 0.3932511 0.45385569 0.46367434 0.42049582
0.32638677 0.18461033 0.0025373 ]]
S:
[[8.77546601e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00]
[0.00000000e+00 8.12627779e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00]
[0.00000000e+00 0.00000000e+00 7.12306373e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00]
[0.00000000e+00 0.00000000e+00 0.00000000e+00 5.87513794e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00]
[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
4.51898828e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00]
[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 3.20442927e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00]
[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 2.08143710e+00 0.00000000e+00
0.00000000e+00]
[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 1.29519131e+00
0.00000000e+00]
[0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
8.58349452e-06]]
V^T:
[[-0.05163034 -0.200725 -0.32728485 -0.41710142 -0.46009127 -0.45142805
-0.39208436 -0.28872254 -0.1529467 ]
[ 0.10139725 0.36129247 0.46335307 0.36299273 0.10405499 -0.20034033
-0.41721476 -0.45182428 -0.28904935]
[ 0.14734538 0.45110258 0.33151438 -0.0991895 -0.4368072 -0.36449526
0.04988386 0.41744857 0.3932511 ]
[-0.18724436 -0.45642105 -0.01247133 0.45096398 0.20979917 -0.35916237
-0.36695748 0.19859317 0.45385569]
[ 0.21811848 0.38377818 -0.31041938 -0.3091205 0.38476467 0.21658234
-0.43685399 -0.1115164 0.46367434]
[-0.2349018 -0.2589122 0.46734938 -0.16066724 -0.32310469 0.4507459
-0.08156838 -0.377515 0.42049582]
[ 0.22623037 0.12232696 -0.40473983 0.46830237 -0.27864513 -0.0616807
0.36865463 -0.47629016 0.32638677]
[-0.16221427 -0.02394212 0.20656476 -0.35869933 0.45789144 -0.48950077
0.44886191 -0.34197299 0.18461033]
[ 0.86604481 -0.43301869 0.21650005 -0.10823051 0.05407577 -0.02695867
0.01332079 -0.00634325 0.0025373 ]]

Question 2 (3 points): Given a binary string of length n ( n > 1). Write a program to generate a
binary string of length n using the Backtracking method
a) (1.0 point) Description of the Backtracking algorithm
# Answer: Paste the block diagram below:
b) (2.0 points) Write a program
# Answer: Paste the code below:
def generate_binary_strings(n):
def backtrack(s):
if len(s) == n:
print(s)
else:
backtrack(s + '0')
backtrack(s + '1')

backtrack("")

# Prompt user for the length of the binary string


n = int(input("Enter the length of the binary string (n > 1): "))
if n > 1:
generate_binary_strings(n)
else:
print("Please enter a value of n greater than 1.")

# Answer: Paste the execution result below with n = 6:

000000
000001
000010
000011
000100
000101
000110
000111
001000
001001
001010
001011
001100
001101
001110
001111
010000
010001
010010
010011
010100
010101
010110
010111
011000
011001
011010
011011
011100
011101
011110
011111
100000
100001
100010
100011
100100
100101
100110
100111
101000
101001
101010
101011
101100
101101
101110
101111
110000
110001
110010
110011
110100
110101
110110
110111
111000
111001
111010
111011
111100
111101
111110
111111

Question 3 (2 points): Given the function

a) (1 point) Expand the first derivative of f(x)


# Answer: Expand derivative:
f'(x) = 4xe^(2x^2 + 1) - 18 + 6x^2

b) (1 point) Write a program (using a function) to calculate the minimum value of f(x) using
gradient descent with the learning rate, number of iterations N and error :

# Answer: Paste the code below:


import math

def gradient_descent(f, df, x0, learning_rate, num_iterations, epsilon):


"""
Thực hiện thuật toán Gradient Descent để tìm cực tiểu của hàm số.

Args:
f: Hàm số cần tìm cực tiểu.
df: Đạo hàm của hàm số f.
x0: Điểm bắt đầu.
learning_rate: Tốc độ học.
num_iterations: Số lần lặp tối đa.
epsilon: Độ chính xác.

Returns:
Giá trị x tại điểm cực tiểu.
"""

x = x0
for i in range(num_iterations):
gradient = df(x)
x = x - learning_rate * gradient
if abs(gradient) < epsilon:
break
return x
# Định nghĩa hàm và đạo hàm
def f(x):
return math.exp(2*x**2+1) - 18*x + 2*x**3 - 5

def df(x):
return 4*x*math.exp(2*x**2+1) - 18 + 6*x**2

# Thiết lập các tham số


x0 = 0 # Điểm bắt đầu
learning_rate = 0.01
num_iterations = 1000
epsilon = 1e-6

# Thực hiện thuật toán


result = gradient_descent(f, df, x0, learning_rate, num_iterations, epsilon)

print("Giá trị x tại điểm cực tiểu:", result)

# Answer: Paste the execution result with the starting point,x = 5, learning rate = 0.001,
number of iterations N = 10000 and error :
Traceback (most recent call last):
File "c:\New folder\math1.py", line 41, in <module>
result = gradient_descent(f, df, x0, learning_rate, num_iterations, epsilon)
File "c:\New folder\math1.py", line 21, in gradient_descent
gradient = df(x)
File "c:\New folder\math1.py", line 32, in df
return 4*x*math.exp(2*x**2+1) - 18 + 6*x**2
OverflowError: math range error

Question 4 (3 point): Give a weighted graph as shown in the figure below:


a) (1 point) Build the minimum spanning tree of the graph using Prim’s algorithm.
# Answer: Paste the code of Prim's algorithm below:
import heapq

def prim(graph, start_node):


mst = [] # List to store the edges of the Minimum Spanning Tree
visited = set() # Set to keep track of visited nodes
min_heap = [(0, start_node, None)] # (weight, node, previous_node)

while min_heap:
weight, current_node, previous_node = heapq.heappop(min_heap)
if current_node not in visited:
visited.add(current_node)
if previous_node is not None:
mst.append((previous_node, current_node, weight))

for neighbor, edge_weight in graph[current_node]:


if neighbor not in visited:
heapq.heappush(min_heap, (edge_weight, neighbor, current_node))
return mst

# Define the graph as an adjacency list


graph = {
'A': [('B', 3), ('C', 5)],
'B': [('A', 3), ('C', 4), ('D', 4)],
'C': [('A', 5), ('B', 4), ('D', 6), ('E', 7)],
'D': [('B', 4), ('C', 6), ('E', 2), ('F', 2)],
'E': [('C', 7), ('D', 2), ('F', 5)],
'F': [('D', 2), ('E', 5)]
}

# Start the algorithm from node 'A'


mst = prim(graph, 'A')
print("Minimum Spanning Tree using Prim's Algorithm:", mst)

# Answer: Paste the execution result:


Minimum Spanning Tree using Prim's Algorithm: [('A', 'B', 3), ('B', 'C', 4), ('B', 'D', 4), ('D', 'E',
2), ('D', 'F', 2)]

b) (1 points) Build the minimum spanning tree of the graph using Kruscal’s algorithm.
# Answer: Paste the code of Kruscal algorithm below:
class DisjointSet:
def __init__(self, vertices):
self.parent = {v: v for v in vertices}
self.rank = {v: 0 for v in vertices}

def find(self, item):


if self.parent[item] != item:
self.parent[item] = self.find(self.parent[item])
return self.parent[item]

def union(self, set1, set2):


root1 = self.find(set1)
root2 = self.find(set2)
if root1 != root2:
if self.rank[root1] > self.rank[root2]:
self.parent[root2] = root1
elif self.rank[root1] < self.rank[root2]:
self.parent[root1] = root2
else:
self.parent[root2] = root1
self.rank[root1] += 1

def kruskal(graph):
edges = []
for node in graph:
for neighbor, weight in graph[node]:
edges.append((weight, node, neighbor))
edges.sort() # Sort edges by weight

mst = []
disjoint_set = DisjointSet(graph.keys())

for weight, u, v in edges:


if disjoint_set.find(u) != disjoint_set.find(v):
disjoint_set.union(u, v)
mst.append((u, v, weight))

return mst

# Define the graph as an adjacency list


graph = {
'A': [('B', 3), ('C', 5)],
'B': [('A', 3), ('C', 4), ('D', 4)],
'C': [('A', 5), ('B', 4), ('D', 6), ('E', 7)],
'D': [('B', 4), ('C', 6), ('E', 2), ('F', 2)],
'E': [('C', 7), ('D', 2), ('F', 5)],
'F': [('D', 2), ('E', 5)]
}

# Execute Kruskal's algorithm


mst = kruskal(graph)
print("Minimum Spanning Tree using Kruskal's Algorithm:", mst)

# Answer: Paste the execution result:


Minimum Spanning Tree using Prim's Algorithm: [('A', 'B', 3), ('B', 'C', 4), ('B', 'D', 4), ('D', 'E',
2), ('D', 'F', 2)]

c) (1 điểm) Distinguish the similarities and differences between Prim's algorithm and Kruskal's
algorithm
# Answer:
Similarities:

 Goal: Both algorithms aim to find a minimum spanning tree of a given graph.
 Data Structure: Both algorithms often use a priority queue to efficiently select edges.
 Output: Both algorithms produce a minimum spanning tree.

Differences:

 Approach:
o Prim's Algorithm: It starts from an arbitrary vertex and grows the MST by adding the
minimum-weight edge connected to the current tree.
o Kruskal's Algorithm: It sorts all the edges by weight and adds the smallest-weight edge
that doesn't form a cycle.
 Time Complexity:
o Prim's Algorithm:
 Using a binary heap: O(E log V)
 Using a Fibonacci heap: O(E + V log V)
o Kruskal's Algorithm: O(E log E)
 Space Complexity:
o Both algorithms generally have a space complexity of O(V + E).

-THE END-
Reviewed and Approved by Head of Computer Science Date:
and Engineering Department Signed by Lecturer:

Hieu Nguyen Van

You might also like