KHOA CÔNG NGHỆ THÔNG TIN Học phần TRÍ TUỆ NHÂN TẠO Bài toán QUA SÔNG Giảng viên hướng dẫn Lớp Nhóm sinh viên thực hiện Hà Nội, tháng 11 năm 2021 2 MỤC LỤC LỜI NÓI ĐẦU 4 I Phân tích bài toán 5 1 Phát b.
KHOA CƠNG NGHỆ THƠNG TIN Học phần: TRÍ TUỆ NHÂN TẠO Bài tốn: QUA SƠNG Giảng viên hướng dẫn: Lớp: Nhóm sinh viên thực hiện: Hà Nội, tháng 11 năm 2021 MỤC LỤC LỜI NÓI ĐẦU I Phân tích tốn Phát biểu tốn Mơ tả tốn II Thuật tốn Best-first Search Giới thiệu thuật tốn Mơ tả thuật toán toán III Giải thuật tốn qua sơng áp dụng thuật tốn Best-first Search Cài đặt thuật tốn Chương trình giải tốn qua sơng TỔNG KẾT 12 LỜI NĨI ĐẦU Bài tốn qua sơng giới thiệu “Những toán đố Matcova Chủ đề tốn có từ nhiều kỷ trước Cùng với phát triển xã hội, việc di chuyển người, hàng hóa thơng tin,… ngày gia tăng Cùng cới gia tăng u cầu cực tiểu chi phí, khoảng cách, thời gian, trở lên quan trọng Theo lý thuyết đồ thị tốn tìm đường ngắn đỉnh đồ thị Chẳng hạn tốn tìm đường ngắn thành phố, Bài tốn tìm tuyến xe bt từ địa điểm đến địa điểm cho tiết kiệm chi phí nhất,… Bài tốn tìm đường ngắn trở nên cấp thiết quan trọng tương lai Do quan trọng cấp thiết tốn tìm đường ngắn nên có nhiều nhà tốn học đưa nhiều thuật toán để giải vận dụng vào để giải nhiều toán thực tế Trong số thuật tốn đưa có thuật tốn Prim tìm khung nhỏ I Phân tích tốn Phát biểu tốn Tại bến sơng có thầy tu quỷ muốn qua sông Tại thời điểm thuyền chở tối đa khách Nếu bờ nào, bên bên số quỷ phải bé số thầy tu, ngược lại quỷ ăn thịt thầy tu Tìm cách để giải toán Giải toán thuật toán Best-first Search để tìm trạng thái cuối Mơ tả tốn Bài tốn qua sơng có input thầy tu quỷ, điều kiện có người qua số thầy tu bờ khơng số quỷ Mục tiêu đưa thầy tu quỷ sang bên sông Dựa vào điều kiện có trường hợp đưa từ bờ trái sang bờ phải có trường hợp đưa lại bờ trái Khi đó, tốn qua sơng trở thành tốn tìm kiếm lựa chọn tốt II Thuật toán Best-first Search Giới thiệu thuật tốn Trong khoa học máy tính, thuật tốn Best-first Search thuật tốn tìm kiếm theo bề rộng (Breadth First Search) hướng dẫn hàm đánh giá Tư tưởng thuật tốn việc tìm kiếm bắt đầu nút gốc tiếp tục cách duyệt nút có giá trị hàm đánh giá thấp so với nút cịn lại nằm hàng đợi Mơ tả thuật tốn tốn - Bài tốn có hai trạng thái: ● Trạng thái bờ trái {số thầy tu, số quỷ} ● Trạng thái bờ phải {số thầy tu, số quỷ} - Mỗi trạng thái có cách thay đổi: ● Trạng thái bờ trái: Di chuyển thầy tu quỷ qua bờ phải ● Trạng thái bờ phải: Di chuyển thầy tu quỷ lại bờ trái - Mỗi cách thay đổi trạng thái có cách thay đổi cụ thể: ● Di chuyển thầy tu quỷ qua bờ phải có ba trường hợp thay đổi trạng thái: + Đưa thầy tu qua bờ phải + Đưa quỷ qua bờ phải + Đưa thầy tu quỷ qua bờ phải ● Di chuyển thầy tu quỷ lại bờ trái có hai trường hợp thay đổi trạng thái: + Đưa quỷ bờ trái + Đưa thầy tu quỷ bờ trái - Mỗi lần thực thay đổi trạng thái cần phải kiểm tra trạng thái có thay đổi hay khơng? ● Số thầy tu phải lớn số quỷ số thầy tu trạng thái III Giải thuật tốn qua sơng áp dụng thuật tốn Best-first Search Cài đặt thuật tốn - Viết ngơn ngữ C++ Chương trình giải tốn qua sông #include #include using namespace std; int brinkLeft[2]; int brinkRight[2]; static int count = 0; void init(int n) { // brinkLeft[0]: monk, brinkLeft[1]: devil // brinkRight[0]: monk, brinkRight[1]: devil brinkLeft[0] = n; brinkLeft[1] = n; brinkRight[0] = 0; brinkRight[1] = 0; } bool check(int monkLeft, int devilLeft, int monkRight, int devilRight, char mode) { if(monkLeft == && devilLeft == && monkRight == && devilRight == && mode == 'Q') return false; else if((monkLeft >= devilLeft || monkLeft == 0) && (monkLeft >= && devilLeft >= 0) && (monkRight >= devilRight || monkRight == 0) && (monkRight >= && devilRight >= 0)) return true; return false; } void brinkLeftToRight(int n) { int tempLeft[2], tempRight[2]; for(int i = 0; i < 3; i++) { tempLeft[0] = brinkLeft[0]; tempLeft[1] = brinkLeft[1]; tempRight[0] = brinkRight[0]; tempRight[1] = brinkRight[1]; switch(i) { case 0: { tempLeft[0] -= 2; tempRight[0] += 2; break; } case 1: { tempLeft[1] -= 2; tempRight[1] += 2; break; } case 2: { tempLeft[0] ; tempLeft[1] ; tempRight[0]++; tempRight[1]++; break; } default: break; } if(check(tempLeft[0], tempLeft[1], tempRight[0], tempRight[1], 'Q')) { count++; brinkLeft[0] = tempLeft[0]; brinkLeft[1] = tempLeft[1]; brinkRight[0] = tempRight[0]; brinkRight[1] = tempRight[1]; switch(i) { case 0: { cout