[英]8 Puzzle with Backtracking
我正在從Skiena,編程挑戰中讀到這本書,在回溯章節之后,有一個關於用回溯來解決15-puzzle的問題,我將它簡化為8-puzzle進行實驗。 我有這個遞歸代碼,我想知道它是否有機會找到解決方案。 代碼有點難看(被警告):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int arr[20][20]={
{3,1,2},
{4,0,5},
{6,8,7}
};
int moveX[20]={1,1,1,0,0,-1,-1,-1};
int moveY[20]={0,1,-1,1,-1,0,1,-1};
int depth=0;
int findRow(){
int i,j;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
if(arr[i][j]==0){
return i;
}
}
}
}
int findCol(){
int i,j;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if(arr[i][j]==0){
return j;
}
}
}
}
void print(){
int i,j;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
printf("%i ",arr[i][j]);
}
printf("\n");
}
printf("\n");
}
int isReady(){
if(arr[0]==1 && arr[1]==2 && arr[2]==3 && arr[3]==4 && arr[4]==5 && arr[5]==6 && arr[6]==7 && arr[7]==8){
return 1;
}
else return 0;
}
void perm(int row,int col,int n){
if(n>=9){
print();
if(isReady())
printf("Finished");
depth++;
return;
}
int i=0;int diffX,diffY,temp;
int r=findRow();
int c=findCol();
temp=arr[r][c];
arr[r][c]=arr[row][col];
arr[row][col]=temp;
for(i=0;i<8;i++){
diffX=row+moveX[i];
diffY=col+moveY[i];
if(diffX>=0 && diffX<4 && diffY>=0 && diffY<4){
perm(diffX,diffY,n+1);
}
}
temp=arr[r][c];
arr[r][c]=arr[row][col];
arr[row][col]=temp;
}
int main()
{
perm(0,0,0);
return 0;
}
我的問題是,這個代碼是否有機會找到解決方案,其次,任何人都可以在合理的時間內解決這個難題嗎?
你有五個問題。 首先, isReady
函數不正確。 它應該如下所示:
int isReady(){
if(arr[0][0]==1 && arr[0][1]==2 && arr[0][2]==3 &&
arr[1][0]==4 && arr[1][1]==5 && arr[1][2]==6 &&
arr[2][0]==7 && arr[2][1]==8){
return 1;
}
else return 0;
}
其次,你使用diffX
和diffY
超越你的拼圖界限。 你需要改變這個:
if(diffX>=0 && diffX<4 && diffY>=0 && diffY<4){
對此:
if(diffX>=0 && diffX<3 && diffY>=0 && diffY<3){
第三,你的findRow
函數也超出了拼圖界限。 將所有4
改為3
。
第四,只有在你移動后才能檢查你的勝利狀態。 所以在交換下面移動你的勝利檢查:
temp=arr[r][c];
arr[r][c]=arr[row][col];
arr[row][col]=temp;
// This victory check is now below the move.
if(n>=9){
print();
if(isReady())
printf("Finished");
depth++;
return;
}
第五,你應該改變你的初始電話:
perm(0,0,0);
對此:
perm(1,1,0);
你擁有它的方式,你總是強行向左上方移動作為你的第一步。 修改后的方式將0保持在中心位置,因此不會強制您第一次移動。 當我使用我所做的所有修改運行此代碼時,它找到了3個解決方案。 當我進一步修改代碼以檢查任何深度的解時,它在深度8找到2個解,在深度9找到3個解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.