Java 实现*以解决难题
我正在尝试实现一个a*算法来解决一个滑动难题,但我无法让这个算法工作,我已经为此工作了几天,但老实说,我不知道现在发生了什么。我一直在关注维基百科和“RedBlobGame”博客上的伪代码,但现在我完全迷路了 这是dea*算法Java 实现*以解决难题,java,artificial-intelligence,a-star,Java,Artificial Intelligence,A Star,我正在尝试实现一个a*算法来解决一个滑动难题,但我无法让这个算法工作,我已经为此工作了几天,但老实说,我不知道现在发生了什么。我一直在关注维基百科和“RedBlobGame”博客上的伪代码,但现在我完全迷路了 这是dea*算法 ArrayList<Node> open = new ArrayList<Node>(); ArrayList<Node> closed = new ArrayList<Node>(); Node
ArrayList<Node> open = new ArrayList<Node>();
ArrayList<Node> closed = new ArrayList<Node>();
Node goal = new Node(myBoard.getGoalBoard());
Node start = new Node(mb);
start.setH(this.heuristic.calculate(start, goal));
start.setG(0);
start.setDepth(0);
open.add(start);
Node current = null;
while(!open.isEmpty() && !myBoard.stopAlgorithm){
current = getLowest(open);
if(current.isGoal()){
System.out.println("done");
return finalise(current.getBoard(), displaySearch, current.getDepth());
}
open.remove(current);
closed.add(current);
int depth = current.getDepth() + 1;
ArrayList<Node> succesors = current.getSuccessors(depth);
for(Node node: succesors){
node.setH(this.heuristic.calculate(node, goal));
node.setG(current.getG() + 1);
node.setParent(current);
if(!closed.contains(node)){
if(!open.contains(node)){
open.add(node);
}else{
Node openN = open.get(open.indexOf(node));
if(node.getG() < openN.getG()){
openN.setG(node.getG());
openN.setParent(node.getParent());
}
}
}
}
}
System.out.println("path not finded");
return null;
ArrayList open=new ArrayList();
ArrayList closed=新建ArrayList();
节点目标=新节点(myBoard.getGoalBoard());
节点开始=新节点(mb);
setH(this.heuristic.calculate(start,goal));
start.setG(0);
start.setDepth(0);
打开。添加(开始);
节点电流=零;
而(!open.isEmpty()&&!myBoard.stopAlgorithm){
电流=最低(打开);
if(current.isGoal()){
系统输出打印项次(“完成”);
返回finalize(current.getBoard(),displaySearch,current.getDepth());
}
打开。移除(当前);
已关闭。添加(当前);
int depth=current.getDepth()+1;
ArrayList Successors=当前.getSuccessions(深度);
用于(节点:成功者){
setH(this.heuristic.calculate(node,goal));
node.setG(current.getG()+1);
node.setParent(当前);
如果(!closed.contains(节点)){
如果(!open.contains(节点)){
打开.添加(节点);
}否则{
Node openN=open.get(open.indexOf(Node));
if(node.getG()
有时他们会找到解决方案,有时,只是不断寻找和扩展更多可能的状态,我看不出问题在哪里。有什么帮助吗
这是节点类中的代码
而启发式演算(本例中为曼哈顿)这只是一个猜测。我已经有一段时间没有编写*了,我看不出您是如何实现node类的。我认为不应该使用node.setG(current.getG()+1)设置G,或者如果node已经添加到打开列表中,则不应该将父节点设置为current 尝试:
int-depth=current.getDepth()+1;
ArrayList Successors=当前.getSuccessions(深度);
用于(节点:成功者){
如果(!closed.contains(节点)&&!open.contains(节点)){
setH(this.heuristic.calculate(node,goal));
node.setG(current.getG()+1);
node.setParent(当前);
打开.添加(节点);
}
}
这是一个更完整的版本,似乎适合我(仅使用3 x 3进行测试。大多数代码只是设置状态。需要注意的是:为了提高效率,您不需要搜索列表以查看其中是否包含状态。最好使用哈希集,但这需要实现hashCode()和equals()一致性。您的IDE可能会生成它们
public static class BoardState {
int positions[];
private int priority;
/**
* Get the value of priority
*
* @return the value of priority
*/
public int getPriority() {
return priority;
}
/**
* Set the value of priority
*
* @param priority new value of priority
*/
public void setPriority(int priority) {
this.priority = priority;
}
private int distFromGoal;
/**
* Get the value of distFromGoal
*
* @return the value of distFromGoal
*/
public int getDistFromGoal() {
return distFromGoal;
}
/**
* Set the value of distFromGoal
*
* @param distFromGoal new value of distFromGoal
*/
public void setDistFromGoal(int distFromGoal) {
this.distFromGoal = distFromGoal;
}
private BoardState goal;
/**
* Get the value of goal
*
* @return the value of goal
*/
public BoardState getGoal() {
return goal;
}
/**
* Set the value of goal
*
* @param goal new value of goal
*/
public void setGoal(BoardState goal) {
this.goal = goal;
}
private int depth;
/**
* Get the value of depth
*
* @return the value of depth
*/
public int getDepth() {
return depth;
}
/**
* Set the value of depth
*
* @param depth new value of depth
*/
public void setDepth(int depth) {
this.depth = depth;
}
private BoardState prev;
/**
* Get the value of prev
*
* @return the value of prev
*/
public BoardState getPrev() {
return prev;
}
/**
* Set the value of prev
*
* @param prev new value of prev
*/
public void setPrev(BoardState prev) {
this.prev = prev;
}
public BoardState(BoardState other) {
this.positions = new int[9];
System.arraycopy(other.positions, 0, this.positions, 0, positions.length);
this.depth = other.depth + 1;
this.goal = other.goal;
this.prev = other;
}
private BoardState() {
}
public static BoardState goal() {
List<Integer> l = new ArrayList<Integer>();
IntStream.range(0, 9).forEach(i -> l.add(i));
BoardState r = new BoardState();
r.positions = new int[9];
Arrays.setAll(r.positions, i -> l.get(i).intValue());
return r;
}
public static BoardState random() {
List<Integer> l = new ArrayList<Integer>();
IntStream.range(0, 9).forEach(i -> l.add(i));
Collections.shuffle(l);
BoardState r = new BoardState();
r.positions = new int[9];
Arrays.setAll(r.positions, i -> l.get(i).intValue());
return r;
}
@Override
public int hashCode() {
int hash = 7;
hash = 83 * hash + Arrays.hashCode(this.positions);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final BoardState other = (BoardState) obj;
if (!Arrays.equals(this.positions, other.positions)) {
return false;
}
return true;
}
int valueAt(int r, int c) {
int pos = r * 3 + c;
for (int i = 0; i < positions.length; i++) {
if (pos == positions[i]) {
return i;
}
}
throw new RuntimeException("invalid board or position");
}
void print() {
System.out.println("depth = " + depth);
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
System.out.print(this.valueAt(r, c) + "\t");
}
System.out.println("");
}
}
int distance(BoardState other) {
int dist = 0;
for (int i = 0; i < positions.length; i++) {
int c0 = this.positions[i] % 3;
int r0 = this.positions[i] / 3;
int c1 = other.positions[i] % 3;
int r1 = other.positions[i] / 3;
dist += Math.abs(r0 - r1) + Math.abs(c0 - c1);
}
return dist;
}
public List<BoardState> moves() {
List<BoardState> newList = new ArrayList<>();
int r0 = this.positions[0] / 3;
int c0 = this.positions[0] % 3;
if (r0 > 0) {
BoardState up = new BoardState(this);
up.positions[0] = (r0 - 1) * 3 + c0;
for (int i = 1; i < 9; i++) {
if (this.positions[i] == up.positions[0]) {
up.positions[i] = this.positions[0];
break;
}
}
newList.add(up);
}
if (r0 < 2) {
BoardState down = new BoardState(this);
down.positions[0] = (r0 + 1) * 3 + c0;
for (int i = 1; i < 9; i++) {
if (this.positions[i] == down.positions[0]) {
down.positions[i] = this.positions[0];
break;
}
}
newList.add(down);
}
if (c0 > 0) {
BoardState left = new BoardState(this);
left.positions[0] = r0 * 3 + (c0 - 1);
for (int i = 1; i < 9; i++) {
if (this.positions[i] == left.positions[0]) {
left.positions[i] = this.positions[0];
break;
}
}
newList.add(left);
}
if (c0 < 2) {
BoardState right = new BoardState(this);
right.positions[0] = r0 * 3 + (c0 + 1);
for (int i = 1; i < 9; i++) {
if (this.positions[i] == right.positions[0]) {
right.positions[i] = this.positions[0];
break;
}
}
newList.add(right);
}
for (BoardState move : newList) {
move.setDistFromGoal(move.distance(goal));
move.setPriority(move.distFromGoal + move.depth);
}
return newList;
}
}
公共静态类BoardState{
int位置[];
私人优先权;
/**
*获取优先级的值
*
*@返回优先级的值
*/
public int getPriority(){
返回优先级;
}
/**
*设置优先级的值
*
*@param priority优先级的新值
*/
公共无效设置优先级(整数优先级){
优先权=优先权;
}
私人目标;
/**
*获取distFromGoal的值
*
*@返回distFromGoal的值
*/
public int getDistFromGoal(){
回归目标;
}
/**
*设置distFromGoal的值
*
*@param distFromGoal distFromGoal的新值
*/
public void setDistFromGoal(int distFromGoal){
this.distFromGoal=distFromGoal;
}
私营部门和国家目标;
/**
*获得目标的价值
*
*@返回目标值
*/
公共董事会状态getGoal(){
回归目标;
}
/**
*设定目标的价值
*
*@param-goal目标的新值
*/
公共无效设置目标(董事会状态目标){
这个。目标=目标;
}
私有整数深度;
/**
*获取深度的值
*
*@返回深度值
*/
公共int getDepth(){
返回深度;
}
/**
*设置深度的值
*
*@param depth深度的新值
*/
公共void setDepth(int-depth){
这个。深度=深度;
}
私人董事会和州议会;
/**
*获取prev的值
*
*@返回prev的值
*/
公共董事会状态getPrev(){
返回上一个;
}
/**
*设置prev的值
*
*@param prev prev的新值
*/
公共无效setPrev(BoardState prev){
this.prev=prev;
}
公共BoardState(BoardState其他){
this.positions=新整数[9];
System.arraycopy(其他.positions,0,this.positions,0,positions.length);
this.depth=other.depth+1;
this.goal=other.goal;
this.prev=其他;
}
私人董事会国家(){
}
公共静态董事会状态目标(){
列表l=新的ArrayList();
IntStream.range(0,9).forEach(i->l.add(i));
BoardState r=新的BoardState();
r、 位置=新整数[9];
setAll(r.positions,i->l.get(i.intValue());
返回r;
}
公共静态BoardState random(){
列表l=新的ArrayList();
IntStream.range(0,9).forEach(i->l.add(i));
收藏。洗牌(l);
BoardState r=新的BoardState();
r、 位置=新整数[9];
setAll(r.positions,i->l.get(i.intValue());
返回r;
}
@凌驾
公共int hashCode(){
int hash=7;
hash=83*hash+Arrays.hashCode(this.positions);
返回散列;
}
@凌驾
公共布尔
public static class BoardState {
int positions[];
private int priority;
/**
* Get the value of priority
*
* @return the value of priority
*/
public int getPriority() {
return priority;
}
/**
* Set the value of priority
*
* @param priority new value of priority
*/
public void setPriority(int priority) {
this.priority = priority;
}
private int distFromGoal;
/**
* Get the value of distFromGoal
*
* @return the value of distFromGoal
*/
public int getDistFromGoal() {
return distFromGoal;
}
/**
* Set the value of distFromGoal
*
* @param distFromGoal new value of distFromGoal
*/
public void setDistFromGoal(int distFromGoal) {
this.distFromGoal = distFromGoal;
}
private BoardState goal;
/**
* Get the value of goal
*
* @return the value of goal
*/
public BoardState getGoal() {
return goal;
}
/**
* Set the value of goal
*
* @param goal new value of goal
*/
public void setGoal(BoardState goal) {
this.goal = goal;
}
private int depth;
/**
* Get the value of depth
*
* @return the value of depth
*/
public int getDepth() {
return depth;
}
/**
* Set the value of depth
*
* @param depth new value of depth
*/
public void setDepth(int depth) {
this.depth = depth;
}
private BoardState prev;
/**
* Get the value of prev
*
* @return the value of prev
*/
public BoardState getPrev() {
return prev;
}
/**
* Set the value of prev
*
* @param prev new value of prev
*/
public void setPrev(BoardState prev) {
this.prev = prev;
}
public BoardState(BoardState other) {
this.positions = new int[9];
System.arraycopy(other.positions, 0, this.positions, 0, positions.length);
this.depth = other.depth + 1;
this.goal = other.goal;
this.prev = other;
}
private BoardState() {
}
public static BoardState goal() {
List<Integer> l = new ArrayList<Integer>();
IntStream.range(0, 9).forEach(i -> l.add(i));
BoardState r = new BoardState();
r.positions = new int[9];
Arrays.setAll(r.positions, i -> l.get(i).intValue());
return r;
}
public static BoardState random() {
List<Integer> l = new ArrayList<Integer>();
IntStream.range(0, 9).forEach(i -> l.add(i));
Collections.shuffle(l);
BoardState r = new BoardState();
r.positions = new int[9];
Arrays.setAll(r.positions, i -> l.get(i).intValue());
return r;
}
@Override
public int hashCode() {
int hash = 7;
hash = 83 * hash + Arrays.hashCode(this.positions);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final BoardState other = (BoardState) obj;
if (!Arrays.equals(this.positions, other.positions)) {
return false;
}
return true;
}
int valueAt(int r, int c) {
int pos = r * 3 + c;
for (int i = 0; i < positions.length; i++) {
if (pos == positions[i]) {
return i;
}
}
throw new RuntimeException("invalid board or position");
}
void print() {
System.out.println("depth = " + depth);
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
System.out.print(this.valueAt(r, c) + "\t");
}
System.out.println("");
}
}
int distance(BoardState other) {
int dist = 0;
for (int i = 0; i < positions.length; i++) {
int c0 = this.positions[i] % 3;
int r0 = this.positions[i] / 3;
int c1 = other.positions[i] % 3;
int r1 = other.positions[i] / 3;
dist += Math.abs(r0 - r1) + Math.abs(c0 - c1);
}
return dist;
}
public List<BoardState> moves() {
List<BoardState> newList = new ArrayList<>();
int r0 = this.positions[0] / 3;
int c0 = this.positions[0] % 3;
if (r0 > 0) {
BoardState up = new BoardState(this);
up.positions[0] = (r0 - 1) * 3 + c0;
for (int i = 1; i < 9; i++) {
if (this.positions[i] == up.positions[0]) {
up.positions[i] = this.positions[0];
break;
}
}
newList.add(up);
}
if (r0 < 2) {
BoardState down = new BoardState(this);
down.positions[0] = (r0 + 1) * 3 + c0;
for (int i = 1; i < 9; i++) {
if (this.positions[i] == down.positions[0]) {
down.positions[i] = this.positions[0];
break;
}
}
newList.add(down);
}
if (c0 > 0) {
BoardState left = new BoardState(this);
left.positions[0] = r0 * 3 + (c0 - 1);
for (int i = 1; i < 9; i++) {
if (this.positions[i] == left.positions[0]) {
left.positions[i] = this.positions[0];
break;
}
}
newList.add(left);
}
if (c0 < 2) {
BoardState right = new BoardState(this);
right.positions[0] = r0 * 3 + (c0 + 1);
for (int i = 1; i < 9; i++) {
if (this.positions[i] == right.positions[0]) {
right.positions[i] = this.positions[0];
break;
}
}
newList.add(right);
}
for (BoardState move : newList) {
move.setDistFromGoal(move.distance(goal));
move.setPriority(move.distFromGoal + move.depth);
}
return newList;
}
}
BoardState goal = BoardState.goal();
System.out.println("goal");
goal.print();
BoardState start = BoardState.random();
System.out.println("start");
start.print();
start.setGoal(goal);
start.setDistFromGoal(start.distance(goal));
start.setPriority(start.distFromGoal + start.depth);
PriorityQueue<BoardState> open = new PriorityQueue<>(Comparator.comparing(b -> b.getPriority()));
open.offer(start);
Set<BoardState> set = new HashSet<>();
set.add(start);
int round = 0;
while (!open.isEmpty()) {
BoardState cur = open.poll();
round++;
if (cur.equals(goal)) {
System.out.println("goal found after " + round + " rounds");
System.out.println("printing boards in reverse order");
do {
cur.print();
} while (null != (cur = cur.getPrev()));
break;
}
for (BoardState move : cur.moves()) {
if (!set.contains(move)) {
set.add(move);
open.offer(move);
}
}
}