所以我正在尝试制作BFS算法,并且我能够计算每2个节点之间的最短路径距离。但是每个节点(即节点A)的邻居不仅是节点,它是作为键的节点字典和每两个节点播放的匹配的哈希集。现在,我不知道如何在BFS中存储路径工作...这是一个返回每个节点的邻居的邻接函数
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;
}
}
}
}
所以,我需要的是去查看路径并读取hashset的值,例如节点A和节点B在3个匹配中一起播放匹配1,匹配2,匹配7所以这应该是路径。所以我要打印到控制台“路径是匹配1,匹配2还是匹配7。”同样的事情,如果我有2个节点没有在一个匹配中一起出现但是它们都与节点A一起出现在2个单独的匹配,所以路径应该通过这两个匹配中的任何一个。如何在操作BFS时跟踪路径并存储路径?这是我正在读取图形的文件。
我通过使用BFS实现了第一个目标(学位)。但现在我不知道如何实现“链条”或路径。链只是路径中电影的数量,所以我想如果我能够在BFS工作的时候保存路径(显示路径),我将能够实现链。所以我的问题是最后一个目标如何保存路径并显示它。
答案 0 :(得分:1)
为了找到从一个节点到另一个节点的最短路径,您可以跟踪每个节点的父节点。例如下面的图表,当我从0到9运行bfs时,我跟踪每个节点到达分配父节点。一旦分配了父母,我就不会重新分配。因此,例如,如果我想找到从0到9的路径和长度,我只需回溯即9-7-3-1-0,所以从9的父母开始并检查7的父母等等,直到你开始节点了。我们可以轻松地获得长度。
对于查询,当您执行类似C / E的操作时,您可以先运行bfs来检查路径&#34;它应该是2来自C-A-E&#34;当然可能有其他路径,但我想最短的路径是你想要的最好的路径? 无论如何,让我们假设我们选择路径C-A-E我们可以更新Rel。通过边数,所以Rel = 2,然后链
//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
父级只是节点的前身。例如,如果从0到1运行Bfs,那么0是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;
}