同一个世界OL游戏 算法求解 改进版

阅读前准备

建议先看这篇文章同一个世界游戏 算法破解

改进思路

对于前篇文章(同一个世界游戏 算法破解)的Node类是通过Map<Integer, Integer>的对象来记录之前的走过的位置,这占用了大量的内存空间,检查的效率也低;节点的节点值等于父节点的值加本身的值(long childValue = parent.getValue() + (long) ),但是针对这个游戏(编码保存方式)而言,是否有可能有更好的方式
对以上两点考虑得到了更好的解决方式

重复位置检查

该游戏的状态是以二进制的方式保存的,经过的点对应的位标志为1,否则为0,也就是说任意一个节点的值实际上就已经保存了它所经过点,所以它的子节点只要检查节点值的二进制对应的位是否为1,即可知道是否走过该点

	// 未经过该点
	private boolean notPassed(long oldPosition, int index) {
   
   
		return (oldPosition >> index & 1) == 0;
	}

这样就节省了大量的时间和内存空间

节点值求和

有了上面的严谨检查,确保了子节点不会走过重复的点,这意味着一个节点值的二进制不会在相同的位上重复出现1的情况,也就是没有进位的情况,这样就可以把原来的加法运算改为或运算

long childValue = parent.getValue() | getValue(childIndex);

但是原本的加法也不可能会出现进位的情况,我想这并没有减少多少时间

其它问题

PathUtils类生成路径的时候可能是闭合路径但是还没有达到指定的路径深度,会造成死循环
重构NodeTree类的代码

代码

Node.java

public class Node {
   
   

	private Node parent; // 父节点
	private long value; // 当前路径值
	private int row; // 当前节点的行
	private int col; // 当前节点的列
	private int index; // 起点序号
	
	public Node getParent() {
   
   
		return parent;
	}
	public void setParent(Node parent) {
   
   
		this.parent = parent;
	}
	public long getValue() {
   
   
		return value;
	}
	public void setValue(long value) {
   
   
		this.value = value;
	}
	public int getRow() {
   
   
		return row;
	}
	public void setRow(int row) {
   
   
		this.row = row;
	}
	public int getCol() {
   
   
		return col;
	}
	public void setCol(int col) {
   
   
		this.col = col;
	}
	public int getIndex() {
   
   
		return index;
	}
	public void setIndex(int index) {
   
   
		this.index = index;
	}
	
}

NodeTree.java

import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class NodeTree {
   
   

	private int[][] state; // 盘面
	private int row, col; // 二维数组行、列
	private long target; // 目标状态值
	private Node[] solveNodes; // 解决路径
	private List<Map<Long, Node>> nodes; // 所有路径
	private Deque<Node> deque; // 可能路径
	private long realSum; // 实际路径数量

	public NodeTree(int[][] state, int[][] startPoint, long target) {
   
   
		this.state = state;
		this.target = target;
		this.row = state.length;
		this.col = state[0].length;
		nodes = new ArrayList<>(startPoint.length);
		for (int i = 0; i < startPoint
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值