美文网首页
爬山法实践

爬山法实践

作者: Nagi | 来源:发表于2017-12-17 16:41 被阅读13次

    人工智能将搜索定义为:从初态开始,找到一系列步骤,通过一组中间的搜索状态,到达预定义的终态。

    以9宫格数字滑块拼图为例:

    • 运算符就是每次可选的动作,即上下左右移动滑块;

    • 评估函数,就是离完成目标还有多少距离;

    • 终止标准,接近目标到一定程度,或者完成目标,或者行动步数、时间超过一定程度。

    • 初始评估函数1,简单为离终态的累计滑动数量之和。在例子中,需要219步才能完成。

    • 评估函数2,增加了数字加权,权值大优先滑动,优化后需要34步完成。

    import copy;
    
    #finalStatus = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]
    finalStatus = [[1, 2, 3], [8, 0 , 4], [7, 6, 5]]
    
    def distance1(number, line, index):
        distancef = 0
        for linef in range(len(finalStatus)):
            for indexf in range(len(finalStatus[linef])):
                numberf = finalStatus[linef][indexf]
                if numberf == number:
                    distancef = abs(line - linef) + abs(index - indexf)
                    break
            if distancef > 0:
                break
        return distancef
    
    def judgement1(status):
        length = 0
        for line in range(len(status)):
            for index in range(len(status[line])):
                number = status[line][index]
                if number != 0 and finalStatus[line][index] != number:
                    length = length + distance1(number, line, index)
        return length
    
    
    def distance2(number, line, index):
        distancef = 0
        for linef in range(len(finalStatus)):
            for indexf in range(len(finalStatus[linef])):
                numberf = finalStatus[linef][indexf]
                if numberf == number:
                    if number == 1:
                        distancef = (abs(line - linef) + abs(index - indexf)) * 10
                    elif number == 2 or number == 3:
                        distancef = (abs(line - linef) + abs(index - indexf)) * 5
                    elif number == 4 or number == 5:
                        distancef = (abs(line - linef) + abs(index - indexf)) * 2
                    else:
                        distancef = abs(line - linef) + abs(index - indexf)
                    break
            if distancef > 0:
                break
        return distancef
    
    def judgement2(status):
        length = 0
        for line in range(len(status)):
            for index in range(len(status[line])):
                number = status[line][index]
                if number != 0 and finalStatus[line][index] != number:
                    length = length + distance2(number, line, index)
        return length
    
    
    
    def new_status_from(status):
        status_list = []
        for line in range(len(status)):
            for index in range(len(status[line])):
                number = status[line][index]
                if number == 0:
                    if line != 0:
                        status_t = copy.deepcopy(status)
                        status_t[line][index] = status[line - 1][index]
                        status_t[line - 1][index] = 0
                        status_list.append(status_t)
                    if line != 2:
                        status_t = copy.deepcopy(status)
                        status_t[line][index] = status[line + 1][index]
                        status_t[line + 1][index] = 0
                        status_list.append(status_t)
                    if index != 0:
                        status_t = copy.deepcopy(status)
                        status_t[line][index] = status[line][index - 1]
                        status_t[line][index - 1] = 0
                        status_list.append(status_t)
                    if index != 2:
                        status_t = copy.deepcopy(status)
                        status_t[line][index] = status[line][index + 1]
                        status_t[line][index + 1] = 0
                        status_list.append(status_t)
                    break
        return status_list
    
    
    listTemp = []
    listSeen = []
    
    def is_new_move(status):
        if status in listSeen:
            return False
        else:
            return True
    
    
    #beginStatus = [[4, 3, 2], [1, 6, 5], [8, 0, 7]]
    beginStatus = [[0, 2, 1], [6, 7, 4], [3, 8, 5]]
    
    listTemp.append(beginStatus)
    while len(listTemp) > 0:
        print len(listSeen)
        status0 = listTemp[0]
        print status0[0]
        print status0[1]
        print status0[2]
        length = judgement1(status0)
        print length
        print '----------'
        if length <= 0:
            break
        else:
            listSeen.append(status0)
            listTemp.pop(0)
            status_list = new_status_from(status0)
            status_list = filter(is_new_move, status_list)
            for status in status_list:
                listTemp.append(status)
            listTemp = sorted(listTemp, key=lambda status: judgement2(status), reverse=False)
    

    相关文章

      网友评论

          本文标题:爬山法实践

          本文链接:https://www.haomeiwen.com/subject/qmikwxtx.html