隐式图的搜索问题预习日志
作者:互联网
A*算法概述:
采用广度优先搜索策略,在搜索过程中使用启发函数,即有大致方向的向前进虽然目标有时候不是很明确。
A*算法核心:
A算法的关键在于启发函数,启发函数的优劣直接影响A算法的效率。
f(n)=g(n)+h(n);
这个式子中:f(n)表示从初始状态到目标状态的估测代价。 g(n)表示从初始状态到当前状态的代价(已经确定)。h(n)表示从当前状态到目标状态的估测代价(预测)。其中:h(n)的好坏直接影响评估函数的好坏。一个好的f(n)总能明确指引算法前进的方向,可以迅速的到达目标状态。f*(n)=g*(n)+h*(n); 我们假设的从初始状态到目标状态的实际最小代价。这个式子中:f(n)表示从初始状态到目标状态的实际代价。 g*(n)表示从初始状态到当前状态的代价(已经确定)g*(n)和g(n)是相等的。h*(n)表示从当前状态到目标状态的实际代价。若h(n)<=h*(n),则总能找到最优解。(当h(n)<h*(n)的时候,不可能找到一条从初始状态到达目标状态的路径。在搜索过程中使得h(n)逐渐接近h*(n),最终找到最优路径。
// 搜索方法
private boolean search() {
// 如果还有要搜索的状态
while(statusToSearch.size() > 0) {
// 队首出列
SearchItem item = statusToSearch.remove(0);
Integer status = item.getStatus();
// 搜到了
if(status.equals(WIN_STATE)) {
// 找到路径
recordRoute(item);
return true;
}
// 根据status还原arr和x,y
recoverStatus(status);
// 4个方向进行遍历
for(int i=0; i<4; i++) {
// 如果能够朝该方向行走
if(canMove(i)) {
// 向前一步
moveForward(i);
status = getStatus();
// 之前搜过的状态
if (statusSet.contains(status)) {
moveBack(i);
// 放弃
continue;
}
// 新状态加入待搜索
statusSet.add(status);
statusToSearch.add(new SearchItem(status, i, item));
moveBack(i);
}
}
}
return false;
}
// 解题入口方法
public boolean solve() {
Integer status = getStatus();
// 如果已经是胜利状态,返回true
if(WIN_STATE.equals(status)) {
return true;
}
// 初始状态先记录
statusSet.add(status);
// 初始状态进入搜索队列
statusToSearch.add(new SearchItem(status, null, null));
return search();
}
// 根据链表顺藤摸瓜,找到路径
private void recordRoute(SearchItem item) {
while(null != item.getLastItem()) {
moveScratchableLatex.add(0, item.getDir());
item = item.getLastItem();
}
}
// 打印路径
public void printRoute() {
for(int i=0; i<moveScratchableLatex.size(); i++) {
System.out.print(getDirString(moveScratchableLatex.get(i)));
System.out.print(" ");
}
}
标签:status,状态,初始状态,预习,item,add,搜索,日志,隐式 来源: https://blog.csdn.net/Ke91n9/article/details/115053605