我正在嘗試在 Unity 中實作 Dijkstras 路徑查找演算法。我有一本字典distances,其中包含所有可能的節點,這些節點可以從GridData.WalkableNodes. distances在嘗試獲取給定節點的已找到鄰居的距離時,由于某種原因,我無法從字典中獲取距離值。它給了我一個 KeyNotFoundError。我做錯了什么但使用 Node 物件作為鍵?在我的測驗中,您可以使用 Object 作為鍵從字典中檢索值,所以我認為這不是問題所在。
腳本檔案可以在 pastebin GridData.cs Dijkstra.cs上看到
Dictionary<Node, int> distances = GridData.WalkableCells.ToDictionary(x => x, x => int.MaxValue);
foreach (Node neighbour in neighbours)
{
if (!visited.Contains(neighbour.Position))
{
int dist = distances[currentCell] 1;
if (dist < distances[neighbour]) // Key not found happens here!
{
distances[neighbour] = dist;
priorityQueue.Enqueue(neighbour, dist);
visited.Add(neighbour.Position);
neighbour.parentNode = currentCell;
parents.Add(neighbour);
}
}
}
如果我使用 Vector3 而不是 Node 作為鍵,它似乎可以作業,但我不明白為什么在使用 Node 時它不起作用。
Dictionary<Vector3, int> distances = GridData.WalkableCells.ToDictionary(x => x.Position, x => int.MaxValue);
foreach (Node neighbour in neighbours)
{
if (!visited.Contains(neighbour.Position))
{
int dist = distances[currentNode.Position] 1;
if (dist < distances[neighbour.Position])
{
distances[neighbour.Position] = dist;
priorityQueue.Enqueue(neighbour, dist);
visited.Add(neighbour.Position);
neighbour.parentNode = currentCell;
parents.Add(neighbour);
}
}
}
節點類
public class Node
{
public Vector3 Position { get; set; }
public CellType CellType { get; set; }
public int Cost { get; set; }
public Node parentNode {get; set;}
public Node(Vector3 position, CellType cellType, int cost)
{
Position = position;
CellType = cellType;
Cost = cost;
}
}
uj5u.com熱心網友回復:
您正在使用new Node填充您的哈希圖和串列。
因此,這些新創建Node的 s 當然與添加到您的字典中的實體并不完全相同!
它之所以有效,是Vector3因為它實作IEquatable<Vector3>了GetHashCode.
如果您沒有顯式覆寫Equals,則默認使用參考相等(請參閱參考資料object.Equals)
您應該簡單地將位置用作鍵,因為您已經發現它已經實作了它。或者只是確保也實作它并將該位置用作哈希碼提供者:
public class Node : IEquatable<Node>
{
public Vector3 Position { get; set; }
public CellType CellType { get; set; }
public int Cost { get; set; }
public Node parentNode {get; set;}
public Node(Vector3 position, CellType cellType, int cost)
{
Position = position;
CellType = cellType;
Cost = cost;
}
public override int GetHashCode()
{
return Position.GetHashCode();
}
public bool Equals(Node other)
{
if (ReferenceEquals(null, other))
{
return false;
}
if (ReferenceEquals(this, other))
{
return true;
}
return GetHashCode() == other.GetHashCode();
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != this.GetType())
{
return false;
}
return Equals((Node)obj);
}
}
如果您想考慮其他屬性,例如Celltype等Cost,并且可以在同一位置有多個節點,您可以簡單地擴展它,例如
public override int GetHashCode()
{
return HashCode.Combine(Position, Cost, CellType);
}
根據您的需要。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/432094.html
