【问题标题】:How to count all of the shortest paths between 2 vertices?如何计算两个顶点之间的所有最短路径?
【发布时间】:2016-03-26 17:59:03
【问题描述】:

因此,如果我在图中有两个顶点,并且它们通过多个边连接,而它们之间的最短路径相同(即,如果我有节点 A 和节点 B,并且它们直接通过三个边连接(有它们之间的距离是 3 条最短路径 1)所以计数应该返回 3)如何修改 BFS 算法来实现这一点?这是我的代码,它只计算 2 个节点之间的最短路径,而不是这些最短路径的数量。

public void BFSDegree(Graph g, string s, string p)
    {
        Queue<string> q = new Queue<string>();
        dist.Add(s, 0);       
        q.Enqueue(s);

        while (q.Count() != 0)
        {
            string j = q.Dequeue();
            foreach (string h in g.adjacentTo(j))
            {
                if (!dist.ContainsKey(h))
                {
                    q.Enqueue(h);
                    dist.Add(h, 1 + dist[j]);
                }

                if (j == p)
                {
                    Console.WriteLine("               " + dist[j]);
                    return;
                }
            }
        }
    }

【问题讨论】:

  • 看来,您当前执行return 的位置,您可以改为增加一个计数器,在while 之前设置为零,然后在while 之后使用该计数器值返回,如果计数器大于零。
  • 哟,看下面我的回答

标签: c# algorithm graph breadth-first-search


【解决方案1】:

如果节点 u 有 x 条最短路径,那么通过它发现的相邻节点 v 将有 x 次 y 最短路径,其中 y 是从 u 到 v 的边数。此外,如果 v 可以通过其他相邻节点到达节点(具有相同的路径长度),那么它的最短路径计数将是为每个父节点计算的所有 xy 因子的总和。

因此该算法将与您的原型完全不同。我会建议一个主循环,它在每次迭代中增加当前长度,然后通过查看队列中节点的所有未访问的相邻节点来处理队列,计算每个相邻节点的 xy 因子的总和,然后清除队列并将所有相邻节点排入队列(并将它们标记为可见)以进行下一次迭代。在第一次迭代中,路径长度为 0,队列只包含源节点。

public void BFSDegree(Graph g, string s, string p)
{
    Queue<string> q = new Queue<string>();
    HashMap<string, int> path_counts = new HashMap<string, int>();
    path_counts.put(s, 1);       
    q.Enqueue(s);

    while (q.size()>0)
    {
        HashMap<string, int> adj_nodes = new HashMap<string, int>();
        foreach (string j in q) 
        {
            foreach (string h in g.adjacentTo(j))
            {
                if (!path_counts.ContainsKey(h))
                {
                    int count = 0;
                    if (adj_nodes.containsKey(h))
                        count=adj_nodes.get(h);
                    count += path_counts.get(j);
                    adj_nodes.put(h, count);
                }
            }
        }
        if (adj_nodes.containsKey(p))
        {
            Console.WriteLine("               " + adj_nodes.get(p));
            return;
        }
        path_counts.putAll(adj_nodes);
        q.clear();
        q.addAll(adj_nodes.keySet());
    }
}

【讨论】:

  • 谢谢!我有一个问题,虽然我不熟悉 c# 中的 HashMaps,而且我不确定 c# 中是否存在 HashMap 类,我认为这段代码是用 java 编写的?但我知道它可以在 c# 中翻译为类 Dictionary 并且我能够翻译除 putAll 函数和 addAll 函数之外的所有函数,就像 Dictionary 类中是否有它们的等价物?
  • 是的,我在给出的代码片段中使用了 Java 集合,但您可以轻松转换为 C# - 请参见此处:stackoverflow.com/questions/3982448/…
  • 对于队列,您也可以做同样的事情(使用 foreach 循环将所有来自 adj_nodes 的键加入队列)。如果您觉得这个答案有用,请投票给它
【解决方案2】:

foreach之前,初始化一个变量int pathCount = 0;

然后,而不是 return; 增量 pathCount

foreach之后,检查是否pathCount &gt; 0,如果是,则返回。当然,您必须将返回类型更改为int

【讨论】:

  • 你看下面我的回答
猜你喜欢
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-30
  • 1970-01-01
相关资源
最近更新 更多