Java 广度优先搜索实现不起作用

Java 广度优先搜索实现不起作用,java,Java,我对广度优先搜索算法的实现有一个问题,我有一个方法,它给我一个0-8的整数数组,以随机顺序排列。我还有一个整数m,它告诉我哪个数字是空的。规则如下: 我得到一组数字,比如: 456 782 301 并且假设8是空白值,我可以将它与5, 7, 2和0交换。因为它们就在它旁边。我必须使用广度优先搜索来解决这个难题。以下是我迄今为止编写的代码: package application; import java.util.ArrayList; import ja

我对广度优先搜索算法的实现有一个问题,我有一个方法,它给我一个0-8的整数数组,以随机顺序排列。我还有一个整数m,它告诉我哪个数字是空的。规则如下:

我得到一组数字,比如:

456           
782        
301

并且假设8是空白值,我可以将它与5, 7, 2和0交换。因为它们就在它旁边。我必须使用广度优先搜索来解决这个难题。以下是我迄今为止编写的代码:

package application;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Vector;

public class Solution {

    /******************************************
     * Implementation Here
     ***************************************/

    /*
     * Implementation here: you need to implement the Breadth First Search
     * Method
     */
    /* Please refer the instruction document for this function in details */

    public static LinkedHashSet<int[]> OPEN = new LinkedHashSet<int[]>();
        public static HashSet<int[]> CLOSED = new HashSet<int[]>();
    public static boolean STATE = false;
    public static int empty;

    public static void breadthFirstSearch(int[] num, int m, Vector solution1) {
        int statesVisited = 0;
        for(int i : num) {
            if(num[i] == m) {
                empty = i;
            }
        }

        int[] start = num;
        int[] goal = {0,1,2,3,4,5,6,7,8};
        int[] X;
        int[] temp = {};

        OPEN.add(start);

        while (OPEN.isEmpty() == false && STATE == false) {

            X = OPEN.iterator().next();
            OPEN.remove(X);

            int pos = empty; // get position of ZERO or EMPTY SPACE
            if (compareArray(X,goal)) {
                System.out.println("SUCCESS");

                STATE = true;
            } else {
                // generate child nodes
                CLOSED.add(X);

                temp = up(X, pos);
                if (temp != null)
                    OPEN.add(temp);
                temp = left(X, pos);
                if (temp != null)
                    OPEN.add(temp);
                temp = down(X, pos);
                if (temp != null)
                    OPEN.add(temp);
                temp = right(X, pos);
                if (temp != null)
                    OPEN.add(temp);
                if(OPEN.isEmpty()) 
                    System.out.println("Ending loop");
            }
        }

    }
    public static boolean compareArray(int[] a, int[] b) {
        for(int i: a) 
            if(a[i] != b[i])
                return false;

        return true;

    }

    public static int[] up(int[] s, int p) {
        int[] str = s;
        if (p > 3) {
            int temp = str[p-3];
            str[p-3] = str[p];
            str[p] = temp;


        }
        // Eliminates child of X if its on OPEN or CLOSED
        if (!OPEN.contains(str) && CLOSED.contains(str) == false)
            return str;
        else
            return null;
    }


    public static int[] down(int[] s, int p) {
        int[] str = s;
        if (p < 6) {
            int temp = str[p+3];
            str[p+3] = str[p];
            str[p] = temp;

        }

        // Eliminates child of X if its on OPEN or CLOSED
        if (!OPEN.contains(str) && CLOSED.contains(str) == false)
            return str;
        else
            return null;
    }


    public static int[] left(int[] s, int p) {
        int[] str = s;
        if (p != 0 && p != 3 && p != 6) {
            int temp = str[p-1];
            str[p-1] = str[p];
            str[p] = temp;

        }
        // Eliminates child of X if its on OPEN or CLOSED
        if (!OPEN.contains(str) && CLOSED.contains(str) == false)
            return str;
        else
            return null;
    }


    public static int[] right(int[] s, int p) {
        int[] str = s;
        if (p != 2 && p != 5 && p != 8) {
            int temp = str[p+1];
            str[p+1] = str[p];
            str[p] = temp;
        }
        // Eliminates child of X if its on OPEN or CLOSED
        if (!OPEN.contains(str) && CLOSED.contains(str) == false)
            return str;
        else
            return null;
    }
    public static void print(String s) {
        System.out.println(s.substring(0, 3));
        System.out.println(s.substring(3, 6));
        System.out.println(s.substring(6, 9));
        System.out.println();
    }
}
包应用;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.HashSet;
导入java.util.Iterator;
导入java.util.LinkedHashSet;
导入java.util.LinkedList;
导入java.util.List;
导入java.util.PriorityQueue;
导入java.util.Queue;
导入java.util.Vector;
公共类解决方案{
/******************************************
*在这里实现
***************************************/
/*
*这里的实现:您需要实现广度优先搜索
*方法
*/
/*有关此功能的详细信息,请参阅说明文件*/
public static LinkedHashSet OPEN=新建LinkedHashSet();
public static HashSet CLOSED=new HashSet();
公共静态布尔状态=false;
公共静态int为空;
公共静态空白宽度优先搜索(int[]num,int m,向量解1){
int statesVisited=0;
for(int i:num){
如果(num[i]==m){
空=i;
}
}
int[]start=num;
int[]目标={0,1,2,3,4,5,6,7,8};
int[]X;
int[]temp={};
打开。添加(开始);
while(OPEN.isEmpty()==false&&STATE==false){
X=OPEN.iterator().next();
打开。移除(X);
int pos=empty;//获取零或空空间的位置
如果(比较雷(X,目标)){
System.out.println(“成功”);
状态=真;
}否则{
//生成子节点
已结束。添加(X);
温度=上升(X,位置);
如果(温度!=null)
打开。添加(临时);
温度=左侧(X,位置);
如果(温度!=null)
打开。添加(临时);
温度=下降(X,位置);
如果(温度!=null)
打开。添加(临时);
温度=右侧(X,位置);
如果(温度!=null)
打开。添加(临时);
if(OPEN.isEmpty())
System.out.println(“结束循环”);
}
}
}
公共静态布尔比较数组(int[]a,int[]b){
对于(int i:a)
如果(a[i]!=b[i])
返回false;
返回true;
}
公共静态int[]向上(int[]s,int p){
int[]str=s;
如果(p>3){
int temp=str[p-3];
str[p-3]=str[p];
str[p]=温度;
}
//如果X的子对象处于打开或关闭状态,则消除其子对象
如果(!OPEN.contains(str)&&CLOSED.contains(str)==false)
返回str;
其他的
返回null;
}
公共静态int[]关闭(int[]s,int p){
int[]str=s;
if(p<6){
int temp=str[p+3];
str[p+3]=str[p];
str[p]=温度;
}
//如果X的子对象处于打开或关闭状态,则消除其子对象
如果(!OPEN.contains(str)&&CLOSED.contains(str)==false)
返回str;
其他的
返回null;
}
公共静态int[]左(int[]s,int p){
int[]str=s;
如果(p!=0&&p!=3&&p!=6){
int-temp=str[p-1];
str[p-1]=str[p];
str[p]=温度;
}
//如果X的子对象处于打开或关闭状态,则消除其子对象
如果(!OPEN.contains(str)&&CLOSED.contains(str)==false)
返回str;
其他的
返回null;
}
公共静态int[]右(int[]s,int p){
int[]str=s;
如果(p!=2&&p!=5&&p!=8){
int temp=str[p+1];
str[p+1]=str[p];
str[p]=温度;
}
//如果X的子对象处于打开或关闭状态,则消除其子对象
如果(!OPEN.contains(str)&&CLOSED.contains(str)==false)
返回str;
其他的
返回null;
}
公共静态无效打印(字符串s){
System.out.println(s.substring(0,3));
System.out.println(s.substring(3,6));
System.out.println(s.substring(6,9));
System.out.println();
}
}
这段代码只会立即结束,永远找不到答案。也许我做错了什么?请帮忙

请注意:这是我关于StackOverFlow的第一个问题,因此,如果有人有任何批评,请告诉我,我将立即解决。

方法up(…)有一个错误:

你有:

 str[p] = str[p-3];
我猜应该是:

 str[p] = temp;

首先,您有一个不起任何作用的参数,
vectorsolution
in:

public static void breadthFirstSearch(int[] num, int m, Vector solution1)
另外,你要传递的是零元素的位置,你表示为m,然后给这个位置分配一个局部变量,对我来说似乎有点毫无意义,如果你要搜索它,就没有必要传递零位置

更新的广度优先搜索方法:

public static void breadthFirstSearch(int[] num) {
    for (int i : num) {
        if (num[i] == 0) {
            empty = i;
        }
    }

    int[] start = num;
    int[] goal = {1, 2, 3, 4, 5, 6, 7, 8, 0};
    int[] X;
    int[] temp = {};

    OPEN.add(start);

    while (OPEN.isEmpty() == false && STATE == false) {

        X = OPEN.iterator().next();
        OPEN.remove(X);
        int pos = empty; // get position of ZERO or EMPTY SPACE
        if (Arrays.equals(X, goal)) {
            System.out.println("SUCCESS");
            STATE = true;
        } else {
            // generate child nodes
            CLOSED.add(X);
            temp = up(X, pos);
            if (temp != null) {
                OPEN.add(temp);
            }
            temp = left(X, pos);
            if (temp != null) {
                OPEN.add(temp);
            }
            temp = down(X, pos);
            if (temp != null) {
                OPEN.add(temp);
            }
            temp = right(X, pos);
            if (temp != null) {
                OPEN.add(temp);
            }
            if (OPEN.isEmpty()) {
                System.out.println("Ending loop");
            }
        }
    }
}
程序的主要问题是在移动方法中
向上()
向下()
左()
右()
。您没有创建阵列的完整副本,因此导致对原始阵列进行修改

因此,本任务:
int[]str=s

必须更改为:

   int[] str = new int[s.length];
   System.arraycopy(s, 0, str, 0, s.length);
下面是一个完整方法的示例:

public static int[] up(int[] s, int p) {
    int[] str = new int[s.length];
    System.arraycopy(s, 0, str, 0, s.length);

    if (p > 3) {
        int temp = str[p - 3];
        str[p - 3] = str[p];
        str[p] = temp;
    }
    // Eliminates child of X if its on OPEN or CLOSED
    if (!OPEN.contains(str) && !CLOSED.contains(str)) {
        return str;
    } else {
        return null;
    }
}
旁注(非必要):

数组的某些排列不会导致目标状态。这个拼图本身可以有一个tota
public  boolean isSolvable(int[] puzzle) {
    boolean parity = true;
    int gridWidth = (int) Math.sqrt(puzzle.length);
    boolean blankRowEven = true; // the row with the blank tile

    for (int i = 0; i < puzzle.length; i++) {
        if (puzzle[i] == 0) { // the blank tile
            blankRowEven = (i / gridWidth) % 2==0;
            continue;
        }
        for (int j = i + 1; j < puzzle.length; j++) {
            if (puzzle[i] > puzzle[j] && puzzle[j] != 0) {
                parity = !parity;
            }
        }
    }

    // even grid with blank on even row; counting from top
    if (gridWidth % 2 == 0 && blankRowEven) { 
        return !parity;
    }
    return parity;
}
private State previousState;
private int[] current;

public State(int[] current, State previousState) {
    this.current = current;
    this.previousState = previousState
}

public State getPreviouState(){
    return previousState;
}
public int[] getCurrentState(){
    return currentState;
}
State current = GOAL;
while(current != null){
    System.out.println(Arrays.toString(current));
    current = current.getPreviousState();
}