题目:
以八数码问题为例,宽度/深度优先搜索方法求解给定初始状态和目标状态的最优搜索路径。
【输入形式】
初始状态和目标状态间用换行符隔开(空格用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);
}
运行结果如下: