八数码问题深度优先算法--C语言版本

题目:

以八数码问题为例,宽度/深度优先搜索方法求解给定初始状态和目标状态的最优搜索路径。
【输入形式】

初始状态和目标状态间用换行符隔开(空格用0表示)
【输出形式】

每一步得到的状态
【样例输入】

3 1 2

4 0 5

6 7 8

0 1 2

3 4 5

6 7 8
【样例输出】

initial

3 1 2

4 0 5

6 7 8

step 1

3 1 2

0 4 5

6 7 8

step 2

0 1 2

3 4 5

6 7 8

注:若问题无解,输出格式为:

no answer

以下是代码:

#include <stdio.h>
#include<stdlib.h>
//位置移动(按先后顺序优先)
int up = 1;
int left = 2;
int down = 3;
int right = 4;
//输入矩阵和输出矩阵
const int start[3][3];
const int end[3][3];
//深度优先允许的最大深度(可以改变)
const int depthmax = 10;
/*//保存当前路径的矩阵
int path[3][3][depthmax];
//最优解的路径矩阵,不需要,因为可以根据directions来得到路径的矩阵
int pathop[3][3][depthmax];*/
//当前路径移动
int waynow[10] = { 0 };
//最优路径移动
int wayop[10] = { 0 };
//当前最优解的深度
int depthmin = 10;
//当前的矩阵深度
int depth = 1;

//变换矩阵,按照up,left,down,right
int exchange[4][2] =
{
    {-1,0},
    {0,-1},
    {1,0},
    {0,1}
};
//是否找到路径
int flag=0;
//矩阵内的元素交换,引用传递,改变空格位置
void swap(int *a,int *b)
{
    int tmp=*a;
    *a = *b;
    *b = tmp;
}
//矩阵是否匹配
int Compare1(const int matrix1[3][3], int matrix2[3][3])
{
    for(int i=0;i<3;i++)
        for (int j = 0; j < 3; j++)
        {
            if (matrix1[i][j] != matrix2[i][j])return 0;
        }
    return 1;
}
//输出结果,根据起始矩阵和方向direction指示打印结果
void print(int* way,int row,int column)
{
    if(flag==0)
    {
        printf("no answer");
        return;
    }
    int matrix[3][3];
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
        {
            matrix[i][j] = start[i][j];
        }
    for (int i = 0; i < depthmin; i++)
    {
        if (way[i] == up)
        {
            swap(&matrix[row][column], &matrix[row - 1][column]);
            row--;
        }
        else if (way[i] == left)
        {
            swap(&matrix[row][column], &matrix[row ][column-1]);
            column--;
        }
        else if (way[i] == down)
        {
            swap(&matrix[row][column], &matrix[row+1][column]);
            row++;
        }
        else if (way[i] == right)
        {
            swap(&matrix[row][column], &matrix[row][column +1]);
            column++;
        }
        if(i==0)
        {
            printf("initial\n");
        }
        else
        {
            printf("step %d\n",i);
        }
        for (int x = 0; x < 3; x++)
        {
            for (int y = 0; y < 3; y++)
            {
                printf("%d ", matrix[x][y]);
            }
            printf("\n");
        }
        printf("\n");
    }
}

//矩阵空格位置变换
void change(int matrix[3][3],int direction, int row,int column)
//该处行列为0在矩阵中的位置
{
    if (direction == 0)
    {
        change(matrix, up, row, column);
        change(matrix, left, row, column);
        change(matrix, down, row, column);
        change(matrix, right, row, column);
        return;
    }
    int row1 = exchange[direction - 1][0]+row;
    int column1 = exchange[direction - 1][1]+column;
    if (row1 < 0 || column1 < 0||row1>2||column1>2)return;
    if (depth + 1 <= depthmin&&depth+1<=depthmax)
    {
        swap(&matrix[row][column], &matrix[row1][column1]);
    }
    else
        return;
    if (Compare1(end, matrix))
    {
        flag=1;
        depth++;
        depthmin = depth;
        waynow[depth - 1] = direction;
        for (int i = 0; i < 7; i++)
            wayop[i] = waynow[i];
        waynow[depth - 1] = 0;
        depth--;
        swap(&matrix[row][column], &matrix[row1][column1]);
        return;//返回上一个节点
    }
    if (direction == up)
    {
        //继续搜索其他节点
        depth++;
        waynow[depth - 1] = up;
        change(matrix, up, row1, column1);
        change(matrix, left, row1, column1);
        change(matrix, right, row1, column1);
        swap(&matrix[row][column], &matrix[row1][column1]);
        //change(mm,left,row-1,column)
        waynow[depth - 1] = 0;
        depth--;
        return;
    }
    else if (direction == left)
    {
        depth++;
        waynow[depth - 1] = left;
        change(matrix, up, row1, column1);
        change(matrix, left, row1, column1);
        change(matrix, down, row1, column1);
        swap(&matrix[row][column], &matrix[row1][column1]);
        waynow[depth - 1] = 0;
        depth--;
        return;
    }
    else if (direction == down)
    {
        depth++;
        waynow[depth - 1] = down;
        change(matrix, left, row1, column1);
        change(matrix, down, row1, column1);
        change(matrix, right, row1, column1);
        swap(&matrix[row][column], &matrix[row1][column1]);
        waynow[depth - 1] = 0;
        depth--;
        return;
    }
    else if (direction == right)
    {
        depth++;
        waynow[depth - 1] = right;
        change(matrix, up, row1, column1);
        change(matrix, down, row1, column1);
        change(matrix, right, row1, column1);
        swap(&matrix[row][column], &matrix[row1][column1]);
        waynow[depth - 1] = 0;
        depth--;
        return;
    }

}
int main()
{
    int currentmatrix[3][3];
    //输入初始和目标矩阵
    int row, column;//0所在的行列
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
        {
            scanf("%d", &start[i][j]);
            currentmatrix[i][j] = start[i][j];
            if (start[i][j] == 0)
            {
                row = i;
                column = j;
            }
        }
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            scanf("%d", &end[i][j]);
    //memcpy(&mm[0][0], &start[0][0], sizeof(mm));
    if(Compare1(end,currentmatrix))
        depthmin=2;
    else
        change(currentmatrix, 0, row, column);
    //printf("%d\n",Compare1(end,currentmatrix));
    //根据directions来打印结果
    /*for(int i=0;i<=depthmin;i++)
    {
        printf("%d ",wayop[i]);
    }
    printf("\n");*/
    print(wayop,row,column);
}

运行结果如下:
在这里插入图片描述

  • 4
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值