2016-09-28 58 views
2

的時候,我不知道如何更好制定問題的標題沒有得到太多的描述得到清除,我提前對不起......對象應用Dijkstra算法實現

總之,我的問題是以下。

我有一個List NodeList和一個名爲Unvisited的輔助列表。

我在未訪問列表上使用方法GetPath(這是Dijkstra的Pathfidning算法的實現)。但是由於某些奇怪的原因,當我繪製存儲在NodeList節點中的紋理時,一些節點(特別是用於跟蹤之間路徑的節點)被刪除。

我找了爲什麼節點不從節點列表刪除,甚至當我明確規定未訪問的節點列表相同...

編輯解釋:如果是缺少了解的問題的任何代碼,問及我會編輯!

相關代碼:

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 上的bug Without the pathfinder turned on 可視化表示沒有探路者開啓

+1

「但是,當我畫存儲在節點紋理NodeList中的一些節點的一些奇怪的原因(特別是用於追蹤之間路徑的節點)「。我想你錯過了那句話的結尾;也許「被刪除」? – RJFalconer

+0

列出程序中刪除節點的每個地方。其中之一是從錯誤的列表中刪除。現在弄清楚哪一個。 –

+0

您可能會考慮重寫您的算法以使用不可變列表;這是一種強大的技術,可以確保您永遠不會遇到由列表變異引起的錯誤;沒有列表突變。 –

回答

2

你的問題就在這裏:

Unvisited = nodeList; 

ŧ帽子是問題,我查看了整個解決方案,並且沒有一個地方將節點從NodeList中刪除。從列表中刪除的任何內容都來自未訪問列表...:s

在該分配之後,任何從未訪問列表中刪除都將從nodeList中刪除。 List是一個引用類型,所以當你用一個賦值改變它的值時,你真的正在改變它引用的對象。在此之後,Unvisited和nodeList都引用同一個對象。爲了避免這種情況,使用舊的,而不是分配兩個列表相同的參考實例化一個新的列表:

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

天啊!謝謝!這正是問題所在!我確實從來沒有初始化它自己的列表,因此我從'NodeList'中刪除。謝謝你的解釋:) –