重排九宫(广度优先算法)

重排九宫问题

问题描述

重排九宫问题:在 3*3 的方格棋盘上放置分别标有数字 1,2,3,4,5,6,7,8 的 8 张牌,初始状态为 s_0,目标状态 为s_g,可使用的算符有空格左移,空格上移,空格右移和空格下移,即它们只允许把位于 空格左,上,右,下边的牌移入空格。要求寻找从初始状态到目的状态的路径。
可以下载全部代码

算法描述

采用了广度优先算法(部分改进),在加入子节点的时候将其按照代价函数从小到大排序,在检测之前是否出现时使用了哈希表,将九个数连起来的数作为该状态在哈希表中的位置,如果出现过设为1

实验结果

《重排九宫(广度优先算法)》

主要代码

1.主要流程

void Solution(Node start, Node target)
{
	int j = 0, c = 0;
	while (1)
	{
		if (k == m)
		{
			cout << "无解" << endl;
			break;
		}

		if (ifTarget(Open[k], target))//是否是目标结点
		{
			Node solution[100];

			int i = 0, j = 0, q;
			cout << "solution:" << endl;
			while (Open[k].father != -1)
			{
				solution[i] = Open[k];
				Open[k] = Open[Open[k].father];

				i++;
			}
			q = i;
			cout << "step 0" << endl;
			start.show();
			for (i = q - 1;i >= 0;i--)
			{
				j++;
				cout << "step " << j << endl;
				solution[i].show();
			}
			//cout << "Solve!" << endl;
			break;
		}
		j = getZeroLocation(Open[k]);//0的位置
		changeOpen(Open[k], j);
		k++;
		c++;
	}
}

2.代价函数

void Node::setEva()
{
	int i, temp = 0;
	for (i = 0;i < 9;i++)
		if (state[i] != tgt[i])
			temp++;
	difference = temp;
	eva = difference + depth;//启发函数值
}

3.节点类

//节点类
class Node
{
public:
	int state[9];

	int father;//父结点编号
	int difference;//与目标的差异
	int depth;//深度
	int eva;//代价
	int loc;//在hsTable表位置
	Node();
	void show();
	void setEva();
	void setState(int a[9]);
	void setLoc();
};

改进建议

这个使用了广度优先算法,在加子节点的时候使用了局部优先算法,但还是效率有点低,在排序的时候自己比较了各种情况,也有点复杂,可以用优先队列来实现,更加简洁,A*算法也由此容易实现。还有输出结果的时候逻辑有点乱,但是输出成功了就没再管。😛

    原文作者:九宫格问题
    原文地址: https://blog.csdn.net/Clauria/article/details/85041006
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞