0

OpenGL を使用して、Python で体心立方結晶構造をシミュレートしたいと考えています。next_nodesノードが境界を満たしている場合は print を取得し、それ以外の場合は再帰的に返される次のノードを探すコードを作成しました。

しかし、コードには無限に実行されるという問題があります。誰でもこの問題を解決するのを手伝ってくれますか? 以下に関連するコードを投稿します (すべての OpenGL 呼び出しが削除されています)。

def get_node(x,y,z,side):
    return [x+side,y,z],[x,y+side,z],[x,y,z+side],[x-side,y,z],[x,y-side,z],[x,y,z-side]

def goto_next_nodes(x,y,z,cube_side,next_nodes,boundary_x,boundary_y,boundary_z):
    for node in next_nodes:
        if 0<=node[0]<=boundary_x and 0<=node[1]<=boundary_y and 0<=node[2]<=boundary_z:
             print node
             x,y,z=node[0],node[1],node[2]
             next_nodes=get_node(x,y,z,cube_side)
             goto_next_nodes(x,y,z,cube_side,next_nodes,boundary_x,boundary_y,boundary_z)
        else:
            return

def display_fcc(cube_side,boundary_x,boundary_y,boundary_z):
     x=y=z=0
     next_nodes=get_node(x,y,z,cube_side)
     goto_next_nodes(x,y,z,cube_side,next_nodes,boundary_x,boundary_y,boundary_z)

display_fcc(5,10,10,10)

display_fcc再帰は関数で始まりgoto_next_node、再帰関数です。

4

2 に答える 2

4

このコードのように、見たノードをメモすることができます。しかし、もう 1 つ修正する必要があると思います。

else:
    return

あなたの for はもう繰り返されないので、私は正しくないと思います。

def get_node(x, y, z, side):
    return [(x+side,y,z), (x,y+side,z), (x,y,z+side),
            (x-side,y,z), (x,y-side,z), (x,y,z-side)]

seen_nodes = set()

def goto_next_nodes(x, y, z, cube_side, next_nodes, boundary_x, boundary_y, boundary_z):
    for node in next_nodes:
        if node not in seen_nodes:
            seen_nodes.add(node)
            if 0<=node[0]<=boundary_x and 0<=node[1]<=boundary_y and 0<=node[2]<=boundary_z:
                 print node
                 x,y,z=node[0],node[1],node[2]
                 next_nodes=get_node(x,y,z,cube_side)
                 goto_next_nodes(x,y,z,cube_side,next_nodes,boundary_x,boundary_y,boundary_z)
    return

def display_fcc(cube_side,boundary_x,boundary_y,boundary_z):
     x=y=z=0
     next_nodes=get_node(x,y,z,cube_side)
     goto_next_nodes(x,y,z,cube_side,next_nodes,boundary_x,boundary_y,boundary_z)

display_fcc(5,10,10,10)
于 2012-08-28T10:33:27.817 に答える
4

関数next_nodeは から 1 ステップ離れたすべてのノードを返し(x,y,z)、次にgoto_next_node境界内にあるすべてのノードにアクセスします。しかし、ノードにアクセスしたときに、以前にそのノードにアクセスしたことがあるかどうかを確認することはありません。そのため、アルゴリズムは隅に行き詰まり、ぐるぐる回って、ノードのループを何度も何度も訪れます。出力を見ると、これがはっきりとわかります。

>>> display_fcc(5,10,10,10)
[5, 0, 0]
[10, 0, 0]
[5, 5, 0]
[10, 5, 0]
[5, 10, 0]
[10, 10, 0]
[5, 5, 5]
[10, 5, 5]
[5, 10, 5]
[10, 10, 5]
[5, 5, 10]
[10, 5, 10]
[5, 10, 10]
[10, 10, 10]
[0, 5, 5]  
[5, 5, 5]      # Oops: we've been here before!
[10, 5, 5]
[5, 10, 5]
[10, 10, 5]
[5, 5, 10]
[10, 5, 10]
[5, 10, 10]
[10, 10, 10]
[0, 5, 5]
[5, 5, 5]      # And around we go again.
...

そのため、どこに行ったかを追跡し、二度とそこに行かないようにする必要があります。

于 2012-08-28T10:29:14.017 に答える