[英]Finding the shortest path between two points(bfs)
我有任务 我需要找到两点之间的最短路径。 为此,我使用广度优先搜索算法。 我创建了具有大量顶点和邻接表的Graph
类。 这是我的代码:
class Graph
{
private int V;
private LinkedList<Integer> adj[]; //Adjacency Lists
// Constructor
Graph(int v)
{
V = v;
adj = new LinkedList[v];
for (int i=0; i<v; ++i)
adj[i] = new LinkedList();
}
// Function to add an edge into the graph
void addEdge(int v,int w)
{
adj[v].add(w);
}
// prints BFS traversal from a given source s
void BFS(int s)
{
// Mark all the vertices as not visited(By default
// set as false)
boolean visited[] = new boolean[V];
// Create a queue for BFS
LinkedList<Integer> queue = new LinkedList<Integer>();
// Mark the current node as visited and enqueue it
visited[s]=true;
queue.add(s);
while (queue.size() != 0)
{
// Dequeue a vertex from queue and print it
s = queue.poll();
System.out.print(s+" ");
// Get all adjacent vertices of the dequeued vertex s
// If a adjacent has not been visited, then mark it
// visited and enqueue it
Iterator<Integer> i = adj[s].listIterator();
while (i.hasNext())
{
int n = i.next();
if (!visited[n])
{
visited[n] = true;
queue.add(n);
}
}
}
}
// Driver method to
public static void main(String args[])
{
Graph g = new Graph(8);
g.addEdge(0, 5);
g.addEdge(0, 7);
g.addEdge(1, 5);
g.addEdge(1, 4);
g.addEdge(1, 2);
g.addEdge(2, 1);
g.addEdge(2, 4);
g.addEdge(2, 3);
g.addEdge(3, 4);
g.addEdge(3, 2);
g.addEdge(4, 5);
g.addEdge(4, 1);
g.addEdge(4, 2);
g.addEdge(4, 3);
g.addEdge(5, 0);
g.addEdge(5, 1);
g.addEdge(5, 4);
g.addEdge(6, 7);
g.addEdge(7,6);
g.addEdge(7,0);
g.BFS(2);
g.BFS(2);
}
}
但是我需要打印从开始索引到结束的最短路径的函数。 我如何组织它。 请帮我。
我使用了递归,其中所有答案都将存储在arrayList中。
getPath(int from,int to,int current,字符串答案)
只需将此代码添加到Graph类。
public ArrayList<String> answers = new ArrayList<String>();
public void printShortAnswer() {
String realAnswer = "";
for (String answer : answers) {
if (realAnswer == "" || realAnswer.length() > answer.length()) {
realAnswer = answer;
}
}
System.err.println("The shortest path is: " + realAnswer);
}
//store all answers in answers
public boolean getPath(int from, int to, int current, String answer) {
boolean visited[] = new boolean[V];
visited[from] = true;
visited[current] = true;
if (current == to) {
answers.add(answer);
return true;
}
Iterator<Integer> i = adj[current].listIterator();
while (i.hasNext())
{
int n = i.next();
if (!visited[n])
{
visited[n] = true;
getPath(from, to, n, answer + " " + n);
}
}
return false;
}
要运行它,只需使用此设置
Graph g = new Graph(12);
g.addEdge(0, 1);
g.addEdge(0, 2);
//set 1
g.addEdge(1, 3);
g.addEdge(3, 4);
g.addEdge(4, 5);
//set 2
g.addEdge(2, 8);
g.addEdge(8, 9);
g.addEdge(9, 11);
g.addEdge(11, 5);
g.addEdge(0, 5);
//g.BFS(0);
int startPoint = 0;
g.getPath(startPoint, 5, startPoint, startPoint + " ");
g.printShortAnswer();
并且不要忘记导入ArrayList。
import java.util.ArrayList;
输出将是:
广度优先搜索在这里是合适的,因为当您第一次访问目标节点时,将通过最短路径进行搜索。 之所以可行,是因为所有边缘的权重均相同。1.如果边缘的权重不同,则边缘最少的路径不一定是最短的路径,并且您将需要其他算法,例如Dijkstra的 。
您的代码不会检查您是否已到达目的地; 它只是按照广度优先顺序访问所有节点。
您也不能随便打印节点,因为当您访问相邻的未访问节点时,您仍然不知道它是否是最短路径的一部分,或者您走错了方向。
一种解决方案是为每个顶点存储先前的顶点,即您来自的顶点。 例如,如果您从顶点0开始搜索,您将访问相邻的顶点5和7。因此,5和7的先前顶点均为0。
此信息可以起到双重作用:如果使用-1表示“无顶点”,则-1的前一个顶点表示尚未访问该顶点。
当您访问目的地时,只需通过先前节点的信息来追溯您的步骤,直到到达原始顶点。 此列表将是从目的地到起点的路径。
这是(我可怜的)Java中的实现:
import java.util.LinkedList;
import java.util.Iterator;
class Graph
{
private int V;
private LinkedList<Integer> adj[];
Graph(int v)
{
V = v;
adj = new LinkedList[v];
for (int i = 0; i < v; i++) {
adj[i] = new LinkedList();
}
}
void addEdge(int v, int w)
{
adj[v].add(w);
}
LinkedList shortest(int from, int to)
{
LinkedList<Integer> queue = new LinkedList<Integer>();
LinkedList<Integer> res = new LinkedList<Integer>();
int prev[] = new int[V];
if (from == to) return res;
queue.add(from);
for (int i = 0; i < V; i++) {
prev[i] = -1;
}
while (queue.size() != 0) {
int curr = queue.poll();
Iterator<Integer> i = adj[curr].listIterator();
while (i.hasNext()) {
int n = i.next();
if (prev[n] == -1) { // unvisited?
prev[n] = curr; // store previous vertex
if (n == to) { // we're finally there!
while (n != from) { // build result list ...
res.addFirst(n);
n = prev[n];
}
return res; // ... and return it
}
queue.add(n);
}
}
}
return res;
}
public static void main(String args[])
{
Graph g = new Graph(9);
g.addEdge(0, 5);
g.addEdge(0, 7);
g.addEdge(1, 5);
g.addEdge(1, 4);
g.addEdge(1, 2);
g.addEdge(2, 1);
g.addEdge(2, 4);
g.addEdge(2, 3);
g.addEdge(3, 4);
g.addEdge(3, 2);
g.addEdge(4, 5);
g.addEdge(4, 1);
g.addEdge(4, 2);
g.addEdge(4, 3);
g.addEdge(5, 0);
g.addEdge(5, 1);
g.addEdge(5, 4);
g.addEdge(6, 7);
g.addEdge(7,6);
g.addEdge(7,0);
for (int a = 0; a < 9; a++) {
System.out.print("--- ");
System.out.println(a);
for (int b = 0; b < 9; b++) {
System.out.println(g.shortest(a, b));
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.