Aprendizaje de inteligencia artificial: Python implementa un algoritmo de búsqueda que prioriza la amplitud

Aprendizaje de inteligencia artificial: Python implementa un algoritmo de búsqueda que prioriza la amplitud


Enlace del blog de este artículo:http://blog.csdn.net/jdh99 , autor: jdh, reimprimir, especifique.

 

alrededores:

Anfitrión: WIN10

Versión de Python: 3.5

Entorno de desarrollo: pyCharm


Descripción:
Aprenda "Un método moderno de inteligencia artificial" para escribir algoritmos basados ​​en la amplitud.
Código fuente del algoritmo en el libro:



Análisis de flujo de algoritmos:

estructura de datos:

  • frontera: el borde. Almacenar nodos no expandidos
  • explorado : Explora el set. El estado se almacena (tenga en cuenta que el algoritmo anterior es diferente)

Proceso:

  • Si el borde está vacío, devuelve falla. Operación: ¿VACÍO? (Frontera)
  • De lo contrario, seleccione un nodo hoja del borde. Operación: POP (frontera)
  • Ponga el estado del nodo hoja en el conjunto de exploración
  • Atraviesa todas las acciones de los nodos hoja
    • Cada acción genera nodos secundarios
    • Si el estado del nodo secundario no está en el conjunto de exploración o en el borde, entonces la prueba de destino: pasar
    • Si falla, ponlo en el borde. Operación: INSERT ( niño , frontera)

 

Nota: El algoritmo solo coloca el estado del nodo hoja en el conjunto de exploración antes de atravesar todas las acciones del nodo hoja, es decir, antes de la búsqueda de ancho. En el proceso de recorrido, si el nodo secundario no supera la prueba de destino, el estado del nodo secundario no se coloca en el conjunto de exploración, pero el nodo secundario se coloca en el borde y la siguiente ronda de recorrido se basa en el ancho del El nodo hijo está preparado.

 

 

Análisis de rendimiento de algoritmos:

  • completo
  • No es optimo
  • complejidad del tiempo:

Suponiendo que cada estado tiene b sucesores y la profundidad de la solución es d, el número total de nodos:

b + b ^ 2 + b ^ 3 +… + b ^ d = O (b ^ d)

El algoritmo anterior realiza la detección de objetivos cuando el nodo se expande en lugar de cuando se genera, por lo que la complejidad del tiempo debe ser O (b ^ (d + 1))

  • Complejidad espacial:

每个已扩展的节点都保存到探索集,探索集的节点数:O(b(d - 1)),边缘节点中:O(b^d)。所以控件复杂度为O(b^d),由边缘集所决定。

 




城市地图:




源码:

import pandas as pd
from pandas import Series, DataFrame

# 城市信息:city1 city2 path_cost
_city_info = None

# 按照路径消耗进行排序的FIFO,低路径消耗在前面
_frontier_priority = []


# 节点数据结构
class Node:
    def __init__(self, state, parent, action, path_cost):
        self.state = state
        self.parent = parent
        self.action = action
        self.path_cost = path_cost


def main():
    global _city_info
    import_city_info()

    while True:
        src_city = input('input src city\n')
        dst_city = input('input dst city\n')
        result = breadth_first_search(src_city, dst_city)
        if not result:
            print('from city: %s to city %s search failure' % (src_city, dst_city))
        else:
            print('from city: %s to city %s search success' % (src_city, dst_city))
            path = []
            while True:
                path.append(result.state)
                if result.parent is None:
                    break
                result = result.parent
            size = len(path)
            for i in range(size):
                if i < size - 1:
                    print('%s->' % path.pop(), end='')
                else:
                    print(path.pop())


def import_city_info():
    global _city_info
    data = [{'city1': 'Oradea', 'city2': 'Zerind', 'path_cost': 71},
            {'city1': 'Oradea', 'city2': 'Sibiu', 'path_cost': 151},
            {'city1': 'Zerind', 'city2': 'Arad', 'path_cost': 75},
            {'city1': 'Arad', 'city2': 'Sibiu', 'path_cost': 140},
            {'city1': 'Arad', 'city2': 'Timisoara', 'path_cost': 118},
            {'city1': 'Timisoara', 'city2': 'Lugoj', 'path_cost': 111},
            {'city1': 'Lugoj', 'city2': 'Mehadia', 'path_cost': 70},
            {'city1': 'Mehadia', 'city2': 'Drobeta', 'path_cost': 75},
            {'city1': 'Drobeta', 'city2': 'Craiova', 'path_cost': 120},
            {'city1': 'Sibiu', 'city2': 'Fagaras', 'path_cost': 99},
            {'city1': 'Sibiu', 'city2': 'Rimnicu Vilcea', 'path_cost': 80},
            {'city1': 'Rimnicu Vilcea', 'city2': 'Craiova', 'path_cost': 146},
            {'city1': 'Rimnicu Vilcea', 'city2': 'Pitesti', 'path_cost': 97},
            {'city1': 'Craiova', 'city2': 'Pitesti', 'path_cost': 138},
            {'city1': 'Fagaras', 'city2': 'Bucharest', 'path_cost': 211},
            {'city1': 'Pitesti', 'city2': 'Bucharest', 'path_cost': 101},
            {'city1': 'Bucharest', 'city2': 'Giurgiu', 'path_cost': 90},
            {'city1': 'Bucharest', 'city2': 'Urziceni', 'path_cost': 85},
            {'city1': 'Urziceni', 'city2': 'Vaslui', 'path_cost': 142},
            {'city1': 'Urziceni', 'city2': 'Hirsova', 'path_cost': 98},
            {'city1': 'Neamt', 'city2': 'Iasi', 'path_cost': 87},
            {'city1': 'Iasi', 'city2': 'Vaslui', 'path_cost': 92},
            {'city1': 'Hirsova', 'city2': 'Eforie', 'path_cost': 86}]

    _city_info = DataFrame(data, columns=['city1', 'city2', 'path_cost'])
    # print(_city_info)


def breadth_first_search(src_state, dst_state):
    global _city_info

    node = Node(src_state, None, None, 0)
    # 目标测试
    if node.state == dst_state:
        return node
    frontier = [node]
    explored = []

    while True:
        if len(frontier) == 0:
            return False
        node = frontier.pop(0)
        explored.append(node.state)
        if node.parent is not None:
            print('deal node:state:%s\tparent state:%s\tpath cost:%d' % (node.state, node.parent.state, node.path_cost))
        else:
            print('deal node:state:%s\tparent state:%s\tpath cost:%d' % (node.state, None, node.path_cost))

        # 遍历子节点
        for i in range(len(_city_info)):
            dst_city = ''
            if _city_info['city1'][i] == node.state:
                dst_city = _city_info['city2'][i]
            elif _city_info['city2'][i] == node.state:
                dst_city = _city_info['city1'][i]
            if dst_city == '':
                continue
            child = Node(dst_city, node, 'go', node.path_cost + _city_info['path_cost'][i])
            print('\tchild node:state:%s path cost:%d' % (child.state, child.path_cost))
            if child.state not in explored and not is_node_in_frontier(frontier, child):
                # 目标测试
                if child.state == dst_state:
                    print('\t\t this child is goal!')
                    return child
                frontier.append(child)
                print('\t\t add child to child')


def is_node_in_frontier(frontier, node):
    for x in frontier:
        if node.state == x.state:
            return True
    return False


if __name__ == '__main__':
    main()




 
     
 
     
利用算法求解:
input src city
Zerind
input dst city
Urziceni
deal node:state:Zerind parent state:None path cost:0
 child node:state:Oradea path cost:71
   add child to child
 child node:state:Arad path cost:75
   add child to child
deal node:state:Oradea parent state:Zerind path cost:71
 child node:state:Zerind path cost:142
 child node:state:Sibiu path cost:222
   add child to child
deal node:state:Arad parent state:Zerind path cost:75
 child node:state:Zerind path cost:150
 child node:state:Sibiu path cost:215
 child node:state:Timisoara path cost:193
   add child to child
deal node:state:Sibiu parent state:Oradea path cost:222
 child node:state:Oradea path cost:373
 child node:state:Arad path cost:362
 child node:state:Fagaras path cost:321
   add child to child
 child node:state:Rimnicu Vilcea path cost:302
   add child to child
deal node:state:Timisoara parent state:Arad path cost:193
 child node:state:Arad path cost:311
 child node:state:Lugoj path cost:304
   add child to child
deal node:state:Fagaras parent state:Sibiu path cost:321
 child node:state:Sibiu path cost:420
 child node:state:Bucharest path cost:532
   add child to child
deal node:state:Rimnicu Vilcea parent state:Sibiu path cost:302
 child node:state:Sibiu path cost:382
 child node:state:Craiova path cost:448
   add child to child
 child node:state:Pitesti path cost:399
   add child to child
deal node:state:Lugoj parent state:Timisoara path cost:304
 child node:state:Timisoara path cost:415
 child node:state:Mehadia path cost:374
   add child to child
deal node:state:Bucharest parent state:Fagaras path cost:532
 nodo hijo: estado: Fagaras costo de la ruta: 743
 nodo hijo: estado: costo de la ruta Pitesti: 633
 nodo secundario: estado: Giurgiu costo de la ruta: 622
   agregar un niño al
 niño nodo secundario: estado: Urziceni costo de la ruta: 617 ¡
   este niño es el objetivo!
desde ciudad: Zerind a ciudad Urziceni búsqueda exitosa
Zerind-> Oradea-> Sibiu-> Fagaras-> Bucarest-> Urziceni

La ruta óptima de Zerind a Urziceni debería ser Zerind-> Arad-> Sibiu-> Rimnicu Vilcea-> Pitesti-> Bucharest-> Urziceni, por lo que este algoritmo no es un algoritmo óptimo, sino solo una solución.


bibliografía:

1. "Un método moderno de inteligencia artificial"





Supongo que te gusta

Origin blog.csdn.net/jdh99/article/details/80851261
Recomendado
Clasificación