八數碼的A 與IDA 演算法 搜尋高階練習1

2021-07-10 16:32:09 字數 2937 閱讀 9378

hdu1043:

poj1077:

題意:眾所周知的八數碼問題,就不再描述了。不得不說,為了練習a*以及ida*就直接看題解了。 了解之後分析如下。

解題報告:

先談a*。a*是一種

啟發式搜尋,也就是說在每次搜尋前,先進行在狀態空間中對每乙個搜尋的位置通過f(n) = g(n) + h(n)進行評估,得到最好的位置,再從這個位置,

進行搜尋直到目標。其中f(n)是從初始點經由節點n到目標點的估價函式,g(n) 是在狀態空間中從初始節點到n節點的實際代價,h(n)是從n到目標節點最佳路徑的估計代價。

然後是ida*。a*演算法和迭代加深演算法的結合。

1.搜尋框架?a*(ida*)演算法。搜尋直到終態結束,或該狀態非法進行下一狀態。

2.狀態?直接記錄每個狀態的maze、x位置資訊以及a*所需f、g、h。同時使用hash值指向所有狀態。

3.狀態轉移?x與上下左右互換,更新狀態資訊。

4.剪枝?乙個簡單有效的剪枝逆序數為奇則必定無解。

5.hash以及h?

hash可通過各位置逆序數乘位置雜湊值之和雜湊。h為所有數字塊的曼哈頓距離和。

具體而言。a*通過構造優先佇列

實現搜尋。

構造優先佇列時當f相同時按照g值從大到小排序,這樣又是乙個很給力的減枝。

#include #include #include #include using namespace std;

//a*: 因為每次移動都會影響乙個點的曼哈頓距離(不算x)

//構造h()為所有數字塊的曼哈頓距離和,用逆序數hash(算x)

//根據逆序數奇偶性(不算x)減掉無法到達的情況,

struct node

node(const node & rhs)

//估價函式小的先出隊,相同則實際代價大的先出隊

friend bool operator < (const node & a, const node & b)

}st;

const int dir[4][2] = ,,, };//方向

char dr[5] = "drul"; //方向查詢表

int pos[9][2] = ; //位置資訊

int fac[9] = ; //hash雜湊因子

char path[370000];

bool vis[370000];

int pre[370000];

int shash;

int h(const node s) //估價函式,偏移步數

return ans;

}int hash_node(const node s) //hash雜湊,儲存狀態

return ans;

}bool check_h() //逆序為奇返回true

} return cnt & 1;

}bool bfs()

} return false;

}void print(int h)

}char in[100];

int main()

if (check_h())

st.g = 0; st.h = h(st); st.f = st.h;

if ((shash = hash_node(st)) == 0)

int thash = bfs();

print(0); //遞迴輸出答案

puts("");

} return 0;

}

而ida*的話,和a*相同的h()函式。

當前h深度下一層一層地進行搜尋

#include #include using namespace std;

struct node

node(const node & rhs)

}ts, s;

const int maxn = 370000;

const int dir[4][2] = ,,, };

const char dr[5] = "drul";

const int fac[9] = ;

const int pos[2] = ;

char path[maxn];

bool vis[maxn];

int deep;

int h(const node st)

return ans;

}int mhash(const node st)

return ans;

}bool check()

} return cnt & 1;

}int dfs(int d)

vis[ihv] = true;

ts.r = nr, ts.c = nc;

path[d] = dr[dd];

if (dfs(d + 1)) return true;

vis[ihv] = false;

ts.r = r, ts.c = c;

ts.maze[nr][nc] = ts.maze[r][c];

ts.maze[r][c] = 'x';

} return false;

}int main()

if (check())

memset(vis, false, sizeof(vis));

vis[mhash(s)] = true;

ts = s; deep = 0;

while (true)

for (int i = 0; i < deep; i++)

putchar(path[i]);

puts("");

} return 0;

}

最後打卡一下。之前ubuntu的ibus預設的中文輸入法雙拼的,當時就感覺是一堆亂碼,玩毛。不幾天前,嘗試用雙拼了。

八數碼(IDA 演算法)

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

A 搜尋演算法,poj1077 八數碼

今天看了a 搜尋演算法,聽說牛逼的很,不過關鍵還是在於它的評估函式,估計也不一定每題都能這麼容易想吧 就 來說吧,s,儲存所有所搜到的結點的資訊,包括空格位置,深度及評估值,這裡不給出h是因為h一直在變,b儲存開始結點資訊,visited儲存是否訪問到,接下來方向,答案,heap是為了提速而寫的堆實...

八數碼問題的A 演算法求解

a 演算法是啟發式搜素演算法中較為出名和高效的演算法之一,其關鍵是對於啟發式函式的實際,啟發式函式h x 需要盡可能的接近實際的h x h x 下面是人工智慧八數碼問題使用a 演算法求解的原始碼放在部落格上記錄一下。程式使用放錯位置的棋子的個數作為啟發式函式。include include incl...