1. Trang chủ
  2. » Giáo án - Bài giảng

ĐỒ ÁN LẬP TRÌNH TÍNH TOÁN ĐỀ TÀI Bạn muốn hẹn hò

20 113 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Bạn muốn hẹn hò
Tác giả Nguyễn Lê Việt Hoàng, Nguyễn Anh Nguyên
Người hướng dẫn ThS. Nguyễn Thị Lệ Quyên
Trường học Trường Đại Học Bách Khoa
Chuyên ngành Công Nghệ Thông Tin
Thể loại Đồ án
Năm xuất bản 2022
Thành phố Đà Nẵng
Định dạng
Số trang 20
Dung lượng 568,77 KB

Nội dung

Phạm vi và đối tượng nghiên cứu: sử dụng bao quát những kiến thức đã học và tập trung chủ yếu tại các cấu trúc trong cấu trúc dữ liệu, đối tượng nghiên cứu chính là cấu trúc dữ liệu tập

Trang 1

TRƯỜNG ĐẠI HỌC BÁCH KHOA KHOA CÔNG NGHỆ THÔNG TIN

ĐỒ ÁN LẬP TRÌNH TÍNH TOÁN

TÊN ĐỀ TÀI

Đề C05: Bạn muốn hẹn hò?

Người hướng dẫn: ThS NGUYỄN THỊ LỆ QUYÊN Sinh viên thực hiện:

Họ và tên:

Nguyễn Lê Việt Hoàng LỚP: 21TCLC-DT1

Họ và tên: Nguyễn Anh Nguyên LỚP: 21TCLC-DT1

NHÓM: 09

Đà Nẵng, 07/2022

Trang 2

1

MỤC LỤC

Trang 3

2

DANH MỤC HÌNH VẼ

Trang 4

1

MỞ ĐẦU

Trong phần này, cần trình bày về: Mục đích thực hiện đề tài, mục tiêu đề tài, phạm vi và đối tượng nghiên cứu, phương pháp nghiên cứu, cấu trúc của đồ môn học} Mục đích thực hiện đề tài: Thông qua quá trình thực hiện đề tài có thêm kiến thức, cũng như áp dụng được những kiến thức đã học để giải quyết vấn đề, bài toán một cách trơn tru tối ưu nhất có thể

Mục tiêu đề tài: giải quyết được bài toán được đưa ra

Phạm vi và đối tượng nghiên cứu: sử dụng bao quát những kiến thức đã học và tập trung chủ yếu tại các cấu trúc trong cấu trúc dữ liệu, đối tượng nghiên cứu chính là cấu trúc

dữ liệu tập hợp rời rạc và ứng dụng của nó

Phương pháp nghiên cứu: sử dụng các tài liệu được phổ cập trên trường cũng như tìm kiếm tài liệu từ Internet, đọc hiểu về cấu trúc dữ liệu tập hợp rời rạc, suy ra ý tưởng áp dụng kiến thức và hoàn thành đề bài

Cấu trúc của đồ môn học:sau khi tìm hiểu các lý thuyết về về thuật toán Disjoint-set và các lý thuyết liên qua lên ý tưởng và giải quyết vấn đề được đưa ra, kiểm tra và nâng cấp thuật toán

Trang 5

1

1 TỔNG QUAN ĐỀ TÀI

Chương trình Bạn muốn hẹn hò đã trở nên quá phổ biến trên truyền hình, và ở bách khoa cũng đã có chương trình tương tự như vậy với quy mô nhỏ hơn Trong đợt này có bạn nam và bạn nữ đăng ký tham gia Ban tổ chức có thông tin của tất cả người tham gia, kể cả trang cá nhân Facebook nên có thể biết được hai sinh viên có phải là bạn của nhau trên Facebook hay không Và ban tổ chức không muốn ghép cặp hai sinh viên

ở trong cùng một nhóm bạn với nhau Cho mối quan hệ bạn bè giữa các bạn sinh viên nam với nhau, mối quan hệ bạn bè giữa các bạn nữ với nhau và mối quan hệ bạn bè giữa nam và nữ Ban tổ chức muốn tính xem tổng cộng có bao nhiêu cặp sinh viên nam nữ

có thể ghép cặp được với nhau

2 CƠ SỞ LÝ THUYẾT

2.1 Ý tưởng

Phân chia các sinh viên thành các nhóm khác nhau theo các nhóm mà sinh viên thuộc về Phương pháp này được gọi là cấu trúc dữ liệu tập hợp phân biệt duy trì tập hợp các tập hợp rời rạc và mỗi tập hợp được đại diện bởi đại diện của nó là một trong các thành viên của nó

2.2 Cơ sở lý thuyết

2.2.1 Disjoint-set data structure

Cấu trúc dữ liệu tập hợp rời rạc , còn được gọi là cấu trúc dữ liệu liên hợp-tìm hoặc hợp nhất hợp-tìm tập hợp , là một cấu trúc dữ liệu lưu trữ một tập hợp các tập hợp rời rạc (không chồng chéo) Tương tự, nó lưu trữ một phân vùng của một tập hợp thành các tập con rời rạc Nó cung cấp các hoạt động để thêm các tập hợp mới, hợp nhất các tập hợp (thay thế chúng bằng liên hiệp của chúng ) và tìm thành viên đại diện của một tập hợp

2.2.2 Union (set theory)

Trong lý thuyết tập hợp, hợp (ký hiệu là ∪) của một tập hợp các tập hợp là tập hợp của tất cả các phần tử trong tập hợp [1] Nó là một trong những phép toán cơ bản

mà qua đó các tập hợp có thể được kết hợp và liên quan với nhau Liên hợp nullary đề cập đến liên hợp của các tập hợp 0 và theo định nghĩa, nó tương đương với tập hợp rỗng

2.2.3 Forest

Rừng là một đồ thị vô hướng trong đó hai đỉnh bất kỳ được nối với nhau bằng nhiều nhất một đường đi Tương tự, rừng là một đồ thị xoay chiều vô hướng, tất cả các

Trang 6

2

thành phần được kết nối của chúng là cây; nói cách khác, biểu đồ bao gồm sự kết hợp rời rạc của các cây Trong những trường hợp đặc biệt, biểu đồ bậc không (một khu rừng không có cây nào), một cây đơn lẻ và một biểu đồ không viền, là những ví dụ về rừng

Vì với mọi cây V - E = 1, chúng ta có thể dễ dàng đếm số cây trong một khu rừng bằng cách trừ đi hiệu số giữa tổng số đỉnh và tổng số cạnh TV - TE = số cây trong rừng

3 TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN

3.1 Phát biểu bài toán

Mô tả đầu vào (Input) và đầu ra (Output)

Input:

- Dòng đầu là số 2 nguyên là số lượng sinh viên nam và số lượng sinh viên

nữ tham gia chương trình

- Dòng tiếp theo chứa số a, theo sau là a dòng, mỗi dòng gồm 2 số và thể hiện bạn nam và bạn nam là bạn của nhau trên Facebook

- Dòng tiếp theo chứa số b, theo sau là b dòng, mỗi dòng gồm 2 số và thể hiện bạn nữ và bạn nữ là bạn của nhau trên Facebook

- Dòng tiếp theo chứa số c, theo sau là c dòng, mỗi dòng gồm 2 số và thể hiện bạn nam và bạn nữ là bạn của nhau trên Facebook

Output:

- In kết quả số cặp sinh viên nam nữ có thể ghép cặp được với nhau

3.2 Cấu trúc dữ liệu

Mảng: Một mảng các số nguyên, được gọi là cha [] Nếu chúng ta đang xử lý n

mục, phần tử thứ i của mảng đại diện cho mặt hàng thứ i Chính xác hơn, phần

tử thứ i của mảng là phần tử cha của mục thứ i Những mối quan hệ này tạo ra một hoặc nhiều cây ảo

Cây: Nó là một tập hợp rời rạc Nếu hai phần tử nằm trong cùng một cây, thì

chúng nằm trong cùng một tập rời rạc Nút gốc (hay nút trên cùng) của mỗi cây được gọi là đại diện của tập hợp Luôn luôn có một đại diện duy nhất duy nhất của mỗi bộ Một quy tắc đơn giản để xác định đại diện là, nếu tôi là đại diện của một tập hợp, thì cha [i] = i Nếu tôi không phải là đại diện của tập hợp của anh ấy, thì có thể tìm thấy nó bằng cách đi lên cây cho đến khi chúng tôi tìm thấy đại diện

Canh lề phải thẳng hàng

Trang 7

3

3.3 Thuật toán

Trình bày các thuật toán và phân tích độ phức tạp của các thuật toán

-Hàm find(): trả về vị trí người đại diện;

-Hàm Union: Trước hết, chúng ta cần một mảng số nguyên mới được gọi là xếp hạng

[] Kích thước của mảng này giống như mảng mẹ Nếu i là đại diện của một tập hợp,

thì rank[i] là chiều cao của cây đại diện cho tập hợp đó Bây giờ những gì chúng ta

muốn làm là giảm thiểu chiều cao của cây kết quả Nếu chúng ta đang hợp nhất hai cây

Code đã có ở phần phụ lục, ko dán code ở đây Thay thế bằng sơ đồ khối hoặc giả code

Canh lề phải thẳng hàng

Trang 8

4

(hoặc tập hợp), hãy gọi chúng là trái và phải, sau đó tất cả phụ thuộc vào thứ hạng của bên trái và thứ hạng của bên phải

● Nếu thứ hạng bên trái nhỏ hơn thứ hạng bên phải, thì tốt nhất bạn nên di chuyển sang trái dưới bên phải, vì điều đó sẽ không thay đổi thứ hạng bên phải (trong khi di chuyển sang phải dưới bên trái sẽ làm tăng chiều cao) Theo cách tương

tự, nếu thứ hạng của bên phải nhỏ hơn thứ hạng của bên trái, thì chúng ta nên di chuyển sang phải dưới bên trái

● Nếu các thứ hạng bằng nhau, không quan trọng cây nào đi dưới cây kia, nhưng thứ hạng của kết quả sẽ luôn lớn hơn thứ hạng của các cây

-Độ phức tạp thuật toán: Độ cao tối đa của cây là log(n)

Do vậy độ phức tạp của mỗi tạo tác find - union là O( log(n) )

Trang 9

5

4 CHƯƠNG TRÌNH VÀ KẾT QUẢ 4.1 Tổ chức chương trình

Gồm hàm Input để nhập dữ liệu , hàm solve để xử lý bài toán , hàm Union để hợp nhất 2 tập hợp , hàm find để tìm người đại diện , hàm main để thực thi các hàm trên

4.2 Ngôn ngữ cài đặt

Ngôn ngữ lập trình C : là một ngôn ngữ mệnh lệnh được phát triển từ đầu thập niên 1970 bởi Dennis Ritchie để dùng trong hệ điều hành UNIX Từ đó, ngôn ngữ này

đã lan rộng ra nhiều hệ điều hành khác và trở thành một những ngôn ngữ phổ dụng nhất C là ngôn ngữ rất có hiệu quả và được ưa chuộng nhất để viết các phần mềm hệ thống, mặc dù nó cũng được dùng cho việc viết các ứng dụng Ngoài ra, C cũng thường được dùng làm phương tiện giảng dạy trong khoa học máy tính mặc dù ngôn ngữ này không được thiết kế dành cho người nhập môn

4.3 Kết quả

4.3.1 Giao diện chính của chương trình

Định dạng văn bản ,

canh lề thống nhất

toàn bộ văn bản

Thiếu chú thích hình

Cần thêm hình demo, 3-4 hình gì đó

Trang 10

6

4.3.2 Kết quả thực thi của chương trình

Mô tả kết quả thực hiện chương trình

Ở đây chúng ta sử dụng 1 thuật toán kém hiệu quả hơn để kiểm tra tính chính xác và thời gian chạy của thuật toán Disjoint Set

test case 1 test case 2 test case 3

4.3.3 Nhận xét đánh giá

Gọi n = Nam + Nữ

- Khi số lượng n bé, 2 thuật toán có thời gian chạy tương đương nhau ; nhưng khi

số lượng n tăng lên, thuật Disjoint Set có thời gian chạy nhanh hơn hẳn

=> thuật Disjoint Set có thời gian chạy tối ưu hơn, thích hợp để tính toán với các số lớn ( n khoảng 10^6 thì thuật Disjoint Set chạy khoảng dưới 1s )

- Thuật tham lam dùng mảng 2 chiều nên không lưu được các giá trị nếu n tương đối lớn ( n> 5000 ) , trong khi đó thuật Disjoint Set chỉ dùng mảng 1 chiều để lưu kết quả nên có thể chứa các giá trị với n rất lớn ( n khoảng 10^6 )

=> thuật Disjoint Set sử dụng bộ nhớ tối ưu hơn và chứa được n tới 10^6 và có thể nâng số phần tử của mảng lên để chứa n tới 10^7

5 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN

5.1 Kết luận

Vậy code áp dụng thuật toán Disjoint set được phát triển tương đối tối ưu

Độ phức tạp về thời gian O(nlog(n))

Độ phức tạp về bộ nhớ O(3*10^6)

Với n<=10^6 code sẽ chạy dưới 1s, đủ để áp dụng cho các bài tập trên lớp hoặc các tình huống thực tế

Trang 11

7

5.2 Hướng phát triển

- Thiết kế giao diện đẹp hơn

- Chuyển sang ngôn ngữ lập trình bậc cao hơn ( như C++ ) để sử dụng các cấu trúc dữ liệu trong thư viện để tối ưu hóa chương trình Vd : dùng cấu trúc dữ liệu map thay cho mảng groupsize để giảm bộ nhớ cần sử dụng

Trang 12

8

TÀI LIỆU THAM KHẢO

[1] Disjoint Set Data Structures : https://www.geeksforgeeks.org/disjoint-set-data-structures/

[2] Độ Phức Tạp Của Thuật Toán Và Lựa Chọn Cách Giải Thuật :

https://codelearn.io/sharing/do-phuc-tap-cua-thuat-toan-va-lua-chon-cach-giai-thuat#:~:text=Tuy%20

nhi%C3%AAn%20v%E1%BB%9Bi%201%20s%E1%BB%91%20gi%E1%BA%A3i

%20thu%E1%BA%ADt%20s%E1%BA%AFp,ch%E1%BA%A1y%20c%C3%B3%20 th%E1%BB%9Di%20gian%20x%E1%BA%A5p%20x%E1%BB%89%20b%E1%BA

%B1ng%20nhau

[3] Zvi Galil and Giuseppe F Italiano : Data structures and algorithms for disjoint set union problems : https://dl.acm.org/doi/abs/10.1145/116873.116878

[4] Ashwin Pananjady : The online disjoint set cover problem and its applications https://ieeexplore.ieee.org/abstract/document/7218497

Trang 13

9

PHỤ LỤC

Sinh viên bỏ Code từng phần vào đây

Code dùng thuật Disjoint-set :

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#define ll long long

int Nam , Nu , a, b , c ;

int Parent[1000009] , Rank[1000009] ;

int find(int i) {

if (Parent[i] == i) return i;

else{

int result = find(Parent[i]);

Parent[i] = result;

return result;

}

}

void Union(int i, int j) {

int irep = find(i);

int jrep = find(j);

if (irep == jrep) return;

int irank = Rank[irep] ;

Trang 14

10

int jrank = Rank[jrep];

if (irank < jrank){

Parent[irep] = jrep;

}

else if (jrank < irank) {

Parent[jrep] = irep;

}

else{

Parent[irep] = jrep;

Rank[jrep]++;

}

}

void Input(){

printf("Nhap so luong nam va so luong nu : ") ;

scanf("%d%d",&Nam,&Nu) ;

int i ,tem1 , tem2 ;

// Buoc khoi tao

for(i=0;i<=Nam+Nu;i++) {

Rank[i]=0;

Parent[i]=i;

}

printf("Nhap so luong cac cap ban be giua cac ban nam : ") ;

Trang 15

11

scanf("%d",&a) ;

printf("Nhap moi quan he ban be giua cac ban nam : \n") ;

for (i=0;i<a;i++) {

scanf("%d%d",&tem1,&tem2) ;

Union(tem1,tem2) ;

}

printf("Nhap so luong cac cap ban be giua cac ban nu : ") ;

scanf("%d",&b) ;

printf("Nhap moi quan he ban be giua cac ban nu : \n") ;

for (i=0;i<b;i++) {

scanf("%d%d",&tem1,&tem2) ;

Union(tem1+Nam,tem2+Nam) ;

}

printf("Nhap so luong cac cap ban be giua cac ban nam va cac ban nu : ") ; scanf("%d",&c ) ;

printf("Nhap moi quan he ban be giua cac ban nam va cac ban nu : \n") ; for (i=0;i<c;i++) {

scanf("%d%d",&tem1,&tem2) ;

Union(tem1,tem2+Nam) ;

}

}

int groupsize[1000009] ;

void solve(){

int i,j ;

for(i=0;i<=Nam+Nu;i++) groupsize[i] = 0 ;

Trang 16

12

for(i=Nam+1;i<=Nam+Nu;i++){

int father = find(i) ;

groupsize[father]++ ;

}

ll res =0 ;

for(i=1;i<=Nam;i++){

res+= Nu-groupsize[find(i)] ;

}

printf("\n\n _\n\n") ;

printf("So cap sinh vien nam nu co the ghep cap voi nhau : %lld",res) ;

printf("\n\nBan co muon liet ke ra so cap nam nu co the ghep cap voi nhau khong

? \n") ;

printf("Co : 1 \n") ;

printf("khong : 0 \n") ;

printf("Nhap lua chon : ") ;

int choose = 1 ;

scanf("%d",&choose) ;

if (choose){

printf("\nKet qua :\n") ;

int i , j ;

for (i=1;i<=Nam;i++){

for(j=1;j<=Nu;j++){

if ( find(i)!=find(j+Nam) ){

printf("Nam : %d va Nu : %d \n",i,j);

}

}

}

}

Trang 17

13

}

int main(){

system("COLOR F4");

printf(" - Program C05 - \n") ;

printf(" - CHUONG TRINH BAN MUON HEN HO -

\n\n") ;

int chon1 , chon2 ;

printf("Chon cach nhap vao du lieu : \n") ;

printf("Nhap vao truc tiep : 1 \n") ;

printf("Nhap vao tu file : 0 \n") ;

scanf("%d",&chon1) ;

printf("Chon cach in ra du lieu : \n") ;

printf("In ra truc tiep : 1 \n") ;

printf("In ra file : 0 \n") ;

scanf("%d",&chon2) ;

if (chon1 == 0) {

freopen( "input.txt", "r", stdin);

}

if (chon2 ==0 ){

freopen( "output.txt", "w", stdout);

}

int luachon = 0 ;

do {

Input() ; solve() ;

Trang 18

14

==================================================") ;

printf("\n\nBan co muon tiep tuc khong ?\n") ;

printf("Co : 1 \n") ;

printf("khong : 0 \n") ;

printf("Nhap lua chon : ") ;

scanf("%d",&luachon) ;

if(luachon) printf("\n\n\n") ;

}

while(luachon) ;

}

Code dùng thuật tham lam :

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#define ll long long

int Nam , Nu , a, b , c ;

int Path[5000][5000] ;

int check[5000] , visited[5000] ;

void DFS(int u) {

if (visited[u]) return ;

Trang 19

15

visited[u] = 1 ; int i ;

for(i=1;i<=Nam+Nu;i++){

if (Path[u][i]){

check[i] = 1 ; DFS(i) ; }

} }

void Input(){

scanf("%d%d",&Nam,&Nu) ; int i ,tem1 , tem2 ;

scanf("%d",&a) ;

for (i=0;i<a;i++) {

scanf("%d%d",&tem1,&tem2) ;

Path[tem1][tem2] = Path[tem2][tem1] = 1 ;

}

scanf("%d",&b) ;

for (i=0;i<b;i++) {

scanf("%d%d",&tem1,&tem2) ;

Path[tem1+Nam][tem2+Nam] = Path[tem2+Nam][tem1+Nam] = 1 ;

}

scanf("%d",&c ) ;

for (i=0;i<c;i++) {

scanf("%d%d",&tem1,&tem2) ;

Path[tem1][tem2+Nam] = Path[tem2+Nam][tem1] = 1 ;

}

Ngày đăng: 06/08/2022, 16:48

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w