2011-02-10 13 views
0

DijkstraのアルゴリズムをPythonで実装する必要があります。しかし、私は2D配列を使用して、前身、長さ、未訪問/訪問の3つの情報を保持する必要があります。 私はC言語で構造体を使うことができますが、私はPythonでこれと同様のことをすることができますが、それは可能だと言われていますが、正直であるとは思わないですPython - Dijkstraのアルゴリズム

+1

おそらく実際にはPythonを学ぶのに役立つでしょうか?基本的なデータ構造などしかし、私はあなたがその時間を持っていないと思います... – nikow

+0

私は少し前にPythonをやったことがありますが、データ構造に関してこのような「複雑な」状況だと感じたことは一度もありません。 – user612041

+0

Cスタイルのコンパクト2D配列で表現する必要がありますか?オブジェクトで行うことができれば、クラスとPythonの組み込みデータ構造を使用して、問題のドメインで言語がより適切に適合するようにすることができます。さもなければ、Cスタイルの構造で改造されたいくつかのハックアシストは避けられないでしょう。楽しいことではありません。 – Santa

答えて

1

前述したように、あなたは、オブジェクトのインスタンスを使用することができます。

この著者はPythonでDijkstrasをかなり説得力のある方法で実装しています。

# 
# This file contains the Python code from Program 16.16 of 
# "Data Structures and Algorithms 
# with Object-Oriented Design Patterns in Python" 
# by Bruno R. Preiss. 
# 
# Copyright (c) 2003 by Bruno R. Preiss, P.Eng. All rights reserved. 
# 
# http://www.brpreiss.com/books/opus7/programs/pgm16_16.txt 
# 
class Algorithms(object): 

    def DijkstrasAlgorithm(g, s): 
     n = g.numberOfVertices 
     table = Array(n) 
     for v in xrange(n): 
      table[v] = Algorithms.Entry() 
     table[s].distance = 0 
     queue = BinaryHeap(g.numberOfEdges) 
     queue.enqueue(Association(0, g[s])) 
     while not queue.isEmpty: 
      assoc = queue.dequeueMin() 
      v0 = assoc.value 
      if not table[v0.number].known: 
       table[v0.number].known = True 
       for e in v0.emanatingEdges: 
        v1 = e.mateOf(v0) 
        d = table[v0.number].distance + e.weight 
        if table[v1.number].distance > d: 

         table[v1.number].distance = d 
         table[v1.number].predecessor = v0.number 
         queue.enqueue(Association(d, v1)) 
     result = DigraphAsLists(n) 
     for v in xrange(n): 
      result.addVertex(v, table[v].distance) 
     for v in xrange(n): 
      if v != s: 
       result.addEdge(v, table[v].predecessor) 
     return result 
    DijkstrasAlgorithm = staticmethod(DijkstrasAlgorithm) 

通知がこれらの情報は、彼がAlgorithms.Entryを呼び出すことによって構築されたオブジェクトに「保有」しています()。エントリはクラスであり、次のように定義されています。

class Entry(object): 
    """ 
    Data structure used in Dijkstra's and Prim's algorithms. 
    """ 

    def __init__(self): 
     """ 
     (Algorithms.Entry) -> None 
     Constructor. 
     """ 
     self.known = False 
     self.distance = sys.maxint 
     self.predecessor = sys.maxint 

これらの情報は、これらの情報です。彼はコンストラクタ(init)でこれらを明示的に設定しませんが、後で設定します。 Pythonでは、ドット表記で属性にアクセスできます。 myObject = Entry()の場合は、次のようにします。 myObject.known、myObject.distance ...これらはすべてpublicです。

1

Pythonオブジェクトあなたは大丈夫でしょう。

2

クラスを作成します。 XXX = collections.namedtuple('XXX', 'predecessor length visited'):自分の行動が、名前のメンバーせずに構造体様化合物の種類を保持するための特別なクールです

class XXX(object): 
    def __init__(self, predecessor, length, visited): 
     self.predecessor = predecessor 
     self.length = length 
     self.visited = visited 

または使用をcollections.namedtuple、。

XXX(predecessor, length, visited)で1つを作成します。

0

Pythonはオブジェクト指向言語です。だから、C言語のStructsからC++のクラスに移行するのが好きです。 Pythonでも同じクラス構造を使うことができます。

1

それとも単にあなたの2次元配列内のタプルや辞書を使用することができます。

width=10 
height=10 

my2darray = [] 
for x in range(width): 
    my2darray[x]=[] 

for x in range(width): 
    for y in range(height): 
     #here you set the tuple 
     my2darray[x][y] = (n,l,v) 
     #or you can use a dict.. 
     my2darray[x][y] = dict(node=foo,length=12,visited=False) 
+2

構文の強調表示が示すように、識別子は数字で始めることはできません。 – delnan

関連する問題