八数码--Astar--启发函数

作业笔记lgm:
八数码--Astar--启发函数_第1张图片

估价函数

f ( x ) = d e e p ( 搜 索 深 度 ) + d i s t a n c e ( 与 目 标 状 态 距 离 ) f(x)=deep(搜索深度)+distance(与目标状态距离) f(x)=deep()+distance()
distance: 曼哈顿距离,棋盘错位距离

1.主函数:实现八数码的求解:start,end,heuristic(启发函数)

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

2.结点Node数据类型

class Node:
    state = None
    distance = None
    deep = None
    value = None
    parent = None
    direction = None

3.距离

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

4.数码移动

# 空格移动
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

5.判断结点是否在list中

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

6.测试

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)

八数码--Astar--启发函数_第2张图片

你可能感兴趣的:(待分类,算法,python)