Está en la página 1de 10

Informe sobre algoritmo de

Búsqueda en Amplitud
Objetivo
El objetivo de este documento es proporcionar una explicación
clara del algoritmo de Búsqueda en Amplitud y su implementación
en Python. El documento tiene como objetivo ilustrar la utilidad
del algoritmo en la resolución de problemas que involucren
encontrar el camino más corto entre dos nodos en un grafo.
Además, busca demostrar cómo funciona el algoritmo y
proporcionar una guía paso a paso para implementarlo en Python.

Problema

El problema a resolver es un puzzle lineal, con variación de


elementos y bidimensional, que debe ser ordenado.
De un estado aleatorio como por ejemplo 3 2 4 1 entonces el estado
final debe ser 1 2 3 4 .

Solución
La solución para poder resolver el problema es con el algoritmo
de búsqueda en amplitud, para ello hay que tener en cuenta el
espacio de los estados, los estados del puzzle (inicial y final)
y cuáles son las operaciones permite pasar de un estado a otro.

Informe sobre algoritmo de Búsqueda en Amplitud 1


Para calcular el espacio de los estados se debe tener en cuenta
que no se puede repetir y el orden importa sería 4! = 4 ∗ 3 ∗ 2 ∗
1 = 24

Herramientas
Para la implementación de los algoritmos, sin importar el tamaño
de los elementos, tiene código que no afecta directamente en el
funcionamiento.

Clase: Nodo
Es un objeto que permite relacionar jerárquicamente con otros
elementos similares

class Nodo:

def __init__(self, datos, hijos=None):

self.datos = datos
self.hijos = None
self.padre = None
self.coste= None

self.set_hijos(hijos)

def set_hijos(self, hijos):

self.hijos=hijos

if self.hijos != None:

for h in self.hijos:

h.padre = self

def get_hijos(self):

return self.hijos

def get_padre(self):

return self.padre

def set_padre(self, padre):

self.padre = padre

Informe sobre algoritmo de Búsqueda en Amplitud 2


def set_datos(self, datos):

self.datos = datos

def get_datos(self):

return self.datos

def set_coste(self, coste):

self.coste = coste

def get_coste(self):

return self.coste

def igual(self, nodo):

if self.get_datos() == nodo.get_datos():
return True
else:
return False

def en_lista(self, lista_nodos):

en_la_lista=False

for n in lista_nodos:

if self.igual(n):

en_la_lista=True

return en_la_lista

def __str__(self):

return str(self.get_datos())

Función crear estado


Es una función que crea el estado inicial del puzzle

Informe sobre algoritmo de Búsqueda en Amplitud 3


🗒 Para el estado lineal el uso de la función debe ser de la
siguiente manera:

# Desencapsulando la matriz
[estado_inicial] = crear_estado(4, 1)

from random import randint

def estado_inicial(ancho, alto):


estado = []

while len(estado) < ancho * alto:


nuevo_elemento = randint(1, ancho * alto)
if not nuevo_elemento in estado:
estado.append(nuevo_elemento)

matriz = []
contador = 0

for i in range(0, alto):


matriz.append([])
for j in range(0, ancho):
matriz[i].append(estado[contador])
contador += 1

return matriz

Función promedio
Es una función para promediar los pasos de cada tipo de puzzle

def promedio(elementos):
suma = 0

for elemento in elementos:


suma += elemento

return suma / len(elementos)

Implementación

Informe sobre algoritmo de Búsqueda en Amplitud 4


Ahora va las diferentes implementaciones de los algoritmos en
casos correspondientes del puzzle

Lineal

def buscar_solucion_BFS_lineal(estado_inicial, solucion):

solucionado=False

nodos_visitados=[]

nodos_frontera=[]

nodoInicial = Nodo(estado_inicial)

nodos_frontera.append(nodoInicial)

while (not solucionado) and len(nodos_frontera)!=0:

nodo=nodos_frontera.pop(0)

# extraer nodo y añadirlo a visitados

nodos_visitados.append(nodo)

if nodo.get_datos() == solucion:

# solucion encontrada

solucionado=True

return nodo

else:

# expandir nodos hijo

dato_nodo = nodo.get_datos()

# operador izquierdo

hijo = [dato_nodo[1], dato_nodo[0], dato_nodo[2], dato_nodo[3]]

hijo_izquierdo = Nodo(hijo)

if not hijo_izquierdo.en_lista(nodos_visitados) \
and not hijo_izquierdo.en_lista(nodos_frontera):

nodos_frontera.append(hijo_izquierdo)

# operador central

Informe sobre algoritmo de Búsqueda en Amplitud 5


hijo = [dato_nodo[0], dato_nodo[2], dato_nodo[1], dato_nodo[3]]

hijo_central = Nodo(hijo)

if not hijo_central.en_lista(nodos_visitados) \
and not hijo_central.en_lista(nodos_frontera):

nodos_frontera.append(hijo_central)

# operador derecho

hijo = [dato_nodo[0], dato_nodo[1], dato_nodo[3], dato_nodo[2]]

hijo_derecho = Nodo(hijo)

if not hijo_derecho.en_lista(nodos_visitados) \
and not hijo_derecho.en_lista(nodos_frontera):

nodos_frontera.append(hijo_derecho)

nodo.set_hijos([hijo_izquierdo, hijo_central, hijo_derecho])

Ampliado

def buscar_solucion_BFS_ambppliado(estado_inicial, solucion):

solucionado=False

nodos_visitados=[]

nodos_frontera=[]

nodoInicial = Nodo(estado_inicial)

nodos_frontera.append(nodoInicial)

while (not solucionado) and len(nodos_frontera)!=0:

nodo=nodos_frontera.pop(0)

# extraer nodo y añadirlo a visitados

nodos_visitados.append(nodo)

if nodo.get_datos() == solucion:

# solucion encontrada

solucionado=True

Informe sobre algoritmo de Búsqueda en Amplitud 6


return nodo

else:

# expandir nodos hijo

dato_nodo = nodo.get_datos()

# operador izquierdo externo

hijo = [dato_nodo[1], dato_nodo[0], dato_nodo[2], dato_nodo[3], dato_nodo[4], dato_n


odo[5]]

hijo_izquierdo_externo = Nodo(hijo)

if not hijo_izquierdo_externo.en_lista(nodos_visitados) \
and not hijo_izquierdo_externo.en_lista(nodos_frontera):

nodos_frontera.append(hijo_izquierdo_externo)

# operador izquierdo interno

hijo=[dato_nodo[0], dato_nodo[2], dato_nodo[1], dato_nodo[3], dato_nodo[4], dato_nod


o[5]]

hijo_izquierdo_interno = Nodo(hijo)

if not hijo_izquierdo_interno.en_lista(nodos_visitados) \
and not hijo_izquierdo_interno.en_lista(nodos_frontera):

nodos_frontera.append(hijo_izquierdo_interno)

# operador central

hijo=[dato_nodo[0], dato_nodo[1], dato_nodo[3], dato_nodo[2], dato_nodo[4], dato_nod


o[5]]

hijo_central = Nodo(hijo)

if not hijo_central.en_lista(nodos_visitados) \
and not hijo_central.en_lista(nodos_frontera):

nodos_frontera.append(hijo_central)

# operador derecho interno

hijo=[dato_nodo[0], dato_nodo[1], dato_nodo[3], dato_nodo[4], dato_nodo[2], dato_nod


o[5]]

hijo_derecho_interno = Nodo(hijo)

if not hijo_derecho_interno.en_lista(nodos_visitados) \
and not hijo_derecho_interno.en_lista(nodos_frontera):

Informe sobre algoritmo de Búsqueda en Amplitud 7


nodos_frontera.append(hijo_derecho_interno)

# operador derecho externo

hijo=[dato_nodo[0], dato_nodo[1], dato_nodo[3], dato_nodo[2], dato_nodo[5], dato_nod


o[4]]

hijo_derecho_externo = Nodo(hijo)

if not hijo_derecho_externo.en_lista(nodos_visitados) \
and not hijo_derecho_externo.en_lista(nodos_frontera):

nodos_frontera.append(hijo_derecho_externo)

nodo.set_hijos([hijo_izquierdo_externo, hijo_izquierdo_interno, hijo_central, hijo_d


erecho_interno, hijo_derecho_externo])

Bidimensional

def buscar_solucion_BFS_bid(estado_inicial, solucion):

solucionado=False

nodos_visitados=[]

nodos_frontera=[]

nodoInicial = Nodo(estado_inicial)

nodos_frontera.append(nodoInicial)

while (not solucionado) and len(nodos_frontera)!=0:

nodo=nodos_frontera.pop(0)

# extraer nodo y añadirlo a visitados

nodos_visitados.append(nodo)

if nodo.get_datos() == solucion:

# solucion encontrada
solucionado=True

return nodo

else:

# expandir nodos hijo

Informe sobre algoritmo de Búsqueda en Amplitud 8


dato_nodo = nodo.get_datos()

# operador 1
hijo=[[dato_nodo[0][1], dato_nodo[0][0]], [dato_nodo[1][0], dato_nodo[1][1]], [dato_
nodo[2][0], dato_nodo[2][1]]]
hijo_1 = Nodo(hijo)

if not hijo_1.en_lista(nodos_visitados) \
and not hijo_1.en_lista(nodos_frontera):
nodos_frontera.append(hijo_1)

# operador 2

hijo=[[dato_nodo[0][0], dato_nodo[1][0]], [dato_nodo[0][1], dato_nodo[1][1]], [dato_


nodo[2][0], dato_nodo[2][1]]]

hijo_2 = Nodo(hijo)

if not hijo_2.en_lista(nodos_visitados) \
and not hijo_2.en_lista(nodos_frontera):
nodos_frontera.append(hijo_2)

# operador 3

hijo=[[dato_nodo[0][0], dato_nodo[0][1]], [dato_nodo[1][1], dato_nodo[1][0]], [dato_


nodo[2][0], dato_nodo[2][1]]]

hijo_3 = Nodo(hijo)

if not hijo_3.en_lista(nodos_visitados) \
and not hijo_3.en_lista(nodos_frontera):
nodos_frontera.append(hijo_3)

# operador 4

hijo=[[dato_nodo[0][0], dato_nodo[0][1]], [dato_nodo[1][0], dato_nodo[2][0]], [dato_


nodo[1][1], dato_nodo[2][1]]]

hijo_4 = Nodo(hijo)

if not hijo_4.en_lista(nodos_visitados) \
and not hijo_4.en_lista(nodos_frontera):
nodos_frontera.append(hijo_4)

# operador 5

hijo=[[dato_nodo[0][0], dato_nodo[0][1]], [dato_nodo[1][0], dato_nodo[1][1]], [dato_


nodo[2][1], dato_nodo[2][0]]]

hijo_5 = Nodo(hijo)

if not hijo_5.en_lista(nodos_visitados) \
and not hijo_5.en_lista(nodos_frontera):
nodos_frontera.append(hijo_5)

Informe sobre algoritmo de Búsqueda en Amplitud 9


nodo.set_hijos([hijo_1, hijo_2, hijo_3, hijo_4, hijo_5])

Resultados

Tipo de puzzle Promedio

Normal (4 elementos) 2.5

Ampliado (6 elementos) 5.0

Bidimensional (2 x 4 elementos) 6.5

Informe sobre algoritmo de Búsqueda en Amplitud 10

También podría gustarte