這兩天學習了下python這個指令碼語言,語法簡單且豐富。
嘗試用python寫了個八數碼問題的演算法,很方便就寫出來了。
使用廣度優先演算法,改進了下,搜尋下乙個節點**估一下,這樣速度會快很多。
# coding=utf-8
'''created on 2023年12月18日
@author: osborn
'''#實現字串任兩個位置的字元交換
def switchchar(str, p1, p2):
left = p1
right = p2
if(p1 > p2):
left = p2
right = p1
elif(p1 == p2):
return str
lstr = ""
rstr = ""
mstr = ""
if(left == 0):
lstr = ""
else:
lstr = str[:left]
if(right == len(str) - 1):
rstr = ""
else:
rstr = str[right + 1:]
if((right - left) == 1):
mstr = ""
else:
mstr = str[left + 1: right]
return lstr + str[right] + mstr + str[left] + rstr
# 用物件表示狀態點
class statenode:
def __init__(self, value, dstvalue, step):
self.value = value
self.index = value.find("*")
self.assess = 0
self.dstvalue = dstvalue
if(self.index < 0):
print(self.tostring() + " error")
raise runtimeerror
for i in range(len(value)):
if(value[i] == dstvalue[i]):
self.assess += 1
self.step = step
def tostring(self):
return "node: assess= step=\n \n \n".format(self.value[:3], self.assess, self.value[3:6], self.value[6:],self.step)
def left(self):
if(self.index % 3 != 0):
return statenode(switchchar(self.value, self.index -1, self.index), self.dstvalue, self.step +1)
def right(self):
if(self.index % 3 != 2):
return statenode(switchchar(self.value, self.index +1, self.index), self.dstvalue, self.step +1)
def up(self):
if(self.index > 2):
return statenode(switchchar(self.value, self.index -3, self.index), self.dstvalue, self.step +1)
def down(self):
if(self.index < 6):
return statenode(switchchar(self.value, self.index +3, self.index), self.dstvalue, self.step +1)
def calc(startval, endval):
startnode = statenode(startval, endval, 0)
openlist = [startnode]
closelist =
while true:
#評估,使用assess值
openlist = sorted(openlist, key=lambda node: node.assess)
curnode = openlist.pop()
if(curnode == none):
print("end")
return
print(curnode.tostring())
if(curnode.assess == 9):
print("found,end!")
return
leftnode = curnode.left()
rightnode = curnode.right()
upnode = curnode.up()
downnode = curnode.down()
if(leftnode != none):
exist = false
for node in openlist:
if(leftnode.value == node.value):
exist = true
break
for node in closelist:
if(leftnode.value == node.value):
exist = true
break
if(not exist):
if(rightnode != none):
exist = false
for node in openlist:
if(rightnode.value == node.value):
exist = true
break
for node in closelist:
if(rightnode.value == node.value):
exist = true
break
if(not exist):
if(upnode != none):
exist = false
for node in openlist:
if(upnode.value == node.value):
exist = true
break
for node in closelist:
if(upnode.value == node.value):
exist = true
break
if(not exist):
if(downnode != none):
exist = false
for node in openlist:
if(downnode.value == node.value):
exist = true
break
for node in closelist:
if(downnode.value == node.value):
exist = true
break
if(not exist):
if __name__ == '__main__':
calc("12345678*","*12345678")
這段**只是找出正確解,但是沒有找最優解。
有時間我會研究下a*演算法,找最優解。
八數碼問題
八數碼問題 一.八數碼問題 八數碼問題也稱為九宮問題。在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 ...