双向广度优先搜索法。

本文介绍了如何使用双向广度优先搜索法解决步数较多的问题,例如将两种特定状态互换。该方法通过同时从起始和目标状态开始搜索并在中间相遇,找到最少步数的解决方案。程序示例展示了如何实现这一方法,并包含关键的数据结构和搜索过程。
摘要由CSDN通过智能技术生成

上一篇文章里讲到了广度优先搜索法,并以8数码问题为例。8数码问题比较简单,一般不超过30步即可求解。搜索的节点也不会超过1000000。而如下这个问题的步数是56,如果直接用广度优先搜索,节点数量会多的难以想象。

#######
#BLACK#
## # ##     #是墙
#WHITE#
#######
 
  |
 
#######
#WHITE#
## # ##
#BLACK#
#######

问题就是将上述两个状态互换。

双向广度优先搜索法我是在“人工智能爱好者”网站上看到的。其思想是同时从开始状态和结束状态开始广度优先搜索,随着搜索的进行,双方会在中间相遇。由此就找到了一个可行解,而且是最少步数解。具体方法是每增加一个节点,就在对方已搜索的节点中查找,如果找到相同状态节点,则为找到解。

以下这个程序和一般的广度优先搜索并无太大区别,区别主要是双向相遇的判断。

/*
-----------
#######
#BLACK#
## # ##     #是墙
#WHITE#
#######
 
  |
 
#######
#WHITE#
## # ##
#BLACK#
#######
-----------
*/
#include <stdio.h>

typedef unsigned long long  UINT64;
typedef struct
{
    char    x;  //位置x和位置y上的数字换位
    char    y;  //其中x是0所在的位置
} PZ_MOVE;

typedef struct  PZ_NODE_Tag
{
    UINT64              v;
    struct PZ_NODE_Tag  *prev, *small, *big;
} PZ_NODE;

#define ROW         3
#define COL         5
#define NUM         (ROW * COL)
#define MAX_NODE    2000000
#define MAX_DEP     100
#define MAX_MOVE    6

#define XCHG(a, b)  { a=a + b; b=a - b; a=a - b; }
#define TRANS(a, b) { long    iii; (b)=0; for(iii=0; iii < NUM; iii++) (b)=((b) << 4) + a[iii]; }   //将数组a转换为一个64位的整数b
#define RTRANS(a, b) /
    { /
        long    iii; /
        UINT64  ttt=(a); /
        for(iii=NUM - 1; iii >= 0; iii--) /
        { /
            b[iii]=ttt & 0xf; /
            ttt>>=4; /
        } /
    }                       //将一个64位整数a转换为数组b

//
PZ_NODE m_ar1[MAX_NODE];
long    m_depth1;           //搜索深度
PZ_NODE m_out1[MAX_DEP];    //输出路径
PZ_NODE *m_root1;
PZ_NODE m_ar2[MAX_NODE];
long    m_depth2;           //搜索深度
PZ_NODE m_out2[MAX_DEP];    //输出路径
PZ_NODE *m_root2;

//
long move_gen(PZ_NODE *node, PZ_MOVE *mv)
{
    long    c=0;
    char    st[NUM];
    RTRANS(node->v, st);
    if((st[0] != 0) && (st[1] == 0))
    {
        mv[c].x=1;
        mv[c].y=0;
        c++;
        if(st[2] == 0)
        {
            mv[c].x=2;
            mv[c].y=0;
            c++;
        }

        if(st[6] == 0)
        {
            mv[c].x=6;
            mv[c].y=0;
            c++;
        }
    }

    if(st[1])
    {
        if(st[0] == 0)
        {
            mv[c].x=0;
            mv[c].y=1;
            c++;
        }

        if(st[2] == 0)
        {
            mv[c].x=2;
            mv[c].y=1;
            c++;
            if(st[3] == 0)
            {
                mv[c].x=3;
                mv[c].y=1;
                c++;
            }
        }

        if(st[6] == 0)
        {
            mv[c].x=6;
            mv[c].y=1;
            c++;
            if(st[11] == 0)
            {
                mv[c].x=11;
                mv[c].y=1;
                c++;
            }
        }
    }

    if(st[2])
    {
        if(st[1] == 0)
        {
            mv[c].x=1;
            mv[c].y=2;
            c++;
            if(st[0] == 0)
            {
                mv[c].x=0;
                mv[c].y=2;
                c++;
            }

            if(st[6] == 0)
            {
                mv[c].x=6;
             

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值