双向广度优先搜索法

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

  双向广度优先搜索法 


  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;
                mv[c].y=2;
                c++;
            }
        }

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

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

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

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

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

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

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

    if((st[10] != 0) && (st[11] == 0))
    {
        mv[c].x=11;
        mv[c].y=10;
        c++;
        if(st[12] == 0)
        {
            mv[c].x=12;
            mv[c].y=10;
            c++;
        }

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

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

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

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

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

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

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

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

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

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

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

    if((st[14] != 0) && (st[13] == 0))
    {
        mv[c].x=13;
        mv[c].y=14;
        c++;
        if(st[12] == 0)
        {
            mv[c].x=12;
            mv[c].y=14;
            c++;
        }

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

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

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

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

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

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

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

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

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

    return c;
}

/* */
long move(PZ_NODE *n1, PZ_MOVE *mv, PZ_NODE *n2)    //走一步,返回走一步后的结果
{
    char    ss[NUM];
    RTRANS(n1->v, ss);
    XCHG(ss[mv->x], ss[mv->y]);
    TRANS(ss, n2->v);
    return 0;
}

/* */
long add_node1(PZ_NODE *node, long r)
{
    PZ_NODE *p=m_root1;
    PZ_NODE *q;
    while(p)
    {
        q=p;
        if(p->v == node->v)
            return 0;
        else if(node->v > p->v)
            p=p->big;
        else if(node->v < p->v)
            p=p->small;
    }

    m_ar1[r].v=node->v;
    m_ar1[r].prev=node->prev;
    m_ar1[r].small=NULL;
    m_ar1[r].big=NULL;
    if(node->v > q->v)
    {
        q->big= &m_ar1[r];
    }
    else if(node->v < q->v)
    {
        q->small= &m_ar1[r];
    }

    return 1;
}

/* */
long add_node2(PZ_NODE *node, long r)
{
    PZ_NODE *p=m_root2;
    PZ_NODE *q;
    while(p)
    {
        q=p;
        if(p->v == node->v)
            return 0;
        else if(node->v > p->v)
            p=p->big;
        else if(node->v < p->v)
            p=p->small;
    }

    m_ar2[r].v=node->v;
    m_ar2[r].prev=node->prev;
    m_ar2[r].small=NULL;
    m_ar2[r].big=NULL;
    if(node->v > q->v)
    {
        q->big= &m_ar2[r];
    }
    else if(node->v < q->v)
    {
        q->small= &m_ar2[r];
    }

    return 1;
}

/*
得到节点所在深度
*/
long get_node_depth(PZ_NODE *node)
{
    long    d=0;
    while(node->prev)
    {
        d++;
        node=node->prev;
    }

    return d;
}

/*
到树2中搜索此节点是否存在
*/
PZ_NODE *check_ok1(PZ_NODE *node)
{
    PZ_NODE *p=m_root2;
    while(p)
    {
        if(p->v == node->v)
            return p;
        else if(node->v > p->v)
            p=p->big;
        else if(node->v < p->v)
            p=p->small;
    }

    return NULL;
}

/*
到树1中搜索此节点是否存在
*/
PZ_NODE *check_ok2(PZ_NODE *node)
{
    PZ_NODE *p=m_root1;
    while(p)
    {
        if(p->v == node->v)
            return p;
        else if(node->v > p->v)
            p=p->big;
        else if(node->v < p->v)
            p=p->small;
    }

    return NULL;
}

/*
返回值:成功-返回1,节点数不够-(-1),无解-(-2)
*/
long bfs_search(char *begin, char *end)
{
    long    h1=0, r1=1, h2=0, r2=1, c, i;
    PZ_NODE node, *pnode;
    PZ_MOVE mv[MAX_MOVE];               //每个局面最多4种走法
    TRANS(end, m_ar2[0].v);
    TRANS(begin, m_ar1[0].v);
    m_ar1[0].prev=NULL;
    m_root1=m_ar1;
    m_root1->small=NULL;
    m_root1->big=NULL;
    m_ar2[0].prev=NULL;
    m_root2=m_ar2;
    m_root2->small=NULL;
    m_root2->big=NULL;
    while((h1 < r1) && (r1 < MAX_NODE - MAX_MOVE))
    {
        c=move_gen(&m_ar1[h1], mv);
        for(i=0; i < c; i++)
        {
            move(&m_ar1[h1], &mv[i], &node);
            node.prev= &m_ar1[h1];
            if(add_node1(&node, r1))    //只能对历史节点中没有的新节点搜索,否则会出现环
            {
                r1++;
                if((pnode=check_ok1(&node)) != NULL)
                {
                    m_depth2=0;
                    while(pnode)
                    {
                        m_out2[m_depth2++].v=pnode->v;
                        pnode=pnode->prev;
                    }

                    pnode= &node;
                    m_depth1=0;
                    while(pnode)
                    {
                        m_out1[m_depth1++].v=pnode->v;
                        pnode=pnode->prev;
                    }

                    return 1;
                }
            }
        }

        h1++;
        c=move_gen(&m_ar2[h2], mv);
        for(i=0; i < c; i++)
        {
            move(&m_ar2[h2], &mv[i], &node);
            node.prev= &m_ar2[h2];
            if(add_node2(&node, r2))    //只能对历史节点中没有的新节点搜索,否则会出现环
            {
                r2++;
                if((pnode=check_ok2(&node)) != NULL)
                {
                    m_depth1=0;
                    while(pnode)
                    {
                        m_out1[m_depth1++].v=pnode->v;
                        pnode=pnode->prev;
                    }

                    pnode= &node;
                    m_depth2=0;
                    while(pnode)
                    {
                        m_out2[m_depth2++].v=pnode->v;
                        pnode=pnode->prev;
                    }

                    return 1;
                }
            }
        }

        h2++;
        printf("/rSearch... %d/%d @ %d | %d/%d @ %d",
                       h1,
                       r1,
                       get_node_depth(&m_ar1[h1]),
                       h2,
                       r2,
                       get_node_depth(&m_ar2[h2]));
    }

    if((h1 == r1) && (h2 == r2))
    {
        return -2;
    }
    else
    {
        return -1;
    }
}

/* */
void output(void)
{
    long    i, j, k;
    char    ss[NUM];
    for(i=m_depth1 - 1; i >= 0; i--)
    {
        RTRANS(m_out1[i].v, ss);
        for(j=0; j < ROW; j++)
        {
            for(k=0; k < COL; k++)
            {
                printf("%3d", ss[COL * j + k]);
            }

            printf("/n");
        }

        printf("/n");
    }

    for(i=1; i < m_depth2; i++)
    {
        RTRANS(m_out2[i].v, ss);
        for(j=0; j < ROW; j++)
        {
            for(k=0; k < COL; k++)
            {
                printf("%3d", ss[COL * j + k]);
            }

            printf("/n");
        }

        printf("/n");
    }
}

/* */
int main(void)
{
#if 1
    char    begin[NUM]={ 1, 2, 3, 4, 5, 15, 0, 15, 0, 15, 6, 7, 8, 9, 10 }; //0表示空格,15表示墙
    char    end[NUM]={ 6, 7, 8, 9, 10, 15, 0, 15, 0, 15, 1, 2, 3, 4, 5 };
#else
    char    begin[NUM]={ 1, 1, 1, 1, 1, 15, 0, 15, 0, 15, 2, 2, 2, 2, 2 };  //0表示空格,15表示墙
    char    end[NUM]={ 2, 2, 2, 2, 2, 15, 0, 15, 0, 15, 1, 1, 1, 1, 1 };
#endif
    long    r=bfs_search(begin, end);
    printf("/n");
    if(r >= 0)
    {
        output();
    }
    else
    {
        printf("bfs_search returns %d/n", r);
    }

    return 0;
}


双向广度优先索(Bi-Directional Breadth First Search)算法 对于拼图游戏来说,已经知道了开始状态(某个乱序的状态)和目标状态(图片复原时的状态),而这两个状态其实是可以互换的,完全可以从目标复原状态开始索,反向推进,直到找出拼图开始时的乱序状态。我们想象一下,让起始于开始状态的树从上往下生长,再让起始于目标状态的树从下往上生长,同时在它们的生长空间中遍布着一个一个的状态结点,等待着这两棵树延伸去触及。要实现双向广,并不需要真的用两条线程分别从开始状态和目标状态对向展开索,在单线程下也完全可以实现,实现的关键是于让两个开放队列交替出列元素。 阅读详情

相关推荐

驯服电源尖峰:从BUCK/BOOST环路剖析到高di/dt噪声的实战抑制

本文深入探讨了电源系统中高di/dt噪声的产生机制及抑制方法,通过BUCK/BOOST电路的环路分析,揭示了电流路径不连续导致的电压尖峰问题。文章提供了实用的PCB布局技巧和噪声抑制策略,包括最短回路原则、铺铜优化和过孔阵列战术,帮助工程师有效降低EMI噪声,提升电源系统的稳定性。

weixin_29587015的博客 245

C++算法(Acwing)学习(持续更新中)---双向BFS(双向广)和A-Star(A*)

A*算法---从起点到终点的最短距离(启发函数)适用于数据范围较大。保证当终点出队时是最小值(但是不保证中间的某个点出队时是最小值)除了存真实距离值外(从起点到当前点的真实距离)还要存一个估计距离(从终点到当前点的估计距离)每次挑一个预测距离+真实距离最短的点扩展。需满足条件---估计的距离<=真实距离(从当前点到终点)基本步骤:(有点像dijkstra(形式上))t<-优先队列的对头(小根堆)dijkstra可看作所有估价为0的A*算法。1.首先将bfs中的队列都换成优先队列。1.BFS 在入队时判重。

m0_74172918的博客 501

英语教学法教程UnitCommunicativePrinciplesTBLTPPT课件.pptx

英语教学法教程UnitCommunicativePrinciplesTBLTPPT课件.pptx

双向广度优先索算法框架及八数码问题例程

双向广度优先索算法是对广度优先算法的一种扩展。广度优先算法从起始节点以广度优先的顺序不断扩展, 直到遇到目的节点;而双向广度优先算法从两个方向以广度优先的顺序同时扩展,一个是从起始节点开始扩展,另 一个是从目的节点扩展,直到一个扩展队列中出现另外一个队列中已经扩展的节点,也就相当于两个扩展方向出现了 交点,那么可以认为我们找到了一条路径。双向广度优先算法相对于广度优先算法来说,

hazqfp的专栏 1459

广度优先索:八数码问题

问题描述 问题分析 状态空间 广度优先索 用队列保存待扩展的节点 从队首队取出节点, 扩展出的新节点放入队尾,直到队首出现目标节点(问题的解) BFS() { 初始化队列; while(队列不为空且未找到目标节点) { 取队首节点扩展,并将扩展出的非重复节点放入队尾; 必要时要记住每个节点的父节点; } } 关键问题 新扩展出的节点如果和以前扩展出的节点相同,则该新节点就不必...

流年的博客 5209

欢迎大家加入我的Q群

如果你对以下Q群感兴趣的话,欢迎加入! 1、编程算法群:32760081     主要研究编程艺术-算法,包括神经网络,人工智能的算法。    举例: 双向广度优先搜索法。      广度优先索遵循从初始结点开始一层层扩展直到找到目标结点的索规则,它只能较好地解决状态不是太多的情况,承受力很有限。如果扩展结点较多,而目标结点又处在较深层,采用前文叙述的广度索解题,索量巨大是

编程的艺术世界 - Bruce Lee 2918

广度优先索算法与双向广度优先索算法

广度优先索算法与双向广度优先索算法 【转】 使用计算机求解的问题中,有许多问题是无法用数学公式进行计算推导采用模拟方法来找出答案的。这样的问题往往需要我们根据问题所给定的一些条件,在问题的所有可能解中用某种方式找出问题的解来,这就是所谓的索法或索技术。通常用索技术解决的问题可以分成两类:一类问题是给定初始结点,要求找出符合约束条件的目标结点;另一类问题是给出初始结点和...

weixin_30751947的博客 217

【LeetCode 127】 单词接龙(BFS—BFS+字典—双向BFS+字典)

题目 给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则: 每次转换只能改变一个字母。 转换过程中的中间单词必须是字典中的单词。 说明: 如果不存在这样的转换序列,返回 0。 所有单词具有相同的长度。 所有单词只由小写字母组成。 字典中不存在重复的单词。 你可以假设 beginWord 和 endWord 是非空的,且二者不相同。 示例 1: 输入: beginWord = “hit”, endWord

SAMCYC的博客 485

优先索算法

<br />使用计算机求解的问题中,有许多问题是无法用数学公式进行计算推导采用模拟方法来找出答案的。这样的问题往往需要我们根据问题所给定的一些条件,在问题的所有可能解中用某种方式找出问题的解来,这就是所谓的索法或索技术。<br />通常用索技术解决的问题可以分成两类:一类问题是给定初始结点,要求找出符合约束条件的目标结点;另一类问题是给出初始结点和目标结点,找出一条从初始结点到达目标结点的路径。<br />常见的索算法有枚举法、广度优先搜索法、深度优先索法、双向广度优先搜索法,A*算法、回溯法、分

王伟挺的专栏 2177

基于二值图像的区域标记算法介绍及其源代码

目前关于图像的标记算法是研究的热点,下面来介绍一下关于二值图像的区域标记算法的原理及其相关说明: 到现在为止,图像的标记算法有很多,这些方法大致可以分为以下3类: 1、像素标记法:根据标记过程中对图像扫描次数的不同可以分为:两次扫描法、单向反复扫描法、以及双向反复扫描法。两次扫描法第一次扫描时记录冲突的标记并形成等价对(存储在特殊的数据结构中),第二次扫描时,把等价标记中最小的标记赋予所有等价...

跑得动就不要歇着 1716

深度优先索和广度优先索的比较与分析

一)深度优先索的特点是: (1)无论问题的内容和性质以及求解要求如何不同,它们的程序结构都是相同的,即都是深度优先算法(一)和深度优先算法(二)中描述的算法结构,不相同的仅仅是存储结点数据结构和产生规则以及输出要求。 (2)深度优先索法有递归以及非递归两种设计方法。一般的,当索深度较小、问题递归方式比较明显时,用递归方法设计好,它可以使得程序结构更简捷易懂。当索深度较大时,当数

xyjikl 4131

八数码问题及A*算法

一.八数码问题 八数码问题也称为九宫问题。在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。 所谓问题的一个状态就是棋子在棋盘上的一种摆法。棋子移动后,状态就...

weixin_34007291的博客 709

127. 单词接龙

给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则: 每次转换只能改变一个字母。 转换过程中的中间单词必须是字典中的单词。 说明: 如果不存在这样的转换序列,返回 0。 所有单词具有相同的长度。 所有单词只由小写字母组成。 字典中不存在重复的单词。 你可以假设 beginWord 和 endW...

蜗牛的博客 434

C++ 算法学习——1.3 双向深度优先

双向深度优先索(Bidirectional Depth-First Search)是一种图索算法,旨在通过从起始节点和目标节点同时开始,沿着深度优先索的路径向前探索,以减少索空间并提高索效率。

William_Edmund的博客 697

C++——广度优先

由于广度优先索是逐层遍历,从根节点开始,先输出根节点的值,然后按照从左到右的顺序依次输出每一层的节点值。广度优先索(Breadth-First Search,BFS)是一种图遍历算法,它从起始节点开始逐层扩展索,直到找到目标节点或遍历完整个图。首先构建了一个示例的二叉树,然后调用BFS函数执行广度优先索,并输出遍历的结果。请注意,广度优先索需要注意避免重复访问节点,通常使用一个额外的数组或集合来记录已访问的节点。4、遍历当前节点的所有邻居节点,若邻居节点未被访问过,则标记为已访问并将其加入队列。

m0_48748418的博客 2471

双向广

双向广 (2011-08-31 16:45:24) Eight 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 讲到双向广,那就不能不讲经典的八数码问题,有人说不做此题人生不完整 。 所谓双向广,就是初始结点向目标结点和目标结点向初始结点同时扩展,直至在两个扩展方向上出现同一个结点,...

weixin_33908217的博客 265

广度优先算法解决8数码问题【c++

8数码问题 (广度优先算法解决----c++) 8数码问题问题描述 八数码问题也称为九宫问题,在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格(空格用0来表示),空格周围的棋子可以移到空格中。 要求解的问题是: 给出一种初始布局(初始状态)和目标布局(目标状态),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。 问题分析 八数码问题的核心在于移动棋子使其得到需要的状态分布(即目标状态),为便于控制操作,我们将每次移动棋子的过程都视为标号为0的棋子与其相邻棋子

siper12138的博客 8945

Java手写双向广度优先和双向广度优先应用拓展案例

双向广度优先索算法是一种从起点和终点同时进行索的算法,通过两个方向的索来减少索空间,从而提高索效率。初始化起点和终点的两个队列,分别为startQueue和endQueue,并将起点和终点分别加入两个队列中。初始化起点和终点的两个访问集合,分别为和endVisited,并将起点和终点分别加入两个集合中。进入循环,直到两个队列中的元素都为空:从startQueue中取出一个节点,并将其标记为已访问。遍历当前节点的所有相邻节点:如果相邻节点在endVisited。

qq_22593423的博客 446

广度优先索(BFS)进阶之双向广度优先

比如下图中,在第三次循环时,我们分别将B,E,I这三个节点的子节点,也就是A,C,H,J,分别入队。适用场景:有确定的起点以及终点,并且能将从起点到终点的单向索,转换成分别从起点和终点出发的相遇问题,那么在这种情况下,如果单向的BFS会超时,那么可以优先考虑双向广,以此减少时间复杂度。,我们提到了广度优先索,即度优先索(BFS),具体的BFS的实现以及原理,大家可以看回上一篇文章。在上篇文章中我们也讲到BFS的实现,那么接下来我们对比一下BFS和双向广的代码,以及所索的节点的个数来比较。

LovelyCat_mm的博客 1304

14 | 树的广度优先索(下):为什么双向广度优先索的效率更高?

上一讲,我们通过社交好友的关系,介绍了为什么需要广度优先策略,以及如何通过队列来实现它。有了广度优先索,我们就可以知道某个用户的一度、二度、三度等好友是谁。不过,在社交网络中,还有一个经常碰到的问题,那就是给定两个用户,如何确定他们之间的关系有多紧密?最直接的方法是,使用这两人是几度好友,来衡量他们关系的紧密程度。今天,就这个问题,来聊聊广度优先策略的一种扩展:双向广度优先索,以及这种策略在工程中的应用。

qq_37756660的博客 1055
上一篇: .NET技术——LINQ简介
下一篇: 双向广度优先搜索(介绍)
fengart
博客等级 码龄20年 91粉丝 45原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值