Разница между алгоритмами Прима и Дейкстры?

Какова точная разница между алгоритмами Дейкстры и Прима? Я знаю, что Prim даст MST, но дерево, созданное Dijkstra, также будет MST. Тогда какова же разница?

Ответ 1

Алгоритм Prim создает минимальное связующее дерево для графа, который является деревом, которое соединяет все узлы в графе и имеет наименьшую общую стоимость среди всех деревьев, соединяющих все узлы. Однако длина пути между любыми двумя узлами в MST может быть не кратчайшим путем между этими двумя узлами в исходном графе. MST полезны, например, если вы хотите физически подключить узлы на графике, чтобы обеспечить электроэнергию им по меньшей мере общей стоимости. Не имеет значения, что длина пути между двумя узлами может быть не оптимальной, поскольку все, о чем вы заботитесь, это факт, что они связаны.

Алгоритм Dijkstra создает кратчайшее дерево путей, начиная с некоторого источника node. Самое короткое дерево путей - это дерево, которое соединяет все узлы в графике с исходным текстом node и обладает тем свойством, что длина любого пути от источника node до любого другого node на графике минимизируется. Это полезно, например, если вы хотите построить дорожную сеть, которая сделала ее максимально эффективной для всех, чтобы добраться до какого-то важного важного ориентира. Однако кратчайшее дерево путей не гарантируется как минимальное связующее дерево, а стоимость построения такого дерева может быть намного больше, чем стоимость MST.

Другое важное различие касается типов графиков, над которыми работают алгоритмы. Алгоритм Prim работает только с неориентированными графами, так как концепция MST предполагает, что графики по своей природе неориентированы. (Для ориентированных графов есть что-то, называемое "минимальным охватывающим arborescence", но алгоритмы их поиска намного сложнее). Алгоритм Дейкстры отлично работает на ориентированных графах, поскольку кратчайшие пути деревьев действительно могут быть направлены. Кроме того, алгоритм Дейкстры не обязательно дает правильное решение в графах, содержащих отрицательные веса границ, в то время как алгоритм Prim может справиться с этим.

Надеюсь, это поможет!

Ответ 2

Алгоритм Дейкстры не создает MST, он находит кратчайший путь.

Рассмотрим этот график

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

Самый короткий путь - 9, а MST - другой "путь" в 10.

Ответ 3

Алгоритм Прима и Дейкстры почти одинаковы, кроме "функции релаксации".

В 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

}

В Дейкстре:

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

}

Единственное различие - последняя строка кода, которая является функцией релаксации. Prim, который ищет минимальное остовное дерево, заботится только о том, что минимум всех ребер покрывает все вершины. поэтому он выглядит так: v.key = w (u, v) Dijkstra, которая ищет минимальную длину пути, поэтому она заботится о накоплении края. Так выглядит: v.key = w (u, v) + u.key

Ответ 4

Dijkstra находит самый короткий путь между ним, начиная с nodeи все остальные node. Поэтому взамен вы получаете минимальное расстояние от начала node, то есть вы можете максимально эффективно использовать любой другой node.

Алгоритм Prims дает вам MST для заданного графика, то есть дерева, которое соединяет все узлы, в то время как сумма всех затрат минимальна.

Чтобы сделать рассказ коротким с реалистичным примером:

  • Dijkstra хочет знать кратчайший путь к каждой точке назначения, экономя время в пути и топливо.
  • Prim хочет знать, как эффективно развернуть систему железнодорожных поездов, т.е. экономить материальные затраты.

Ответ 5

Непосредственно из статьи в Википедии Dijkstra Algorithm's:

Процесс, лежащий в основе алгоритма Дейкстры, похож на жадный процесс, используемый в алгоритме Прима. Цель Prim - найти минимальное связующее дерево, которое связывает все узлы в графике; Дейкстра занимается только двумя узлами. Prim не оценивает общий вес пути от начального node, только отдельный путь.

Ответ 6

Ключевое различие между основными алгоритмами заключается в их различных критериях выбора края. Как правило, они используют приоритетную очередь для выбора следующих узлов, но имеют разные критерии для выбора соседних узлов текущих узлов обработки: Prim Algorithm требует, чтобы следующие соседние узлы также содержались в очереди, а Dijkstra Algorithm:

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--------
            ...

Вычисления vertex.distance - вторая точка.

Ответ 7

@templatetypedef охватывает разницу между MST и кратчайшим путем. Я рассмотрел разницу в алгоритме другой так ответ, продемонстрировав, что оба варианта могут быть реализованы с использованием того же универсального алгоритма, который принимает еще один параметр: function f(u,v). Разница между алгоритмом Prim и Dijkstra заключается в том, что вы используете f(u,v).

Ответ 8

На уровне кода другим отличием является API.

Вы инициализируете Prim с исходной вершиной s, т.е. Prim.new(s); s может быть любой вершиной, и независимо от s конечный результат, являющийся ребрами минимального остовного дерева (MST), одинаковый. Чтобы получить ребра MST, мы вызываем метод edges().

Вы инициализируете Dijkstra с исходной вершиной s, т.е. Dijkstra.new(s), что вы хотите получить кратчайший путь/расстояние до всех других вершин. Конечные результаты, которые являются кратчайшим путем/расстоянием от s до всех других вершин; различаются в зависимости от s. Чтобы получить кратчайшие пути/расстояния от s до любой вершины v, мы будем называть методы distanceTo(v) и pathTo(v) соответственно.

Ответ 9

Первое отличие состоит в том, что алгоритм Дейкстраса решает другую проблему, чем Kruskal и Prim. Dijkstra решает проблему кратчайшего пути (из указанного node), в то время как Kruskal и Prim находит минимальное себестоимость. Ниже приведена измененная форма описания, которое я написал на этой странице: Графические алгоритмы.

Для любого графа остовное дерево представляет собой набор ребер, достаточных для обеспечения ровно одного пути между каждой парой вершин. Это ограничение означает, что не может быть цепей, образованных выбранными ребрами.

Дерево минимальной стоимости - это та, которая имеет наименьший возможный общий вес (где вес представляет собой стоимость или расстояние). Там может быть более одного такого дерева, но Prim и Kruskal гарантированно найдут один из них.

Для указанной вершины (например, X) кратчайшее дерево путей является связующим деревом, так что путь от X до любой другой вершины как можно короче (т.е. имеет минимально возможный вес).

Прим и Дейкстра "вырастают" дерево из стартовой вершины. Другими словами, у них есть "локальный" фокус; на каждом шаге мы рассматриваем только те грани, которые смежны с ранее выбранными вершинами, выбирая самый дешевый вариант, который удовлетворяет наши потребности. Между тем, Kruskal является "глобальным" алгоритмом, что означает, что каждое ребро (жадно) выбрано из всего графика. (Фактически, Дейкстра может рассматриваться как имеющий некоторый глобальный аспект, как указано ниже.)

Чтобы найти дерево с минимальной стоимостью:

Kruskal (глобальный подход): на каждом шаге выберите самый дешевый доступный край в любом месте, который не нарушает цель создания остовного дерева. Prim (локальный подход): выберите начальную вершину. На каждом последующем шаге выберите самый дешевый доступный край, прикрепленный к любой ранее выбранной вершине, которая не нарушает цель создания остовного дерева. Чтобы найти кратчайшее связующее дерево:

Dijkstra: На каждом шаге выберите край, прикрепленный к любой ранее выбранной вершине (локальный аспект), которая делает как можно меньше общего расстояния от начальной вершины (глобального аспекта) и не нарушает цель создания остовное дерево.

Деревья минимальной стоимости и деревья кратчайшего пути легко путаются, как и алгоритмы Prim и Dijkstra, которые их решают. Оба алгоритма "растут" из начальной вершины, на каждом шаге выбирают ребро, которое соединяет вершину Y, которая находится в дереве, к вершине Z, которой нет. Однако, в то время как Prim выбирает самый дешевый такой край, Дейкстра выбирает ребро, которое приводит к кратчайшему пути от X до Z.

Простая иллюстрация помогает понять разницу между этими алгоритмами и деревьями, которые они производят. На приведенном ниже графике, начиная с вершины A, как Prim, так и Dijkstra начинаются с выбора края AB, а затем добавления края BD. Здесь два алгоритма расходятся: Prim завершает дерево, добавляя край DC, а Dijkstra добавляет AC или BC, потому что пути AC и ABC (оба с общим расстоянием 30) короче, чем путь ABDC (общее расстояние 31).

Ответ 10

Алгоритм Дейкстраса используется только для поиска кратчайшего пути.

В Минимальное связующее дерево (алгоритм Prim или Kruskal) вы получаете минимальные значения с минимальным значением края.

Например: - рассмотрите ситуацию, когда вы не создадите огромную сеть, для которой u будет требовать большое количество проводов, поэтому этот подсчет провода может быть выполнен с использованием Минимального связующего дерева (Prim или Kruskal алгоритм) (т.е. он даст вам минимальное количество проводов для создания огромного проводного сетевого соединения с минимальными затратами).

В то время как "алгоритм Дейкстры" будет использоваться для получения кратчайшего пути между двумя узлами при подключении любых узлов друг к другу.