Data structure/graph theory: minimum path problem

Data structure/graph theory: minimum path problem

1. Problem description and classification

The shortest path problem (short-path problem) means that if each edge in the network has a number (weight) value (length, cost, time, etc.), then finding the total weight and the smallest path between two nodes is The shortest path problem.
●The classification of the shortest path problem: the shortest path problem with
known global information The shortest path problem with
known local information
The classification of the shortest path problem: the
shortest path in a
weighted graph The shortest path in a weighted graph has a weighted graph
with negative edges The shortest path
in the classification of the shortest path problem:
single source shortest path
global shortest path
two-point shortest path

Two, algorithm implementation

1. Dijkstra algorithm

Type of problem to be solved: Single source shortest path problem
Algorithm idea: The sub-path of the shortest path is still the shortest path. In order to find the shortest path, the algorithm increases the length of the shortest path and generates the shortest path successively.
(1) The characteristics of the shortest path with the shortest path length:
This path must contain only one arc, and the weight of this arc is the smallest.
(2) The characteristics of the shortest path with the next shortest path length:
It can only have two situations: either directly from the source point to the point (with only one arc); or from the source point through vertex v1 and then arrive The vertex (consisting of two arcs).
(3) The characteristics of the next shortest path with the next shortest path length:
It may have three situations: either directly from the source point to the point (with only one arc); or from the source point through the vertex V1, and then reach the point Vertex (composed of two arcs); or from the source point through vertex v2, and then to the vertex.
(4) The characteristics of the remaining shortest paths:
either directly from the source point to the point (with only one arc); or passing from the source point through the vertex of the shortest path that has been calculated. Reach the vertex again.

Pseudo code implementation:

// Compute shortest path distances from s,
// return them in D
void Dijkstra(Graph* G,int* D,int s)
{
    
    
	//对图G求从s出发到其他顶点的最短距离
	int i,v,w;
	for(i=0;i<G->n();i++)
	{
    
     // Do vertices
	v=minVertex(G,D);// 取目前未访问的距离最短的顶点
	if(D[v]==INFINITY) return;//不可达顶点
	G->setMark(v,VISITED);//加入S集合
	for (w=G->first(v);w<G->n();w= G->next(v,w))
	if(D[w]>(D[v]+G->weight(v,w)))
	D[w]=D[v]+G->weight(v,w);//若从源至W的路径经过V的距离更短,则更新最短距离
	}
}

minVertex function:

// Find min cost vertex寻找未访问的最短距离顶点
int minVertex(Graph* G,int* D)
{
    
    
	int i,V;
	// Set v to an unvisited vertex
	for(i=0;i<G->n();i++)
	if(G->getMark(i)==UNVISITED)
	{
    
    v=i;break;}
	// Now find smallest D va lue
	for(i++;i<G->n0;i++)
	if((G->getMark(i)==UNVISITED)&&(i<D[v1]))
	v=i;
	return V;
}

Algorithms implemented by priority queues:

void Dijkstra(Graph* G, int* D, ints)
{
    
    
	int i, v, w;
	// v is current vertex
	DijkElem temp;
	DijkElem E[G->e0]; // Heap array
	temp.distance=0;
	temp.vertex=s;
	E[0]=temp; // Initialize heap array
	minheap<DijkElem,DDComp> H(E,1,G->e0);
	for(i=0;i<G->n();i++)
	{
    
    // Get distances
	do
		{
    
    if(H.size()==0) return;//无数据可删除
		temp=H.removefirst();//取出第一一个元素,即最短距离
		V=temp.vertex;
		} while(G->getMark(v)==VISITED);
	G->setMark(v,VISITED);
	if(D[v]==INFINITY) return;//不可达顶点
	for(w=G->first(V);w<G->n();w=G->next(v,w))
	if (D[w]>(D[v]+G->weight(v, w))
	{
    
    // 更新D
	D[w]=D[v]+G->weight(v,w);
	temp.distance=D[w];
	temp.vertex=w;
	H.insert(temp); // Insert in heap
	}
}

Note: Djkstra algorithm is only suitable for graphs with non-negative weights.

2. Bellman-Ford algorithm

Type of problem to be solved: Single source shortest path problem
Algorithm idea: Construct a shortest path length array sequence dist1 [u], dist2 [u],..., dist n-1 [u]. Among them, dist1 [u] is the length of the shortest path from the source point v to the end point u passing through only one edge, dist1 [u] = Edge[v][u]; dist2 [u] is the length of the shortest path from the source point v through at most two The length of the shortest path from the edge to the end point u, dist3 [u] is the length of the shortest path from the source point v through at most three edges that do not form an edge loop with negative length to the end point u, ..., dist n-1 [u ] Is the length of the shortest path starting from the source point v through at most n-1 edges that do not form a side loop with negative length to the end point u.
Assuming that distk1[i], j=0, 1,...n-1 has been calculated, this is the length of the shortest path from the source point v through k-1 edges that do not form a side loop with negative length to the end point j.
From the adjacency matrix of the graph, we can find the distance Edge[j][u] from each vertex j to the vertex u, calculate min {dist k-1 [j] + Edge[j][u]}, we can get from the source point v Bypassing each vertex, the length of the shortest path to the end point u through k edges that do not constitute an edge loop with negative length at most.
Use it to compare with dist k-1 [u], and take the smaller as the value of dist k [u].

Pseudo code implementation:

void Graph::BellmanFord ( const int n, const int v )
{
    
    
	//在带权有向图中有的边具有负的权值。从顶点V找到所有其它顶点的最短路径
	for( int i=0;i<n;i++ )
	{
    
    dist[i]=Edge[v][i];
	if(i!=v&&dist[i]<MAXINT)
	path[i]=V;
	else path[i]=-1;
	}
	for(int k=2;k<n;k++)
	for(int u=0;u<n;u++)
	if(u!=v)
		for(i=0;i<n;i++ )
			if(Edge[i][u]>0 && Edge[i][u]<MAXINT && dist[u]>dist[i]+Edge[i][u])
			{
    
    dist[u]=dist[i]+Edge[i][u];
			path[u]=i;
			}
}

Note: The Bellman-Ford algorithm is suitable for graphs with negative weights.

3. Floyd algorithm

Type of problem to be solved: the shortest path problem of all sources.
Algorithm idea:
(1) Define k-path as any path from vertex v to u, with the intermediate vertex number less than k. 0-path is the edge directly from v to u.
(2) Define Dk(v, u) as the length of the smallest k-path
from v to u (3) Assuming the shortest k-path path from v to u is known, then the shortest (k+1)-path Passing or not passing vertex k:
If it passes vertex k, part of the shortest (k+1)-path is the shortest k-path from v to k, and the other part is the shortest k-path from k to u.
Otherwise, keep its value as the shortest k-path unchanged.

Pseudo code implementation:

//Floyd's all-pairs shortest paths algorithm
void Floyd(Graph* G)
{
    
    
	int D[G->n()][G->n()]; // Store distances
	for(int i=0;i<G->n();i++) // Initialize
	for(int j=0;j<G->n();j++)
	D[i][j]=G->weight(i,j); // Compute all k paths
	for(int k=0;k<G->n();k++)
	for(int i=0;i<G->n();i++)
	for(int j=0;j<G->n();j++)
	if(D[i][j]>(D[i][k]+D[k][j]))
	D[i][j]=D[i][k]+D[k][j];
}

Note: Floyd algorithm is also suitable for graphs with negative weights.

Guess you like

Origin blog.csdn.net/hyl1181/article/details/107780194