栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

A*求解八数码问题(Java语言)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

A*求解八数码问题(Java语言)

八数码 描述

在九宫格里放在1到8共8个数字还有一个是空格,与空格相邻的数字可以移动到空格的位置,问给定的状态最少需要几步能到达目标状态(用0表示格):
120345678

输入

输入一个给定的状态。

输出

输出到达目标状态的最小步数。不能到达时输出-1。

输入样例

012345678

输出样例

2


public class Node {
	private int state;
	private Node parent;
	private int value;
	private int depth;
	public int getState() {
		return state;
	}
	public void setState(int state) {
		this.state = state;
	}
	public Node getParent() {
		return parent;
	}
	public void setParent(Node parent) {
		this.parent = parent;
	}
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
	public int getDepth() {
		return depth;
	}
	public void setDepth(int depth) {
		this.depth = depth;
	}
	public class astarEight {
	static Comparator cmp = new Comparator() {

		//按照value值和Depth值最小的方式构造优先队列
		@Override
		public int compare(Node n1, Node n2) {
			// TODO Auto-generated method stub
			return (n1.getDepth() + n1.getValue()) - (n2.getDepth() + n2.getValue());
		}
	};
	
	static Queue openTable = new PriorityQueue<>(cmp); //用优先队列存储open表
	static Deque closeTable = new linkedList<>(); //close表
	static Stack path = new Stack(); //用栈来存储路径
	static Map vis = new HashMap<>(); //用来存储遍历过的状态
	static int r; // 行
	static int c; // 列
	static int[][] mat = new int[3][3]; // 将一个九位整数转化为一个3X3的矩阵
	static int[][] dir = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; // 上、下、左、右

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int start, goal;
		Scanner input = new Scanner(System.in);
		start = input.nextInt(); //初始状态
		goal = input.nextInt(); //目标状态
		Node Nstart = new Node();
		Node Ngoal = new Node();
		
		//对初始状态和目标状态进行初始化
		init(Nstart, Ngoal, start, goal);
		//将初始状态入队列
		openTable.add(Nstart);
		
		while (true) {
			
			closeTable.add(openTable.peek()); //将open表中优先级最高的放入close表中
			vis.put(start, 1); //保存出现过的状态
			
			openTable.poll();//将open表中优先级最高的元素删除
			
			if (closeTable.peekLast().getState() == goal) { //如果当前状态与目标状态相同,退出循环
				break;
			} else {
				//扩展子节点
				extendNode(closeTable.peekLast(), Ngoal);
			}
		}
		
		Node tmpNode = new Node();
		tmpNode = closeTable.peekLast(); //返回close表中最后一个元素
		while (tmpNode.getParent() != null) {
			path.add(tmpNode);
			tmpNode = tmpNode.getParent();  //找父节点
		}
		path.add(tmpNode);
		
		System.out.println(path.size()-1);
		while (path.size() > 0) {
			Node t = (Node) path.peek();

			System.out.println(t.getState());
			path.pop();
		}
	}

	
	//计算估计函数值,函数值由曼哈顿距离与深度之和确定
	public static int value(Node s, Node g) {
		int count = 0;
		int start = s.getState();
		int goal = g.getState();
		int[][] begin = new int[3][3];
		int[][] end = new int[3][3];

		for (int i = 2; i >= 0; i--) {
			for (int j = 2; j >= 0; j--) {
				begin[i][j] = start % 10;
				start = start / 10;
				end[i][j] = goal % 10;
				goal = goal / 10;
			}
		}
		for (int i = 0; i < 3; i++) // 检查当前图形的正确度
			for (int j = 0; j < 3; j++) {
				if (begin[i][j] != end[i][j]) {
					for (int k = 0; k < 3; k++)
						for (int w = 0; w < 3; w++)
							if (begin[i][j] == end[k][w])
								//计算曼哈顿距离
								count = (int) (count + Math.abs(i - k * 1.0) + Math.abs(j - w * 1.0)); // 累加计算每个数字当前状态与最终状态的曼哈顿距离
				} else {
					continue;
				}
			}
		return count + s.getDepth();
	}

	
	//扩展子节点
	public static void extendNode(Node S, Node G) {
		for (int i = 0; i < 4; i++) {
			if (judge(S, i)) {
				int t = 0;
				Node tmp = new Node();
				int ur = r + dir[i][0];
				int uc = c + dir[i][1];
				mat[r][c] = mat[ur][uc];
				mat[ur][uc] = 0;
				for (int j = 0; j < 3; j++) {
					for (int z = 0; z < 3; z++) {
						t = t * 10 + mat[j][z];
					}
				}
				
				if (vis.get(t) == null) {
					tmp.setState(t);
					tmp.setDepth(S.getDepth() + 1);
					tmp.setValue(value(tmp, G));
					tmp.setParent(S);
					// System.out.println(tmp.getState());
					openTable.add(tmp);
				} else {
					continue;
				}

			}
		}
	}

	// 判断该状态是都可行
	public static boolean judge(Node u, int d) {

		int t = u.getState();
		for (int i = 2; i >= 0; i--) {
			for (int j = 2; j >= 0; j--) {
				mat[i][j] = t % 10;
				t = t / 10;
				if (mat[i][j] == 0) {
					r = i;
					c = j;
				}
			}
		}

		// 判断四个方向
		if ((d == 0 && r == 0) || (d == 1 && r == 2) || (d == 2 && c == 0) || (d == 3 && c == 2))
			return false;
		return true;
	}

	//对初始状态和目标状态进行初始化
	public static void init(Node S, Node G, int start, int goal) {
		S.setParent(null);
		S.setDepth(0);
		S.setValue(0);
		S.setState(start);
		G.setParent(null);
		G.setDepth(0);
		G.setValue(0);
		G.setState(goal);
	}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/582303.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号