Spaces:
Sleeping
Sleeping
Update algorithm_3d_1.py
Browse files- algorithm_3d_1.py +23 -23
algorithm_3d_1.py
CHANGED
|
@@ -20,9 +20,9 @@ from utils import (
|
|
| 20 |
|
| 21 |
def is_slide_3d(c, e, blocks_set):
|
| 22 |
"""
|
| 23 |
-
|
| 24 |
Ràng buộc 4-cycle: Phải tồn tại một chu trình 4 ô trong lưới Z^3, trong đó c, e
|
| 25 |
-
|
| 26 |
"""
|
| 27 |
dx = e[0] - c[0]
|
| 28 |
dy = e[1] - c[1]
|
|
@@ -51,9 +51,9 @@ def is_slide_3d(c, e, blocks_set):
|
|
| 51 |
|
| 52 |
def is_convex_3d(c, e, blocks_set):
|
| 53 |
"""
|
| 54 |
-
|
| 55 |
Khoảng cách Manhattan bằng 2, thay đổi đúng 2 tọa độ.
|
| 56 |
-
|
| 57 |
"""
|
| 58 |
dx = e[0] - c[0]
|
| 59 |
dy = e[1] - c[1]
|
|
@@ -131,7 +131,7 @@ def generate_valid_moves_3d(blocks_set):
|
|
| 131 |
# ============================================================
|
| 132 |
|
| 133 |
def finished_holes_3d(blocks_set):
|
| 134 |
-
|
| 135 |
holes = set()
|
| 136 |
for x, y, z in blocks_set:
|
| 137 |
for i in range(x + 1):
|
|
@@ -143,7 +143,7 @@ def finished_holes_3d(blocks_set):
|
|
| 143 |
|
| 144 |
|
| 145 |
def compact_target_3d(n):
|
| 146 |
-
|
| 147 |
if n <= 0:
|
| 148 |
return set()
|
| 149 |
|
|
@@ -245,17 +245,17 @@ def choose_best_candidate_3d(candidates):
|
|
| 245 |
0 if is_finished_3d(item[4]) else 1,
|
| 246 |
compaction_score_3d(item[4]),
|
| 247 |
potential(item[4], 3),
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
)
|
| 252 |
)
|
| 253 |
|
| 254 |
|
| 255 |
def local_z_reduction(blocks_set):
|
| 256 |
-
|
| 257 |
def filt(c, e, move_type):
|
| 258 |
-
|
| 259 |
|
| 260 |
candidates = one_step_candidates_3d(blocks_set, "local_z_reduction", filt)
|
| 261 |
res = choose_best_candidate_3d(candidates)
|
|
@@ -267,13 +267,13 @@ def get_pillar_heights(blocks_set, x, y):
|
|
| 267 |
|
| 268 |
|
| 269 |
def pillar_shove_heuristic(blocks_set):
|
| 270 |
-
|
| 271 |
def filt(c, e, move_type):
|
| 272 |
-
#
|
| 273 |
heights = get_pillar_heights(blocks_set, c[0], c[1])
|
| 274 |
if len(heights) < 2:
|
| 275 |
return False
|
| 276 |
-
#
|
| 277 |
return e[2] <= c[2] or e[0] < c[0] or e[1] < c[1]
|
| 278 |
|
| 279 |
candidates = one_step_candidates_3d(blocks_set, "pillar_shove", filt)
|
|
@@ -282,7 +282,7 @@ def pillar_shove_heuristic(blocks_set):
|
|
| 282 |
|
| 283 |
|
| 284 |
def local_potential_reduction_3d(blocks_set):
|
| 285 |
-
|
| 286 |
candidates = one_step_candidates_3d(blocks_set, "local_potential_reduction")
|
| 287 |
res = choose_best_candidate_3d(candidates)
|
| 288 |
return (res[0], res[1], res[2], res[3]) if res else None
|
|
@@ -319,18 +319,18 @@ def connected_components_3d(cells):
|
|
| 319 |
|
| 320 |
|
| 321 |
def get_low_high_components_3d(blocks_set):
|
| 322 |
-
|
| 323 |
-
|
| 324 |
return connected_components_3d(low_cells), connected_components_3d(high_cells)
|
| 325 |
|
| 326 |
|
| 327 |
def handling_low_components_3d(blocks_set):
|
| 328 |
-
|
| 329 |
low_comps, _ = get_low_high_components_3d(blocks_set)
|
| 330 |
if not low_comps:
|
| 331 |
return None
|
| 332 |
|
| 333 |
-
#
|
| 334 |
root_comp = None
|
| 335 |
for comp in low_comps:
|
| 336 |
if (0, 0, 0) in comp:
|
|
@@ -347,7 +347,7 @@ def handling_low_components_3d(blocks_set):
|
|
| 347 |
if not non_root_cells:
|
| 348 |
return None
|
| 349 |
|
| 350 |
-
#
|
| 351 |
def filt(c, e, move_type):
|
| 352 |
if c not in non_root_cells:
|
| 353 |
return False
|
|
@@ -375,8 +375,8 @@ def move_sort_key_3d(blocks_set, move):
|
|
| 375 |
|
| 376 |
def beam_escape_sequence_3d(blocks_set, max_depth=4, beam_width=40, branch_limit=20):
|
| 377 |
"""
|
| 378 |
-
|
| 379 |
-
|
| 380 |
"""
|
| 381 |
start_score = compaction_score_3d(blocks_set)
|
| 382 |
start_pot = potential(blocks_set, 3)
|
|
@@ -448,7 +448,7 @@ def choose_next_sequence_3d(blocks_set):
|
|
| 448 |
if move is not None:
|
| 449 |
return [move]
|
| 450 |
|
| 451 |
-
# 2.
|
| 452 |
macro_seq = beam_escape_sequence_3d(blocks_set, max_depth=4, beam_width=40, branch_limit=20)
|
| 453 |
if macro_seq:
|
| 454 |
return macro_seq
|
|
|
|
| 20 |
|
| 21 |
def is_slide_3d(c, e, blocks_set):
|
| 22 |
"""
|
| 23 |
+
Slide trong 3D: Khối di chuyển theo đường thẳng c-e (khoảng cách Manhattan bằng 1).
|
| 24 |
Ràng buộc 4-cycle: Phải tồn tại một chu trình 4 ô trong lưới Z^3, trong đó c, e
|
| 25 |
+
và ô kề bên của c đều thuộc blocks_set, tạo điểm tựa song song với hướng trượt.
|
| 26 |
"""
|
| 27 |
dx = e[0] - c[0]
|
| 28 |
dy = e[1] - c[1]
|
|
|
|
| 51 |
|
| 52 |
def is_convex_3d(c, e, blocks_set):
|
| 53 |
"""
|
| 54 |
+
Convex transition trong 3D: c và e nằm chéo nhau trên một mặt phẳng lưới 2x2.
|
| 55 |
Khoảng cách Manhattan bằng 2, thay đổi đúng 2 tọa độ.
|
| 56 |
+
Đúng một trong hai ô trung gian nối giữa c và e phải chứa khối làm điểm tựa xoay góc.
|
| 57 |
"""
|
| 58 |
dx = e[0] - c[0]
|
| 59 |
dy = e[1] - c[1]
|
|
|
|
| 131 |
# ============================================================
|
| 132 |
|
| 133 |
def finished_holes_3d(blocks_set):
|
| 134 |
+
"""Tính các vị trí ô trống còn thiếu trong Cuboid để cấu hình đạt trạng thái Finished."""
|
| 135 |
holes = set()
|
| 136 |
for x, y, z in blocks_set:
|
| 137 |
for i in range(x + 1):
|
|
|
|
| 143 |
|
| 144 |
|
| 145 |
def compact_target_3d(n):
|
| 146 |
+
"""Xây dựng tập bia đích dồn n khối về phía gốc tọa độ tối ưu theo thế năng."""
|
| 147 |
if n <= 0:
|
| 148 |
return set()
|
| 149 |
|
|
|
|
| 245 |
0 if is_finished_3d(item[4]) else 1,
|
| 246 |
compaction_score_3d(item[4]),
|
| 247 |
potential(item[4], 3),
|
| 248 |
+
item[1][2], # Ưu tiên tọa độ z đích thấp hơn
|
| 249 |
+
item[1][1], # Tiếp đến y đích thấp hơn
|
| 250 |
+
item[1][0] # Cuối cùng là x đích thấp hơn
|
| 251 |
)
|
| 252 |
)
|
| 253 |
|
| 254 |
|
| 255 |
def local_z_reduction(blocks_set):
|
| 256 |
+
"""Operation [a-d]: Kéo hạ độ cao khối xuống tầng dưới."""
|
| 257 |
def filt(c, e, move_type):
|
| 258 |
+
return e[2] < c[2] # Giảm cao độ z mang tính quyết định
|
| 259 |
|
| 260 |
candidates = one_step_candidates_3d(blocks_set, "local_z_reduction", filt)
|
| 261 |
res = choose_best_candidate_3d(candidates)
|
|
|
|
| 267 |
|
| 268 |
|
| 269 |
def pillar_shove_heuristic(blocks_set):
|
| 270 |
+
"""Operation [e]: Tịnh tiến cấu trúc cột hoặc xử lý kéo nghiêng."""
|
| 271 |
def filt(c, e, move_type):
|
| 272 |
+
# Ưu tiên các khối thuộc một trụ thẳng đứng có chiều cao >= 2
|
| 273 |
heights = get_pillar_heights(blocks_set, c[0], c[1])
|
| 274 |
if len(heights) < 2:
|
| 275 |
return False
|
| 276 |
+
# Di chuyển đẩy sang bên cạnh hoặc đi xuống dưới
|
| 277 |
return e[2] <= c[2] or e[0] < c[0] or e[1] < c[1]
|
| 278 |
|
| 279 |
candidates = one_step_candidates_3d(blocks_set, "pillar_shove", filt)
|
|
|
|
| 282 |
|
| 283 |
|
| 284 |
def local_potential_reduction_3d(blocks_set):
|
| 285 |
+
"""Operation [f]: Tìm mọi bước đi đơn lẻ tối ưu thế năng cục bộ."""
|
| 286 |
candidates = one_step_candidates_3d(blocks_set, "local_potential_reduction")
|
| 287 |
res = choose_best_candidate_3d(candidates)
|
| 288 |
return (res[0], res[1], res[2], res[3]) if res else None
|
|
|
|
| 319 |
|
| 320 |
|
| 321 |
def get_low_high_components_3d(blocks_set):
|
| 322 |
+
low_cells = {b for b in blocks_set if b[2] == 0} # Mặt phẳng đáy z = 0
|
| 323 |
+
high_cells = {b for b in blocks_set if b[2] > 0} # Thành phần trên cao z > 0
|
| 324 |
return connected_components_3d(low_cells), connected_components_3d(high_cells)
|
| 325 |
|
| 326 |
|
| 327 |
def handling_low_components_3d(blocks_set):
|
| 328 |
+
"""Operation [g-j]: Xử lý dồn ép các cấu trúc khối nằm ở lớp đáy z=0."""
|
| 329 |
low_comps, _ = get_low_high_components_3d(blocks_set)
|
| 330 |
if not low_comps:
|
| 331 |
return None
|
| 332 |
|
| 333 |
+
# Tìm thành phần root chứa gốc (0,0,0)
|
| 334 |
root_comp = None
|
| 335 |
for comp in low_comps:
|
| 336 |
if (0, 0, 0) in comp:
|
|
|
|
| 347 |
if not non_root_cells:
|
| 348 |
return None
|
| 349 |
|
| 350 |
+
# Lọc dịch chuyển thuộc thành phần không phải root hướng về phía gốc tọa độ
|
| 351 |
def filt(c, e, move_type):
|
| 352 |
if c not in non_root_cells:
|
| 353 |
return False
|
|
|
|
| 375 |
|
| 376 |
def beam_escape_sequence_3d(blocks_set, max_depth=4, beam_width=40, branch_limit=20):
|
| 377 |
"""
|
| 378 |
+
Chuỗi dịch chuyển vĩ mô nhiều bước. Giải phóng các trường hợp bị nghẽn (Unlock trụ).
|
| 379 |
+
Chấp nhận thế năng tăng tạm thời ở các bước trung gian.
|
| 380 |
"""
|
| 381 |
start_score = compaction_score_3d(blocks_set)
|
| 382 |
start_pot = potential(blocks_set, 3)
|
|
|
|
| 448 |
if move is not None:
|
| 449 |
return [move]
|
| 450 |
|
| 451 |
+
# 2. Nếu kẹt, sử dụng Beam Search tìm chuỗi thoát hiểm phục vụ "Unlock"
|
| 452 |
macro_seq = beam_escape_sequence_3d(blocks_set, max_depth=4, beam_width=40, branch_limit=20)
|
| 453 |
if macro_seq:
|
| 454 |
return macro_seq
|