2010-11-27 6 views
0

J'essaie de me familiariser avec python. Je pensais résoudre ce puzzle de chameaux. C'est le code que j'ai jusqu'ici. J'ai quelques problèmes maintenant:Comment procéder avec ce programme python

fCamel = 'F' 
bCamel = 'B' 
gap = 'G' 

def solution(formation): 
    return len([i for i in formation[formation.index(fCamel) + 1:] if i == bCamel]) == 0 

def heuristic(formation): 
    fCamels, score = 0, 0 
    for i in formation: 
     if i == fCamel: 
      fCamels += 1; 
     elif i == bCamel: 
      score += fCamels; 
     else: 
      pass 
    return score 

def getneighbors (formation): 
    igap = formation.index(gap) 
    res = [[]] 
    # AB_CD --> A_BCD | ABC_D | B_ACD | ABD_C 
    def genn(i,j): 
     temp = list(formation) 
     temp[i], temp[j] = temp[j], temp[i] 
     res.append(temp) 

    if(igap > 0): 
     genn(igap, igap-1) 
    if(igap > 1): 
     genn(igap, igap-2) 
    if igap < len(formation) - 1: 
     genn(igap, igap+1) 
    if igap < len(formation) - 2: 
     genn(igap, igap+2) 

    return res 

def astar (formation, heuristicf, solutionf, getneighborsf): 
    openlist = [].append(formation) 
    closedlist = [] 

#Example usage (I think) 
#astar([fCamel, fCamel, fCamel, gap, bCamel, bCamel, bCamel], heuristic, solution, getneighbors) 

J'ai quelques problèmes maintenant.

  1. Je dois avoir 3 champs de données supplémentaires avec une formation. g = distance actuelle, f = valeur totale (valeur heuristique + g), p = parent. Comment faire une structure incluant tous ces éléments?
  2. Je dois être en mesure de déterminer si une formation donnée est dans la liste fermée. Efficacement. Comment faire ça?

Répondre

2

Je dois avoir 3 champs de données supplémentaires avec une formation. g = distance actuelle, f = valeur totale (valeur heuristique + g), p = parent. Comment faire une structure incluant tous ces éléments?

Vous devez utiliser une classe pour représenter une formation:

class Formation(object): 
    """A formation of camels.""" 
    def __init__(self, camels, parent): 
     self.camels = camels 
     self.current_distance = 0 
     self.parent = parent 

    @property 
    def total_distance(self): 
     """The total distance.""" 
     return self.current_distance + self.heuristic 

La chose @property (appelé décorateur) modifie la fonction suivante il ressemble à une propriété de la classe. C'est pourquoi Python ne se soucie pas des méthodes d'accès explicites (c'est-à-dire des choses comme GetDistance() et SetDistance); Au lieu de faire ressembler toutes les propriétés aux méthodes, vous faites que les méthodes ressemblent à des propriétés si nécessaire. Donc, pour obtenir la distance totale d'une formation, il suffit de dire theFormation.total_distance; pas () après.

Je ne connais pas le problème que vous essayez de résoudre, mais j'ai quelques commentaires sur votre code:

def solution(formation): 
    return len([i for i in formation[formation.index(fCamel) + 1:] if i == bCamel]) == 0 

Ceci est en fait mieux mis en œuvre en boucle standard. L'écriture comme une autre propriété de la classe Formation:

@property 
    def solution(self): 
     for camel in self.camels[self.camels.index(fCamel) + 1:]: 
      if camel == bCamel: 
       return False 
     return True 

Aucun point de créer une liste (len() ne fonctionnera pas sur un générateur) si vous êtes juste compter les articles. Cela peut également être fait une propriété.

En ce qui concerne heuristic, vous n'avez pas besoin else: pass, vous ne ned points-virgules, et s'il vous plaît faites une affectation par ligne:

@property 
    def heuristic(self): 
     fCamels = 0 
     score = 0 
     for camel in self.camels: 
      if camel == fCamel: 
       fCamels += 1 
      elif camel == bCamel: 
       score += fCamels 
     return score 

Sur à getneighbors. Dans genn, list(...) ne copie pas la liste, il prend juste ce qu'il est donné et en fait une liste.Si son paramètre est déjà une liste, alors il ne fait rien et retourne l'entrée. Si vous voulez faire une copie, vous devrez faire from copy import copy et ensuite utiliser la fonction copy. (Il y a aussi une fonction deep_copy dans le module copy.):

def copy_swapping_camels(self, i, j): 
     newCamels = copy(self.camels) 
     newCamels[i], newCamels[j] = newCamels[j], newCamels[i] 
     return Formation(newCamels, self) 

    def get_neighbors(self): 
     igap = self.camels.index(gap) 
     result = [[]] 

     if igap > 0: 
      result.append(self.copy_swapping_camels(igap, igap - 1)) 
     if igap > 1: 
      result.append(self.copy_swapping_camels(igap, igap - 2)) 
     if igap < len(self.camels) - 1: 
      result.append(self.copy_swapping_camels(igap, igap + 1)) 
     if igap < len(self.camels) - 2: 
      result.append(self.copy_swapping_camels(igap, igap + 2)) 

     return result 

Ici, faire deux missions sur une ligne est correct car il est un swap (les missions sont liées les unes aux autres).

1
  1. Vous pouvez utiliser dict.
  2. Si vous testez si une seule valeur figure dans une liste, vous pouvez utiliser l'ensemble.

    test_set = set(test_list) 
    if your_var in test_set: 
        # do something 
    

Mais si vous voulez vérifier si une séquence est dans une liste efficace, vous devez implémenter des algorithmes tels que des algorithmes de recherche de chaîne.

Questions connexes