2016-09-28 5 views
2

적용 할 때 제거 얻을, 나는 객체는 내가 너무 설명받지 않고 더 나은 질문 제목을 공식화하는 방법을 알고하지 않았다 익스트라의 알고리즘 구현

어쨌든, 내 문제가 있습니다 ... 미리 미안 해요 수행원.

저는 List NodeList와 Unvisited라는 보조 목록을 가지고 있습니다.

나는 Dijkstra의 Pathfidning 알고리즘 구현 인 Unvisited 목록에서 GetPath 메서드를 사용합니다. 그러나 NodeList의 노드에 저장된 텍스처를 그릴 때 어떤 이상한 이유 때문에 일부 노드 (특히 그 사이의 경로를 추적하는 데 사용되는 노드)가 제거됩니다.

내가 노드는 심지어 내가 명확하게 방문하지 않은 동일 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

"하지만 노드 목록의 노드의 일부를 노드에 저장되어있는 텍스처를 그릴 몇 가지 이상한 이유 (특히, 경로를 추적하는 데 사용되는 노드). " 나는 그 문장의 끝을 놓치고 있다고 생각한다. 아마도 "제거"될까요? – RJFalconer

+0

노드가 제거 된 프로그램의 모든 위치를 나열하십시오. 그들 중 하나가 잘못된 목록에서 제거하고 있습니다. 이제 어느 것이 있는지 알아보십시오. –

+0

불변 목록을 사용하도록 알고리즘을 다시 작성하는 것이 좋습니다. 이는 목록 변이로 인한 버그가 결코 없도록하는 강력한 기술입니다. 목록 변이가 없습니다. –

답변

2

켜져 :

Unvisited = nodeList; 

T 모자가 문제이고, 전체 솔루션을 살펴 보았고 NodeList에서 노드가 제거되는 곳이 하나도 없다. 목록에서 제거하는 것이 Unvisited 목록에 있습니다. : s

이 할당 후에 Unvisited 목록에서 제거하면 nodeList에서 제거됩니다. List는 참조 유형이므로 할당을 통해 값을 변경하면 실제로 참조되는 객체가 변경됩니다. Unvisited와 nodeList는 모두 같은 객체를 참조합니다. 이를 방지하려면 동일한 참조에 두 목록을 이전 하나를 사용하는 대신 할당 새로운 목록을 인스턴스화 :

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

오 마이 갓! 고맙습니다! 그게 바로 문제였습니다! 나는 실제로 자신의 목록을 초기화하지 않으므로'NodeList'에서 삭제했습니다.설명 주셔서 감사합니다 :) –