• 八数码问题——双向广度优先搜索解决


    八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。

                                             

                                        

                                        

    搜索顺序有两种:

    (1)两个方向交替进行扩展

    (2)每次选择节点少的那个扩展

    一般来说方法(2)可以克服两端生长不平衡的现象

    // eight.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include<vector>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    #define N 3
    #define SIZE 9
    typedef unsigned char BYTE;
    /*const int src[N][N] = { { 2, 5, 4 },
    { 3, 0, 7 },
    { 1, 8, 6 } };*/
    const int src[N][N] = { { 8, 7, 1 },
    { 5, 2, 6 },
    { 3, 4, 0 } };
    
    /*const int dst[N][N] = { { 1, 2, 3 },
    { 8, 0, 4 },
    { 7, 6, 5 } };*/
    const int dst[N][N] = { { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 0 } };
    
    struct Code
    {
    	BYTE value[SIZE];
    	bool operator== (const Code &a) const
    	{
    		for (int i = 0; i < SIZE;i++)
    		if( a.value[i] !=value[i])
    			return false;
    		return true;
    	}
    	Code& operator=(const Code& a)
    	{
    		for (int i = 0; i < SIZE; i++)
    		value[i] = a.value[i];
    		return *this;
    	}
    };
    
    Code up(Code a)
    {
    	int ii=-1;
    	for (int i = 0; i < SIZE; i++)
    		if (a.value[i] == 0)
    		{
    		ii = i;
    		break;
    		}
    	if (ii > 2)
    	{
    		BYTE temp = a.value[ii - 3];
    		a.value[ii - 3] = 0;
    		a.value[ii] = temp;
    	}
    	return a;
    }
    
    Code right(Code a)
    {
    	int ii = -1;
    	for (int i = 0; i < SIZE; i++)
    		if (a.value[i] == 0)
    		{
    		ii = i;
    		break;
    		}
    	if (ii>=0&&(ii+1)%3!=0)
    	{
    		BYTE temp = a.value[ii +1];
    		a.value[ii +1] = 0;
    		a.value[ii] = temp;
    	}
    	return a;
    }
    Code down(Code a)
    {
    	int ii = -1;
    	for (int i = 0; i < SIZE; i++)
    		if (a.value[i] == 0)
    		{
    		ii = i;
    		break;
    		}
    	if (ii>=0&&ii <6)
    	{
    		BYTE temp = a.value[ii + 3];
    		a.value[ii + 3] = 0;
    		a.value[ii] = temp;
    	}
    	return a;
    }
    
    
    Code left(Code a)
    {
    	int ii = -1;
    	for (int i = 0; i < SIZE; i++)
    		if (a.value[i] == 0)
    		{
    		ii = i;
    		break;
    		}
    	if (ii >= 0&&ii%3!=0)
    	{
    		BYTE temp = a.value[ii - 1];
    		a.value[ii - 1] = 0;
    		a.value[ii] = temp;
    	}
    	return a;
    }
    
    vector<Code>solution;
    
    bool expand(vector<vector<Code>>&tobeexpanded, vector<vector<Code>>&a_b, vector<Code>&front_tobeexpanded, vector<Code>&front_a_b)
    {
    	vector<vector<Code>>bbb;
    	vector<Code>::iterator it;
    	front_tobeexpanded.clear();
    	for (int i = 0; i < tobeexpanded.size(); i++)
    	{
    		if (!(up(tobeexpanded[i].back()) == tobeexpanded[i].back()) && find(tobeexpanded[i].begin(), tobeexpanded[i].end(), up(tobeexpanded[i].back())) == tobeexpanded[i].end())
    		{
    			it = find(front_a_b.begin(), front_a_b.end(), up(tobeexpanded[i].back()));
    			if (it != front_a_b.end())
    			{
    				solution = a_b[it - front_a_b.begin()];
    				reverse(tobeexpanded[i].begin(), tobeexpanded[i].end());
    				solution.insert(solution.end(), tobeexpanded[i].begin(), tobeexpanded[i].end());
    				return true;
    			}
    			front_tobeexpanded.push_back(up(tobeexpanded[i].back()));
    			bbb.push_back(tobeexpanded[i]);
    			bbb.back().push_back(up(tobeexpanded[i].back()));
    		}
    		if (!(right(tobeexpanded[i].back()) == tobeexpanded[i].back()) && find(tobeexpanded[i].begin(), tobeexpanded[i].end(), right(tobeexpanded[i].back())) == tobeexpanded[i].end())
    		{
    			it = find(front_a_b.begin(), front_a_b.end(), right(tobeexpanded[i].back()));
    			if (it != front_a_b.end())
    			{
    				solution = a_b[it - front_a_b.begin()];
    				reverse(tobeexpanded[i].begin(), tobeexpanded[i].end());
    				solution.insert(solution.end(), tobeexpanded[i].begin(), tobeexpanded[i].end());
    				return true;
    			}
    			front_tobeexpanded.push_back(right(tobeexpanded[i].back()));
    			bbb.push_back(tobeexpanded[i]);
    			bbb.back().push_back(right(tobeexpanded[i].back()));
    		}
    		if (!(down(tobeexpanded[i].back()) == tobeexpanded[i].back()) && find(tobeexpanded[i].begin(), tobeexpanded[i].end(), down(tobeexpanded[i].back())) == tobeexpanded[i].end())
    		{
    			it = find(front_a_b.begin(), front_a_b.end(), down(tobeexpanded[i].back()));
    			if (it != front_a_b.end())
    			{
    				solution = a_b[it - front_a_b.begin()];
    				reverse(tobeexpanded[i].begin(), tobeexpanded[i].end());
    				solution.insert(solution.end(), tobeexpanded[i].begin(), tobeexpanded[i].end());
    				return true;
    			}
    			front_tobeexpanded.push_back(down(tobeexpanded[i].back()));
    			bbb.push_back(tobeexpanded[i]);
    			bbb.back().push_back(down(tobeexpanded[i].back()));
    		}
    		if (!(left(tobeexpanded[i].back()) == tobeexpanded[i].back()) && find(tobeexpanded[i].begin(), tobeexpanded[i].end(), left(tobeexpanded[i].back())) == tobeexpanded[i].end())
    		{
    			it = find(front_a_b.begin(), front_a_b.end(), left(tobeexpanded[i].back()));
    			if (it != front_a_b.end())
    			{
    				solution = a_b[it - front_a_b.begin()];
    				reverse(tobeexpanded[i].begin(), tobeexpanded[i].end());
    				solution.insert(solution.end(), tobeexpanded[i].begin(), tobeexpanded[i].end());
    				return true;
    			}
    			front_tobeexpanded.push_back(left(tobeexpanded[i].back()));
    			bbb.push_back(tobeexpanded[i]);
    			bbb.back().push_back(left(tobeexpanded[i].back()));
    		}
    	}
    	tobeexpanded = bbb;
    	return false;
    }
    void DBFS()
    {
    	vector<vector<Code>>aa,bb;
    	Code start, ending;
    	for (int i = 0; i < SIZE; i++)
    	{
    		start.value[i] = src[i / 3][i % 3];
    		ending.value[i] = dst[i / 3][i % 3];
    	}
    	vector<Code>a1, b1;
    	a1.push_back(start);
    	b1.push_back(ending);
    	aa.push_back(a1);
    	bb.push_back(b1);
    	vector<Code>front_a, front_b;
    	front_a.push_back(start);
    	front_b.push_back(ending);
    	while (true)
    	{
    		if (aa.size()>bb.size())
    		{
    			if(expand(bb, aa, front_b, front_a))
    				return;
    		}
    		else
    		{
    			if(expand(aa, bb, front_a, front_b))
    				return;
    		}
    	}
    }
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	DBFS();
    
    	system("pause");
    	return 0;
    }
    


    版权声明:

  • 相关阅读:
    生成随机串码并保存到Excel中
    制作100份word表
    抓取网页图片-以本地IIS网页为实践对象
    使用xlsxwriter 创建图表chart
    照片查看器2.0
    编程注意事项-记踩过的坑
    STC12C5A60S2的定时器模式16位的时候没有自动重载功能
    Keil C51 一个警告 '=': pointer: different mspace
    RT-Thread 使用笔记二
    Keil-C51读取ROM数据
  • 原文地址:https://www.cnblogs.com/walccott/p/4956883.html
Copyright © 2020-2023  润新知