C#中的节点/边缘寻路

问题描述

我的节点字典结构为:

Dictionary<int,List<int>> edges

您可以想象什么样的外观:

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,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;
    }
}

我想选择一个节点,并针对该节点测试大约2000个节点,以创建一个较大的距离列表。我最终得到一个像这样的列表:

Node Name|distance
Node1|1
Node2|2
Node3|2

技术上可行,但我的图形是:

  • 节点:5431
  • 优势:11962年

,它运行有点慢。我已经看到使用QuickGraph.Net库的建议,但是我似乎在文档方面找不到很多东西,而且我不太了解自己在读什么。

同样,我已经看到了针对基于C#的算法的一些“优化”建议,但是我还不够聪明,不足以理解它们的意思。

有人可以帮助您优化或建议替代方案吗?我的数据结构本身不是固定的,但我希望将其保持在理想的格式。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)