Graph search

In many cases, we need to traverse the graph to get some properties of the graph. For example, it is a very common requirement to find out all vertices connected with the specified vertices in the graph, or to determine whether a vertex is connected with the specified vertices.

For graph search, the most classic algorithms are depth first search and breadth first search. Next, we will explain these two search algorithms respectively.

• Depth first search

Depth first search

Find the child node first, and then the brother node

• The so-called depth first search means that when searching, if a node has both child nodes and brother nodes, find the child nodes first and then the brother nodes.

Obviously, because the edge has no direction, if 4 and 5 vertices are connected, then 4 will appear in the adjacent list of 5 and 5 will also appear in the adjacent list of 4. In order not to search the vertices repeatedly, there should be corresponding marks to indicate whether the current vertex has been searched. You can use a Boolean array boolean[V] marked, and the index represents the vertex, The value represents whether the current vertex has been searched. If it has been searched, it is marked as true. If it has not been searched, it is marked as false;

code:

Figure Graph

```package graph;

import java.util.Queue;

public class Graph {
//Number of vertices
private final int V;
//Number of edges
private int E;

public Graph(int V){
//Number of initialization vertices
this.V = V;
//Number of initialization edges
this.E = 0;

for (int i = 0; i < adj.length; i++) {
}
}

//Gets the number of vertices
public int V(){
return V;
}

//Gets the number of edges
public int E(){
return E;
}

//Add an edge to the graph v-w
public void addEdge(int v, int w) {
//In an undirected graph, the edge has no direction, so the edge can be either an edge from V to w or an edge from w to v. therefore, it is necessary to make w appear in the adjacency table of V and V appear in the adjacency table of W

//Number of sides + 1
E++;

}

//Gets all vertices adjacent to vertex v
}

}

```

Depth first search - DepthFirstSearch

```package graph;

public class DepthFirstSearch {
//The index represents the vertex, and the value indicates whether the current vertex has been searched
private boolean[] marked;
//Record how many vertices are connected to the s vertex
private int count;

//Construct a depth first search object, and use depth first search to find all adjacent vertices of s vertex in G graph
public DepthFirstSearch(Graph G,int s){
//Initialize marked array
this.marked = new boolean[G.V()];
//Initializes the number of vertices communicating with vertex s
this.count=0;

dfs(G,s);
}

//Use depth first search to find all connected vertices of v vertices in G graph
private void dfs(Graph G, int v){
//Identify v vertices as searched
marked[v] = true;

for (Integer w : G.adj(v)) {
//Judge whether the current w vertex has been searched. If not, recursively call the dfs method for depth search
if (!marked[w]){
dfs(G,w);
}

}

//Number of connected vertices + 1
count++;
}

//Judge whether the w vertex is connected with the s vertex
public boolean marked(int w){
return marked[w];
}

//Gets the total number of all vertices connected to vertex s
public int count(){
return count;
}

}

```

test

```public class DepthFirstSearchTest {
public static void main(String[] args) {

//Preparing Graph objects
Graph G = new Graph(13);

//Prepare depth first search objects
DepthFirstSearch search = new DepthFirstSearch(G, 0);

//Test the number of vertices connected to a vertex
int count = search.count();
System.out.println("The number of vertices communicating with the starting point 0 is:"+count);

//Test whether a vertex is the same as the starting point
boolean marked1 = search.marked(5);
System.out.println("Whether vertex 5 and vertex 0 are connected:"+marked1);

boolean marked2 = search.marked(7);
System.out.println("Whether vertex 7 and vertex 0 are connected:"+marked2);

}
}

```

First find the sibling node, and then find the child node

• The so-called depth first search means that when searching, if a node has both child nodes and brother nodes, first find the brother nodes, and then find the child nodes.

Train of thought analysis:

Implementation steps:

1. Create a queue to store the nodes of each layer;
2. Use the loop to pop up a node from the queue:
3. Get the key of the current node;
4. If the left child node of the current node is not empty, the left child node is put into the queue
5. If the right child node of the current node is not empty, the right child node is put into the queue

code:

```package graph;

import java.util.Queue;

//The index represents the vertex, and the value indicates whether the current vertex has been searched
private boolean[] marked;
//Record how many vertices are connected to the s vertex
private int count;
//The point used to store the adjacency table to be searched
private Queue<Integer> waitSearch;

//Construct a breadth first search object, and use breadth first search to find all adjacent vertices of s vertex in G graph
public BreadthFirstSearch(Graph G, int s) {
this.marked = new boolean[G.V()];
this.count=0;

bfs(G,s);
}

//Use breadth first search to find all adjacent vertices of v vertex in G graph
private void bfs(Graph graph, int v){
//Identifies the current vertex v as searched
marked[v] = true;
//Let vertex v enter the queue to be searched
waitSearch.offer(v);
//Through the loop, if the queue is not empty, a vertex to be searched will pop up from the queue for search
while (!waitSearch.isEmpty()){
//Pop up a vertex to search
Integer wait = waitSearch.poll();

//Traversing the adjacency table of wait vertices
// The vertex has not been searched yet. Search it
if(!marked(w)){
marked[w] = true;
// The node is put on the stack for subsequent acquisition of the child nodes of the node
waitSearch.offer(w);
//Let the connected vertex + 1;
count++;
System.out.print( +w);
}
}
}
System.out.println();
}

//Judge whether the w vertex is connected with the s vertex
public boolean marked(int w) {
return marked[w];
}

//Gets the total number of all vertices connected to vertex s
public int count() {
return count;
}
}

```

Test:

```package graph;

public static void main(String[] args) {

//Preparing Graph objects
Graph G = new Graph(13);

//Test the number of vertices connected to a vertex
int count = search.count();
System.out.println("The number of vertices communicating with the starting point 0 is:"+count);

//Test whether a vertex is the same as the starting point
boolean marked1 = search.marked(5);
System.out.println("Whether vertex 5 and vertex 0 are connected:"+marked1);

boolean marked2 = search.marked(7);
System.out.println("Whether vertex 7 and vertex 0 are connected:"+marked2);

}
}

```

Case - unblocked project continued 1

• A province investigates the urban traffic conditions and obtains the statistical table of existing urban roads, which lists the cities and towns directly connected by each road. The goal of the provincial government's "unblocked project" is to enable any two cities and towns in the province to realize traffic (but there is not necessarily a direct road connection, as long as they can reach each other indirectly through the road). According to the current road conditions, are city 9 and city 10 connected? Are cities 9 and 8 interlinked?
• There is a trffic in our test data folder_ Project.txt file, which is the statistical table of Zhengzheng road. The following is the interpretation of the data:

Requirements:

• There are 20 cities in total. At present, 7 roads have been modified. Do cities 9 and 10 are connected? Are cities 9 and 8 interlinked?

Problem solving ideas:

1. Create a Graph object to represent the city;
3. Construct DepthFirstSearch object or BreadthFirstSearch object through Graph object and vertex 9;
4. By calling the marked(10) and marked(8) methods of the search object, we can get whether the 9 and city are connected with the 10 city and whether the 9 city is connected with the 8 city.

code:

```package graph;

public class Traffic_Project_Test2 {

public static void main(String[] args) throws Exception{

//Read the first row of data 20

//Build a Graph object
Graph G = new Graph(totalNumber);

//Read the second row of data 7
int v = Integer.parseInt(str[0]);
int w = Integer.parseInt(str[1]);
//Call the addEdge method of the graph to add an edge to the graph to represent the built road

}

//Build a depth first search object with the starting point set to vertex 9
DepthFirstSearch search = new DepthFirstSearch(G, 9);

//Call the marked method to judge whether the 8 vertices and 10 vertices are connected with the starting point 9
System.out.println("Whether vertex 8 and vertex 9 are connected:"+search.marked(8));
System.out.println("Whether vertex 10 and vertex 9 are connected:"+search.marked(10));

}
}

```

Path lookup

In real life, map is a tool we often use. Usually, we use it for navigation, enter a departure city and a destination city, and we can plan the route. On the planned route, we will pass through many middle cities. Such questions are translated into professional questions:

Requirements:

Is there a path from s vertex to v vertex? If so, find this path.

• For example, in the above figure, the path from vertex 0 to vertex 4 is marked in red, so we can represent the path as 0-2-3-4.

Train of thought analysis:

• When we implement path search, the most basic operation is to traverse and search the graph. Therefore, our implementation is based on depth first search for the time being. The search process is relatively simple. We added edgeTo [] integer array, which will record the path from each vertex to the starting point s.

If we set the vertex to 0, its search can be represented as the following figure:

According to the result of the final edgeTo, we can easily find the path from the starting point 0 to any vertex;

code:

DepthFirstPaths

```import java.util.Stack;

public class DepthFirstPaths {
//The index represents the vertex, and the value indicates whether the current vertex has been searched
private boolean[] marked;
//starting point
private int s;
//The index represents the vertex, and the value represents the last vertex on the path from the starting point s to the current vertex
private int[] edgeTo;

//Construct the depth first search object, and use the depth first search to find all paths with the starting point of s in the G graph
public DepthFirstPaths(Graph G, int s){
//Initialize marked array
this.marked = new boolean[G.V()];
//Initialization starting point
this.s = s;
//Initialize edgeTo array
this.edgeTo = new int[G.V()];

dfs(G,s);
}

//Use depth first search to find all adjacent vertices of v vertex in G graph
private void dfs(Graph G, int v){
//Represent v as searched
marked[v] = true;

//Traverse the adjacency table of vertex v, get each adjacent vertex, and continue the recursive search
for (Integer w : G.adj(v)) {
//If the vertex w is not searched, the recursive search continues

if (!marked[w]){
edgeTo[w] = v;//The last vertex on the path to vertex w is v
dfs(G,w);
}

}
}

//Judge whether there is a path between w vertex and s vertex
public boolean hasPathTo(int v){
return marked[v];
}

//Find the path from the starting point s to the vertex v (that is, the vertex through which the path passes)
public Stack<Integer> pathTo(int v){
if (!hasPathTo(v)){
return null;
}

//Create a stack object and save all vertices in the path
Stack<Integer> path = new Stack<>();

//Through the loop, start from vertex v and look forward until you find the starting point
for (int x = v; x!=s;x = edgeTo[x]){
path.push(x);
}

//Put the starting point s on the stack
path.push(s);

return path;
}

}
```

Test code

```package graph;

import java.util.Stack;

public class DepthFirstPathsTest {
public static void main(String[] args) throws Exception{

//Read the first row of data 6

//Build a Graph based on the first row of data
Graph G = new Graph(total);
//Read the second row of data 8
//Continue to read the two vertices associated with each edge through the loop, and call the addEdge method to add the edge
for (int i = 1;i<=edgeNumbers;i++){
String[] str = edge.split(" ");
int v = Integer.parseInt(str[0]);
int w = Integer.parseInt(str[1]);
}

//Build a path to find the object and set the starting point to 0
graph.DepthFirstPaths paths = new graph.DepthFirstPaths(G, 0);
//Call pathTo(4), find the path from start point 0 to end point 4, and return to Stack
Stack<Integer> path = paths.pathTo(4);
StringBuilder sb = new StringBuilder();
//Traversal stack object
for (Integer v : path) {
sb.append(v+"-");
}

sb.deleteCharAt(sb.length()-1);

System.out.println(sb);
}
}

```

Posted on Thu, 07 Oct 2021 02:02:16 -0400 by mamuni