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
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
bibliografía: