Độ phức tạp của thuật toán này phụ thuộc vào 36 lượng trạng thái có thé cd trong trò chơi và độ sâu của cây trò chơi trong đó mỗi nút đại điện cho một trạng thái của trò chơi, các nhánh
Trang 2MUC LUC
I, Bối cảnh, xuất xứ ra đời của thuật toán Minimax 3
H Mô tả thuật toán: điều kiện, cấu trúc dữ liệu sử dụng, các bước của thuật toán 3
1 Điều kiện áp dụng thuật toán: 3
2 Cấu trúc dữ liệu sử dụng và các hàm phụ: 3
2.1 Cấu trúc cây: 3
2.2 Hàm đánh giá: 3
3 Các bước của thuật toán: 3
HI Độ phức tạp của thuật toán Minimax 4
VI Nhận xét chung và Kết luận 14
1, Nhận xét chung về thuật toán Minimax 14
Trang 3I Bối cảnh, xuất xứ ra đời của thuật toán Minimax
Thuật toán Minimax xuất hiện từ các nghiên cứu về lý thuyết trò chơi, lĩnh vực đã được các nhà toán học phát triển vào đầu thế kỷ 20 Một trong những nhà toán học noi tiếng liên quan đến lý thuyết này là John von Neymamn, người đã phát triển “Minimax
Theorem” vào năm 1928, giúp đưa ra cách tiếp cận đề tìm chiên lược tôi ưu trong các trò
chơi đôi kháng với tông điểm không đôi (zero-sum games)
II Mô tả thuật toán: điều kiện, cấu trúc dữ liệu sử dụng, các bước của thuật toán
1 Điều kiện áp dụng thuật toán:
- Có 2 người chơi đối kháng nhau: lợi ích của người này là bat lợi của người kia -_ Thông tin hoàn hảo: cả 2 người chơi đều biết toàn bộ trạng thái trò chơi
- _ Phải kết thúc sau một số nước đi hữu hạn bước
- _ Các người chơi thực hiện nước di lần lượt
> Các trò chơi phu hop: Co vua, co caro, Tic-tac-toe
- Tuy ttmg tro choi ma ta có những hàm đánh giá khác nhau
3 Cac buéc cia thuat toan:
Bước |: Khoi tao trang thai ban dau, xac dinh người chơi hiện tại:
- Guia sử người chơi hiện tại là MAX, MAX sẽ chơi sao để số điểm của mình là
Trang 4+ MAX thắng nều điểm của trạng thái đó > 0
+ MAX thua nêu điểm của trạng thái đó < 0
+ Hòa nêu điểm của trạng thái đo = 0
min
*
Cách hoạt động của Minimax
Bước 2: Đánh giá các trạng thai co thé xảy ra:
Quy ước:
MAX thắng hay MIN thua với nước đi tiếp theo hàm đánh giá trả về +10 Max thua hay MIN thắng với nước đi tiếp theo hàm đánh giá trả vé -10 Nếu không xác định được MAX có thăng hay không hàm đánh giá trả về 0
Bước 3: Xác định nước đi tối ưu:
Với các trạng thái xác định được giá trị thì:
Nước đi tối ưu của MAX Ia trang thái có giá trị lớn nhất hay
Value= Max ( nextStage 1 ,nextStage 2, )
Nước đi tối ưu của MIN là trạng thái có giá trị bé nhất hay
Value= Min (nextStage 1, nextStage2, )
Đối với các trạng thái chưa thể xác định gia tri, thi ta coi trang thai do la trang thai ban dau, quay lại bước 1, tuy nhién người chơi hiện tại sẽ đổi vai
Dùng DFS/BFS đề duyệt các trạng thái có thể xảy ra từ trạng thái ban đầu (có thê
áp dụng thêm thuật toán cat tia alpha Beta đề giảm số node phải duyệt)
II Độ phức tạp của thuật toán Minimax
- _ Thuật toán Mimimax là một thuật toán đệ quy dựa trên cau trúc cây tìm kiếm được
sử dụng rộng rãi trong các trò chơi đối kháng như cờ vua, cờ vây , cờ caro Độ phức tạp
của thuật toán này phụ thuộc vào 36 lượng trạng thái có thé cd trong trò chơi và độ sâu của cây trò chơi trong đó mỗi nút đại điện cho một trạng thái của trò chơi, các nhánh đại
điện cho các hành động khả thị từ trạng thái hiện tại và các lá của cây tương ứng với các trạng thái kết thúc của trò chơi
Trang 5Thuật toán Minimax
- Nếu blà số lượng nhánh con trung bình tại mỗi nút và d là độ sâu của cây trò
chơi thì số lượng nút mà thuật toán cần duyệt là b1 Vì vậy, độ phức tạp thời gian của thuật
toán Mimimax là O(b*) Béi vay, Minimax chi cé thể được áp dụng cho các trò chơi với
lượt đi xen kẽ và có số lượng trạng thái hữu hạn, không áp dụng cho các trò chơi thời gian
thực hoặc trò chơi với số lượng trạng thái vô hạn bởi độ phức tạp tính toán của thuật toán
sẽ tăng lên rất nhanh do kích thước của cây trò chơi tăng như trong trò chơi cờ vua
(b=35,d=80), từ đó dẫn đến những tính toán không thực tế và khiến độ phức tạp thời gian
là rất lớn
- _ Do độ phức tạp về thời gian của Minimax là tương đối lớn, nên hiện nay đã có nhiều kỹ thuật được sử dụng đề tôi ưu hóa làm giảm độ phức tạp thời gian của Minimax như: Cắt tia Alpha-Beta - Alpha-Beta Prunning, Giới hạn độ sâu - Depth Limit, Sử dụng hàm đánh giá — Heuristic,
2 Độ phức tạp về không gian
- _ Độ phức tạp không gian của thuật toán Mimimax phụ thuộc vào việc sử dụng DFS (Depth-First Search) hay BFS (Breadth-first search)
Trang 62.1 DFS
- Duyệt theo chiều sâu DFS (Depth-First Search), là việc di sâu vào một nhánh cây cho đến khi gặp nút lá hoặc không thê tiếp tục, sau đó quay lại duyệt nhánh khác rồi quay lại và duyệt qua nhánh khác Cách duyệt này sử dụng ngăn xếp đệ quy đề lưu trữ trạng thái hiện tại trong quá trình duyệt và các trạng thái cũ sẽ được giải phóng khỏi ngăn
xếp khi trong quá trình duyệt, thuật toán duyệt qua một nhánh khác Bởi vậy, bộ nhớ của
việc duyệt bằng DES tỉ lệ với độ sâu tối đa của cây, vì mỗi lần đi sâu vào một nhánh, một trạng thái mới sẽ được lưu vào ngăn xếp Nếu cây có độ sâu tối đa là d thì độ phức tạp không gian của thuật toán Minimax khi sử đụng DFS là O(đ) DFS giúp tiết kiệm bộ nhớ
và có hiệu quả khi giải pháp nằm sâu trong cây Tuy nhiên, viêc duyệt này không chắc chắn sẽ tìm được giải pháp nhanh bởi nó có thê đi qua các nhánh không cần thiết hoặc phải duyệt hết cây trước khi tìm ra giải pháp Bên cạnh đó, nêu cây có độ rộng rât lớn và
không có cat tia, DFS co thé rat cham va dé roi vao trạng thái vô han trong các trò chơi
phức tạp
Duyệt theo chiều sâu — DFS (Depth-First Search) 2.2 BFS
- _ Duyệt theo chiều rộng BFS (Breadth-First Search), là phương pháp mà thuật
toán sẽ duyệt qua tất cả các trạng thái ở một mức độ sâu nhất định trước khi tiếp tục duyệt
qua các mức độ sâu tiếp theo và, tất cả các trạng thái của mức đang xét sẽ được lưu trong hàng đợi trước khi duyệt đến mức tiếp theo và lặp lại quá trình trên cho đến khi tìm được
trạng thái kết thúc Nếu ta có một cây trò chơi có độ sâu toi da d va sé lượng nhánh trung
bình từ mỗi nút là b thì độ phức tạp không gian của thuật toán Minimax khi duyệt bằng
6
Trang 7BFS la O(b*) BFS sé dam bao tim duoc giai phap téi ưu nếu nó tồn tại đo nó duyệt qua toàn bộ cây theo timg muc BFS dat duoc higu quả cao đối với cây có độ sâu nhỏ và sô nhánh không quá lớn Tuy nhiên, việc lưu trữ tất cả trạng thái ở mỗi mức có thê dẫn dé việc yêu cầu bộ nhớ rất lớn khi cây trò chơi quá rộng
Trang 8IV Ví dụ cài đặt bằng C++
struct Node
{
vector<Node*> children; // cdc kHal nang wally ra
int value; // Dieloh dala nuit nay
bool isMaximizingPlayer; /¡ xác định ngươi chơi
}
if (maximizingPlayer)
{
int maxValue = INT_MIN;
for (Node* child : node->children)
{
int value = minimax(child, depth - 1, false);
max Value = max(max Value, value);
int minValue = INT_MAX;
for (Node* child : node->children)
{
int value = minimax(child, depth - 1, true);
minValue = min(minValue, value);
}
return minValue;
}
}
Trang 9vector<Node *> children; // các kHải nang Maly ra
int vảlue; // Điển dHả nút này (Node vảlue)
bool isMảximizingPlảyer; // xác định người chơi
vector<vector<char>> board; // Trang thai dala ban co (Board state)
pair<int, int> move; // Nước đi tới nút nay (Move to this node)
if (board[i][O] == board[i][1] && board[i][0] ==
board[i][2] && board[i][O] != '_')
{
if (board[i][O] == 'x') return 1; // x thahg
else return -1; // o thahg
}
//¡ Kiếm trả các cột
for (int 1 = 0; 1 <3; i++)
{
Trang 10if (board[O][i] == board[1][i] && board[O][i] == board[2][i] && board[O][i] != '_')
{
if (board[O][i] == 'x’) return 1;
else return -1;
t
// Kiểm trả các đường chéo
if (board[O][0] == board[1][1] && boảrd[0][0] ==
board[2][2] && board[0][0] != '_')
{
if (board[O][0] == 'x') return 1;
else return -1;
if (board[0][2] == board[1][1] && boảrd[0][2| ==
board[2][0] && board[0][2] != '_')
// Ham minimax duyệt dfs
int minimax(Node *root, int depth, bool MaximizingPlayer)
Trang 11for(int i = 0; i< 3; i++)
}
}
root->vảlue = bestVảlue;
else
int bestValue = INT_MAX;
for(int i = 0; i< 3; i++)
Trang 12nextState->move = {i,j};
root->children.push_back(nextState);
bestValue = min(bestValue, minimax(nextState, depth-1, !MaximizingPlayer));
// Tìm nước đi tôEnhất.,
pair<int,int> findBestMove(const vector<vector<char>>
Trang 13{
// x dai dién cho max, 0 đại điện cho min
/] Khidli tao ban co
vector<vector<char>> board = {{'o'", 'x', ' 1, 41),
x! T a {o' TT Yh:
cout << "Ban co hién tai: "<< endl;
for(auto row: board)
Trang 14VI Nhận xét chung và Kết luận
1 Nhận xét chung về thuật toán Minimax
+ Dễ hiểu và triển khai: Thuật toán sử dụng quy tắc đơn giản là tôi đa hóa lợi ích của mình đồng thời tối thiêu hóa lợi ích của đối thủ, để dàng lập trình khi vấn đề được mô hình hóa tốt
+ Tính kết hợp: Minmax có thê kết hợp với kĩ thuật cắt tia Alpha-Beta đề làm giảm độ phức tạp
1.2 Nhược điểm:
+ Tốn tài nguyên tính toán: Minimax có độ phức tạp tính toán rất cao, cụ
thé la O(b’), trong đó b là số lượng nhánh và d là độ sâu tối đa của cây trạng thái Điều này làm cho thuật toán khó áp dụng trực tiếp với các trò chơi có không gian trạng thái lớn (như cờ vua, cờ vây)
+ Phụ thuộc vào độ sâu giới hạn: Nếu không xét hết toàn bộ cây trò chơi,
kết quả sẽ phụ thuộc nhiều vào các hàm đánh giá, mà việc thiết kế hàm đánh giá
chính xác lại không đơn giản
+ Không xử lý tốt các trò chơi phi đối xứng: Minimax chí phù hợp với trò
choi co tong bang 0, trong các trò chơi khác có yếu tố bất cân bằng, thuật toán này
cần được điều chỉnh
2 Kết luận:
Minimax là một thuật toán nền tảng, đóng vai trò quan trọng trong lý thuyết trò
chơi và trí tuệ nhân tạo Dù có một số hạn chế về hiệu suất và khả năng áp dụng vào các
bài toán thực tế phức tạp, Minimax vẫn là cơ sở đề phát triển các thuật toán cải tiễn như
cat tia alpha - beta hoặc tích hợp với các kỹ thuật hiện đại
Trong các trò chơi có không gian trạng thái nhỏ và quy tắc rõ ràng, Minimax là lựa chọn xuất sắc cho việc xây dựng chiến lược tối ưu Tuy nhiên, để giải quyết các trò chơi hoặc vấn đề phức tạp hơn, cần tích hợp Minimax với các phương pháp tối ưu hóa
hoặc học máy đề đạt hiệu quả cao hơn
14
Trang 15VI So sánh thuật toán liên quan
Thuật toán Ưu điểm Hạn chê Ứng dụng thích hợp
Minimax | Tìm ra nước đi tôi ưu | Không hiệu quả với | Trò chơi đơn giản
chính xác không gian trạng thái | kích thước nhỏ: cờ
lớn caro Alpha-Beta Tăng hiệu xuat Hiệu quả phụ thuộc | Trò chơi phức tạp Pruning Minimax, giảm số vào thứ tự duyệt nút | hơn với không gian
nút phải duyệt trung bình: cờ vua Negamax Đơn giản hóa Không gian cải thiện | Trò chơi đôi kháng
Minimax nhờ tính đối hiệu suất so với đơn giản: cờ đam
xứng Minimax MCTS Phù hợp với không | Không ôn định, cần | Trò chơi phức tap
gian trạng thái lớn, thời gian dé tăng độ | như cờ vây, cờ vua
nhiều lựa chọn chính xác
15
Trang 16VIII Bai tap 4p dung
Cải tiên minimax v6i cat tia alpha, beta:
vector<Node*> children; // các kHảI năng xâly rả
int vảlue; // Điển dHả nút này (Node vảlue)
bool isMảximizingPlảyer; // xác định người chơi
vector<vector<char>> board; // Trang thai dala ban co (Board state)
pair<int, int> move; // Nước đi tới nút nay (Move to this node)
Trang 17// Kieth tra cdc hang
for (int 1 = 0; 1 <3; i++)
{
if (board[i][O] == board[i][1] && board[i][0] ==
board[i][2] && board[i][O] != '_')
{
if (board[i][O] == 'x') return 1; // x thahg
else return -1; // o thahg
}
//¡ Kiếm trả các cột
for (int 1 = 0; 1 <3; i++)
{
if (boảrd[0][i] == boảrd[I][i] && boảrd[0][i] ==
board[2][i] && board[O][i] != '_')
{
if (board[O][i] == 'x’) return 1;
else return -1;
}
// Kiểm trả các đường chéo
IÝ (boảrd[0][0] == boảrd[1][1]| && boảrd[0][0] board[2][2] && board[0][0] != '_')
{
if (board[O][0] == 'x') return 1;
else return -1;
if (board[0][2] == board[1][1] && board[0][2]
board[2][0] && board[0][2] != '_')
{
if (board[0][2] == 'x') return 1;
17
Trang 18t
return 0; // Không ải thăhg
t
// Ham minimax duyét dfs voi cabiila alpha-beta
int minimax(Node* root, int depth, bool MaximizingPlayer, int alpha, int beta)
int bestValue = INT_MIN;
for (int i = 0; 1 <3; i++)
alpha = max(alpha, bestValue);
if (beta <= alpha)
break;
18
Trang 19}
root->vảlue = bestVảlue;
else
int bestValue = INT_MAX;
for (int i = 0; 1 <3; i++)
bestValue = min(bestValue, minimax(nextState, depth - 1, !MaximizingPlayer, alpha, beta));
beta = min(beta, bestValue);
Trang 20pair<int, ¡in fñndBestMove(const vector<vector<char>>& board)
Node* root = new Node;
root->board = board;
minimax(root, 9, true, INT_MIN, INT_MAX);
int bestValue = INT_MAX;
pair<int, int> bestMove;
for (auto child : root->children)
// x dai dién cho max, 0 đại điện cho min
/] Khidli tao ban co
vector<vector<char>> board = { {'o'", 'x', "}, {1