Cấu trúc dữ liệu và Phân tích, thiết kế giải thuật là hai học phần rất quan trọng đối với người lập trình. Học phần này được xem như nền tảng của lập trình máy tính. Nó là cơ sở vững chắc để giải quyết nhiều bài toán, đồng thời cung cấp cho chúng ta hiểu biết về các giải thuật tác động lên dữ liệu, cũng như cách tổ chức dữ liệu hiệu quả để tối ưu bài toán. Sau khi học xong học phần lí thuyết, em đã nghiên cứu và thực hiện đồ án này như là một cách để củng cố và mở rộng kiến thức. Thông qua quá trình thực hiện đồ án, chúng em đã nắm bắt được những kỹ thuật quan trọng của việc xây dựng cấu trúc dữ liệu và phân tích, thiết kế giải thuật sao cho tối ưu nhất.
Trang 1ĐẠI HỌC BÁCH KHOA KHOA CÔNG NGHỆ THÔNG TIN
ĐỒ ÁNGIẢI THUẬT VÀ LẬP TRÌNH
Trang 2MỤC LỤC
MỤC LỤC 1
LỜI MỞ ĐẦU 2
DANH MỤC HÌNH VẼ 3
1 GIỚI THIỆU ĐỀ TÀI 4
2 CƠ SỞ LÝ THUYẾT 4
2.1 Ý tưởng 4
2.2 Cơ sở lý thuyết 4
3 TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN 4
3.1 Phát biểu bài toán 4
3.2 Cấu trúc dữ liệu 6
3.3 Thuật toán 7
4 CHƯƠNG TRÌNH VÀ KẾT QUẢ 8
4.1 Tổ chức chương trình 8
4.2 Ngôn ngữ cài đặt 17
4.3 Kết quả 17
4.3.1 Giao diện chính của chương trình 17
4.3.2 Kết quả thực thi của chương trình 18
4.3.3 Nhận xét 20
5 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN 21
5.1 Kết luận 21
5.2 Hướng phát triển 21
TÀI LIỆU THAM KHẢO 21
Trang 3để tối ưu bài toán
Sau khi học xong học phần lí thuyết, em đã nghiên cứu và thực hiện đồ án nàynhư là một cách để củng cố và mở rộng kiến thức Thông qua quá trình thực hiện đồ
án, chúng em đã nắm bắt được những kỹ thuật quan trọng của việc xây dựng cấu trúc
dữ liệu và phân tích, thiết kế giải thuật sao cho tối ưu nhất
Bài toán “ Xếp lịch thi ” mà em nghiên cứu và trình bày trong báo cáo sau đây
là một ví dụ
Em xin chân thành cảm ơn thầy Võ Đức Hoàng đã bổ sung ý tưởng và tận tìnhgiúp đỡ chúng em thực hiện đồ án này Em cũng rất mong nhận được sự góp ý từ phíathầy để bài làm của em được hoàn thiện hơn
Trang 4DANH MỤC HÌNH VẼ
Hình 1 : Danh sách môn học đọc được từ tệp văn bản (Input) 18
Hình 2 : Danh sách môn học của các sinh viên đọc được từ tệp văn bản (Input) 18
Hình 3 : Kết quả mảng thể hiện các môn học kề nhau để xử lý 19
Hình 4 : Kết quả mã màu sau khi xử lý của từng môn học 19
Hình 5 : Kết quả lịch thi sau khi xếp lịch xong (Output) 20
Trang 51 GIỚI THIỆU ĐỀ TÀI
Mô tả: Giả sử mỗi sinh viên phải thi một số môn trong n môn thi Hãy lập lịch thi saocho không có sinh viên nào có 2 môn thi cùng 1 thời gian và số đợt thi là ít nhất
Đầu vào: Các tập tin văn bản chứa thông tin về: Số môn thi, Tên của các môn thi Sốsinh viên, Các môn học của từng sinh viên
Đầu ra: Tập tin văn bản chứa Lịch thi với số đợt thi ít nhất và không có sinh viên nào thinhiều hơn 1 môn ở mỗi đợt thi
2 CƠ SỞ LÝ THUYẾT
2.1 Ý tưởng
Như chúng ta đã biết , khi lên đại học thì mỗi sinh viên cho dù học cùng lớp thì vẫn cóthể học khác giờ nhau Vì thế thì việc sắp xếp lịch thi bằng tay sẽ mất rất nhiều thời gian Cho nên ý tưởng xây dựng một chương trình “ Xếp lịch thi ” bằng cấu trúc dữ liệu và thuậttoán sẽ giúp chúng ta giải quyết vấn đề đó
2.2 Cơ sở lý thuyết
Tạo một struct Student để chứa thông tin sinh viên và môn học của từng sinh viên.Khởi tạo một Array(mảng) Student để chứa tất cả sinh viên
Áp bài toán tô màu để giải quyết vấn đề
Giải thuật tham lam
Dựa trên cấu trúc dữ liệu và các thuật toán để xây dựng các giải thuật đáp ứng được vớiyêu cầu đề bài
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
a) Đầu vào (Input)
Các tập tin văn bản chứa thông tin về: Số môn thi, Tên của các môn thi Sốsinh viên, Các môn học của từng sinh viên
Trang 6+ Tệp văn bản số sinh viên và các môn học của từng sinh viên
students.txt
Dòng đầu tiên là số lượng sinh viên
Các dòng tiếp theo là tuần tự môn học của cácsinh viên được tổ chức theo hình thức :
+ Dòng đầu tiên là tên của sinh viên đó.+ Dòng thứ hai là số lượng môn học của sinhviên đó
+ Các dòng tiếp theo là tên của các môn họccủa sinh viên đó
+ Dòng cuối cùng là dấu ‘-‘ để báo hiệu chochương trình là đã đọc hết môn học của sinhviên đó
Giữa các sinh viên sẽ có dấu ‘-‘ để ngăn cáchnhau
Như tệp văn bản student.txt phía bên :
+ Nhìn dòng đầu tiên sẽ biết số sinh viên là : 4+ Tiếp đến là sinh viên đầu tiên tên Tran VanHien, có số lượng môn học là 3 và các mônhọc đó là Lap trinh java,Cong nghe di dong vaLap trinh oop
+ Sau khi đọc xong sinh viên đầu tiên thì sẽđến dấu ‘-‘ thì tiếp tục đọc các sinh viên tiếptheo cho đến hết
Trang 7+ Tệp văn bản số môn học để xếp lịch thi và danh sách các môn đó
subjects.txt
Dòng đầu tiên là số lương môn họcCác dòng tiếp theo là tên của các mônhọc
b) Đầu ra (Output)
Tập tin văn bản chứa Lịch thivới số đợt thi ít nhất và không có sinhviên nào thi nhiều hơn 1 môn ở mỗiđợt thi
Trang 8Giải thuật tham lam lựa chọn giải pháp nào được cho là tốt nhất ở thời điểm hiện tại vàsau đó giải bài toán con nảy sinh từ việc thực hiện lựa chọn đó Lựa chọn của giải thuật thamlam có thể phụ thuộc vào lựa chọn trước đó Việc quyết định sớm và thay đổi hướng đi củagiải thuật cùng với việc không bao giờ xét lại các quyết định cũ sẽ dẫn đến kết quả là giảithuật này không tối ưu để tìm giải pháp toàn cục.
Trong đề tài này thuật toán của em chỉ xoay quanh việc tô màu cho các đỉnh, cụ thể ởđây là các môn học Em tiến hành kiểm tra những đỉnh nào chưa tô màu và các đỉnh kề nó đã
tô màu hiện tại hay chưa nếu thoả mãn điều kiện thì em sẽ tô Với màu hiện tại em sẽ tô cácđỉnh tối đa có thể tô được Sau mỗi lần tô thì em sẽ kiểm tra xem thử đã tô hết chưa nếu hếtrồi thì đưa ra kết quả nếu chưa thì dùng màu khác để thực hiện lại bước đầu
Trang 9int **array; // mảng để lưu đỉnh kề nhau
int *cov; // color of vertex : màu của từng đỉnh
int number_student; // số lượng sinh viên
int number_subjects; // số lượng môn học
string *subjects;
ifstream file_students("students.txt"); // đầu vào danh sách học sinh
ifstream file_subjects("subjects.txt"); // đầu vào danh sách môn học
ofstream file_kq("LichThi.txt"); // đầu ra danh sách ca thi
4.1.2 Khởi tạo cấu trúc dữ liệu.
Trang 114.1.3 Đọc dữ liệu từ file
+ Hàm readStudents() : Đọc môn học của từng sinh viên từ file Biến number_student sẽ dùng để chứa số lượng sinh viên Dùng phương thức getline() của lớp ifstream để đọc từng dòng của tệp văn bản.Dòng đầu tiên trong tệp là số lượng sinh viên sẽ
được gán vào biến number_student Tiếp theo là đọc các sinh viên được ngăn cách nhau với dấu '-' Tên, số lương môn học và tên các môn học được đưa vào mảng students để quản lý Biến i=0 sẽ dùng để xem vị trí hàng của từng sinh viên khi đọc Hàng đầu tiên là tên,thứ hai là
số lượng môn học của sinh viên đó và các hàng tiếp theo là chi tiết các môn học sau khi đọc
xong thì khởi tạo đối tượng student thông qua hàm dựng có tham số
Student(name,sub_number) rồi gán vào mảng students theo chỉ số index Đến khi gặp dấu
'-' thì sẽ tăng index lên 1 rồi gán i=0 để chương trình biết được là đã đến sinh viên tiếp theo.
Cứ lặp lại như thế cho đến hết dòng trng tệp
int index=0; // vị trí sinh viên thứ mấy
int sub_number=0; // số lượng môn học của từng sinh viên
//lấy thông tin môn học của các sinh viên
while(file_students.getline(temp,255)){
if(temp[0]=='-'){
Trang 13+ Hàm readSubjects() : Đọc môn học từ fie Dùng phương thức getline() của lớp
ifstream để đọc từng dòng của tệp văn bản.Khởi tạo biến i=0 để quản lý chỉ số dòng trong tệp
văn bản Dòng đầu tiên là số lượng môn học cần xếp lịch thi, gán vào biến number_subjects Khởi tạo biến index=0 để quản lý thứ tự của từng môn học Sau đó đọc tuần tự các môn học theo từng hàng rồi gán vào mảng subjects dùng để chứa các môn học cần xếp lịch thi theo chỉ
Trang 154.1.5 Các hàm xử lý chính
+ Hàm check(int i,int color) : kiểm tra xem đỉnh i có kể đỉnh j không để tô màu.
bool check(int i,int color)
+ Hàm colorAll() : dùng để tô tất cả các đỉnh, ban đầu khởi gán tất cả các đỉnh có màu
0, biến cnumber : là màu dùng để tô, biến count : để đếm số đỉnh đã tô,sau đó vào vòng lặpwhile để tô màu Ta sử dụng hàm color1(int color) (hàm tô 1 màu cho nhiều đỉnh nhất có thể)
để tô màu trả số đỉnh tô được thì cộng vào biến count cho đến khi nào bằng số môn học thì kếtthúc
void colorAll(int a[][MAX],int n,int cov[]) // hàm tô màu tất cả các đỉnh
Trang 16void colorAll() // hàm tô màu tất cả các đỉnh
{
cov=new int[number_subjects];
for(int i=0;i<number_subjects;i++) cov[i]=0; // ban đầu khởi gán cho các đỉnh =
0 ( chưa tô đỉnh nào cả)
4.1.6 Ghi dữ liệu vào file
+ Hàm writeFile() : dùng để viết kết quả lịch thi vào file
Trang 184.2 Ngôn ngữ cài đặt
Bài toán được cài đặt bằng ngôn ngữ lập trình C++ quen thuộc và cơ bản với phần lớnsinh viên Công nghệ thông tin nói riêng và sinh viên ngành Kỹ thuật nói chung Sử dụng phầnmềm Visual Sutdio Code được phát triển bởi Microsoft dành cho Windows, Linux, macOS,
có hỗ trợ nhiều tính năng Đây là một phần mền miễn phí, mã nguồn mở [3] C++ là một loạingôn ngữ lập trình bậc trung Đây là ngôn ngữ lập trình đa năng được tạo ra bởi BjarneStroustrup như một phần mở rộng của ngôn ngữ lập trình C, hoặc "C với các lớp Class", Ngônngữ đã được mở rộng đáng kể theo thời gian và C ++ hiện đại có các tính năng: lập trình tổngquát, lập trình hướng đối tượng, lập trình thủ tục, ngôn ngữ đa mẫu hình tự do có kiểu tĩnh, dữliệu trừu tượng, và lập trình đa hình Ngoài ra còn có thêm các tính năng, công cụ để thao tácvới bộ nhớ cấp thấp Từ thập niên 1990, C++ đã trở thành một trong những ngôn ngữ thươngmại ưa thích và phổ biến của lập trình viên [4]
4.3 Kết quả
4.3.1 Giao diện chính của chương trình
Do đầu vào của đề tài là các file chứa môn học và môn học của từng sinh viên ghi file,đầu ra là file kết quả lịch thi và trong quá trình xử lý không cần nhập từ bàn phím nên giaodiện hình chính của chương trình em sẽ thông báo quá trình xử lý của bài toán
Trang 194.3.2 Kết quả thực thi của chương trình
+Đọc dũ liệu từ file
Hình 1: Danh sách môn học đọc được từ tệp văn bản
Trang 20Hình 2: Danh sách môn học của các sinh viên đọc được từ tệp văn bản
Hình 3 : Kết quả mảng thể hiện các môn học kề nhau để xử lý
+ Kết quả mã m àu sau khi xử lý của từng môn học
Hình 4 : Kết quả mã m àu sau khi xử lý của từng môn học
Trang 21+ Kết quả được lưu vào file
Hình 5 : Kết quả lịch thi sau khi xếp lịch xong
Trang 225 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
5.1 Kết luận
Qua quá trình nghiên cứu và tìm hiểu đề tài đồ án, em đã có thêm nhiều kiến thức lýthuyết về bài toán tô màu đồ thị Những bài toán sắp xếp lịch luôn đòi hỏi người lập trình phảiphân tích bài toán cụ thể, thiết kế hệ thông tối ưu để đảm bảo giải quyết đầy đủ các yêu cầu,
tránh tình trạng bị trùng lặp ca thi của các sinh viên Bài toán “Xếp lịch thi” đã được em giải
quyết và đem lại một phần mềm cơ bản đáp ứng yêu cầu của người sử dụng Các cấu trúc dữliệu và thuật toán đã được phân tích và lựa chọn kỹ lưỡng nhằm đem lại hiệu quả xử lý và tàinguyên bộ nhớ
5.2 Hướng phát triển
Có thể phá triển bài toán thành một phần mềm cho phép tất cả những ai tổ chức cáccuộc thi có thể sắp xếp lịch thi phù hợp với những yêu của họ Làm giao diện đẹp mắt hơn vàcho phép đọc dữ liệu từ nhiều loại file khác nhau
TÀI LIỆU THAM KHẢO
Sách Effective Modern C++
Trang web 1 : https://vi.wikipedia.org/wiki/Tô_màu_đồ_thị
Trang web 2 : trinh-c-dao-tao-lap-trinh-c/
https://myvancoder.wordpress.com/cach-doc-va-ghi-file-trong-lap-Trang web 3 : https://vi.wikipedia.org/wiki/C++