C# C语言中的节点/边寻路#
我有以下节点的字典结构:C# C语言中的节点/边寻路#,c#,path-finding,C#,Path Finding,我有以下节点的字典结构: Dictionary<int, List<int>> edges 这在技术上是可行的,但我的图表是: 节点:5431 电话:11962 而且速度有点慢。我看到过使用QuickGraph.Net库的建议,但我似乎找不到太多文档,我也不太明白我在读什么 类似地,我也看到过一些针对基于C#的算法的“优化”建议,比如这样,但我还不够聪明,无法理解他们在说什么 有人能帮忙优化或建议替代方案吗?我的数据结构本身不是固定的,但我希望理想情况下保持这种格式
Dictionary<int, List<int>> edges
这在技术上是可行的,但我的图表是:
- 节点:5431
- 电话:11962
有人能帮忙优化或建议替代方案吗?我的数据结构本身不是固定的,但我希望理想情况下保持这种格式。有加权图吗?从存储它的数据结构来看,它不是。然后您不需要Dijkstra,尤其是它的这种缓慢实现(在每次迭代中排序),您可以从拾取的节点到每个输入节点运行BFS。
new Dictionary<int, List<int>>() {
{ "A" = new [] { "B", "C", "D" },
{ "B" = new [] { "A", "C" },
{ "C" = new [] { "A", "B" },
{ "D" = new [] { "A" },
}
public class Dijkstra<TNode>
{
/// <summary>
/// Calculates the shortest route from a source node to a target node given a set of nodes and connections. Will only work for graphs with non-negative path weights.
/// </summary>
/// <param name="connections">All the nodes, as well as the list of their connections.</param>
/// <param name="sourceNode">The node to start from.</param>
/// <param name="targetNode">The node we should seek.</param>
/// <param name="fnEquals">A function used for testing if two nodes are equal.</param>
/// <param name="fnDistance">A function used for calculating the distance/weight between two nodes.</param>
/// <returns>An ordered list of nodes from source->target giving the shortest path from the source to the target node. Returns null if no path is possible.</returns>
public static List<TNode> ShortestPath(IDictionary<TNode, List<TNode>> connections, TNode sourceNode, TNode targetNode, Func<TNode, TNode, bool> fnEquals, Func<TNode, TNode, double> fnDistance)
{
// Initialize values
Dictionary<TNode, double> distance = new Dictionary<TNode, double>(); ;
Dictionary<TNode, TNode> previous = new Dictionary<TNode, TNode>(); ;
List<TNode> localNodes = new List<TNode>();
// For all nodes, copy it to our local list as well as set it's distance to null as it's unknown
foreach (TNode node in connections.Keys)
{
localNodes.Add(node);
distance.Add(node, double.PositiveInfinity);
}
// We know the distance from source->source is 0 by definition
distance[sourceNode] = 0;
while (localNodes.Count > 0)
{
// Return and remove best vertex (that is, connection with minimum distance
TNode minNode = localNodes.OrderBy(n => distance[n]).First();
localNodes.Remove(minNode);
// Loop all connected nodes
foreach (TNode neighbor in connections[minNode])
{
// The positive distance between node and it's neighbor, added to the distance of the current node
double dist = distance[minNode] + fnDistance(minNode, neighbor);
if (dist < distance[neighbor])
{
distance[neighbor] = dist;
previous[neighbor] = minNode;
}
}
// If we're at the target node, break
if (fnEquals(minNode, targetNode))
break;
}
// Construct a list containing the complete path. We'll start by looking at the previous node of the target and then making our way to the beginning.
// We'll reverse it to get a source->target list instead of the other way around. The source node is manually added.
List<TNode> result = new List<TNode>();
TNode target = targetNode;
while (previous.ContainsKey(target))
{
result.Add(target);
target = previous[target];
}
result.Add(sourceNode);
result.Reverse();
if (result.Count > 1)
return result;
else
return null;
}
}
Node Name|Distance
Node1|1
Node2|2
Node3|2