通过宽度优先,深度优先,A*来求解8数码难题(滑动谜题)

通过宽度优先,深度优先,A*来求解8数码难题(滑动谜题)(Java实现)

1. 要求

  • 初始状态以及目标状态如下图所示。

在这里插入图片描述

  • 输出完整的从初始状态到目标状态的Action序列。
  • 对比三种算法的时间、空间消耗。

2. 设计思路

(1) 将该“棋盘”抽象为一个二维数组 int[][] state ,空的位置当作是 数字0 ,将二维矩阵转换为String(这样处理有利于比较和存储,但是String类型会消耗内存空间),那么例如:

初始状态可以定义为 String startstring =“724506831”

目标状态可以定位为 String goalstate = “012345678”

(2) 可以将该“棋盘”的每一个状态看作是一个树节点 **Node** ,每次移动 **Action** 后产生一个新的状态,每次移动可以看作是二维数组中某个数与0交换位置。

(3) 每次交换前的节点都会被保存在一个集合容器中(**栈或队列**

并与目标状态进行比较,若相同则输出完整的从初始状态到目标状态的Action序列,若不同则保存在该集合容器中(保存的状态不能重复,也需要比较)。这样循环实现直到遍历完所有状态。

(4) 与0交换的某个数即方向定义为:

int[][] DIRECTIONS = {
    {
    0, -1 }, {
    -1, 0 }, {
    0, 1 }, {
    1, 0 } };

即相当于以****“0”为中心画“十”字****,实现:****列或行+1或-1****。

(5) 移动的方式由不同算法实现,如下:

3. 实现

关于算法的消耗时间和内存,在程序内用以下实现:
Runtime r = Runtime.getRuntime();
r.gc();
// 主方法开始运行的时间
long startTime = System.currentTimeMillis();
// 主方法开始时的剩余内存
long startMem = r.freeMemory();
//********************** TODO here ********************
//********************** TODO here ********************
// 主方法结束的时间
long endTime = System.currentTimeMillis();
// 主方法结束剩余内存
long endMem = r.freeMemory();

System.out.println("程序用时: " + (endTime - startTime) + " ms");
System.out.println("程序消耗内存: " + (startMem - endMem) / 1024 + " Kb");
BFS(广度优先搜索)

  1. 从初始状态节点开始,每一个节点都对0进行四个方向的移动,得到四个新的节点,对新节点重复操作

  2. 对新的节点判别:

(1) 若之前没有访问过,就存入队列;

(2) 若与目标状态相同,就停止循环输出该节点及所有移动action。

  1. 若已经遍历了所有状态节点没有得到目标状态,就输出无法到达目标状态。

  2. 优先度如图:

在这里插入图片描述

节点类

package exp1.expbfs;

import java.util.Arrays;

/**
 * 此类为封装的节点类
 * 
 * @author 
 *
 */
public class NodeBFS {
   
	//0所在位置
	int zero_row,zero_column;
	
	int[][] state;
	//将数组转化为String(或者可以重写toString方法)
	String statestring;
	//记录父节点
	NodeBFS father;
	//记录移动的次数
	int counts;
	/**
	 * 
	 * @param father	父节点
	 * @param state	状态
	 * @param zero_row	0所在的行
	 * @param zero_column	0所在的列
	 */
	public NodeBFS(NodeBFS father,int[][] state,int zero_row,int zero_column) {
   
		this.father=father;
		this.state=state;
		this.zero_row=zero_row;
		this.zero_column=zero_column;
		this.statestring=Arrays.deepToString(state);
		
		if(null==this.father)
			this.counts=0;
		else
			this.counts=this.father.counts+1;
	}
}
package exp1.expbfs;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;

public class BFS {
   

	
	// 初始状态 START_STATE
//	public static final int[][] START_STATE = { {3 ,1, 2 }, {4 , 0, 5}, { 6, 7,8 } };
	public static final int[][] START_STATE = {
    {
   7 ,2, 4 }, {
   5, 0, 6}, {
    8, 3,
  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值