Tải bản đầy đủ (.docx) (22 trang)

Báo cáo Đồ án sắp xếp lịch thi

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (205.29 KB, 22 trang )

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

ĐỒ ÁN
GIẢI THUẬT VÀ LẬP TRÌNH
Đề tài 3: XẾP LỊCH THI

GIẢNG VIÊN HƯỚNG DẪN: Võ Đức Hoàng
SINH VIÊN THỰC HIỆN: Trần Văn Hiền
Lớp : 18T1 Nhóm : 18N10A

Đà Nẵng, 12/2020


MỤ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

3.

4.

2.1.



Ý tưởng....................................................................................................4

2.2.

Cơ sở lý thuyết.........................................................................................4

TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TỐN.................................4
3.1.

Phát biểu bài tốn.....................................................................................4

3.2.

Cấu trúc dữ liệu........................................................................................6

3.3.

Thuật tốn................................................................................................7

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

1


LỜI MỞ ĐẦU
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 q 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ình
giú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ía
thầy để bài làm của em được hoàn thiện hơn.

2


DANH 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

3


1. 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 sao
cho 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 thi
nhiề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ật
toá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 tố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ới
yê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.

4


+ 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ác
sinh 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 sinh
viên đó.
+ Các dịng tiếp theo là tên của các mơn học
của sinh viên đó.
+ Dịng cuối cùng là dấu ‘-‘ để báo hiệu cho
chương trình là đã đọc hết mơn học của sinh
viên đó.
Giữa các sinh viên sẽ có dấu ‘-‘ để ngăn cách
nhau.

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 Van
Hien, có số lượng mơn học là 3 và các mơn
học đó là Lap trinh java,Cong nghe di dong va
Lap 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ếp
theo cho đến hết.

5


+ 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ọc
Các dịng tiếp theo là tên của các môn
học


b) Đầu ra (Output)
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 thi nhiều hơn 1 môn ở mỗi
đợt thi.

3.2. Cấu trúc dữ liệu
Struct Student
struct Student
{
string name;
string *student_subjects;
int amount;
Student(){
name="";
amount=0;
}
Student(string ten,int so_luong) {
name=ten;
amount=so_luong;
student_subjects=new string[amount];
}
void setSubject(string s,int i) {

6


this->student_subjects[i]=s;
}
void setName(string s){

this->name=s;
}
void show(){
cout<for(int i=0;icout<<"\tMon thu "<}
cout<}
string getSubject(int i){
return student_subjects[i];
}
};

3.3. Thuật toán
Giải thuật tham lam (Greedy Algorithm) là giải thuật tối ưu hóa tổ hợp. Giải thuật tìm
kiếm, lựa chọn giải pháp tối ưu địa phương ở mỗi bước với hi vọng tìm được giải pháp tối ưu
tồn cục.
Giả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 tố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 tham
lam 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ủa
giả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ải
thuật này khơng tối ưu để tìm giải pháp tồ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ết
rồ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.

7



4. CHƯƠNG TRÌNH VÀ KẾT QUẢ
4.1. Tổ chức chương trình
4.1.1. Khởi tạo thư viện
#include <iostream>
#include <fstream>
using namespace std;
int **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.
Struct Student
struct Student
{
string name;
string *student_subjects;
int amount;
Student(){
name="";
amount=0;
}
Student(string ten,int so_luong) {
name=ten;
amount=so_luong;
student_subjects=new string[amount];

8


}
void setSubject(string s,int i) {
this->student_subjects[i]=s;
}
void setName(string s){
this->name=s;
}
void show(){
cout<for(int i=0;i

cout<<"\tMon thu "<}
cout<}
string getSubject(int i){
return student_subjects[i];
}
};

9


4.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

void readStudents()
{
char temp[50];
string name;
int i=0;

number_student=0;
file_students.getline(temp,50);
// lấy số lượng sinh viên
while(temp[i]){
number_student*=10;
number_student+=temp[i]-48;
i++;
}
students=new Student[number_student]; // khởi tạo bộ nhớ
i=0;
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]=='-'){

10


i=0;
index++;
continue;
}
if(i==0) name=temp;
else if(i==1){
int k=0;
while(temp[k]){
sub_number*=10;
sub_number+=temp[k]-48;
k++;

}
students[index]= Student(name,sub_number);
sub_number=0;
}
else{
students[index].setSubject(temp,i-2); // gán giá trị môn học cho sinh viên ngay vị
trí i-2 ( vì bắt đầu đọc giá trị môn học từ hàng thứ 2)
}
i++;
}
cout<<"\n--------------Doc danh sach sinh vien thanh cong--------------"<}

11


+ 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ỉ
số index.

void readSubjects()
{
char temp[50];
file_subjects.getline(temp,50);
int i=0;
while(temp[i]){
number_subjects*=10;

number_subjects+=temp[i]-48;
i++;
}
subjects=new string[number_subjects];
int index=0;
while(file_subjects.getline(temp,50)){
subjects[index]=temp;
index++;
}
cout<<"--------------Doc danh sach mon hoc thanh cong----------------"<}

12


4.1.4. Các hàm hỗ trợ
+ Hàm getIndexSubject(string s) :
lấy vị trí mơn học của sinh viên trong danh sách
mơn học dùng xếp lịch thi để đưa vào mảng.

int getIndexSubject(string s)
{
for(int i=0;iif(s==subjects[i]) return i;
}
return NULL;
}
+ Hàm putArray() : dùng để đưa dữ liệu các môn học vào mảng nhằm quản lý những
môn học kề nhau.
void putArray()

{
for(int i=0;ifor(int j=0;jfor(int k=j+1;kint num1=getIndexSubject(students[i].getSubject(j));
int num2=getIndexSubject(students[i].getSubject(k));
array[num1][num2]=array[num2][num1]=1;
}
}
}
}

13


4.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)
{
for(int j=0;jif(array[i][j]==1&&cov[j]==color) return false;
j(color) thì i khơng thể tơ màu color nữa

// kiểm tra nếu đinh i kề đình

}
return true;
}
+ Hàm color1(int color) : hàm này dùng màu color là tham số truyền vào để tơ nhiều
đỉnh nhất có thể và trả về số lương đỉnh đã tô

int color1(int color)

// hàm tô 1 màu cho nhiều đỉnh nhất có thể

{
int count=0;

// đếm bao nhiêu đỉnh được tô bằng màu color

for(int i=0;iif(!cov[i] && check(i,color)) // kiểm tra đỉnh i chưa tô và tô được màu color thì tơ
{
cov[i]=color;

//tơ màu cho đỉnh i

count++;
}
}
return count;
}
+ 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ặp
while để 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ết
thúc.
void colorAll(int a[][MAX],int n,int cov[])

// hàm tô màu tất cả các đỉnh


14


void colorAll()

// hàm tô màu tất cả các đỉnh

{
cov=new int[number_subjects];
for(int i=0;i0 ( chưa tô đỉnh nào cả)

cov[i]=0;

// ban đầu khởi gán cho các đỉnh =

int color_number=0;
int count=0;
while(count{
color_number++;
count+=color1(color_number);
}
}

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

void writeFile()
{

int n=0; int k=1;
while(nfile_kq<<"Ca : "<for(int i=0;iif(cov[i]==k){
file_kq<<"

"<
n++;
}
}
k++;
}
}

15


4.1.7. Hàm main
int main() {

readSubjects();

viewSubjects();

readStudents();

viewStudents();


putArray();

viewArray();

colorAll();

viewColorSubjects();

writeFile();

viewExamSchedule();

deleteMemory();

return 0;
}

16


4.2. Ngơn ngữ cài đặt
Bài tố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ớn
sinh 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ần
mề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ại
ngơ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 Bjarne
Stroustrup 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ơn
ngữ đã đượ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ổng
quá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. Ngồi ra cịn có thêm các tính năng, cơng cụ để thao tác

vớ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ương
mạ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 giao
diện hình chính của chương trình em sẽ thơng báo q trình xử lý của bài toán.

17


4.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

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

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

19



+ 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

4.3.3. Nhận xét
Cài đặt thuật toán và giải thuật đã giải quyết phần lớn những yêu cầu cơ bản của bài
toán đặt ra. Các kết quả thực hiện đều thỏa mãn những tiêu chí ban đầu của bài tốn, bên cạnh
đó cịn phát triển thêm một số tính năng bổ sung nhằm hồn thiện bài toán. Tốc độ thực thi bài
toán nhanh do sử dụng các thuật tốn có độ phức tạp thấp và sắp xếp giải thuật hợp lý. Nếu số
lượng mẫu tin tăng lên thì sẽ ảnh hưởng đến tốc độ nhưng không đáng kể, do giao diện đồ họa
đơn giản và tối ưu các thuật toán, cấu trúc dữ liệu sử dụng trong bài.

20


5. 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 tốn tơ màu đồ thị. Những bài tốn sắp xếp lịch ln địi hỏi người lập trình phải
phân tích bài tố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 tố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ài
nguyên bộ nhớ.

5.2. Hướng phát triển
Có thể phá triển bài tốn thành một phần mềm cho phép tất cả những ai tổ chức các
cuộ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 : />Trang web 2 : />Trang web 3 : />
21



×