zoukankan      html  css  js  c++  java
  • 八数码问题——双向广度优先搜索解决

    八数码问题:在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;
    }
    



    题目来源:NOIP2002提高组试题
    描写叙述 Description
    已知有两个字串 A$, B$ 及一组字串变换的规则(至多6个规则):
    A1$ -> B1$
    A2$ -> B2$
    规则的含义为:在 A$中的子串 A1$ 能够变换为 B1$、A2$ 能够变换为 B2$ …。
    比如:A$='abcd' B$='xyz'
    变换规则为:
    ‘abc’->‘xu’ ‘ud’->‘y’ ‘y’->‘yz’
    则此时。A$ 能够经过一系列的变换变为 B$,其变换的过程为:
    ‘abcd’->‘xud’->‘xy’->‘xyz’
    共进行了三次变换,使得 A$ 变换为B$。
    输入格式 Input Format
    A$ B$
    A1$ B1$
    A2$ B2$ |-> 变换规则
    ... ... /
    全部字符串长度的上限为 20。


    输出格式 Output Format
    若在 10 步(包括 10步)以内能将 A$ 变换为 B$ 。则输出最少的变换步数;
    否则输出"NO ANSWER!"
    例子输入:
    abcd xyz
    abc xu
    ud y
    y yz
    例子输出:
    3
    题目类型:双向广搜




  • 相关阅读:
    SQL优化索引
    如何减轻工作压力(一)
    奥巴马对美国影响最大的十句话
    10种职场潜规则
    Linux中的7件武器详解
    linux时间同步,ntpd、ntpdate
    Style中Position属性详解
    vsftp配置大全超完整版
    Linux 技巧:使用 screen 管理你的远程会话
    MySQL下mysql.sock丢失问题的解决
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7135950.html
Copyright © 2011-2022 走看看