Thực hành Toán rời rạc - Chương 1: Cơ sở logic và tập hợp. Chương này cung cấp cho học viên những nội dung về: các phép toán luận lý trong Python; dữ liệu dạng tập hợp trong Python: Set; dữ liệu dạng tập hợp trong Sympy: FiniteSet;... Mời các bạn cùng tham khảo!
THỰC HÀNH TOÁN RỜI RẠC TÀI LIỆU PHỤC VỤ SINH VIÊN NGÀNH KHOA HỌC DỮ LIỆU Nhóm biên soạn Giảng viên có đóng góp ý kiến: TS Hồng Lê Minh – Khưu Minh Cảnh – Lê Ngọc Thành – Phạm Trọng Nghĩa - Nguyễn Công Nhựt – Trần Ngọc Việt - Hoàng Thị Kiều Anh – Huỳnh Thái Học TP.HCM – Năm 2019 MỤC LỤC BÀI 1: CƠ SỞ LOGIC VÀ TẬP HỢP Các phép toán luận lý Python 1.1 Luận lý Python 1.2 Biểu thức điều kiện if 1.3 Thứ tự tính tốn Python Dữ liệu dạng tập hợp Python: Set Dữ liệu dạng tập hợp Sympy: FiniteSet 3.1 Xây dựng thao tác tập hợp 3.1.1 Xây dựng tập hợp 3.1.2 Kiểm tra số tập hợp 3.1.3 Tạo tập hợp rỗng 10 3.1.4 Tạo tập hợp từ List Tuple 10 3.1.5 Loại bỏ phần tử trùng thứ tự tập hợp 10 3.2 Tập (subset), tập cha (superset) tập tập (power set) 12 3.3 Các phép toán tập hợp 13 3.3.1 Union Intersection 14 3.3.2 Tích Descart – Cartesian Product 16 3.3.3 Áp dụng công thức cho tập nhiều biến 16 3.3.4 Ứng dụng: Tính tốn xác suất kiện A kiện B xảy 17 BÀI TẬP CHƯƠNG 18 BÀI 1: CƠ SỞ LOGIC VÀ TẬP HỢP Mục tiêu: - Nắm vững Python để viết đoạn lệnh xử lý về: mệnh đề, logic, đúng/sai - Sử dụng tốt công cụ xử lý tập hợp, bao gồm: định nghĩa phép tốn Nội dung chính: Các phép tốn luận lý Python 1.1 Luận lý Python Python có kiểu liệu luận lý True False cho phép xử lý == (so sánh bằng), != (so sánh khác), , is (là), is not phép toán liên quan là: and, or, not, ^ (XOR) Ví dụ: >>> a = True >>> b = False >>> a and b False >>> a or b True >>> a ^ b True 1.2 Biểu thức điều kiện if Trong Python, biểu thức điều kiện if else cấu trúc rẽ nhánh Cấu trúc lệnh if sau: >>> if (điều kiện 1): # khối lệnh xử lý điều kiện elif (điều kiện 2): # khối lệnh xử lý điều kiện elif (điều kiện 3…): # khối lệnh xử lý điều kiện 3… else: # trường hợp lại # khối lệnh xử lý trường hợp lại Việc sử dụng hiệu cấu trúc dẫn đến chương trình tinh gọn Sinh viên thực hành lệnh đây: >>> def kiemtra_nuocsoi(nhiet_do): if nhiet_do < 100: return "Nuoc chua soi!" else: return "Nuoc da soi!" >>> kiemtra_nuocsoi(100) ……….………………………………… …………………… sinh viên ghi kết >>> kiemtra_nuocsoi(99) ……….……………………………………… ……………… sinh viên ghi kết Sau đó, sinh viên thử cách viết hàm tinh gọn sau: Và thực kiểm tra: >>> kiemtra_nuocsoi1(100) ……….………………………………… …………………… sinh viên ghi kết >>> kiemtra_nuocsoi1(99) ……….………………………………… …………………… sinh viên ghi kết Hơn nữa, lệnh rẽ nhánh if sử dụng “thiết kế” danh sách giá trị Sinh viên thực lệnh sau: - Xây dựng danh sách gồm phần tử thỏa điều kiện >5: >>> for diem_so in range(10): if diem_so > 5: ds_dau.append(str(diem_so)) >>> ds_dau ……….………………………… …………………… sinh viên ghi kết Và đoạn code ngắn gọn: >>> ds_dau = [str(diem_so) for value in range(10) if diem_so > 5] >>> ds_dau ……….………………………… …………………… sinh viên ghi kết 1.3 Thứ tự tính tốn Python Bên cạnh đó, ngơn ngữ lập trình, trình biên dịch Python thường xử lý phép toán từ trái sang phải (left-to-right order) Theo đó, biểu thức logic bị ảnh hưởng thứ tự tính tốn Ví dụ: phép tốn AND, yếu tố khơng thỏa biểu thức mang giá trị False (sai), nhầm giảm thiểu tính tốn khơng cần thiết; với phép toán OR, biểu thức thỏa biểu thức phía sau khơng cần tính toán Sinh viên thực hành lệnh sau để hiểu thứ tự tính tốn Python: Kết câu lệnh if là: ………………………………………………………………… Sinh viên thực hành đoạn lệnh khác: Sinh viên ghi nhận kết đoạn lệnh giải thích ……….……….………………………………… …………………………………………… Dữ liệu dạng tập hợp Python: Set Python cung cấp cú pháp đơn giản để thể khái niệm liệu rời rạc tập hợp, … với kỹ thuật tính tốn đếm tổ hợp Cụ thể: Phép tốn tập hợp (set operators): Tập hợp phép toán tập khái niệm toán rời rạc Theo đó, Python hỗ trợ kiểu liệu list set đối tượng tập phép toán hai kiểu liệu Với list, tập đối tượng sửa đổi Ví dụ 1: Tập 20 số nguyên chẵn từ theo toán học định nghĩa là: = { | = ;0 ≤ ≤ 19} Python mô tả tập (kiểu list) theo định nghĩa là: S = [2*x for x in range(20)] Lệnh: >>> S = [2*x for x in range(20)] Sau đó, sinh viên điền kết với lệnh sau: >>> S ……………………………………………………………………………………………… Ví du 2: Bên cạnh list, Python hỗ trợ kiểu liệu set với phép toán so sánh tập Sinh viên thực tập: So sánh tập nghiệm phương trình = { | + − = 0} tập = {−3,2} >>> A = set([x for x in range(-50, 50) if x**2 + x - == 0]) >>> B = set([2, -3]) >>> A == B ………………………………… sinh viên ghi kết (gợi ý: True False) Câu hỏi cho sinh viên: khoảng (-50, 50) có ý nghĩa lệnh trên? Thay khoảng khác khơng? Lí do? Sinh viên trả lời: ………………………………………… …………………………………… Ví dụ 3: Xây dựng tập số nguyên tố nhỏ 40 Theo định nghĩa, số nguyên tố số chia hết cho Do vậy, Python, xây dựng hàm kiểm tra, trả False số không thỏa điều kiện định nghĩa số nguyên tố, ngược lại trả True >>> def isPrime(N): for i in [ x+1 for x in range(N) ]: if N % i == and (i!=1 and i!=N): return False return True Và sau đó, xây dựng tập hợp số nguyên tố: >>> S_prime = [isPrime(k) for k in range(1,40)] Kết là: Sinh viên thực hành: - Số 36 số nguyên tố nên S_prime[36] = True, ngược lại số S_prime[37] = False Sinh viên thay lệnh S_prime cách viết theo set sau: >>> S_prime = set([x for x in range(40) if (isPrime(x) == True and x>0)]) >>> S_prime ……………………………………………………………………… Sinh viên điền kết Ví dụ 4: Tạo tập tích từ hai tập (set product) Giả sử, cần lấy lần giá trị nghiệm, 20 lần giá trị nghiệm 200 lần giá trị nghiệm phương trình + − = Chúng ta viết lệnh sau: >>> Apro = set([2*x *y for x in range(-50,50) if x**2+x-6 == for y in [1, 10, 100]]) >>> Apro ……………………………………………………………………… sinh viên điền kết Ví dụ 5: Ý tưởng tương tự ví dụ tập tích tạo giữ hai nhóm giá trị từ tập nguồn: >>> AB = set([ (x, 2*y) for x in range(-50,50) if x**2+x-6 == for y in [1, 10, 100]]) >>> AB ……………………………………………………………………… sinh viên điền kết Dữ liệu dạng tập hợp Sympy: FiniteSet Trong kí hiệu tốn học, thể phần tử tập hợp nằm dấu {} (curly brackets) Ví dụ : {3,5,7} tập hợp thể phần là: 3, 5, 3.1 Xây dựng thao tác tập hợp 3.1.1 Xây dựng tập hợp Để tạo tập hợp gói sympy Python, sử dụng lớp FiniteSet từ gói sympy sau: >>> from sympy import FiniteSet >>> s = FiniteSet(3, 5, 7) >>> s {3, 5, 7} Trong đoạn lệnh trên, import lớp FiniteSet từ gói SymPy sau tạo đối tượng từ lớp việc chuyển phần tử tập hợp Chúng ta đặt tập hợp tên s Để lưu trữ loại số khác nhau, bao gồm số nguyên, số thực, phân số tập hợp sau: >>> from sympy import FiniteSet >>> from fractions import Fraction >>> s = FiniteSet(1, 1.5, Fraction(1, 5)) >>> s {1/5, 1, 1.5} Số lượng (cardinality) tập hợp số lượng phần tử tập hợp Hàm len() sử dụng để đếm số lượng phần tử: >>> s = FiniteSet(1, 1.5, Fraction(8, 2)) >>> s {1, 1.5, 4} >>> len(s) 3.1.2 Kiểm tra số tập hợp Để kiểm tra tồn số tập hợp, sử dụng toán tử in Toán tử trả giá trị chân trị True (nếu tồn tại) False (nếu không tồn tại) Ví dụ: kiểm tra giá trị có nằm tập s bên lệnh sau: >>> in s False >>> in s True 3.1.3 Tạo tập hợp rỗng Để tạo tập rỗng (empty set), nghĩa tập khơng có phần tử, tạo đối tượng FiniteObject mà không cần đưa thông số vào Lệnh sau: >>> from sympy import FiniteSet >>> s = FiniteSet() >>> s EmptySet() 3.1.4 Tạo tập hợp từ List Tuple Trong Python, tập hợp tạo từ List Tuple sau: >>> phantu = [2, 4, 6, 8, 10] >>> tap = FiniteSet(*phantu) >>> tap {2, 4, 6, 8, 10} Ở đây, ta thấy: thay chuyển danh sách phần tử trực tiếp vào tham số FiniteSet lưu trữ chúng danh sách phantu (kiểu list) Sau đó, chuyển danh sách vào FiniteSet cú pháp Python đặc biệt Bằng phương pháp này, sử dụng uyển chuyển viết chương trình phần tử tập hợp tính tốn chương trình 3.1.5 Loại bỏ phần tử trùng thứ tự tập hợp Kiểu tập hợp Python (như tập hợp toán học) loại bỏ phần tử trùng không quan tâm đến thứ tự phần tử tập hợp (nghĩa tập hợp xếp lại, khơng giữ thứ tự ban đầu) Ví dụ: tạo tập từ list có nhiều phần tử giống nhau, đó, số thêm vào tập hợp lần Xét ví dụ sau: >>> from sympy import FiniteSet >>> phantu = [6, 7, 8, 9, 6, 7] >>> taphop = FiniteSet(*phantu) >>> taphop {6, 7, 8, 9} Rõ ràng danh sách ban đầu có phần tử có trùng Tuy nhiên, đưa vào tập hợp chúng loại bỏ cách tự động Lưu ý: Trong Python, hai kiểu danh sách list tuple lưu trữ phần tử theo thứ tự phần tử Tuy nhiên, với kiểu tập hợp điều khơng cịn Xét chương trình in liệu từ tập trên: >>> from sympy import FiniteSet >>> phantu = [6, 7, 8, 9, 6, 7] >>> taphop = FiniteSet(*phantu) >>> taphop {6, 7, 8, 9} >>> for thanhphan in taphop: print(thanhphan) ……………………………………………… sinh viên điền vào kết Thực đoạn lệnh lặp in nhiều lần thấy thứ tự phần tử xuất khơng vấn đề Khi đó, có khái niệm so sánh hai tập hợp Hai tập hợp theo toán học chúng phần tử Trong Python, sử dụng phép toán == để so sánh hai tập hợp nhau: >>> from sympy import FiniteSet >>> ds1 = [2, 4, 6] >>> ds2 = [6, 2, 4] >>> ds1 == ds2 ………………………………………… sinh viên điền kết >>> s = FiniteSet(*ds1) >>> t = FiniteSet(*ds2) >>> s == t ………………………………………… sinh viên điền kết Kết cho thấy thứ tự phần tử không ảnh hưởng đến tập hợp 3.2 Tập (subset), tập cha (superset) tập tập (power set) Một tập s tập tập t phần tử s phần tử t Ví dụ: tập {1} tập tập {1, 2} Việc kiểm tra tập thực lệnh is_subset() >>> s = FiniteSet(1) >>> t = FiniteSet(1,2) >>> s.is_subset(t) ………………………………………… sinh viên điền kết >>> t.is_subset(s) ………………………………………… sinh viên điền kết >>> t.is_subset(t) ………………………………………… sinh viên điền kết Tương tự, ta gọi tập t superset (tập cha) tập s t chứa tất phần tử chứa s Lệnh kiểm tra is_superset(): >>> s.is_superset(t) ………………………………………… sinh viên điền kết >>> t.is_superset(s) ………………………………………… sinh viên điền kết Tập tập (powerset) tập s tập tất tập s Từ đó, với tập, có 2| | phần tử (mỗi phần tử tập hợp) với | | số phần tử tập hợp Ví dụ: tập {1,2,3} có phần tử, vậy, số lượng tập = 8, bao gồm: {} (tập rỗng), {1}, {2}, {3}, {1,2}, {1,3}, {2,3} {1,2,3} Kiểu liệu tập FiniteSet cung cấp hàm để xử lý, hàm powerset() Ví dụ: >>> s = FiniteSet(1,2,3) >>> ps = s.powerset() >>> len(ps) ………………………………………… sinh viên điền kết >>> ps ………………………………………… sinh viên điền kết Bên cạnh đó, theo định nghĩa tốn học, tập vừa tập vừa tập cha Bên cạnh đó, phép so sánh tập cha “ngặt” tập “ngặt” để đảm bảo số phần từ tập cha lớn số phần tử tập Ví dụ: tập s = {1,2,3} tập cha “ngặt” tập {1}, {2,3}, {1,3} ngược lại, tập {1}, {2,3}, {1,3} có số phần tử tập cha {1,2,3} Quan hệ thể kiểu liệu FiniteSet qua lệnh kiểm tra tập “ngặt” tập cha “ngặt” là: is_proper_subset() is_proper_superset() Ví dụ: >>> from sympy import FiniteSet >>> s = FiniteSet(1, 2, 3) >>> t = FiniteSet(3, 2, 1) >>> s.is_proper_subset(t) ………………………………………… sinh viên điền kết >>> t.is_proper_powerset(s) ………………………………………… sinh viên điền kết >>> t = FiniteSet(3, 2, 1, 4) >>> s.is_proper_subset(t) ………………………………………… sinh viên điền kết >>> t.is_proper_ powerset (s) ………………………………………… sinh viên điền kết 3.3 Các phép toán tập hợp Các phép tốn tập hợp hợp, giao tích Cartesian cho phép tổ hợp tập hợp số phương cách định Những phép tính tập hợp hữu dụng giới thực để giải toán cần xử lý nhiều tập hợp với Ngồi ra, phép tính tiền đề để tính tốn liệu xác suất kiện ngẫu nhiên 3.3.1 Union Intersection Union tập hợp phép nối/hợp tập chứa phần tử khác tập Trong lý thuyết tập hợp kí hiệu ∪ Ví dụ: {1,2} ∪ {2,3} = {1,2,3} Trong Sympy, phép hợp thực phương thức union(): >>> from sympy import FiniteSet >>> s = FiniteSet(2, 4, 6) >>> t = FiniteSet(3, 5, 7) >>> kq = s.union(t) >>> kq {2, 3, 4, 5, 6, 7} Như vậy, bên trên, tìm hợp tập s t phương thức union Kết trả tập thứ có tên kq Ở đây, phần tử tập kq phần tử hai tập Ngoài ra, xử dụng phép tốn + để hợp nối tập hợp >>> from sympy import FiniteSet >>> u = FiniteSet(10, 20, 50) >>> v = FiniteSet(1, 2, 5) >>> u + v {1, 2, 5, 10, 20, 50} Phép toán giao (intersection) hai tập việc tạo lập tập từ phần tử chung tập Ví dụ: giao tập {1, 2, 10} {1, 3, 10} kết tâp gồm phần tử chung, nghĩa tập {1, 10} Về mặt toán học, viết sau {1,2,10} ∩ {1,3,10} = {1,10} Trong SymPy, lệnh intersect() để tìm tập giao: >>> from sympy import FiniteSet >>> s = FiniteSet(1, 2, 10) >>> t = FiniteSet(1, 3, 10) >>> giao = s.intersect(t) >>> giao {1, 10} Lưu ý: với phép toán union() intersect() trả tập hợp (các FiniteSet) nên sử dụng phép lồng có tính tốn liên tiếp Ví dụ: >>> from sympy import FiniteSet >>> s = FiniteSet(1, 2, 10) >>> t = FiniteSet(1, 3, 10) >>> u = FiniteSet(10, 20, 50) >>> hop = s.union(t).union(u) >>> hop {1, 2, 3, 10, 20, 50} >>> giao = s.intersect(t).intersect(u) >>> giao {10} Nếu tập trả tập rỗng SymPy báo tập EmptySet() Ví dụ: >>> from sympy import FiniteSet >>> u = FiniteSet(10, 20, 50) >>> v = FiniteSet(1, 2, 5) >>> rong = u.intersect(v) >>> rong EmptySet() >>> rong = v.intersect(u) >>> rong EmptySet() 3.3.2 Tích Descart – Cartesian Product Tích Descart tập hữu dụng để tìm tất tổ hợp phần tử tập hợp Bằng cách sử dụng tích tập với (có thể sử dụng phép toán nhân * lũy thừa **), tìm tổ hợp tập hợp, cụ thể chỉnh hợp Ví dụ: >>> from sympy import FiniteSet >>> v = FiniteSet(1, 2, 5) >>> p = v ** >>> p {1, 2, 5} x {1, 2, 5} >>> for phantu in p: print(phantu) ……………… ……………… ……………… … ……………… sinh viên liệt kê 3.3.3 Áp dụng công thức cho tập nhiều biến Để xử lý phần tử tập FiniteSet, sử dụng lệnh lặp for sau: >>> from sympy import FiniteSet >>> K = FiniteSet(35, 18, 27, 29, 24) >>> for k in K: T = k/10.0 print (T, k) ……………… sinh viên liệt kê Thứ tự số xếp tăng dần 3.3.4 Ứng dụng: Tính tốn xác suất kiện A kiện B xảy Khi có kiện muốn tính tốn xác suất xảy kiện lúc Ví dụ: hội cho lựa chọn vừa số nguyên tố vừa số lẻ (như chọn biển số xe) Để tính tốn được, cần xác định xác suất kiện giao kiện: = ∩ = {2, 3, 5, 7} ∩ {1, 3, 5, 7, 9} = {3, 5, 7} Chúng ta tính tốn xác suất kiện cho A B xảy lúc phương thức intersect() Cụ thể: >>> from sympy import FiniteSet >>> s = FiniteSet(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) # cac so co the bien so >>> a = FiniteSet(2, 3, 5, 7) # cac so nguyen to >>> b = FiniteSet(1, 3, 5, 7, 9) # cac so le >>> e = a.intersect(b) >>> len(e)/len(s) 0.333333333333 Như vậy, xác suất để số số nguyên tố lẻ chọn từ 10 số từ đến 0.33, nghĩa 33% Thông tin thêm: Ứng dụng y tế cộng đồng: Bài toán đơn giản thường áp dụng tìm kiếm ca nghi bệnh với tập hợp người xuất khu thương mại nơi có bệnh nhân Để có tập hợp, người ta sử dụng cơng nghệ dị sóng điện thoại GMS/3G/4G/…, để định vị trí người mang theo điện thoai Và sau xử lý để thơng báo y tế địa phương người cư ngụ BÀI TẬP CHƯƠNG Bài 1: Tìm hiểu khác giống loại kiểu liệu tập hợp: set (của ngơn ngữ Python) FiniteSet (của gói sympy) Hướng dẫn: tìm kiếm Google Bài 2: Ở trường, hiệu trưởng quy định xét học bổng, tất sinh viên có điểm trung bình điểm rèn luyện không xét học bổng, trường hợp ngược lại Được xem xét học bổng Hãy cho biết đoạn script thể đắn theo quy định xét học bổng chưa, muốn mơ tả theo ý quy định cần điều chỉnh lại nào? if not (diemtrungbinh > and diemrenluyen > 7): print ("Khong duoc xet hoc bong") else: print ("Duoc xem xet hoc bong") Bài 3: Bác sĩ yêu cầu kỹ sư viết phần mềm với bảng liệu bệnh huyết áp thấp/cao thu thập sau: Phân loại (huyết áp) Tâm thu (Systolic) Biểu thức Tâm trương (díatolic)