2016-09-28 3 views
2

ダイクストラのアルゴリズムの実装を適用するとき、私はあまりにも記述取得せずに任意のより良い質問のタイトルを策定する方法を知りませんでした、私は事前にごめんなさい削除されます...リスト内のオブジェクト

とにかく、私の問題があります以下。

私はList NodeListとUnvisitedという二次リストを持っています。

私はUnijitedリスト(DijkstraのPathfidningアルゴリズムの実装です)でMethod GetPathを使用します。しかし、NodeListにノードに格納されているテクスチャを描画すると、ノードの一部(特に、その間のパスをトレースするノード)が削除されるという奇妙な理由があります。

私はノードでも、私ははっきりと未表示同等のNodeListを設定するとき...

EDITのNodeListから削除されます理由の説明を探しています:問題を理解するために不足している任意のコードがある場合は、尋ねると、私は編集します!

関連するコード:パスファインダーなしバグ Without the pathfinder turned on

public class Hotel 
{ 
    public List<Node> nodeList; 

     //constructor loadscontent and initialises list, ommitted here. 

    public void BuildHotel(ContentManager content) 
    { 
     for (int i = 0; i < 5; i++) 
     { 
      GuestRoom temp = new GuestRoom(100 + i, content, new Point(64 + (i * 64), 128), new Point(2, 1)); 
      nodeList.Add(new Node(temp, new Point(64 + (i * 64), 128))); 
     } 

     // add edges between some nodes 
     for (int i = 0; i < 4; i++) 
     { 
      AddEdge(nodeList[i].Room.RoomId, nodeList[i + 1].Room.RoomId, 2); 
     } 

     guest = new Guest(content); 
     guest.Setpath(100, 104, nodeList); 
    } 


} 
class PathFinding 
{ 
    public List<Node> Unvisited; 
    public List<Node> Visited; 
    private Stack<Node> _temp = new Stack<Node>(); 

    public Stack<Node> GetPath(int startroom, int finalroom, List<Node> nodeList) 
    { 
     Unvisited = nodeList; 
     Node startNode = Unvisited.DefaultIfEmpty(null).FirstOrDefault(x => x.Room.RoomId == startroom); 
     Node finalNode = Unvisited.DefaultIfEmpty(null).FirstOrDefault(x => x.Room.RoomId == finalroom); 

     if (startNode == null || finalNode == null) 
     { 
      Console.WriteLine("At least one of the nodes does not exist"); 
      return null; 
     } 

     startNode.Distance = 0; 

     Node currentNode = startNode; 

     while (!IsVisited(currentNode, finalNode)) 
     { 
      currentNode = Unvisited.Aggregate((l, r) => l.Distance < r.Distance ? l : r); 
     } 

     //reverse nodes in queue 
     Queue<Node> reversedqueue = MakePath(startNode, currentNode, finalNode); 
     for (int i = 0; i < MakePath(startNode, currentNode, finalNode).Count; i++) 
     { 
      _temp.Push(reversedqueue.Dequeue()); 
     } 
     return _temp; 
    } 
} 

public class SimulationScreen : Screen 
{ 
    private Hotel hotel; 
    //.. other methods ommited. 
    public override void Activate(bool instancePreserved) 
    { 
     if (!instancePreserved) 
     { 
      if (_content == null) 
       _content = new ContentManager(ScreenManager.Game.Services, "Content"); 

      ScreenManager.Game.ResetElapsedTime(); 
     } 
     hotel = new Hotel(_content); 
    } 
} 

Visual Representation on the bug 視覚的な表現は、あなたの問題はここで

+1

「しかし、私はのNodeList内のノードの一部をノードに保存されたテクスチャーを描くいくつかの奇妙な理由で(特に、間のパスをトレースするために使用されるノード)。私はあなたがその文の終わりを見逃していると思います。おそらく "取り除かれる"でしょうか? – RJFalconer

+0

ノードが削除されたプログラム内のすべての場所をリストします。そのうちの1人が間違ったリストから削除されています。今度はどれを見つけますか? –

+0

不変のリストを使用するようにアルゴリズムを書き直すことを検討するかもしれません。これは、リストの突然変異によって引き起こされるバグを決して起こさないための強力なテクニックです。リスト突然変異は存在しない。 –

答えて

2

オン:

Unvisited = nodeList; 

T帽子は問題ですが、私は自分のソリューション全体を見てきましたが、ノードがNodeList。_から削除される場所は1つではありません。リストからの削除は、Unvisitedリストからのものです。:s

この割り当ての後、Unvisitedリストから削除すると、nodeListから削除されます。 Listは参照型なので、代入でその値を変更すると、参照するオブジェクトが実際に変更されます。 UnvisitedとnodeListは両方とも同じオブジェクトを参照します。これを避けるために、同じ参照に両方のリストを古いものを使用してではなく、割り当てる新しいリストをインスタンス化:

Unvisited = new List<Node>(nodeList); 
+1

ああ私の神!ありがとうございました!それはまさに問題の原因です!私は本当に自分自身のリストを初期化していないので、 'NodeList'から削除しました。あまりにも説明をありがとう:) –

関連する問題