everblut

A*

Feb 17th, 2013
2,376
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.74 KB | None | 0 0
  1. #!/usr/bin/python
  2. import sys
  3.  
  4. #####################################################################
  5. #####################CLASE AESTRELLA#################################
  6.  
  7. class AEstrella:
  8.     """
  9.    laberinto : laberinto en ASCII
  10.    pos_final : punto objetivo
  11.    inicio : Nodo que contiene el punto inicial
  12.    fin : Nodo que contiene el punto final
  13.    abierta : lista con caminos abiertos
  14.    cerrada : lista con caminos cerrados o inutiles
  15.    """
  16.     def __init__(self,laberinto):
  17.         self.laberinto = laberinto
  18.         self.pos_final = buscarPosicion('F',self.laberinto)
  19.         self.inicio = Nodo(self.pos_final,buscarPosicion('I',laberinto),None)
  20.         self.fin = Nodo(self.pos_final,self.pos_final,None)
  21.         self.abierta = []
  22.         self.cerrada = []
  23.         self.cerrada.append(self.inicio)
  24.         self.abierta += self.vecinos(self.inicio)
  25.         while self.objetivo():
  26.             self.buscar()
  27.         self.camino = self.camino()
  28.  
  29.  
  30.     #Devuelve una lista con vecinos transitables
  31.     def vecinos(self,nodo):
  32.         vecinos = []
  33.         try:
  34.             if self.laberinto[nodo.posicion[0]+1][nodo.posicion[1]] != '0':
  35.                 vecinos.append(Nodo(self.pos_final,[nodo.posicion[0]+1, nodo.posicion[1]],nodo))
  36.         except IndexError,e:
  37.             pass
  38.         try:
  39.             if self.laberinto[nodo.posicion[0]-1][nodo.posicion[1]] != '0':
  40.                 vecinos.append( Nodo(self.pos_final,[nodo.posicion[0]-1, nodo.posicion[1]],nodo))
  41.         except IndexError,e:
  42.             pass
  43.         try:
  44.             if self.laberinto[nodo.posicion[0]][nodo.posicion[1]-1] != '0':
  45.                 vecinos.append(Nodo(self.pos_final,[nodo.posicion[0], nodo.posicion[1]-1],nodo))
  46.         except IndexError,e:
  47.             pass
  48.         try:
  49.             if self.laberinto[nodo.posicion[0]][nodo.posicion[1]+1] != '0':
  50.                 vecinos.append( Nodo(self.pos_final,[nodo.posicion[0], nodo.posicion[1]+1],nodo))
  51.         except IndexError, e:
  52.             pass
  53.         return vecinos
  54.  
  55.     #Pasa el vecino con menor costo (G+H) a la lista cerrada
  56.     def f_menor(self):
  57.         actual = self.abierta[0]
  58.         n = 0
  59.         for i in range(1, len(self.abierta)):
  60.             if self.abierta[i].f < actual.f:
  61.                 actual = self.abierta[i]
  62.                 n = i
  63.         self.cerrada.append(self.abierta[n])
  64.         del self.abierta[n]
  65.  
  66.     #comprueba la existencia de un nodo en una lista
  67.     def exists(self,nodo,lista):
  68.         for i in range(len(lista)):
  69.             if nodo.posicion == lista[i].posicion:
  70.                 return True
  71.         return False
  72.  
  73.     #Se evaluan los movimientos buscando que los nodos esten en lista cerrada o abierta
  74.     #Si un nodo mejora el valor G del padre se comprueba en la lista abierta  y el padre se manda a la cerrada.
  75.     #Despues el nodo que contenia un mejor valor se manda a la lista abierta
  76.     def ruta(self):
  77.         for i in range(len(self.nodos)):
  78.             if self.exists(self.nodos[i], self.cerrada):
  79.                 continue
  80.             elif not self.exists(self.nodos[i], self.abierta):
  81.                 self.abierta.append(self.nodos[i])
  82.             else:
  83.                 if self.select.g+1 < self.nodos[i].g:
  84.                     for j in range(len(self.abierta)):
  85.                         if self.nodos[i].posicion == self.abierta[j].posicion:
  86.                             del self.abierta[j]
  87.                             self.abierta.append(self.nodos[i])
  88.                             break
  89.                    
  90.     # Analiza el elemento que recien se agrego a la lista cerrada es decir el nodo padre.
  91.     def buscar(self):
  92.         self.f_menor()
  93.         self.select = self.cerrada[-1]
  94.         self.nodos = self.vecinos(self.select)
  95.         self.ruta()
  96.  
  97.     #Comprueba si el objetivo esta en la lista abierta para terminar de buscar.
  98.     def objetivo(self):
  99.         for i in range(len(self.abierta)):
  100.             if self.fin.posicion == self.abierta[i].posicion:
  101.                 return False
  102.         return True
  103.  
  104.     #Retorna una lista con las posiciones del mejor camino a seguir
  105.     def camino(self):
  106.         print len(self.abierta)
  107.         for i in range(len(self.abierta)):
  108.             if self.fin.posicion == self.abierta[i].posicion:
  109.                 objetivo = self.abierta[i]
  110.         camino = []
  111.         while objetivo.padre != None:
  112.             camino.append(objetivo.posicion)
  113.             objetivo = objetivo.padre
  114.         camino.reverse()
  115.         return camino
  116. #####################################################################
  117.  
  118.  
  119. #####################################################################
  120. #####################CLASE Nodo######################################
  121.  
  122. class Nodo:
  123.     """
  124.    pos_final : punto objetivo
  125.    posicion : localizacion x,y del nodo
  126.    padre : Nodo padre
  127.    h : valor Heuristico, costo desde el nodo actual hasta el objetivo
  128.    g : valor g, costo desde el nodo inicial hasta el nodo actual
  129.    """
  130.     def __init__(self,pos_final,posicion=[0,0],padre=None):
  131.         self.posicion = posicion
  132.         self.padre = padre
  133.         self.h = manhattan(self.posicion,pos_final)
  134.         if self.padre == None:
  135.             self.g = 0
  136.         else:
  137.             self.g = self.padre.g + 1
  138.         self.f = self.g + self.h
  139.  
  140. #Calcula la distancia manhattan
  141. def manhattan(a,b):
  142.     return abs(a[0] - b[0]) + abs(a[1] - b[1])
  143.  
  144. #busca la posicion de X en el laberinto
  145. def buscarPosicion(x,laberinto):
  146.     for fila in range(len(laberinto)):
  147.         for columna in range(len(laberinto[0])):
  148.             if laberinto[fila][columna] == x:
  149.                 return [fila,columna]
  150.  
  151. #Para leer un archivo y crear el laberinto
  152. def leerArchivo(name):
  153.     archivo = open(name,'r')
  154.     laberinto = [linea.split() for linea in archivo.readlines()]
  155.     archivo.close()
  156.     return laberinto
  157.  
  158. #Escribe una ruta con caracteres ASCII en un archivo
  159. def escribirSolucion(camino,laberinto,name):
  160.     sname = "solucion_"+name
  161.     solucion = open(sname,'w')
  162.     for posicion in camino:
  163.         laberinto[ posicion[0]][ posicion[1]] = 'R'
  164.     for i in range(len(laberinto)):
  165.         linea = ""
  166.         for j in range(len(laberinto[0])):
  167.             linea = linea + laberinto[i][j] + " "
  168.         solucion.write(linea+"\n")
  169.     solucion.close()
  170.  
  171. # Toma un archivo con el laberinto en ASCII, imprime el inicio, el final y busca el mejor camino.
  172. # Por ultimo escribe un archivo con formato solucion_archivo.txt en donde escribe el mejor camino encontrado.
  173. def main():
  174.     name = sys.argv[1]
  175.     laberinto = leerArchivo(name)
  176.     print "inicio %s " % buscarPosicion('I',laberinto)
  177.     print "final %s " % buscarPosicion('F',laberinto)
  178.     algoritmo = AEstrella(laberinto)
  179.     escribirSolucion(algoritmo.camino,laberinto,name)
  180.  
  181. main()
Advertisement
Add Comment
Please, Sign In to add comment