字典键作为返回 KeyNotFoundError 的对象
我正在尝试在 Unity 中实现 Dijkstras 寻路算法。我有一个字典distances
,其中包含从GridData.WalkableNodes
获得的所有可能行走的节点。当尝试获取给定节点的已找到邻居的距离时,由于某种原因,我无法从 distances
字典中获取距离值。它给了我一个 KeyNotFoundError 。我是否做错了什么但使用 Node 对象作为键?在我的测试中,您可以使用对象作为从字典中检索值的键,因此我认为这不是问题。
脚本文件可以在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.js 时不起作用?
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;
}
}
I am trying to implement Dijkstras path finding algorithm in Unity. I have a dictionary distances
containing all the possible Nodes that can be walked on which is obtained from GridData.WalkableNodes
. When trying to obtain the distance of the found neighbours for a given Node, I am not able to obtain the distance value from the distances
dictionary for some reason. It gives me a KeyNotFoundError. Am I doing something wrong but using the Node object as the key? In my testing, you can use an Object as the key to retrieve a value from a dictionary so I do not think this is the issue.
Script files can be seen on 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);
}
}
}
If I use Vector3 instead of a Node as the key, it seems to work but I do not understand why it does not work when using 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);
}
}
}
Node class
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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您正在使用
new Node
来填充哈希图和列表。因此,这些新创建的
Node
当然与添加到字典中的实例不完全相同!它适用于
Vector3
因为它实现了IEquatable< ;Vector3>
以及GetHashCode
。如果您没有显式重写
Equals
,则默认情况下 使用引用相等(请参阅object.Equals
)您应该简单地使用位置作为键,因为正如您已经发现的那样,它已经实现了它。或者只需确保也实现它并使用该位置作为哈希代码提供程序:
如果您还想考虑其他属性,例如
Celltype
和Cost
等,并且可以 简单地扩展它。在同一位置有多个节点,您可以根据您的需要
You are using
new Node
to fill your hashmap and lists.Therefore these newly crated
Node
s are o course not the exact same instances as the ones added into your dictionary!It works for
Vector3
because it implementsIEquatable<Vector3>
and alsoGetHashCode
.If you don't explicitly override
Equals
then by default reference equality is used (seeobject.Equals
)You should either simply use the positions as keys since as you already figured out it already implements it. Or just make sure to implement it as well and use the position as hash code provider:
if you want to take the other properties like
Celltype
andCost
etc also into account and can have multiple nodes on the same position you can simply extend it doing e.g.according to your needs.