八数码问题(双向BFS,A*算法,康托展开,逆序优化)

该博客介绍了八数码问题的解决方法,包括使用双BFS(D_B解法)和A*算法。通过康拓展开进行状态表示,并讨论了A*算法中启发式函数的设计。还提及了2006年百度之星比赛中楼天城采用A*算法的优秀表现。此外,提出了优化策略——逆序对优化,分析了逆序对数奇偶性与问题解的存在性关系。
摘要由CSDN通过智能技术生成


题目

描述
在一个3*3的九宫格棋盘里,放有8个数码,数码的数字分别是1~8。棋盘中还有一个位置是空着的,用0表示。可以通过在九宫格里平移数码来改变状态(即空格位在九宫格内能上下左右移动)。数码在任何情况下都不能离开棋盘。给出8个数码的初始状态(没放数码的空格用0表示)和目标状态,问从初始状态到目标状态,最少需要经过多少次移动操作。 例如 初始状态为:
2 6 4 1 3 7 0 5 8 \begin{matrix} 2 & 6 & 4 \\ 1 & 3 & 7\\ 0 & 5 & 8 \end{matrix} 210635478
目标状态为:
8 1 5 7 3 6 4 0 2 \begin{matrix} 8 & 1 & 5 \\ 7 & 3 & 6\\ 4 & 0 & 2 \end{matrix} 874130562
输入
两行 第一行9个数字,用空格隔开,表示初始状态 第二行9个数字,用空格隔开,表示目标状态
输出
一个数,即最短路径,如果没有答案,则输出-1
样例输入
2 6 4 1 3 7 0 5 8
8 1 5 7 3 6 4 0 2
样例输出
31

思路

此题要用康拓展开
康托展开

D_B解法(double_BFS)

显然,题目把初始状态和目标状态都告诉了你,典型的双B啊,注意一下空位的移动方式和移动之后的图的状态

代码
#include <cstdio>
#include <queue>
#include <iostream>
using namespace std;

struct node{
   
    int step;
    int a[12], area[4][4];
    int flag;
    int xx, yy, c;
}A, B;

queue<node>G;

int dx[4] = {
   0, 0, 1, -1},
    dy[4] = {
   1, -1, 0, 0};

int v[2][362890], f[10] = {
   1,1,2,6,24,120,720,5040,40320,362880};

inline int contor(int *A){
   
    int sum = 0;
    for(int i = 0; i < 9 ; i ++){
   
        int x;
        x = 0;
        for(int j = i+1; j < 9; j ++){
   
            if( A[j] < A[i] )
                x++;
        }
        sum += f[8-i]*x;
    }
    return sum;
}

inline void Two_ways_BFS(){
   
    while( !G.empty() ){
   
        node t = G.front();
        G
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值