f ( x ) = d e e p ( 搜 索 深 度 ) + d i s t a n c e ( 与 目 标 状 态 距 离 ) f(x)=deep(搜索深度)+distance(与目标状态距离) f(x)=deep(搜索深度)+distance(与目标状态距离)
distance: 曼哈顿距离,棋盘错位距离
def eight_digit(start, end, heuristic=None):
# 初始化结点
node = Node()
node.state = start
node.distance = distance(node.state,end,heuristic)
node.deep = 0
node.value = node.distance + node.deep
# 初始化openList,closedList
openList = []
closedList = []
openList.append(node)
# 是否寻找到目标状态
complete = False
while openList:
# 是否使用启发函数
if heuristic:
openList.sort(key=lambda x: x.value)
node = openList.pop(0)
closedList.append(node)
# 四个移动的方向
directions = ['up','down','left','right']
for direction in directions:
move_node = move(node, end, heuristic, direction)
if move_node:
if not node_in_list(move_node,openList):
if not node_in_list(move_node,closedList):
openList.append(move_node)
# 到达目标状态
if move_node.distance==0:
closedList.append(move_node)
complete = True
break
if complete:
break
# 提取开始状态到目标状态的所经历的状态
node = closedList.pop()
process_state = []
while node:
process_state.insert(0,(node.direction,node.state))
node = node.parent
return process_state
class Node:
state = None
distance = None
deep = None
value = None
parent = None
direction = None
def distance(state:list, end:list, heuristic='Manhattan'):
# 错位距离
distance = 0
if heuristic == 'misplace':
for i in range(9):
if state[i]!=end[i]:
distance += 1
return distance
# 曼哈顿距离
distance = 0
for num in range(1,9):
index = state.index(num) + 1
sta_row = index//3 if index%3==0 else index//3 + 1
sta_col = 3 if index%3==0 else index%3
index = end.index(num) + 1
end_row = index//3 if index%3==0 else index//3 + 1
end_col = 3 if index%3==0 else index%3
distance += abs(sta_col-end_col) + abs(sta_row-end_row)
return distance
# 空格移动
def move(last_node:Node, end, heuristic, direction=None):
if not direction: return None
node = deepcopy(last_node)
index = node.state.index(0)
# 判断是否能完成指定方向的移动
if direction=='up' and 0<=index<=2: return None
if direction=='down' and 6<=index<=8: return None
if direction=='left' and index in [0,3,6]: return None
if direction=='right' and index in [2,5,8]: return None
# 移动
if direction == 'up': step = -3
elif direction == 'down': step = 3
elif direction == 'left': step = -1
elif direction == 'right': step = 1
node.direction = direction
node.state[index] = node.state[index + step]
node.state[index+step] = 0
node.distance = distance(node.state, end, heuristic)
node.deep = node.deep + 1
node.value = node.distance + node.deep
node.parent = last_node
return node
def node_in_list(node:Node, nodeList:list):
state_list = [n.state for n in nodeList]
if node.state in state_list:
return True
else:
return False
def main(start,end):
show(start)
show(end)
start_time = time.time()
result_M = eight_digit(start,end)
end_time = time.time()
spend_time0 = round(end_time - start_time, 2)
start_time = time.time()
result_M = eight_digit(start,end,'misplace')
end_time = time.time()
spend_time1 = round(end_time - start_time, 2)
start_time = time.time()
result_ = eight_digit(start,end,'Manhattan')
end_time = time.time()
spend_time2 = round(end_time - start_time, 2)
print('非启发式搜索: ', 'step',len(result_M),'time', spend_time0,'s')
print('启发函数,错位距离: ','step',len(result_), 'time',spend_time1,'s')
print('启发函数,曼哈顿距离: ','step',len(result_M), 'time', spend_time2,'s')
start = [0,8,3,1,6,4,7,2,5]
end = [1,2,3,8,0,4,7,6,5]
main(start,end)