深度优先搜索解决八数码难题

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-18 05:17:09

八数码问题
以前用java写的通过深度优先瘦素解决八数码难题。
在这里插入图片描述

对于八数码难题来说,可以把9宫格看成一个[3][3]的二维数组,将空格位置看成0,将0可以移动的方向看成树的枝丫,分为上下左右4个方向。
具体实现思路:

  1. 每调用一次深度+1,如果深度达到指定深度,结束
  2. 找出0所在位置,对0的位置进行判断,判断是否能移动。判断顺序为左,上,右,下(列与行不能小于0,不能大于2)。为了避免出现先左移后右移等状况,需要设置一个变量,当变量为某个值时不能向某个方向移动。
  3. 判断能否向左移动,如果能,对0进行移动,将移动后的数组与最终数组进行判断,如果正确,则输出right,停止程序。如果不是则再次调用移动函数(递归调用)。
  4. 恢复原状态,写4个还原函数分别将数组还原到移动前的状态,将判断移动方向的变量还原到移动前的状态(回朔法)。
  5. 判断能否向其他方向移动(之后流程与向左移动相同)。
  6. 如果4个方向都判断完,结束
package aa;
import java.util.Scanner;

public class Az {
	static int[][] arr2 = new int[3][3];//= { { 1, 2, 3 }, { 8, 0, 4 }, { 7, 6, 5 } };
	static int aaa;		//用于记录移动步数
	static int bbb=5;	//用于记录深度

	public static void main(String[] args) {
		int[][] arr1 = new int[3][3];	//定义二维数组
		System.out.println("请输入最终数组(空格用0代替)(按行输入):");
		Scanner input = new Scanner(System.in);		//创建键盘输入函数
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				int ss =input.nextInt();
				arr2[i][j] = ss; 
			}
		}
		System.out.println("$$$$$$$$$$$$$$$$$$$$$$$");
		System.out.println("最终状态:");
		shuchu(arr2);
		System.out.println("$$$$$$$$$$$$$$$$$$$$$$$");
		System.out.println("请输入要判断的数组(空格用0代替)(按行输入):");
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				int ss =input.nextInt();
				arr1[i][j] = ss; 
			}
		}
		System.out.println("你输入的数组:");
		shuchu(arr1);
		System.out.println(" ");
		yidong(arr1, 1, 0);	//调用移动函数
		System.out.println("..................................................");
		System.out.println("没有找到");
		input.close();
	}

	public static void shuchu(int a[][]) { // 输出二维数组

		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a[i].length; j++) {
				System.out.print(a[i][j] + " ");
			}
			System.out.println();
		}
	}

	public static boolean panduan(int a[][], int b[][]) { // 判断两个二维数组的内容是否相等
		boolean esta = true;

		for (int i = 0; i < a.length && esta == true; i++) {
			for (int j = 0; j < a[i].length && esta == true; j++) {
				if (a[i][j] != b[i][j]) {
					esta = false;

				}
			}
			
		}
		return esta;
	}
	public static void jieshu() { // 结束函数
		aaa++;	//移动步数
		System.out.println("jieshu");
		System.out.println("共用了" + aaa +"步" );
		System.exit(0);
	}

	public static int[][] zuoyi(int a2[][]) { // 还原左移函数
	
		int[][] a1 = a2;
		int n1=0;
		int n2=0;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				if (a1[i][j] == 0) {
					
					n1 = i;// 移动格所在的行
					n2 = j;// 移动格所在的列
				}
			}
		}
		int t1 = a1[n1][n2 + 1];
		a1[n1][n2 + 1] = a1[n1][n2];
		a1[n1][n2] = t1;
		return a1;
	}
	public static int[][] shangyi(int a2[][]) { // 还原上移函数
		int[][] a1 = a2;
		int n1=0;
		int n2=0;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				if (a1[i][j] == 0) {
					
					n1 = i;// 移动格所在的行
					n2 = j;// 移动格所在的列
				}
			}
		}
		int t1 = a1[n1 + 1][n2];
		a1[n1 + 1][n2] = a1[n1][n2];
		a1[n1][n2] = t1;
		return a1;
	}
	public static int[][] youyi(int a2[][]) { // 还原右移函数
		int[][] a1 = a2;
		int n1=0;
		int n2=0;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				if (a1[i][j] == 0) {
					
					n1 = i;// 移动格所在的行
					n2 = j;// 移动格所在的列
				}
			}
		}
		int t1 = a1[n1][n2 - 1];
		a1[n1][n2 - 1] = a1[n1][n2];
		a1[n1][n2] = t1;
		return a1;
	}
	public static int[][] xiayi(int a2[][]) { // 还原下移函数
		int[][] a1 = a2;
		int n1=0;
		int n2=0;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				if (a1[i][j] == 0) {
					n1 = i;// 移动格所在的行
					n2 = j;// 移动格所在的列
				}
			}
		}
		int t1 = a1[n1 - 1][n2];
		a1[n1 - 1][n2] = a1[n1][n2];
		a1[n1][n2] = t1;
		return a1;
	}
	public static void yidong(int a[][], int s, int x) {

		aaa++;	//移动步数
		int[][] ar2 = a;	//传过来的数组
		int q = s;		//深度
		int c=x;		//用来判断不能向哪个方向移动(1,不能右移 2,不能下移 3,不能左移 4,不能上移)
		System.out.println("第"+ aaa +"步"+ ":");
		System.out.println("深度: " + q);
		shuchu(ar2);
		if (q == bbb) {
			System.out.println("*********************************");
			System.out.println("到达设定的深度");
			System.out.println("*********************************");
		} else {
			int num1 = -1;
			int num2 = -1;
			for (int i = 0; i < 3; i++) {
				for (int j = 0; j < 3; j++) {
					if (a[i][j] == 0) {

						num1 = i;// 移动格所在的行
						num2 = j;// 移动格所在的列
					}
				}
			}
			int pan = c;
			int o = num2 - 1;
			// System.out.println(o);
			if (o < 0 || pan == 1) {		//左移
				System.out.println("");
			} else {
				
				System.out.println("左移:");
				pan = 3;
				int t1 = ar2[num1][num2 - 1];
				ar2[num1][num2 - 1] = ar2[num1][num2];
				ar2[num1][num2] = t1;
				boolean aa = panduan(ar2, arr2);
				if (aa == true) {
					System.out.println("right");
					jieshu();
				}
				else {
					yidong(ar2,q+1,pan);
					pan=c;
					ar2=zuoyi(ar2);		//调用左移还原函数
					System.out.println("还原:");
					shuchu(ar2);
					System.out.println(" ");
				}
			}
			if (num1 - 1 < 0 || pan == 2) {		//上移
				System.out.println("");
			} else {
				
				System.out.println("上移:");
				pan = 4;
				int t1 = ar2[num1 - 1][num2];
				ar2[num1 - 1][num2] = ar2[num1][num2];
				ar2[num1][num2] = t1;
				boolean aa = panduan(ar2, arr2);
				if (aa == true) {
					System.out.println("right");
					jieshu();
				}
				else {
					yidong(ar2,q+1,pan);
					pan=c;
					ar2=shangyi(ar2);		//调用上移还原函数
					System.out.println("还原:");
					shuchu(ar2);
					System.out.println(" ");
				}
			}
			if (num2 + 1 > 2 || pan == 3) {		//右移
				System.out.println("");
			} else {
				
				System.out.println("右移:");
				pan = 1;
				int t1 = ar2[num1][num2 + 1];
				ar2[num1][num2 + 1] = ar2[num1][num2];
				ar2[num1][num2] = t1;
				boolean aa = panduan(ar2, arr2);
				if (aa == true) {
					System.out.println("right");
					jieshu();
				}
				else {
					yidong(ar2,q+1,pan);
					pan=c;
					ar2=youyi(ar2);		//调用右移还原函数
					System.out.println("还原:");
					shuchu(ar2);
					System.out.println(" ");
				}
			}
			if (num1 + 1 > 2 || pan == 4) {		//下移
				System.out.println("");;
			} else {
				
				System.out.println("下移:");
				pan = 2;
				int t1 = ar2[num1 + 1][num2];
				ar2[num1 + 1][num2] = ar2[num1][num2];
				ar2[num1][num2] = t1;
				boolean aa = panduan(ar2, arr2);
				if (aa == true) {
					System.out.println("right");
					jieshu();
				}
				else {
					yidong(ar2,q+1,pan);
					pan=c;
					ar2=xiayi(ar2);		//调用下移还原函数
					System.out.println("还原:");
					shuchu(ar2);
					System.out.println(" ");
				}
			
			}

		}
	}
}


输入格式:
在这里插入图片描述
深度需要在全局变量里修改,我设定的是5。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!