Đang tải…
Đang tải…
Luôn mở rộng nút trông gần đích nhất chỉ dựa trên heuristic. Rất nhanh và nhắm hướng, nhưng đường đi không đảm bảo ngắn nhất.
Khởi tạo tập mở với điểm đầu.
1open.add(new int[]{h(start), start}); queued[start] = true; // Nạp tập mở theo heuristic h2while (!open.isEmpty()) { // Đến khi tập mở rỗng3 int node = open.poll()[1]; // Lấy ô gần đích nhất4 if (visited[node]) continue; // Bỏ qua nếu đã thăm5 if (node == goal) return buildPath(); // Tới đích — truy vết đường6 visited[node] = true; // Đánh dấu ô đã thăm7 for (int neighbor : neighbors(node)) // Duyệt các ô kề đi được8 if (!visited[neighbor] && !queued[neighbor]) { // Chỉ ô hoàn toàn mới9 parent[neighbor] = node; queued[neighbor] = true; // Lưu cha, đánh dấu đã xếp10 open.add(new int[]{h(neighbor), neighbor}); // Xếp chỉ theo h11 }12}13 14int h(int cell) { // Khoảng cách Manhattan tới đích15 int r = cell / COLS, c = cell % COLS;16 int gr = goal / COLS, gc = goal % COLS;17 return Math.abs(r - gr) + Math.abs(c - gc);18}19 20List<Integer> neighbors(int cell) { // Các ô kề đi được21 int r = cell / COLS, c = cell % COLS;22 int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};23 List<Integer> out = new ArrayList<>();24 for (int[] d : dirs) {25 int nr = r + d[0], nc = c + d[1];26 if (nr < 0 || nr >= ROWS || nc < 0 || nc >= COLS) continue;27 int nbr = nr * COLS + nc;28 if (!walls.contains(nbr)) out.add(nbr);29 }30 return out;31}32 33List<Integer> buildPath() { // Lần theo cha từ đích34 List<Integer> path = new ArrayList<>();35 for (int at = goal; at != -1; at = parent[at]) path.add(at);36 Collections.reverse(path);37 return path;38}