# -*- coding:utf-8 -*-
class Solution:
def salvePuzzle(self, init, targ):
''' 求解8数码问题
参数:
init - 初始状态 例如'123046758'
targ - 目标状态 均为'012345678'
返回值:
clf - 由udlr组成的移动路径字符串
'''
#请在这里补充代码,完成本关任务
#********** Begin **********#
clf = ''
state_open = []
state_close = []
state_open.append([init,99,'test',init,0])
fn = 2
flag = 1
while True:
cur_state = state_open.pop(0)
state_close.append(cur_state)
if cur_state[0] == targ :
while 1:
clf += cur_state[2]
if cur_state[3] == init:
break
for id,item in enumerate(state_close[1:]):
if item[0] == cur_state[3]:
cur_state = item
return clf[::-1]
i = cur_state[0].find('0')
flag = 1
if str(i) not in '036':
tmp_map = self.moveMap(cur_state[0],i,i-1)
if tmp_map not in [tmp[0] for tmp in state_close]:
for id,item in enumerate(state_open):
if item[0] == tmp_map:
if item[1] + item[4] > self.calcDistH(tmp_map,targ) + cur_state[4] + fn:
state_open[id] = [tmp_map,self.calcDistH(tmp_map,targ),'l',cur_state[0],cur_state[4]+fn]
flag = 0
break
break
if flag == 1:
state_open.append([tmp_map,self.calcDistH(tmp_map,targ),'l',cur_state[0],cur_state[4]+fn])
flag = 1
if str(i) not in '258':
tmp_map = self.moveMap(cur_state[0],i,i+1)
if tmp_map not in [tmp[0] for tmp in state_close]:
for id,item in enumerate(state_open):
if item[0] == tmp_map:
if item[1] + item[4] > self.calcDistH(tmp_map,targ) + cur_state[4] + fn:
state_open[id] = [tmp_map,self.calcDistH(tmp_map,targ),'r',cur_state[0],cur_state[4]+fn]
flag = 0
break
if flag ==1:
state_open.append([tmp_map,self.calcDistH(tmp_map,targ),'r',cur_state[0],cur_state[4]+fn])
flag = 1
if i-3>=0:
tmp_map = self.moveMap(cur_state[0],i,i-3)
if tmp_map not in [tmp[0] for tmp in state_close]:
for id,item in enumerate(state_open):
if item[0] == tmp_map:
if item[1] + item[4] > self.calcDistH(tmp_map,targ) + cur_state[4] + fn:
state_open[id] = [tmp_map,self.calcDistH(tmp_map,targ),'u',cur_state[0],cur_state[4]+fn]
flag = 0
break
if flag ==1:
state_open.append([tmp_map,self.calcDistH(tmp_map,targ),'u',cur_state[0],cur_state[4]+fn])
flag = 1
if i+3<=8:
tmp_map = self.moveMap(cur_state[0],i,i+3)
if tmp_map not in [tmp[0] for tmp in state_close]:
for id,item in enumerate(state_open):
if item[0] == tmp_map:
if item[1] + item[4] > self.calcDistH(tmp_map,targ) + cur_state[4] + fn:
state_open[id] = [tmp_map,self.calcDistH(tmp_map,targ),'d',cur_state[0],cur_state[4]+fn]
flag = 0
break
if flag ==1:
state_open.append([tmp_map,self.calcDistH(tmp_map,targ),'d',cur_state[0],cur_state[4]+fn])
state_open.sort(key=lambda x : x[1] + x[4])
#********** End **********#
def calcDistH(self, src_map, dest_map):
'''启发式函数h(n)
参数:
src_map - 当前8数码状态
dest_map - 目标8数码状态
返回值:
clf - 当前状态到目标状态的启发式函数值
'''
#请在这里补充代码,完成本关任务
#********** Begin **********#
distance = 0
for i in range(9):
if src_map[i] != '0':
current_pos = i
target_pos = dest_map.index(src_map[i])
distance += abs(current_pos//3 - target_pos//3) + abs(current_pos % 3 - target_pos % 3)
return distance
#current_pos // 3 表示的是current_pos所在的行
#current_pos % 3 表示的是current_pos所在的列
#以上式子表示的就是曼哈顿距离
#********** End **********#
def moveMap(self, cur_map, i, j):
'''状态转换(交换位置i和j)
参数:
cur_map - 当前8数码状态
i - 当前8数码状态中空格0的位置索引
j - 将空格0的位置i移动到位置j,位置j移动到位置i
返回值:
clf - 新的8数码状态
'''
#请在这里补充代码,完成本关任务
#********** Begin **********#
clf = list(cur_map) #将原来的数码状态转换为列表
lst[i],lst[j] = lst[j],lst[i] #进行交换
return ''.join(clf) #将交换后的列表合并 并返回
#********** End **********#