八數碼問題 python實現 A 啟發式搜尋

2021-10-14 21:47:57 字數 4143 閱讀 5074

class

board

(object):

def__init__

(self)

:# self.groud = [1,0,2,3,4,5,6,7,8]

# 棋盤,0代表空

self.groud =[7

,2,4

,5,0

,6,8

,3,1

]#移動的路徑

self.route =

def__lt__

(self,other)

:return self.priority(

))# 是否到達正確狀態

defguiwei

(self)

: flag =

true

for i in

range(9

):if self.groud[i]

!= i:

flag =

false

break

return flag

# 兩個位置數字進行交換

defexchange

(self, index1, index2)

: temp = self.groud[index1]

self.groud[index1]

= self.groud[index2]

self.groud[index2]

= temp

# 空格向左移動

defleft

(self)

: index = self.groud.index(0)

if index %3!=

0:self.exchange(index, index-1)

# 空格向右移動

defright

(self)

: index = self.groud.index(0)

if index %3!=

2:self.exchange(index, index+1)

# 空格向上移動

defup

(self)

: index = self.groud.index(0)

ifint

(index/3)

!=0: self.exchange(index, index-3)

# 空格向下移動

defdown

(self)

: index = self.groud.index(0)

ifint

(index/3)

!=2: self.exchange(index, index+3)

# 返回空格能移動的方位的列表,比如[0,1,2,3]代表空格能向左右上下進行移動

defcan_move

(self)

: index = self.groud.index(0)

can =

if index %3!=

0:0)

if index %3!=

2:1)

ifint

(index/3)

!=0:2

)ifint(index/3)

!=2:3

)return can

# 展示棋盤

defshow_board

(self)

:print

(self.groud)

# 路徑

defshow_route

(self)

:print

(self.route)

print

(len

(self.route)

)# 通過route路徑進行移動,route是路徑列表

defmove

(self, route)

:for i in route:

if i ==0:

self.left(

)elif i ==1:

self.right(

)elif i ==2:

self.up(

)else

: self.down(

)# 僅移動一步

defmove_one

(self, i)

:if i ==0:

self.left(

)elif i ==1:

self.right(

)elif i ==2:

self.up(

)else

: self.down(

)# 測試如果向目標方向移動,棋盤的變化,返回變化的棋盤

deftest

(self, i)

: groud =

if i ==0:

self.left(

) groud = self.groud[:]

self.right(

)elif i ==1:

self.right(

) groud = self.groud[:]

self.left(

)elif i ==2:

self.up(

) groud = self.groud[:]

self.down(

)else

: self.down(

) groud = self.groud[:]

self.up(

)return groud

defroute_0

(self,route)

: route_0 =

for x in route:

self.move_one(x)0)

)print

(route_0)

# 優先順序計算

defpriority

(self)

: p =

0for i in

range(9

):if self.groud[i]

!= i:

p+=1# return p

return p+

len(self.route)

import queue

defa_star()

:# 值越小,優先順序越高

deq = queue.priorityqueue(

)set()

#使用set進行檢索極快,hash檢索

temp = board())

for x in temp.can_move():

b = board(

) b.move_one(x)

) deq.put(b)

flag =

0while

true

: flag+=

1 temp = deq.get(

)if flag%

10000==0

: flag=

0 temp.show_board(

) temp.show_route(

)if temp.guiwei():

temp.show_board(

) temp.show_route(

)break

for x in temp.can_move():

# 篩選掉重複的棋盤情況,加快搜尋速度

if list2str(temp.test(x)

)not

new_temp=copy.deepcopy(temp)

new_temp.move_one(x)

deq.put(new_temp)

)

要點

只用復位,即不追求最短

追求最短

八數碼問題

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

八數碼問題

2 6 4 1 3 7 0 5 8 8 1 5 7 3 6 4 0 2 樣例輸出 還有就是重判的問題,如何重判呢?第一種方法 把排列變成整數,然後只開乙個一維陣列,也就是說設計一套排列的編碼和解碼函式,把0 8的全排列和0 362879的整數意義一一對應起來。時間效率高,但編碼解碼法適用範圍並不大,...

八數碼問題

八數碼問題 題意 編號為1 8的8個正方形滑塊被擺成3行3列 有乙個格仔留空 如下圖所示 每次可以把與空格相鄰的滑塊 有公共邊才算相鄰 移到空格中,而他原來的位置 就成為了新的空格。如果無法到達目標局面,則輸出 1。2 6 4 13 75 8 移到後 8 1 5 73 642 樣例輸入 2 6 4 ...