如何显示 Bfs 的路径?
How do I show the path of Bfs?
所以我正在尝试制作 BFS 算法,并且能够计算出每 2 个节点之间的最短路径距离。但是每个节点(即节点 A)的邻居不仅是节点,它还是作为键的节点字典和每两个节点参与的匹配哈希集。现在,我不知道如何在 BFS 时存储路径正在工作...这是 returns 每个节点的邻居
的邻接函数
Dictionary<string, Dictionary<string, HashSet<string>>> dic= new Dictionary<string, Dictionary < string,, HashSet < string >>>;
public IEnumerable<KeyValuePair<string, HashSet<string>>> adjacentto(string v)
{
return dic[v];
}
这是我的 BFS 函数:
private Dictionary<string, int> dist = new Dictionary<string, int>();
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();
//count = 0;
foreach (KeyValuePair<string, HashSet<string>> h in g.adjacentto(j))
{
if (!dist.ContainsKey(h.Key))
{
q.Enqueue(h.Key);
dist.Add(h.Key, 1 + dist[j]);
}
if (j == p)
{
Console.WriteLine(" " + dist[j]);
return;
}
}
}
}
所以,我需要的是查看路径并读取哈希集的值,例如节点 A 和节点 B 在 3 场比赛中一起比赛,第 1 场、第 2 场、第 7 场,所以这应该是小路。所以我要打印到控制台“路径是匹配 1、匹配 2 或匹配 7”。如果我有 2 个节点没有一起参加比赛但他们都以节点 A 为主角2 个单独的匹配项,因此路径应该通过这 2 个匹配项中的任何一个。我如何在操作 BFS 时跟踪路径并存储路径?这是我从中读取图表的文件。
这就是我构建图表的方式
这就是我想要实现的
我通过使用 BFS 实现了第一个目标(学位)。但是现在我不知道如何实现 "chain" 或路径。链条只不过是路径中的电影数量,所以我认为如果我能够在 BFS 工作时保存路径(显示路径),我将能够实现链条。所以我的问题是最后一个目标如何保存路径并显示它。
为了找到从一个节点到另一个节点的最短路径,您可以跟踪每个节点的 parents。例如下图,当我 运行 bfs 从 0 到 9 时,我跟踪每个节点到达并分配一个 parent。一旦分配了 parent,我就不会重新分配。因此,例如,如果我想找到从 0 到 9 的路径和长度,我只需回溯即 9-7-3-1-0 所以从 9 的 parent 开始并检查 7 的 parent 等等,直到你开始节点。然后我们可以很容易地得到长度。
至于查询,当你做类似 C/E 的事情时,你可以先 运行 bfs 检查路径 "which should be 2 going from C-A-E" 当然可能还有其他路径,但我猜最短路径最适合您想要的东西?
无论如何,假设我们选择路径 C-A-E 我们可以更新 Rel。按边数,因此 Rel = 2 然后 Chain 将是
//Nodes -> [C, A, E]
//Parents ->[C, C, A]
Start from E // which is destination
Get movies of parent // parent is A, returns Movies 2
move to parent // now we are checking A
Get movies of parent // parent is C, returns Movies 1 Movies 7
break;
一到达源头就中断,反之亦然
最后你有电影 2,1 和 7
一个parent只是一个节点的前身。例如,当你 运行 Bfs 如果你从 0 到 1 那么 0 是 parent of 1
这是一个实现,希望能帮助您更好地理解它。
private Map<Integer, List<Integer>> _adjacencyList;
private Map<Integer, String> _movies; // will store neighbors here
private Queue<Integer> queue;
private int [] visited;
public BaconNumber(int V){// v here is number of vertices
_adjacencyList = new HashMap<Integer, List<Integer>>();
_movies = new HashMap<Integer, String>();
queue = new LinkedList<Integer>();
visited = new int[V];
for(int i = 0; i < V; i++){
_adjacencyList.put(i, new LinkedList<Integer>());// add a linkedlist for each vertex
visited[i] = -1;
}
}
在这里放电影
private void fillNeighbors(){
//0 = A, 1 = B, 2 = C, 3 = D, 4 = E
_movies.put(0, "Z Movie 0 | B Movie 1 Movie 2 Movie 7 | C Movie 1 Movie 7 | D Movie 2 Movie 7 | E Movie 2");
_movies.put(1, "A Movie 1 Movie 2 Movie 7 | C Movie 1 Movie 7 | D Movie 2 Movie 7 | E Movie 2");
_movies.put(2, "A Movie 1 Movie 7 | B Movie 1 Movie 7 | D Movie 7");
_movies.put(3, "E Movie 2 | A Movie 2 Movie 7 | B Movie 2 Movie 7 | C Movie 7");
_movies.put(4, "D Movie 2 | A Movie 2 | B Movie 2 | F Movie 3 | G Movie 3");
}
获取电影。这需要两个参数。一个用于我们从何处获取电影,另一个用于我们正在寻找的节点。请注意,我将第二个参数转换为一个字母,所以它看起来像你所拥有的
public String getMovies(int s, int v){
String result = "";
// just getting corresponding character
int rem = v % 26;
char l = (char)((int)'A' + rem);
//System.out.println("this is char "+l);
String movie = _movies.get(s);
String [] tokens = movie.split("\|");
for(int i = 0; i < tokens.length; i++){
String next = tokens[i];
if(next.contains(String.valueOf(l))){
result = next;
break;
}
}
return result;
}
现在是查询部分
String query(int source, int dest){
List<Integer> nodes = new LinkedList<Integer>();
int i, element;
visited[source] = source;
queue.add(source);
while(!queue.isEmpty()){
element = queue.remove();
i = element;
if(i == dest) break; // we stop as soon as we reach destination
nodes.add(element);
List<Integer> iList = getEdge(i);
System.out.println(i+" -> "+iList);
int x = 0;
while(x < iList.size()){
int index = iList.get(x);
if(visited[index] == -1){
queue.add(index);
visited[index] = i;
}
x++;
}
}
String result = "";
for(int x = dest; x >= 0; x= visited[x]){
if(x == source) break; // we are done
if(visited[x] != -1){
result += getMovies(x,visited[x]); // get predecessor of x movies from x
}
}
return result;
}
所以我正在尝试制作 BFS 算法,并且能够计算出每 2 个节点之间的最短路径距离。但是每个节点(即节点 A)的邻居不仅是节点,它还是作为键的节点字典和每两个节点参与的匹配哈希集。现在,我不知道如何在 BFS 时存储路径正在工作...这是 returns 每个节点的邻居
的邻接函数 Dictionary<string, Dictionary<string, HashSet<string>>> dic= new Dictionary<string, Dictionary < string,, HashSet < string >>>;
public IEnumerable<KeyValuePair<string, HashSet<string>>> adjacentto(string v)
{
return dic[v];
}
这是我的 BFS 函数:
private Dictionary<string, int> dist = new Dictionary<string, int>();
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();
//count = 0;
foreach (KeyValuePair<string, HashSet<string>> h in g.adjacentto(j))
{
if (!dist.ContainsKey(h.Key))
{
q.Enqueue(h.Key);
dist.Add(h.Key, 1 + dist[j]);
}
if (j == p)
{
Console.WriteLine(" " + dist[j]);
return;
}
}
}
}
所以,我需要的是查看路径并读取哈希集的值,例如节点 A 和节点 B 在 3 场比赛中一起比赛,第 1 场、第 2 场、第 7 场,所以这应该是小路。所以我要打印到控制台“路径是匹配 1、匹配 2 或匹配 7”。如果我有 2 个节点没有一起参加比赛但他们都以节点 A 为主角2 个单独的匹配项,因此路径应该通过这 2 个匹配项中的任何一个。我如何在操作 BFS 时跟踪路径并存储路径?这是我从中读取图表的文件。
这就是我构建图表的方式
这就是我想要实现的
我通过使用 BFS 实现了第一个目标(学位)。但是现在我不知道如何实现 "chain" 或路径。链条只不过是路径中的电影数量,所以我认为如果我能够在 BFS 工作时保存路径(显示路径),我将能够实现链条。所以我的问题是最后一个目标如何保存路径并显示它。
为了找到从一个节点到另一个节点的最短路径,您可以跟踪每个节点的 parents。例如下图,当我 运行 bfs 从 0 到 9 时,我跟踪每个节点到达并分配一个 parent。一旦分配了 parent,我就不会重新分配。因此,例如,如果我想找到从 0 到 9 的路径和长度,我只需回溯即 9-7-3-1-0 所以从 9 的 parent 开始并检查 7 的 parent 等等,直到你开始节点。然后我们可以很容易地得到长度。
至于查询,当你做类似 C/E 的事情时,你可以先 运行 bfs 检查路径 "which should be 2 going from C-A-E" 当然可能还有其他路径,但我猜最短路径最适合您想要的东西? 无论如何,假设我们选择路径 C-A-E 我们可以更新 Rel。按边数,因此 Rel = 2 然后 Chain 将是
//Nodes -> [C, A, E]
//Parents ->[C, C, A]
Start from E // which is destination
Get movies of parent // parent is A, returns Movies 2
move to parent // now we are checking A
Get movies of parent // parent is C, returns Movies 1 Movies 7
break;
一到达源头就中断,反之亦然 最后你有电影 2,1 和 7
一个parent只是一个节点的前身。例如,当你 运行 Bfs 如果你从 0 到 1 那么 0 是 parent of 1
这是一个实现,希望能帮助您更好地理解它。
private Map<Integer, List<Integer>> _adjacencyList;
private Map<Integer, String> _movies; // will store neighbors here
private Queue<Integer> queue;
private int [] visited;
public BaconNumber(int V){// v here is number of vertices
_adjacencyList = new HashMap<Integer, List<Integer>>();
_movies = new HashMap<Integer, String>();
queue = new LinkedList<Integer>();
visited = new int[V];
for(int i = 0; i < V; i++){
_adjacencyList.put(i, new LinkedList<Integer>());// add a linkedlist for each vertex
visited[i] = -1;
}
}
在这里放电影
private void fillNeighbors(){
//0 = A, 1 = B, 2 = C, 3 = D, 4 = E
_movies.put(0, "Z Movie 0 | B Movie 1 Movie 2 Movie 7 | C Movie 1 Movie 7 | D Movie 2 Movie 7 | E Movie 2");
_movies.put(1, "A Movie 1 Movie 2 Movie 7 | C Movie 1 Movie 7 | D Movie 2 Movie 7 | E Movie 2");
_movies.put(2, "A Movie 1 Movie 7 | B Movie 1 Movie 7 | D Movie 7");
_movies.put(3, "E Movie 2 | A Movie 2 Movie 7 | B Movie 2 Movie 7 | C Movie 7");
_movies.put(4, "D Movie 2 | A Movie 2 | B Movie 2 | F Movie 3 | G Movie 3");
}
获取电影。这需要两个参数。一个用于我们从何处获取电影,另一个用于我们正在寻找的节点。请注意,我将第二个参数转换为一个字母,所以它看起来像你所拥有的
public String getMovies(int s, int v){
String result = "";
// just getting corresponding character
int rem = v % 26;
char l = (char)((int)'A' + rem);
//System.out.println("this is char "+l);
String movie = _movies.get(s);
String [] tokens = movie.split("\|");
for(int i = 0; i < tokens.length; i++){
String next = tokens[i];
if(next.contains(String.valueOf(l))){
result = next;
break;
}
}
return result;
}
现在是查询部分
String query(int source, int dest){
List<Integer> nodes = new LinkedList<Integer>();
int i, element;
visited[source] = source;
queue.add(source);
while(!queue.isEmpty()){
element = queue.remove();
i = element;
if(i == dest) break; // we stop as soon as we reach destination
nodes.add(element);
List<Integer> iList = getEdge(i);
System.out.println(i+" -> "+iList);
int x = 0;
while(x < iList.size()){
int index = iList.get(x);
if(visited[index] == -1){
queue.add(index);
visited[index] = i;
}
x++;
}
}
String result = "";
for(int x = dest; x >= 0; x= visited[x]){
if(x == source) break; // we are done
if(visited[x] != -1){
result += getMovies(x,visited[x]); // get predecessor of x movies from x
}
}
return result;
}