cần map làm gì.
A* y hệt như Dijkstra vậy đó. Dijkstra tính “điểm” hay weight của từng vertex theo công thức w = g, với g là số bước đi từ start tới vertex hiện tại. Vd start là
6 4 1 0 3 5 9 7 2 10 11 8
có g = 0
thì
6 4 1 3 0 5 9 7 2 10 11 8
có g = 1
6 0 1 3 4 5 9 7 2 10 11 8
có g = 2
v.v…
với Dijkstra g
có thể được xem là “quá khứ” của vertex hiện tại, và xét vertex tiếp theo dựa trên điểm số “quá khứ”. A* kèm thêm “tương lai” vô công thức tính điểm nữa: w = g + h. Với h là ước lượng số bước đi tối thiểu cần có để đi từ vertex hiện tại tới end. Ở đây “tối thiểu” nghĩa là h ko được ước lượng quá cao mà phải luôn ước lượng <= số bước cần thiết thật sự. Vd 1 0 2 3 4 5 6 7 8 9 10 11
thì chỉ cần 1 lần swap nữa là ra, thì h phải <= 1. Nếu h > 1 thì A* sai.
tìm tối thiểu là khó nhất. Nếu cho h = 0, tức là luôn luôn thỏa điều kiện h <= số bước cần thật sự thì A* trở thành Dijkstra. h càng nhỏ thì A* càng giống với Dijkstra. h càng gần với số bước cần thật sự thì A* càng lẹ. Vì vậy phải tìm 1 cái h sao cho hợp lý.
ở bài này từ 2 điều kiện, vẽ hình cái graph ra ta có:
3 - 4 - 5
| | |
0 - 1 - 2
| | |
6 - 7 - 8
| | |
9 -10 -11
| | |
3 - 4 - 5
tức là vd nếu số 0 ở vị trí 3 thì nó có thể swap với số ở vị trí 0, 4, 9, vd
6 4 1 0 3 5 9 7 2 10 11 8
, số 0 có thể swap với số 6, 3, 10.
lưu ý có 1 đặc điểm ở đây là nếu số đã trùng với vị trí của nó rồi thì nó ko cần swap nữa, vd 1 10 2 3 0 5 7 4 8 6 9 11
thì 2, 3, 5, 8, 11 ko cần swap nữa.
với những số ko trùng vị trí của nó, số lần swap tối thiểu là số bước đi từ số đó tới vị trí hiện tại của nó trong cái graph trên. Vd 6 4 1 0 3 5 9 7 2 10 11 8
thì số bước tối thiểu của 6 (đang ở vị trí 0) là số bước đi tối thiểu từ 6 tới 0 trong cái graph trên, hay là 1 lần swap. Tương tự: 4 ở vị trí 1 cần tối thiểu 1 swap, 1-2 cần 1 swap, v.v… tổng cộng ta cần tối thiểu 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 1 = 9 lần swap.
tới đây thì gần xong rồi đó. Còn duy nhất trường hợp sai: 1 0 2 3 4 5 6 7 8 9 10 11
thì h tính như trên ra h = 2, sai, overestimate vì chỉ cần 1 swap là đủ. Vậy để cho chắc ăn ta trừ đi số lần swap tại vị trí 0 đi cho chắc. Vd 1 7 2 3 4 5 6 0 8 9 10 11
thì h = 1 + 1 + 2 = 4, phải trừ đi số lần swap của 0-7 là 2 ta còn h=2 là đúng.
làm nháp thì thấy h này gần đúng với số lần swap luôn nên mình chơi w = h luôn, nó chạy ra sai
nản quá nên bỏ luôn ko ngờ gà vl ko nhận ra A* cộng thêm cái g nữa là được rồi =)