如何计算2个顶点之间的所有最短路径?
How to count all of the shortest paths between 2 vertices?
因此,如果我在图中有两个顶点,并且它们通过一条以上的边连接,同时它们之间具有相同的最短路径(即,如果我有节点 A 和节点 B,并且它们通过三个边直接连接(它们之间有 3 条最短路径,每条距离为 1)所以计数应该 return 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;
}
}
}
}
在foreach
之前初始化一个变量int pathCount = 0;
然后,而不是 return;
增量 pathCount
。
在 foreach
之后,检查是否 pathCount > 0
,如果是,则 return。当然,您必须将 return 类型更改为 int
。
如果节点 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());
}
}
因此,如果我在图中有两个顶点,并且它们通过一条以上的边连接,同时它们之间具有相同的最短路径(即,如果我有节点 A 和节点 B,并且它们通过三个边直接连接(它们之间有 3 条最短路径,每条距离为 1)所以计数应该 return 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;
}
}
}
}
在foreach
之前初始化一个变量int pathCount = 0;
然后,而不是 return;
增量 pathCount
。
在 foreach
之后,检查是否 pathCount > 0
,如果是,则 return。当然,您必须将 return 类型更改为 int
。
如果节点 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());
}
}