IDA 演算法解決十五數碼問題

2021-07-09 10:19:50 字數 1786 閱讀 4920

原稿:

ida*演算法是a*演算法和迭代加深演算法的結合.

a*演算法需要維護open表和close表,以及排序選擇最小代價的結點記憶體空間消耗過多。

ida*的答題思路是。首先 根據最初的數碼表

5 1 2 4

9 6 3 8

13 15 10 11

14 0 7 12

目標狀態:

1 2 3 4

5 6 7 8

9 10 11 12

13 14 15 0

計算它到目標狀態的曼哈頓距離之和,以它作為乙個標尺即整個程式的走步最多也不會多於初狀態的曼哈頓距離。

曼哈頓距離就是 每個數字最少需要幾步走到最終位置。

下面的程式按照 上左右下的順序執行,遞迴呼叫.先呼叫dfs()函式執行0與其上面的數字交換,此處是15 判斷是否可解(逆序數),可解可用則遞迴呼叫dfs() 如果ok 則繼續呼叫深一層,不ok 進行向左 ,當上左右下都判斷完畢不ok的話 回退一層,判斷上一層的左 、右、下情況可以走通的話則繼續向下遞迴。

每一步執行之前 使用判斷語句 當前呼叫深度+當前的曼哈頓距離<=最初的曼哈頓距離則可以繼續。一旦大於就可以直接捨棄了。

#include

#include

#include

#define size 4

int move[4][2]=,,,};//上 左 右 下 置換順序

char op[4]=;

intmap[size][size],map2[size*size],limit,path[100];

int flag,length;

int goal[16][2]= ,,, ,, ,

, , ,, , ,,,,};//各個數字應在位置對照表

int nixu(int a[size*size])

} x=w/size;

y=w%size;

ni+=abs(x-3)+abs(y-3); //最後加上0的偏移量

if(ni%2==1)

return

1;

else

return

0;

} int hv(int a[size])//估價函式,曼哈頓距離,小等於實際總步數

} return cost;

} void swap(int*a,int*b)

void dfs(int sx,int sy,int len,int pre_move)//sx,sy是空格的位置

else

return; //超過預設長度 回退

} else

if(lenif(dv==0) //短於預設長度 成功!退出

} for(i=0;i<4;i++)

swap(&map[sx][sy],&map[nx][ny]); //不合理則回退一步

} }

} int main()

else

}

if(nixu(map2)==1) //該狀態可達

if(flag)

} else

if(!nixu(map2)||!flag)

printf("this puzzle is not solvable.\n");

} return

0;

}

八數碼(IDA 演算法)

八數碼 ida 就是迭代加深和a 估價的結合 在迭代加深的過程中,用估計函式剪枝優化 並以比較優秀的順序進行擴充套件,保證最早搜到最優解 需要空間比較小,有時跑得比a 還要快 include include include include include using namespace std in...

A 演算法解決八數碼問題(C 版本)

八數碼問題也稱為九宮問題。在3 3的棋盤,擺有八個棋子,每個棋子上標有1至8的某一數字,不同棋子上標的數字不相同。棋盤上還有乙個空格,與空格相鄰的棋子可以移到空格中。要求解決的問題是 給出乙個初始狀態和乙個目標狀態,找出一種從初始轉變成目標狀態的移動棋子步數最少的移動步驟。關鍵之處 要維護兩個結構 ...

演算法篇 14 A 演算法解決八數碼問題

八數碼問題 在3 3的方格棋盤上,擺放著1到8這八個數碼,有1個方格是空的,其初始狀態如圖1所示,要求對空格執行空格左移 空格右移 空格上移和空格下移這四個操作使得棋盤從初始狀態到目標狀態。a 初始狀態 b 目標狀態 a 演算法實際是一種啟發式搜尋,所謂啟發式搜尋,就是利用乙個估價函式評估每次決策的...