Difference between Prim's and Dijkstra's algorithms?

戏子无情 提交于 2019-11-28 15:04:16
templatetypedef

Prim's algorithm constructs a minimum spanning tree for the graph, which is a tree that connects all nodes in the graph and has the least total cost among all trees that connect all the nodes. However, the length of a path between any two nodes in the MST might not be the shortest path between those two nodes in the original graph. MSTs are useful, for example, if you wanted to physically wire up the nodes in the graph to provide electricity to them at the least total cost. It doesn't matter that the path length between two nodes might not be optimal, since all you care about is the fact that they're connected.

Dijkstra's algorithm constructs a shortest path tree starting from some source node. A shortest path tree is a tree that connects all nodes in the graph back to the source node and has the property that the length of any path from the source node to any other node in the graph is minimized. This is useful, for example, if you wanted to build a road network that made it as efficient as possible for everyone to get to some major important landmark. However, the shortest path tree is not guaranteed to be a minimum spanning tree, and the cost of building such a tree could be much larger than the cost of an MST.

Another important difference concerns what types of graphs the algorithms work on. Prim's algorithm works on undirected graphs only, since the concept of an MST assumes that graphs are inherently undirected. (There is something called a "minimum spanning arborescence" for directed graphs, but algorithms to find them are much more complicated). Dijkstra's algorithm will work fine on directed graphs, since shortest path trees can indeed be directed. Additionally, Dijkstra's algorithm does not necessarily yield the correct solution in graphs containing negative edge weights, while Prim's algorithm can handle this.

Hope this helps!

Dijkstra's algorithm doesn't create a MST, it finds the shortest path.

Consider this graph

       5     5
  s *-----*-----* t
     \         /
       -------
         9

The shortest path is 9, while the MST is a different 'path' at 10.

Prim and Dijkstra algorithm are almost the same, except for the "relax function".

In Prim:

MST-PRIM (G, w, r) {

        for each key ∈ G.V

            u.key = ∞
            u.parent = NIL

        r.key = 0
        Q = G.V
        while (Q ≠ ø)

            u = Extract-Min(Q)
            for each v ∈ G.Adj[u]

                if (v ∈ Q) and w(u,v) < v.key

                    v.parent = u
                    v.key = w(u,v)    <== relax function, Pay attention here

}

In Dijkstra:

Dijkstra (G, w, r) {

        for each key ∈ G.V

            u.key = ∞
            u.parent = NIL

        r.key = 0
        Q = G.V
        while (Q ≠ ø)

            u = Extract-Min(Q)
            for each v ∈ G.Adj[u]

                if (v ∈ Q) and w(u,v) < v.key

                    v.parent = u
                    v.key = w(u,v) + u.key  <== relax function, Pay attention here

}

The only difference is the last line of the code, which is the relax function. The Prim, which searches for the minimum spanning tree, only cares about the minimum of the total edges cover all the vertices. so it looks like: v.key = w(u,v) The Dijkstra, which searches for the minimum path length, so it cares about the edge accumulation. So it looks like :v.key = w(u,v) + u.key

Dijkstra finds the shortest path between it's beginning node and every other node. So in return you get the minimum distance tree from beginning node i.e. you can reach every other node as efficiently as possible.

Prims algorithm gets you the MST for a given graph i.e. a tree that connects all nodes while the sum of all costs is the minimum possible.

To make a story short with a realistic example:

  1. Dijkstra wants to know the shortest path to each destination point by saving traveling time and fuel.
  2. Prim wants to know how to efficiently deploy a train rail system i.e. saving material costs.

Directly from Dijkstra's Algorithm's wikipedia article:

The process that underlies Dijkstra's algorithm is similar to the greedy process used in Prim's algorithm. Prim's purpose is to find a minimum spanning tree that connects all nodes in the graph; Dijkstra is concerned with only two nodes. Prim's does not evaluate the total weight of the path from the starting node, only the individual path.

The key difference between the basic algorithms lies in their different edge-selection criteria. Generally, they both use a priority queue for selecting next nodes, but have different criteria to select the adjacent nodes of current processing nodes: Prim's Algorithm requires the next adjacent nodes must be also kept in the queue, while Dijkstra's Algorithm does not:

def dijkstra(g, s):
    q <- make_priority_queue(VERTEX.distance)
    for each vertex v in g.vertex:
        v.distance <- infinite
        v.predecessor ~> nil
        q.add(v)
    s.distance <- 0
    while not q.is_empty:
        u <- q.extract_min()
        for each adjacent vertex v of u:
            ...

def prim(g, s):
    q <- make_priority_queue(VERTEX.distance)
    for each vertex v in g.vertex:
        v.distance <- infinite
        v.predecessor ~> nil
        q.add(v)
    s.distance <- 0
    while not q.is_empty:
        u <- q.extract_min()
        for each adjacent vertex v of u:
            if v in q and weight(u, v) < v.distance:// <-------selection--------
            ...

The calculations of vertex.distance are the second different point.

The first distinction is that Dijkstra’s algorithm solves a different problem than Kruskal and Prim. Dijkstra solves the shortest path problem (from a specified node), while Kruskal and Prim finds a minimum-cost spanning tree. The following is a modified form of a description I wrote at this page: Graph algorithms.

For any graph, a spanning tree is a collection of edges sufficient to provide exactly one path between every pair of vertices. This restriction means that there can be no circuits formed by the chosen edges.

A minimum-cost spanning tree is one which has the smallest possible total weight (where weight represents cost or distance). There might be more than one such tree, but Prim and Kruskal are both guaranteed to find one of them.

For a specified vertex (say X), the shortest path tree is a spanning tree such that the path from X to any other vertex is as short as possible (i.e., has the minimum possible weight).

Prim and Dijkstra "grow" the tree out from a starting vertex. In other words, they have a "local" focus; at each step, we only consider those edges adjacent to previously chosen vertices, choosing the cheapest option which satisfies our needs. Meanwhile, Kruskal is a "global" algorithm, meaning that each edge is (greedily) chosen from the entire graph. (Actually, Dijkstra might be viewed as having some global aspect, as noted below.)

To find a minimum-cost spanning tree:

Kruskal (global approach): At each step, choose the cheapest available edge anywhere which does not violate the goal of creating a spanning tree. Prim (local approach): Choose a starting vertex. At each successive step, choose the cheapest available edge attached to any previously chosen vertex which does not violate the goal of creating a spanning tree. To find a shortest-path spanning tree:

Dijkstra: At each step, choose the edge attached to any previously chosen vertex (the local aspect) which makes the total distance from the starting vertex (the global aspect) as small as possible, and does not violate the goal of creating a spanning tree.

Minimum-cost trees and shortest-path trees are easily confused, as are the Prim and Dijkstra algorithms that solve them. Both algorithms "grow out" from the starting vertex, at each step choosing an edge which connects a vertex Y which is in the tree to a vertex Z which is not. However, while Prim chooses the cheapest such edge, Dijkstra chooses the edge which results in the shortest path from X to Z.

A simple illustration is helpful to understand the difference between these algorithms and the trees they produce. In the graph below, starting from the vertex A, both Prim and Dijkstra begin by choosing edge AB, and then adding edge BD. Here is where the two algorithms diverge: Prim completes the tree by adding edge DC, while Dijkstra adds either AC or BC, because paths A-C and A-B-C (both with total distance 30) are shorter than path A-B-D-C (total distance 31).

Dijkstras algorithm is used only to find shortest path.

In Minimum Spanning tree(Prim's or Kruskal's algorithm) you get minimum egdes with minimum edge value.

For example:- Consider a situation where you wan't to create a huge network for which u will be requiring a large number of wires so these counting of wire can be done using Minimum Spanning Tree(Prim's or Kruskal's algorithm) (i.e it will give you minimum number of wires to create huge wired network connection with minimum cost).

Whereas "Dijkstras algorithm" will be used to get the shortest path between two nodes while connecting any nodes with each other.

Shital Shah

@templatetypedef has covered difference between MST and shortest path. I've covered the algorithm difference in another So answer by demonstrating that both can be implemented using same generic algorithm that takes one more parameter as input: function f(u,v). The difference between Prim and Dijkstra's algorithm is simply which f(u,v) you use.

At the code level, the other difference is the API.

You initialize Prim with a source vertex, s, i.e., Prim.new(s); s can be any vertex, and regardless of s, the end result, which are the edges of the minimum spanning tree (MST) are the same. To get the MST edges, we call the method edges().

You initialize Dijkstra with a source vertex, s, i.e., Dijkstra.new(s) that you want to get shortest path/distance to all other vertices. The end results, which are the shortest path/distance from s to all other vertices; are different depending on the s. To get the shortest paths/distances from s to any vertex, v, we call the methods distanceTo(v) and pathTo(v) respectively.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!