2010-11-27 5 views
0

私はPythonに慣れようとしています。私はそのラクダのパズルを解決するだろうと思った。これはこれまでのコードです。私は現在いくつかの問題を抱えています:この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) 

私は今、いくつかの問題があります。

  1. さらに3つのデータフィールドを構成する必要があります。 g =現在の距離、f =合計値(ヒューリスティック値+ g)、p =親。これらすべてを含む構造を作るには?
  2. 指定されたフォーメーションが閉じたリストにあるかどうかを判断できる必要があります。効率的に。これを行う方法?

答えて

2

3つのデータフィールドが編成とともに必要です。 g =現在の距離、f =合計値(ヒューリスティック値+ g)、p =親。これらすべてを含む構造を作るには?

あなたは形成を表すためにクラスを使用する必要があります。それは、クラスのプロパティのように見えます(デコレータと呼ばれる)

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 

@property事は、以下の機能を変更します。これは、Pythonが明示的なアクセサメソッド(例えば、GetDistance()SetDistanceのようなもの)を気にしない理由です。すべてのプロパティをメソッドのように見せる代わりに、メソッドを必要に応じてプロパティのように見せます。したがって、編隊の総距離を得るには、theFormation.total_distanceと言うだけです。その後は()となります。

は、私はあなたが解決しようとしている問題に慣れていないんだけど、私はあなたのコードのいくつかのコメントを持っている:これは実際にはより良い標準ループとして実装されて

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

Formationクラスの別のプロパティとしてそれを書いていない:

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

リストを作成しない点は、(len()は発電機では動作しません)あなただけのアイテムをカウントしている場合。これはプロパティにすることもできます。 heuristicについて

は、あなたがelse: passを必要としない、あなたはセミコロンを定義され、1行に1つずつ割り当て行ってくださいません:getneighbors

@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 

を。 gennでは、list(...)はリストをコピーせず、指定されたものだけを取り出し、そこからリストを作成します。そのパラメータが既にリストである場合、何もせずに入力を返します。コピーを作成する場合は、from copy import copyを実行してからcopy関数を使用する必要があります。 (copyモジュールでdeep_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 

、1本のライン上の2つの割り当てを行うことは大丈夫です。

1
  1. dictを使用するとよいでしょう。
  2. 単一の値がリストにあるかどうかをテストする場合は、そのセットを使用できます。

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

しかし、あなたは順序が効率的にリストにあるかどうかをテストしたい場合は、文字列検索アルゴリズムのようないくつかのアルゴリズムを実装する必要があります。

関連する問題